# 语音识别

# 简介

语音识别(Automatic Speech Recognition, ASR)是将人类的语音信号自动转换为对应文字的技术,它使计算机能够“听懂”人说的话,是人机语音交互的核心技术,广泛应用于智能助手、语音输入、客服系统等场景。

# 准备工作

# JDK 版本要求

11及以上

# Maven引入

在项目的 pom.xml 中添加以下依赖以及平台依赖库。如需引入全部功能,请使用 smartjavaai-all(依然需要引入FFmpeg 依赖) 模块。

# 基础依赖

<dependency>
    <groupId>cn.smartjavaai</groupId>
    <artifactId>smartjavaai-speech</artifactId>
    <version>1.0.23</version>
</dependency>

# FFmpeg 依赖

语音模块依赖 FFmpeg,可引入 jave-all-deps 或按平台引入对应原生库(推荐按平台选择,减小包体积)。

<dependency>
    <groupId>ws.schild</groupId>
    <artifactId>jave-all-deps</artifactId>
    <version>3.5.0</version>
</dependency>

# 按平台选择(推荐):

<!-- windows平台 (保留对应平台的配置,可以减小包大小)-->
<dependency>
    <groupId>ws.schild</groupId>
    <artifactId>jave-nativebin-win64</artifactId>
    <version>3.5.0</version>
</dependency>

<!-- linux x86 平台 (保留对应平台的配置,可以减小包大小)-->
<dependency>
    <groupId>ws.schild</groupId>
    <artifactId>jave-nativebin-linux64</artifactId>
    <version>3.5.0</version>
</dependency>

<!-- linux arm64 平台 (保留对应平台的配置,可以减小包大小)-->
<dependency>
    <groupId>ws.schild</groupId>
    <artifactId>jave-nativebin-linux-arm64</artifactId>
    <version>3.5.0</version>
</dependency>

<!-- linux arm32 平台 (保留对应平台的配置,可以减小包大小)-->
<dependency>
    <groupId>ws.schild</groupId>
    <artifactId>jave-nativebin-linux-arm32</artifactId>
    <version>3.5.0</version>
</dependency>


<!-- macOS osx64 平台  (保留对应平台的配置,可以减小包大小)-->
<dependency>
    <groupId>ws.schild</groupId>
    <artifactId>jave-nativebin-osx64</artifactId>
    <version>3.5.0</version>
</dependency>

<!-- macOS M系列 平台  (保留对应平台的配置,可以减小包大小)-->
<dependency>
    <groupId>ws.schild</groupId>
    <artifactId>jave-nativebin-osxm1</artifactId>
    <version>3.5.0</version>
</dependency>

# 模型简介及下载

这里仅介绍模型的开源项目,每个开源项目通常包含多个具体模型,本文不逐一列出。

模型下载-百度网盘地址 (opens new window)

网盘仅包含部分常用模型,如需获取更多模型,请点击下方链接自行下载。

模型名称 模型简介 模型官网 下载地址
Whisper OpenAI 开源的通用语音识别(ASR)模型,支持多语言转写和翻译,具有较高的识别精度,尤其在嘈杂环境中表现良好,适合离线和批量音频处理。 Github (opens new window) 官方下载 (opens new window)
Vosk 一个轻量级离线语音识别工具包,支持多种语言和平台(包括移动端与嵌入式设备),可在低资源环境中运行,适合实时语音识别场景。 Github (opens new window) 官方下载 (opens new window)

# 获取语音识别模型

AsrModelConfig config = new AsrModelConfig();
config.setModelEnum(AsrModelEnum.WHISPER);
config.setModelPath("/model/speech/ggml-medium.bin");
return SpeechRecognizerFactory.getInstance().getModel(config);

AsrModelConfig参数说明

字段名称 字段类型 必选 默认值 说明
modelEnum TranslationModeEnum 语音识别模型枚举
modelPath String 模型路径,需手动指定
libPath Path 依赖库目录

注意事项:

1、每个模型枚举对应一个语音识别开源项目,每个开源项目包含多个具体模型,使用时需通过 modelPath 指定模型路径 modelPath

2、Whisper 模型分为英文模型和多语言模型,模型名称中带en的为英文模型,仅支持英语,其他为多语言模型,支持100种语言

