安卓版本,语音识别SenseVoice模型,初始化时报错

by ADMIN 29 views

问题描述

在使用安卓版本的语音识别SenseVoice模型时,初始化时报错。错误信息如下:

2025-05-23 09:17:16.179 7906-8069 va.hellocordova io.cordova.hellocordova A java_vm_ext.cc:594] JNI DETECTED ERROR IN APPLICATION: attempt to access field java.lang.String com.k2fsa.sherpa.onnx.OfflineNemoEncDecCtcModelConfig.model from an object argument of type com.k2fsa.sherpa.onnx.OfflineDolphinModelConfig: 0xb1 java_vm_ext.cc:594] in call to GetObjectField java_vm_ext.cc:594] from long com.k2fsa.sherpa.onnx.OfflineRecognizer.newFromAsset(android.content.res.AssetManager, com.k2fsa.sherpa.onnx.OfflineRecognizerConfig)

初始化代码

初始化的代码参考了v1.12.0版本的SherpaOnnxSimulateStreamingAsr项目的文件:

https://github.com/k2-fsa/sherpa-onnx/blob/v1.12.0/android/SherpaOnnxSimulateStreamingAsr/app/src/main/java/com/k2fsa/sherpa/onnx/simulate/streaming/asr/SimulateStreamingAsr.kt

具体代码如下:

private OfflineRecognizer recognizer;
private Vad vad;

