diff --git a/.github/workflows/apk-qnn-asr.yaml b/.github/workflows/apk-qnn-asr.yaml
new file mode 100644
index 0000000000..4025e50b6d
--- /dev/null
+++ b/.github/workflows/apk-qnn-asr.yaml
@@ -0,0 +1,168 @@
+name: apk-qnn-asr
+
+on:
+ push:
+ branches:
+ - apk
+ - android-qnn-asr
+
+ workflow_dispatch:
+
+concurrency:
+ group: apk-qnn-asr-${{ github.ref }}
+ cancel-in-progress: true
+
+permissions:
+ contents: write
+
+env:
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
+
+jobs:
+ asr:
+ if: github.repository_owner == 'csukuangfj' || github.repository_owner == 'k2-fsa'
+ runs-on: ${{ matrix.os }}
+ name: ${{ matrix.index }}/${{ matrix.total }}
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [ubuntu-latest]
+ total: ["1"]
+ index: ["0"]
+
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - name: Update version
+ shell: bash
+ run: |
+ ./new-release.sh
+ git diff .
+
+ - uses: actions/setup-java@v4
+ with:
+ distribution: 'temurin'
+ java-version: '21'
+
+ - name: ccache
+ uses: hendrikmuhs/ccache-action@v1.2
+ with:
+ key: ${{ matrix.os }}-android-qnn-asr
+
+ - name: Display NDK HOME
+ shell: bash
+ run: |
+ echo "ANDROID_NDK_LATEST_HOME: ${ANDROID_NDK_LATEST_HOME}"
+ ls -lh ${ANDROID_NDK_LATEST_HOME}
+
+ - name: Install Python dependencies
+ shell: bash
+ run: |
+ python3 -m pip install --upgrade pip jinja2
+
+ - name: Setup build tool version variable
+ shell: bash
+ run: |
+ BUILD_TOOL_VERSION=$(ls /usr/local/lib/android/sdk/build-tools/ | tail -n 1)
+ echo "BUILD_TOOL_VERSION=$BUILD_TOOL_VERSION" >> $GITHUB_ENV
+ echo "Last build tool version is: $BUILD_TOOL_VERSION"
+
+ - name: Generate build script
+ shell: bash
+ run: |
+ cd scripts/apk
+
+ total=${{ matrix.total }}
+ index=${{ matrix.index }}
+
+ python3 ./generate-qnn-asr-apk-script.py --total $total --index $index
+
+ chmod +x build-apk-qnn-asr.sh
+ mv -v ./build-apk-qnn-asr.sh ../..
+
+ - uses: actions/upload-artifact@v4
+ with:
+ name: build-script-${{ matrix.total }}-${{ matrix.index }}
+ path: ./build-apk-qnn-asr.sh
+
+ - name: build APK
+ shell: bash
+ run: |
+ export CMAKE_CXX_COMPILER_LAUNCHER=ccache
+ export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
+ cmake --version
+
+ export ANDROID_NDK=$ANDROID_NDK_LATEST_HOME
+ ./build-apk-qnn-asr.sh
+
+ - name: Display APK
+ shell: bash
+ run: |
+ ls -lh ./apks/
+ du -h -d1 .
+
+ - uses: r0adkll/sign-android-release@v1
+ name: Sign app APK
+ with:
+ releaseDirectory: ./apks
+ signingKeyBase64: ${{ secrets.ANDROID_SIGNING_KEY }}
+ alias: ${{ secrets.ANDROID_SIGNING_KEY_ALIAS }}
+ keyStorePassword: ${{ secrets.ANDROID_SIGNING_KEY_STORE_PASSWORD }}
+ env:
+ BUILD_TOOLS_VERSION: ${{ env.BUILD_TOOL_VERSION }}
+
+ - name: Display APK after signing
+ shell: bash
+ run: |
+ ls -lh ./apks/
+ du -h -d1 .
+
+ - name: Rename APK after signing
+ shell: bash
+ run: |
+ cd apks
+ rm -fv signingKey.jks
+ rm -fv *.apk.idsig
+ rm -fv *-aligned.apk
+
+ all_apks=$(ls -1 *-signed.apk)
+ for apk in ${all_apks[@]}; do
+ n=$(echo $apk | sed -e s/-signed//)
+ mv -v $apk $n
+ done
+
+ cd ..
+
+ - name: Publish to huggingface
+ env:
+ HF_TOKEN: ${{ secrets.HF_TOKEN }}
+ uses: nick-fields/retry@v3
+ with:
+ max_attempts: 20
+ timeout_seconds: 200
+ shell: bash
+ command: |
+ git config --global user.email "csukuangfj@gmail.com"
+ git config --global user.name "Fangjun Kuang"
+
+ rm -rf huggingface
+ export GIT_LFS_SKIP_SMUDGE=1
+ export GIT_CLONE_PROTECTION_ACTIVE=false
+
+ SHERPA_ONNX_VERSION=$(grep "SHERPA_ONNX_VERSION" ./CMakeLists.txt | cut -d " " -f 2 | cut -d '"' -f 2)
+
+ git clone https://csukuangfj2:$HF_TOKEN@huggingface.co/csukuangfj2/sherpa-onnx-apk huggingface
+ cd huggingface
+ git fetch
+ git pull
+ git merge -m "merge remote" --ff origin main
+
+ d=qnn-asr/$SHERPA_ONNX_VERSION
+ mkdir -p $d
+ cp -v ../apks/*.apk $d/
+ git lfs track "*.apk"
+ git add .
+ git commit -m "add more qnn asr apks"
+ git push https://csukuangfj2:$HF_TOKEN@huggingface.co/csukuangfj2/sherpa-onnx-apk main
diff --git a/android/SherpaOnnx/app/src/main/AndroidManifest.xml b/android/SherpaOnnx/app/src/main/AndroidManifest.xml
index c0c79ddd3b..8fe6cb451f 100644
--- a/android/SherpaOnnx/app/src/main/AndroidManifest.xml
+++ b/android/SherpaOnnx/app/src/main/AndroidManifest.xml
@@ -14,6 +14,17 @@
android:supportsRtl="true"
android:theme="@style/Theme.SherpaOnnx"
tools:targetApi="31">
+
+
+
+ FileOutputStream(outFile).use { output: OutputStream ->
+ input.copyTo(output)
+ }
+ }
+ Log.i(TAG, "Copied $path to $targetRoot/$path")
+
+ return outFile.absolutePath
+}
+
+private fun copyAssetListToInternalStorage(paths: String, context: Context): String {
+ if (paths.isBlank()) return paths
+
+ return paths.split(",")
+ .map { it.trim() }
+ .filter { it.isNotEmpty() }
+ .map { copyAssetToInternalStorage(it, context) }
+ .joinToString(",")
+}
+
class MainActivity : AppCompatActivity() {
private val permissions: Array = arrayOf(Manifest.permission.RECORD_AUDIO)
@@ -232,8 +283,54 @@ class MainActivity : AppCompatActivity() {
config.hr = hr
}
+ var assetManager: AssetManager? = application.assets
+ if (config.modelConfig.provider == "qnn") {
+ Log.i(TAG, "nativelibdir: ${applicationInfo.nativeLibraryDir}")
+ OnlineRecognizer.prependAdspLibraryPath(applicationInfo.nativeLibraryDir)
+
+ val transducer = config.modelConfig.transducer
+ val qnnConfig = transducer.qnnConfig
+
+ if (qnnConfig.backendLib.isEmpty()) {
+ throw IllegalArgumentException("You should provide libQnnHtp.so for qnn")
+ }
+
+ config.modelConfig.tokens =
+ copyAssetToInternalStorage(config.modelConfig.tokens, this)
+
+ if (transducer.encoder.isNotEmpty()) {
+ transducer.encoder =
+ copyAssetToInternalStorage(transducer.encoder, this)
+ }
+
+ if (transducer.decoder.isNotEmpty()) {
+ transducer.decoder =
+ copyAssetToInternalStorage(transducer.decoder, this)
+ }
+
+ if (transducer.joiner.isNotEmpty()) {
+ transducer.joiner =
+ copyAssetToInternalStorage(transducer.joiner, this)
+ }
+
+ if (qnnConfig.contextBinary.isNotEmpty()) {
+ qnnConfig.contextBinary =
+ copyAssetListToInternalStorage(qnnConfig.contextBinary, this)
+ }
+
+ if (config.hr.lexicon.isNotEmpty()) {
+ config.hr.lexicon = copyAssetToInternalStorage(config.hr.lexicon, this)
+ }
+
+ if (config.hr.ruleFsts.isNotEmpty()) {
+ config.hr.ruleFsts = copyAssetToInternalStorage(config.hr.ruleFsts, this)
+ }
+
+ assetManager = null
+ }
+
recognizer = OnlineRecognizer(
- assetManager = application.assets,
+ assetManager = assetManager,
config = config,
)
}
diff --git a/android/SherpaOnnx/app/src/main/java/com/k2fsa/sherpa/onnx/QnnConfig.kt b/android/SherpaOnnx/app/src/main/java/com/k2fsa/sherpa/onnx/QnnConfig.kt
new file mode 120000
index 0000000000..cfd1fc18fa
--- /dev/null
+++ b/android/SherpaOnnx/app/src/main/java/com/k2fsa/sherpa/onnx/QnnConfig.kt
@@ -0,0 +1 @@
+../../../../../../../../../../sherpa-onnx/kotlin-api/QnnConfig.kt
\ No newline at end of file
diff --git a/scripts/apk/build-apk-qnn-asr.sh.in b/scripts/apk/build-apk-qnn-asr.sh.in
new file mode 100644
index 0000000000..9f739865d2
--- /dev/null
+++ b/scripts/apk/build-apk-qnn-asr.sh.in
@@ -0,0 +1,100 @@
+#!/usr/bin/env bash
+#
+# Auto generated! Please DO NOT EDIT!
+
+# Please set the environment variable ANDROID_NDK
+# before running this script
+
+# Inside the $ANDROID_NDK directory, you can find a binary ndk-build
+# and some other files like the file "build/cmake/android.toolchain.cmake"
+
+set -ex
+
+log() {
+ # This function is from espnet
+ local fname=${BASH_SOURCE[1]##*/}
+ echo -e "$(date '+%Y-%m-%d %H:%M:%S') (${fname}:${BASH_LINENO[0]}:${FUNCNAME[1]}) $*"
+}
+
+SHERPA_ONNX_VERSION=$(grep "SHERPA_ONNX_VERSION" ./CMakeLists.txt | cut -d " " -f 2 | cut -d '"' -f 2)
+
+log "Building streaming ASR APK + QNN for sherpa-onnx v${SHERPA_ONNX_VERSION}"
+
+export SHERPA_ONNX_ENABLE_TTS=OFF
+export SHERPA_ONNX_ENABLE_SPEAKER_DIARIZATION=OFF
+export SHERPA_ONNX_ENABLE_QNN=ON
+export SHERPA_ONNX_ENABLE_BINARY=OFF
+
+log "Download qnn header files"
+
+curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models-qnn/qnn-include-2.40.0.251030.tar.bz2
+tar xf qnn-include-2.40.0.251030.tar.bz2
+rm qnn-include-2.40.0.251030.tar.bz2
+ls -lh qnn-include-2.40.0.251030
+
+export QNN_SDK_ROOT=$PWD/qnn-include-2.40.0.251030
+
+log "====================arm64-v8a================="
+./build-android-arm64-v8a.sh
+
+cp -v ./build-android-arm64-v8a/install/lib/*.so ./android/SherpaOnnx/app/src/main/jniLibs/arm64-v8a/
+
+log "=======Download qnn libs============"
+curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models-qnn/qnn-libs-2.40.0.251030.tar.bz2
+tar xvf qnn-libs-2.40.0.251030.tar.bz2
+rm qnn-libs-2.40.0.251030.tar.bz2
+cp -v qnn-libs-2.40.0.251030/*.so ./android/SherpaOnnx/app/src/main/jniLibs/arm64-v8a/
+
+rm -rf qnn-libs-2.40.0.251030
+
+ls -lh ./android/SherpaOnnx/app/src/main/jniLibs/arm64-v8a/
+
+mkdir -p apks
+
+{% for model in model_list %}
+pushd ./android/SherpaOnnx/app/src/main/assets/
+model_name={{ model.model_name }}
+type={{ model.idx }}
+lang={{ model.lang }}
+short_name={{ model.short_name }}
+
+curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models-qnn/${model_name}.tar.bz2
+tar xvf ${model_name}.tar.bz2
+
+{{ model.cmd }}
+
+rm -rf *.tar.bz2
+ls -lh $model_name
+
+popd
+# Now we are at the project root directory
+
+git checkout .
+pushd android/SherpaOnnx/app/src/main/java/com/k2fsa/sherpa/onnx
+sed -i.bak s/"type = 0/type = $type/" ./MainActivity.kt
+
+git diff
+popd
+
+for arch in arm64-v8a; do
+ log "------------------------------------------------------------"
+ log "build ASR apk for $arch"
+ log "------------------------------------------------------------"
+
+ pushd ./android/SherpaOnnx
+ sed -i.bak s/2048/9012/g ./gradle.properties
+ git diff ./gradle.properties
+ ./gradlew assembleRelease
+ popd
+
+ mv android/SherpaOnnx/app/build/outputs/apk/release/app-release-unsigned.apk ./apks/sherpa-onnx-${SHERPA_ONNX_VERSION}-qnn-$arch-asr-$lang-$short_name.apk
+ ls -lh apks
+done
+
+rm -rf ./android/SherpaOnnx/app/src/main/assets/$model_name
+{% endfor %}
+
+rm -v ./android/SherpaOnnx/app/src/main/jniLibs/arm64-v8a/*.so
+git checkout .
+
+ls -lh apks/
diff --git a/scripts/apk/generate-qnn-asr-apk-script.py b/scripts/apk/generate-qnn-asr-apk-script.py
new file mode 100644
index 0000000000..937480ac0a
--- /dev/null
+++ b/scripts/apk/generate-qnn-asr-apk-script.py
@@ -0,0 +1,100 @@
+#!/usr/bin/env python3
+
+import argparse
+from dataclasses import dataclass
+from pathlib import Path
+
+import jinja2
+
+
+def get_args():
+ parser = argparse.ArgumentParser()
+ parser.add_argument(
+ "--total",
+ type=int,
+ default=1,
+ help="Number of runners",
+ )
+ parser.add_argument(
+ "--index",
+ type=int,
+ default=0,
+ help="Index of the current runner",
+ )
+ return parser.parse_args()
+
+
+@dataclass
+class Model:
+ model_name: str
+ idx: int
+ lang: str
+ short_name: str = ""
+ cmd: str = ""
+
+
+def get_models():
+ return [
+ Model(
+ model_name="sherpa-onnx-qnn-streaming-zipformer-transducer-zh-en-2023-03-20-chunk-size-32-android-aarch64",
+ idx=9025,
+ lang="zh_en",
+ short_name="streaming_zipformer_transducer_2023_03_20_chunk_32",
+ cmd="""
+ pushd $model_name
+
+ rm -rfv test_wavs
+
+ ls -lh
+
+ popd
+ """,
+ ),
+ ]
+
+
+def main():
+ args = get_args()
+ index = args.index
+ total = args.total
+ assert 0 <= index < total, (index, total)
+
+ all_model_list = get_models()
+ num_models = len(all_model_list)
+
+ num_per_runner = num_models // total
+ if num_per_runner <= 0:
+ raise ValueError(f"num_models: {num_models}, num_runners: {total}")
+
+ start = index * num_per_runner
+ end = start + num_per_runner
+ remaining = num_models - args.total * num_per_runner
+
+ print(f"{index}/{total}: {start}-{end}/{num_models}")
+
+ d = {"model_list": all_model_list[start:end]}
+ if index < remaining:
+ s = args.total * num_per_runner + index
+ d["model_list"].append(all_model_list[s])
+ print(f"{s}/{num_models}")
+
+ filename_list = [
+ "./build-apk-qnn-asr.sh",
+ ]
+ for filename in filename_list:
+ environment = jinja2.Environment()
+ if not Path(f"{filename}.in").is_file():
+ print(f"skip {filename}")
+ continue
+
+ with open(f"{filename}.in") as f:
+ s = f.read()
+ template = environment.from_string(s)
+
+ s = template.render(**d)
+ with open(filename, "w") as f:
+ print(s, file=f)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/sherpa-onnx/csrc/qnn/utils.cc b/sherpa-onnx/csrc/qnn/utils.cc
index 48a41150db..0158ee8bc6 100644
--- a/sherpa-onnx/csrc/qnn/utils.cc
+++ b/sherpa-onnx/csrc/qnn/utils.cc
@@ -49,8 +49,9 @@ std::string QuantizationEncodingToString(Qnn_QuantizationEncoding_t q) {
SHERPA_ONNX_TO_STRING(QNN_QUANTIZATION_ENCODING_BLOCKWISE_EXPANSION);
SHERPA_ONNX_TO_STRING(QNN_QUANTIZATION_ENCODING_VECTOR);
SHERPA_ONNX_TO_STRING(QNN_QUANTIZATION_ENCODING_UNDEFINED);
+ default:
+ return "Unknown";
}
- return "Unknown";
}
std::string TensorDataTypeToString(Qnn_DataType_t t) {
diff --git a/sherpa-onnx/java-api/src/main/java/com/k2fsa/sherpa/onnx/OnlineTransducerModelConfig.java b/sherpa-onnx/java-api/src/main/java/com/k2fsa/sherpa/onnx/OnlineTransducerModelConfig.java
index 29ba0f87e8..6649b2c31e 100644
--- a/sherpa-onnx/java-api/src/main/java/com/k2fsa/sherpa/onnx/OnlineTransducerModelConfig.java
+++ b/sherpa-onnx/java-api/src/main/java/com/k2fsa/sherpa/onnx/OnlineTransducerModelConfig.java
@@ -7,11 +7,13 @@ public class OnlineTransducerModelConfig {
private final String encoder;
private final String decoder;
private final String joiner;
+ private final QnnConfig qnnConfig;
private OnlineTransducerModelConfig(Builder builder) {
this.encoder = builder.encoder;
this.decoder = builder.decoder;
this.joiner = builder.joiner;
+ this.qnnConfig = builder.qnnConfig;
}
public static Builder builder() {
@@ -30,10 +32,15 @@ public String getJoiner() {
return joiner;
}
+ public QnnConfig getQnnConfig() {
+ return qnnConfig;
+ }
+
public static class Builder {
private String encoder = "";
private String decoder = "";
private String joiner = "";
+ private QnnConfig qnnConfig = QnnConfig.builder().build();
public OnlineTransducerModelConfig build() {
return new OnlineTransducerModelConfig(this);
@@ -53,5 +60,10 @@ public Builder setJoiner(String joiner) {
this.joiner = joiner;
return this;
}
+
+ public Builder setQnnConfig(QnnConfig qnnConfig) {
+ this.qnnConfig = qnnConfig;
+ return this;
+ }
}
}
diff --git a/sherpa-onnx/jni/online-recognizer.cc b/sherpa-onnx/jni/online-recognizer.cc
index 9e9cddb61a..40f7ac10b1 100644
--- a/sherpa-onnx/jni/online-recognizer.cc
+++ b/sherpa-onnx/jni/online-recognizer.cc
@@ -31,6 +31,20 @@ OnlineModelConfig GetOnlineModelConfig(JNIEnv *env, jclass model_config_cls,
SHERPA_ONNX_JNI_READ_STRING(ans.transducer.joiner, joiner,
transducer_config_cls, transducer_config);
+ fid = env->GetFieldID(transducer_config_cls, "qnnConfig",
+ "Lcom/k2fsa/sherpa/onnx/QnnConfig;");
+ jobject qnn_config = env->GetObjectField(transducer_config, fid);
+ jclass qnn_config_cls = env->GetObjectClass(qnn_config);
+
+ SHERPA_ONNX_JNI_READ_STRING(ans.transducer.qnn_config.backend_lib, backendLib,
+ qnn_config_cls, qnn_config);
+
+ SHERPA_ONNX_JNI_READ_STRING(ans.transducer.qnn_config.context_binary,
+ contextBinary, qnn_config_cls, qnn_config);
+
+ SHERPA_ONNX_JNI_READ_STRING(ans.transducer.qnn_config.system_lib, systemLib,
+ qnn_config_cls, qnn_config);
+
fid = env->GetFieldID(model_config_cls, "paraformer",
"Lcom/k2fsa/sherpa/onnx/OnlineParaformerModelConfig;");
jobject paraformer_config = env->GetObjectField(model_config, fid);
@@ -300,6 +314,16 @@ JNIEXPORT jlong JNICALL Java_com_k2fsa_sherpa_onnx_OnlineRecognizer_newFromFile(
return (jlong)recognizer;
}
+SHERPA_ONNX_EXTERN_C
+JNIEXPORT void JNICALL
+Java_com_k2fsa_sherpa_onnx_OnlineRecognizer_prependAdspLibraryPath(
+ JNIEnv *env, jclass /*cls*/, jstring new_path) {
+ const char *p = env->GetStringUTFChars(new_path, nullptr);
+ sherpa_onnx::PrependAdspLibraryPath(p);
+
+ env->ReleaseStringUTFChars(new_path, p);
+}
+
SHERPA_ONNX_EXTERN_C
JNIEXPORT void JNICALL Java_com_k2fsa_sherpa_onnx_OnlineRecognizer_delete(
JNIEnv * /*env*/, jobject /*obj*/, jlong ptr) {
diff --git a/sherpa-onnx/jni/sherpa-onnx-symbols.exp b/sherpa-onnx/jni/sherpa-onnx-symbols.exp
index 38d6dd5251..bb3ef6c313 100644
--- a/sherpa-onnx/jni/sherpa-onnx-symbols.exp
+++ b/sherpa-onnx/jni/sherpa-onnx-symbols.exp
@@ -65,6 +65,7 @@ _Java_com_k2fsa_sherpa_onnx_OnlineRecognizer_isEndpoint
_Java_com_k2fsa_sherpa_onnx_OnlineRecognizer_isReady
_Java_com_k2fsa_sherpa_onnx_OnlineRecognizer_newFromAsset
_Java_com_k2fsa_sherpa_onnx_OnlineRecognizer_newFromFile
+_Java_com_k2fsa_sherpa_onnx_OnlineRecognizer_prependAdspLibraryPath
_Java_com_k2fsa_sherpa_onnx_OnlineRecognizer_reset
_Java_com_k2fsa_sherpa_onnx_OnlineSpeechDenoiser_delete
_Java_com_k2fsa_sherpa_onnx_OnlineSpeechDenoiser_flush
diff --git a/sherpa-onnx/kotlin-api/OnlineRecognizer.kt b/sherpa-onnx/kotlin-api/OnlineRecognizer.kt
index c0a1873e08..8bb9ede7da 100644
--- a/sherpa-onnx/kotlin-api/OnlineRecognizer.kt
+++ b/sherpa-onnx/kotlin-api/OnlineRecognizer.kt
@@ -18,6 +18,7 @@ data class OnlineTransducerModelConfig(
var encoder: String = "",
var decoder: String = "",
var joiner: String = "",
+ var qnnConfig: QnnConfig = QnnConfig(),
)
data class OnlineParaformerModelConfig(
@@ -145,6 +146,9 @@ class OnlineRecognizer(
init {
System.loadLibrary("sherpa-onnx-jni")
}
+
+ @JvmStatic
+ external fun prependAdspLibraryPath(newPath: String) // for qnn
}
}
@@ -187,6 +191,14 @@ by following the code)
https://huggingface.co/csukuangfj/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20
encoder int8, decoder/joiner float32
+9025 - sherpa-onnx-qnn-streaming-zipformer-transducer-zh-en-2023-03-20-chunk-size-32-android-aarch64
+ QNN model libs with writable binary context files
+ libencoder.so, libdecoder.so, libjoiner.so
+
+9026 - sherpa-onnx-qnn-SM8850-binary-streaming-zipformer-transducer-zh-en-2023-03-20-chunk-size-32
+ QNN binary context files only
+ encoder.bin, decoder.bin, joiner.bin
+
*/
fun getModelConfig(type: Int): OnlineModelConfig? {
when (type) {
@@ -601,6 +613,46 @@ fun getModelConfig(type: Int): OnlineModelConfig? {
)
}
+ 9025 -> {
+ val modelDir =
+ "sherpa-onnx-qnn-streaming-zipformer-transducer-zh-en-2023-03-20-chunk-size-32-android-aarch64"
+ return OnlineModelConfig(
+ transducer = OnlineTransducerModelConfig(
+ encoder = "$modelDir/libencoder.so",
+ decoder = "$modelDir/libdecoder.so",
+ joiner = "$modelDir/libjoiner.so",
+ qnnConfig = QnnConfig(
+ backendLib = "libQnnHtp.so",
+ systemLib = "libQnnSystem.so",
+ // The following three *.bin files are generated during the first run
+ // and are used to replace the corresponding *.so files in later runs
+ contextBinary = "$modelDir/encoder.bin,$modelDir/decoder.bin,$modelDir/joiner.bin",
+ ),
+ ),
+ tokens = "$modelDir/tokens.txt",
+ provider = "qnn",
+ modelType = "zipformer",
+ )
+ }
+
+ 9026 -> {
+ // for Xiaomi 17 Pro
+ val modelDir =
+ "sherpa-onnx-qnn-SM8850-binary-streaming-zipformer-transducer-zh-en-2023-03-20-chunk-size-32"
+ return OnlineModelConfig(
+ transducer = OnlineTransducerModelConfig(
+ qnnConfig = QnnConfig(
+ backendLib = "libQnnHtp.so",
+ systemLib = "libQnnSystem.so",
+ contextBinary = "$modelDir/encoder.bin,$modelDir/decoder.bin,$modelDir/joiner.bin",
+ ),
+ ),
+ tokens = "$modelDir/tokens.txt",
+ provider = "qnn",
+ modelType = "zipformer",
+ )
+ }
+
1000 -> {
val modelDir = "sherpa-onnx-rk3588-streaming-zipformer-bilingual-zh-en-2023-02-20"
return OnlineModelConfig(
@@ -666,4 +718,3 @@ fun getEndpointConfig(): EndpointConfig {
rule3 = EndpointRule(false, 0.0f, 20.0f)
)
}
-