3、Whisper 依规格大小排序:ggml-tiny → ggml-base → ggml-small → ggml-medium → ggml-large-v1 → ggml-large-v2 → ggml-large-v3 ,模型越大,识别精度越高,但识别速度越慢

4、Vosk 模型都为单语言模型,仅能识别单一语言

5、可通过设置 libPath 自定义依赖库目录,使用前需将所需依赖库放入该目录。

6、macOS M 系列芯片注意事项:必须指定libPath,并将依赖库放入到该目录下,依赖库下载链接:https://pan.baidu.com/s/1wMSBHpBBDJu3f32wNd8XYg?pwd=1234 提取码: 1234

# 语音识别方法

R<AsrResult> recognize(String audioPath, RecParams params)
R<AsrResult> recognize(byte[] audioData, RecParams params)
R<AsrResult> recognize(InputStream audioStream, RecParams params)

使用默认参数识别

R<AsrResult> recognize(String audioPath)
R<AsrResult> recognize(byte[] audioData)
R<AsrResult> recognize(InputStream audioStream)

WhisperVosk 使用的识别参数不一样

Whisper 识别参数 WhisperParams 字段如下:

字段名称 字段类型 必选 默认值 说明
language Language Language.ZH(中文) 语言,需要和AsrModelConfig中modelPath模型支持的语言一致
params WhisperFullParams whisper-jni内置参数

WhisperFullParams参数如下:

字段名称 字段类型 默认值 说明
language String zh 语言,需要和AsrModelConfig中modelPath模型支持的语言一致
nThreads int 0 线程数,设为 0 表示使用最大核心数。
nMaxTextCtx int 0 解码器使用的历史文本作为提示的最大 token 数。
offsetMs int 0 解码起始偏移(毫秒)
durationMs int 0 解码持续时长(毫秒),超过此长度的音频将被截断
translate boolean false 是否翻译为英文,不支持直接翻译为其他语言
initialPrompt String 0 初始提示,用于提供上下文或样例,帮助模型更准确地理解语音内容
noContext boolean true 禁用上下文链接,不使用前一段解码结果作为上下文
singleSegment boolean false 是否强制仅输出一个段落(适用于短语音)
printSpecial boolean false 是否打印特殊标记
printRealtime boolean false 是否直接从 whisper.cpp 中打印结果(不推荐,建议使用回调方式替代)
suppressNonSpeechTokens boolean false 抑制非语音token输出
grammar String NULL 限定词汇表

更多参数请查看官网 (opens new window)

Vosk 识别参数 VoskParams 字段如下:

字段名称 字段类型 必选 默认值 说明
language Language Language.ZH(中文) 语言,需要和AsrModelConfig中modelPath模型支持的语言一致
grammar String NULL 限定词汇表

识别结果AsrResult字段说明:

  • 返回并非json格式,仅用于字段讲解
  • text: 识别完整结果
  • segments: 识别结果分段
  • segments.text: 识别分段结果
  • segments.startTime: 识别分段结果开始时间(ms)
  • segments.endTime: 识别分段结果结束时间(ms)
{
  "text": "smart java AI 是专为 java 开发者打造的一个功能丰富,开箱即用的 java AI 算法工具包。\n致力于帮助 java 开发者零门槛使用各种 AI 算法模型,开发者无需深入了解底层实现,\n",
  "segments": [
    {
      "text": "smart java AI 是专为 java 开发者打造的一个功能丰富,开箱即用的 java AI 算法工具包。",
      "startTime": 0,
      "endTime": 8000
    },
    {
      "text": "致力于帮助 java 开发者零门槛使用各种 AI 算法模型,开发者无需深入了解底层实现,",
      "startTime": 8000,
      "endTime": 15940
    }
  ]
}

# Whisper高级用法

# 使用Grammar语法规则

示例代码如下(完整示例请参见 example (opens new window)):

  • WhisperRecognizer 继承自 SpeechRecognizer
  • SpeechRecognizer 强制类型转换为 WhisperRecognizer 后,可解锁更多扩展方法。
  • grammar语法规则需自行查阅相关资料并学习使用。