private boolean initModel() {
    try {
        // 创建并初始化离线识别器实例
        if (recognizer == null) {
            // 设置ASR模型类型为15
            // 可用模型列表参见:https://k2-fsa.github.io/sherpa/onnx/pretrained_models/index.html
            int asrModelType = 15;

            // 初始化ASR规则FST为空
            String asrRuleFsts = null;

            // 配置同音字替换功能
            boolean useHr = false;
            HomophoneReplacerConfig hr = new HomophoneReplacerConfig(
                    // 仅在useHr为true时使用
                    // 需要从以下地址下载三个文件:
                    // https://github.com/k2-fsa/sherpa-onnx/releases/tag/hr-files
                    "dict",      // 字典目录
                    "lexicon.txt", // 词典文件
                    "replace.fst"  // 替换规则文件
            );

            // 创建离线识别器配置
            OfflineRecognizerConfig config = new OfflineRecognizerConfig(
                    getFeatureConfig(sampleRateInHz, 80),
                    getOfflineModelConfig(asrModelType),
                    hr,
                    "greedy_search",
                    4,
                    "",
                    1.5f,
                    "",
                    "",
                    0.0f
            );

            // 如果线程数为1,设置为2以提高性能
            if (config.getModelConfig().getNumThreads() == 1) {
                config.getModelConfig().setNumThreads(2);
            }

            // 如果存在ASR规则FST,添加到配置中
            if (rRuleFsts != null) {
                config.setRuleFsts(asrRuleFsts);
            }

            // 如果启用同音字替换功能
            if (useHr) {
                // 检查字典目录路径
                if (!hr.getDictDir().isEmpty() && hr.getDictDir().charAt(0) != '/') {
                    // 从assets目录复制到应用目录
                    String newDir = copyDataDir(hr.getDictDir());
                    hr.setDictDir(newDir + "/" + hr.getDictDir());
                }
                config.setHr(hr);
            }

            // 创建并初始化离线识别器实例
            recognizer = new OfflineRecognizer(
                    mContext.getAssets(),
                    config
            );
        }

        // 创建并初始化VAD实例
        if (vad == null) {
            VadModelConfig vadConfig = getVadModelConfig(0);
            vad = new Vad(
                    mContext.getAssets(),
                    vadConfig
            );
        }

        return true;
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
}

OfflineRecognizer.kt相关代码

Image

模型及相关文件引入情况

Image

模型文件下载地址

https://github.com/k2-fsa/sherpa-onnx/releases/tag/asr-models

Image

Image

解决方案

根据错误信息,问题可能出在 OfflineRecognizerConfiggetModelConfig() 方法中。该方法返回一个 OfflineModelConfig 对象,用于配置离线识别器模型。然而,在 OfflineRecognizerConfig 的构造函数中,传入的 OfflineModelConfig 对象可能是错误的类型。

为了解决这个问题,我们需要检查 OfflineModelConfig 对象的类型是否正确。我们可以通过以下方式检查:

if (config.getModelConfig() is OfflineNemoEncDecCtcModelConfig) {
    // 使用 OfflineNemoEncDecCtcModelConfig 类型的配置
} else if (config.getModelConfig() is OfflineDolphinModelConfig) {
    // 使用 OfflineDolphinModelConfig 类型的配置
} else {
    // 使用其他类型的配置
}

如果 OfflineModelConfig 对象的类型不正确,我们需要修改 OfflineRecognizerConfig 的构造函数,传入正确的类型的 OfflineModelConfig 对象。

优化建议

  1. 检查 OfflineModelConfig 对象的类型是否正确。
  2. 修改 OfflineRecognizerConfig 的构造函数,传入正确的类型的 OfflineModelConfig象。
  3. 使用 OfflineNemoEncDecCtcModelConfig 类型的配置。
  4. 使用 OfflineDolphinModelConfig 类型的配置。
  5. 使用其他类型的配置。

Q1:什么是SenseVoice模型?

A1:SenseVoice模型是一种基于深度学习的语音识别模型,用于识别语音输入并转换为文本。

Q2:SenseVoice模型的初始化时报错,如何解决?

A2:SenseVoice模型的初始化时报错可能是由于 OfflineModelConfig 对象的类型不正确。我们需要检查 OfflineModelConfig 对象的类型是否正确,并修改 OfflineRecognizerConfig 的构造函数,传入正确的类型的 OfflineModelConfig 对象。

Q3:如何检查 OfflineModelConfig 对象的类型?

A3:我们可以通过以下方式检查 OfflineModelConfig 对象的类型:

if (config.getModelConfig() is OfflineNemoEncDecCtcModelConfig) {
    // 使用 OfflineNemoEncDecCtcModelConfig 类型的配置
} else if (config.getModelConfig() is OfflineDolphinModelConfig) {
    // 使用 OfflineDolphinModelConfig 类型的配置
} else {
    // 使用其他类型的配置
}

Q4:如何修改 OfflineRecognizerConfig 的构造函数?

A4:我们需要修改 OfflineRecognizerConfig 的构造函数,传入正确的类型的 OfflineModelConfig 对象。例如:

OfflineRecognizerConfig config = new OfflineRecognizerConfig(
        getFeatureConfig(sampleRateInHz, 80),
        new OfflineNemoEncDecCtcModelConfig(), // 使用 OfflineNemoEncDecCtcModelConfig 类型的配置
        hr,
        "greedy_search",
        4,
        "",
        1.5f,
        "",
        "",
        0.0f
);

Q5:如何使用 OfflineNemoEncDecCtcModelConfig 类型的配置?

A5:我们可以使用 OfflineNemoEncDecCtcModelConfig 类型的配置,例如:

OfflineNemoEncDecCtcModelConfig modelConfig = new OfflineNemoEncDecCtcModelConfig();
modelConfig.setNumThreads(2);
modelConfig.setBatchSize(32);
// ...
OfflineRecognizerConfig config = new OfflineRecognizerConfig(
        getFeatureConfig(sampleRateInHz, 80),
        modelConfig,
        hr,
        "greedy_search",
        4,
        "",
        1.5f,
        "",
        "",
        0.0f
);

Q6:如何使用 OfflineDolphinModelConfig 类型的配置?

A6:我们可以使用 OfflineDolphinModelConfig 类型的配置,例如:

OfflineDolphinModelConfig modelConfig = new OfflineDolphinModelConfig();
modelConfig.setNumThreads(2);
modelConfig.setBatchSize(32);
// ...
OfflineRecognizerConfig config = new OfflineRecognizerConfig(
        getFeatureConfig(sampleRateInHz, 80),
        modelConfig,
        hr,
        "greedy_search",
        4,
        "",
 1.5f,
        "",
        "",
        0.0f
);

Q7:如何使用其他类型的配置?

A7:我们可以使用其他类型的配置,例如:

OfflineModelConfig modelConfig = new OfflineModelConfig();
modelConfig.setNumThreads(2);
modelConfig.setBatchSize(32);
// ...
OfflineRecognizerConfig config = new OfflineRecognizerConfig(
        getFeatureConfig(sampleRateInHz, 80),
        modelConfig,
        hr,
        "greedy_search",
        4,
        "",
        1.5f,
        "",
        "",
        0.0f
);

通过以上 Q&A,我们可以解决 安卓版本,语音识别SenseVoice模型,初始化时报错 的问题。