public void testWhisperWithGrammar() {
    try {
        WhisperRecognizer whisperRecognizer = (WhisperRecognizer)getWhisperRecognizer();
        //语法规则
        String grammarText = "root ::= \" And so, my fellow American, ask not what your country can do for you, ask what you can do for your country.\"";
        try (WhisperGrammar grammar = whisperRecognizer.parseGrammar(grammarText)){
            WhisperParams params = new WhisperParams();
            WhisperFullParams fullParams = new WhisperFullParams(WhisperSamplingStrategy.BEAN_SEARCH);
            //语言:英文
            fullParams.language = Language.EN.getCode();
            fullParams.grammar = grammar;
            params.setParams(fullParams);
            //建议上传 WAV 格式音频。其他格式将自动转换为 WAV,可能影响处理速度
            R<AsrResult> result = whisperRecognizer.recognize("src/main/resources/jfk_en.wav", params);
            if (result.isSuccess()){
                log.info("识别成功:{}", JsonUtils.toJson(result.getData()));
            }else{
                log.info("识别失败:{}", result.getMessage());
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
}

注意事项:

1、上述代码仅为示例,需根据实际业务场景进行适当修改。

# Vosk高级用法

# 使用Grammar语法规则

示例代码如下(完整代码在example中):

  • grammar语法规则需自行查阅相关资料并学习使用。
public void testVoskWithGrammar() {
    try {
        //获取英文模型
        SpeechRecognizer recognizer = geEnVoskRecognizer();
        VoskParams voskParams = new VoskParams();
        //英文
        voskParams.setLanguage(Language.EN);
        voskParams.setGrammar("[\"one two three four five six seven eight nine zero oh\"]");
        //建议上传 WAV 格式音频。其他格式将自动转换为 WAV,可能影响处理速度
        R<AsrResult> result = recognizer.recognize("src/main/resources/test_en.wav",voskParams);
        if (result.isSuccess()){
            log.info("识别成功:{}", JsonUtils.toJson(result.getData()));
        }else{
            log.info("识别失败:{}", result.getMessage());
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Whisper 注意事项:

1、上述代码仅为示例,需根据实际业务场景进行适当修改。

2、当前版本不支持 CentOS 7。若必须在旧版 Linux 系统(如 CentOS 7)上运行,可选择使用 Vosk 语音识别模型。

3、模型越大,识别精度越高,但耗时也会增加。

4、当前版本暂不支持 GPU,如需 GPU 加速,请自行编译:https://github.com/ggml-org/whisper.cpp/tree/master?tab=readme-ov-file#nvidia-gpu-support

# 使用Vosk内置识别器

示例代码如下(完整示例请参见 example (opens new window)):

  • VoskRecognizer 继承自 SpeechRecognizer
  • SpeechRecognizer 强制类型转换为 VoskRecognizer 后,可解锁更多扩展方法。
  • 可通过 recognizer.createAdvancedRecognizer() 获取内置的 Recognizer 实例,关于 Recognizer 接口的详细说明,请参考开源项目文档VoskRecognizer (opens new window)
public void testVoskAdvanced() {
    try {
        VoskRecognizer recognizer = (VoskRecognizer)geVoskRecognizer();
        //使用vosk内部接口,需要指定识别音频的采样率
        Recognizer voskRecognizer = recognizer.createAdvancedRecognizer(16000);
        voskRecognizer.setWords(true);
        voskRecognizer.setPartialWords(true);
        // 使用vosk内部接口,只支持wav格式
        String audioPath = "src/main/resources/lff_zh.wav";
        InputStream ais = AudioSystem.getAudioInputStream(new BufferedInputStream(new FileInputStream(audioPath)));
        int nbytes;
        byte[] b = new byte[4096];
        while ((nbytes = ais.read(b)) >= 0) {
            if (voskRecognizer.acceptWaveForm(b, nbytes)) {
                log.info(voskRecognizer.getResult());
            } else {
                log.info(voskRecognizer.getPartialResult());
            }
        }
        log.info(voskRecognizer.getFinalResult());
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Vosk 语音识别注意事项:

1、支持 20 多种语言和方言,包括:英语、印度英语、德语、法语、西班牙语、葡萄牙语、中文、俄语、土耳其语、越南语、意大利语、荷兰语、加泰罗尼亚语、阿拉伯语、希腊语、波斯语、菲律宾语、乌克兰语、哈萨克语、瑞典语、日语、世界语、印地语、捷克语、波兰语等。

2、每个模型仅支持一种语言,请下载与目标语言对应的模型。

3、若音频中包含多种语言,不建议使用 Vosk,可选择 Whisper 以获得更好的识别效果,推荐使用 WAV 格式,可提升识别速度。

原因:语音识别模型原生仅支持 WAV 格式。

SmartJavaAI 内置 WAV 转换工具,若输入其他格式(如 MP3、M4A 等),程序会先进行转码,增加额外耗时。

5、模型越大,识别精度越高,但耗时也会增加。

6、当前版本暂不支持 GPU,如需 GPU 加速,请自行编译:https://alphacephei.com/vosk/install

# 语言列表

代码 英文名称 中文名称
en English 英语
zh Chinese 中文
de German 德语
es Spanish 西班牙语
ru Russian 俄语
ko Korean 韩语
fr French 法语
ja Japanese 日语
pt Portuguese 葡萄牙语
tr Turkish 土耳其语
pl Polish 波兰语
ca Catalan 加泰罗尼亚语
nl Dutch 荷兰语
ar Arabic 阿拉伯语
sv Swedish 瑞典语
it Italian 意大利语
id Indonesian 印尼语
hi Hindi 印地语
fi Finnish 芬兰语
vi Vietnamese 越南语
he Hebrew 希伯来语
uk Ukrainian 乌克兰语
el Greek 希腊语
ms Malay 马来语
cs Czech 捷克语
ro Romanian 罗马尼亚语
da Danish 丹麦语
hu Hungarian 匈牙利语
ta Tamil 泰米尔语
no Norwegian 挪威语
th Thai 泰语
ur Urdu 乌尔都语
hr Croatian 克罗地亚语
bg Bulgarian 保加利亚语
lt Lithuanian 立陶宛语
la Latin 拉丁语
mi Maori 毛利语
ml Malayalam 马拉雅拉姆语
cy Welsh 威尔士语
sk Slovak 斯洛伐克语
te Telugu 泰卢固语
fa Persian 波斯语
lv Latvian 拉脱维亚语
bn Bengali 孟加拉语
sr Serbian 塞尔维亚语
az Azerbaijani 阿塞拜疆语
sl Slovenian 斯洛文尼亚语
kn Kannada 卡纳达语
et Estonian 爱沙尼亚语
mk Macedonian 马其顿语
br Breton 布列塔尼语
eu Basque 巴斯克语
is Icelandic 冰岛语
hy Armenian 亚美尼亚语
ne Nepali 尼泊尔语
mn Mongolian 蒙古语
bs Bosnian 波斯尼亚语
kk Kazakh 哈萨克语
sq Albanian 阿尔巴尼亚语
sw Swahili 斯瓦希里语
gl Galician 加利西亚语
mr Marathi 马拉地语
pa Punjabi 旁遮普语
si Sinhala 僧伽罗语
km Khmer 高棉语
sn Shona 修纳语
yo Yoruba 约鲁巴语
so Somali 索马里语
af Afrikaans 南非荷兰语
oc Occitan 奥克语
ka Georgian 格鲁吉亚语
be Belarusian 白俄罗斯语
tg Tajik 塔吉克语
sd Sindhi 信德语
gu Gujarati 古吉拉特语
am Amharic 阿姆哈拉语
yi Yiddish 意第绪语
lo Lao 老挝语
uz Uzbek 乌兹别克语
fo Faroese 法罗语
ht Haitian Creole 海地克里奥尔语
ps Pashto 普什图语
tk Turkmen 土库曼语
nn Nynorsk 新挪威语
mt Maltese 马耳他语
sa Sanskrit 梵语
lb Luxembourgish 卢森堡语
my Myanmar 缅甸语
bo Tibetan 藏语
tl Tagalog 他加禄语
mg Malagasy 马尔加什语
as Assamese 阿萨姆语
tt Tatar 鞑靼语
haw Hawaiian 夏威夷语
ln Lingala 林加拉语
ha Hausa 豪萨语
ba Bashkir 巴什基尔语
jw Javanese 爪哇语
su Sundanese 巽他语
yue Cantonese 粤语

注意事项:

1、Whisper的多语言模型,支持上面所有语言

2、Vosk仅支持上面部分语言,使用时需下载对应语言的模型。