内容摘选自: https://github.com/modelscope/FunASR/blob/main/runtime/docs/SDK_advanced_guide_offline_zh.md
FunASR
FunASR是一个基础语音识别工具包,提供多种功能,包括语音识别(ASR)、语音端点检测(VAD)、标点恢复、语言模型、说话人验证、说话人分离和多人对话语音识别等。FunASR提供了便捷的脚本和教程,支持预训练好的模型的推理与微调。
此文章补充了一些内容,让小白更容易上手
bash
注意:
1. certfile ssl证书问题,不了解的话就关闭即可
2. 关闭FunASR服务(有守护线程杀完会自动启动,如果想修改启动命令的话就kill和nohup全部编辑好在贴进去执行)
镜像启动
通过下述命令拉取并启动FunASR软件包的docker镜像:
bash
# 拉取镜像
sudo docker pull \
registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-cpu-0.4.6
# 当前文件路径下创建目录 用于挂载模型
mkdir -p ./funasr-runtime-resources/models
# 启动镜像
sudo docker run -p 10095:10095 -it --privileged=true \
-v $PWD/funasr-runtime-resources/models:/workspace/models \
registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-cpu-0.4.6
服务端启动
docker启动之后,进入到docker里边
bash
docker exec -it <imageid> /bin/bash
启动funasr-wss-server
服务程序(有16K 和 8K模型可选择):
bash
cd FunASR/runtime
nohup bash run_server.sh \
--download-model-dir /workspace/models \
--vad-dir damo/speech_fsmn_vad_zh-cn-16k-common-onnx \
--model-dir damo/speech_paraformer-large-vad-punc_asr_nat-zh-cn-16k-common-vocab8404-onnx \
--punc-dir damo/punc_ct-transformer_cn-en-common-vocab471067-large-onnx \
--lm-dir damo/speech_ngram_lm_zh-cn-ai-wesp-fst \
--itn-dir thuduj12/fst_itn_zh \
--hotword /workspace/models/hotwords.txt > log.txt 2>&1 &
查看打印日志
bash
tail -f log.txt
- 如果您想关闭SSL,增加参数:
--certfile 0
- 如果您想使用SenseVoiceSmall模型、时间戳、nn热词模型进行部署,请设置
--model-dir
为对应模型:iic/SenseVoiceSmall-onnx
damo/speech_paraformer-large-vad-punc_asr_nat-zh-cn-16k-common-vocab8404-onnx
(时间戳)damo/speech_paraformer-large-contextual_asr_nat-zh-cn-16k-common-vocab8404-onnx
(nn热词)
- 如果您想在服务端加载热词,请在宿主机文件
./funasr-runtime-resources/models/hotwords.txt
配置热词(docker映射地址为/workspace/models/hotwords.txt
):每行一个热词,格式(热词 权重):阿里巴巴 20
(注:热词理论上无限制,但为了兼顾性能和效果,建议热词长度不超过10,个数不超过1k,权重1~100) - SenseVoiceSmall-onnx识别结果中
<|zh|><|NEUTRAL|><|Speech|>
分别为对应的语种、情感、事件信息
如果您想部署8k的模型,请使用如下命令启动服务:
bash
cd FunASR/runtime
nohup bash run_server.sh \
--download-model-dir /workspace/models \
--vad-dir damo/speech_fsmn_vad_zh-cn-8k-common-onnx \
--model-dir damo/speech_paraformer_asr_nat-zh-cn-8k-common-vocab8358-tensorflow1-onnx \
--punc-dir damo/punc_ct-transformer_cn-en-common-vocab471067-large-onnx \
--lm-dir damo/speech_ngram_lm_zh-cn-ai-wesp-fst-token8358 \
--itn-dir thuduj12/fst_itn_zh \
--hotword /workspace/models/hotwords.txt > log.txt 2>&1 &
使用客户端测试
官方提供了:html页面、java、python、cpp
将docker镜像中的html页面下载到宿主机,然后下载到本机
bash
docker cp <容器 ID 或名称>:/workspace/FunASR/runtime/html5 /funasr-runtime-resources
在浏览器中打开html/static/index.html
,即可出现如下页面,支持麦克风输入与文件上传,直接进行体验。
服务端用法详解
启动FunASR服务(注意:certfile SSL证书问题,小心访问不通):
bash
cd /workspace/FunASR/runtime
nohup bash run_server.sh \
--download-model-dir /workspace/models \
--model-dir damo/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-onnx \
--vad-dir damo/speech_fsmn_vad_zh-cn-16k-common-onnx \
--punc-dir damo/punc_ct-transformer_cn-en-common-vocab471067-large-onnx \
--lm-dir damo/speech_ngram_lm_zh-cn-ai-wesp-fst \
--itn-dir thuduj12/fst_itn_zh \
--certfile ../../../ssl_key/server.crt \
--keyfile ../../../ssl_key/server.key \
--hotword ../../hotwords.txt > log.txt 2>&1 &
run_server.sh命令参数介绍
--download-model-dir
:模型下载地址,通过设置model ID从Modelscope下载模型--model-dir
:modelscope model ID 或者 本地模型路径--vad-dir
:modelscope model ID 或者 本地模型路径--punc-dir
:modelscope model ID 或者 本地模型路径--lm-dir
:modelscope model ID 或者 本地模型路径--itn-dir
:modelscope model ID 或者 本地模型路径--port
:服务端监听的端口号,默认为10095--decoder-thread-num
:服务端线程池个数(支持的最大并发路数),脚本会根据服务器线程数自动配置decoder-thread-num、io-thread-num--io-thread-num
:服务端启动的IO线程数--model-thread-num
:每路识别的内部线程数(控制ONNX模型的并行),默认为1,其中建议decoder-thread-num*model-thread-num等于总线程数--certfile
:SSL的证书文件,默认为:../../../ssl_key/server.crt
,如果需要关闭SSL,参数设置为0--keyfile
:SSL的密钥文件,默认为:../../../ssl_key/server.key
--hotword
:热词文件路径,每行一个热词,格式:热词 权重(例如:阿里巴巴 20),如果客户端提供热词,则与客户端提供的热词合并一起使用,服务端热词全局生效,客户端热词只针对对应客户端生效
关闭FunASR服务
- 查看
funasr-wss-server
对应的PID:
bash
ps -x | grep funasr-wss-server
- 杀死进程:
bash
kill -9 PID
修改模型及其他参数
替换正在使用的模型或者其他参数,需先关闭FunASR服务,修改需要替换的参数,并重新启动FunASR服务。其中模型需为ModelScope中的ASR/VAD/PUNC模型,或者从ModelScope中模型finetune后的模型。
例如替换ASR模型为damo/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-onnx
,则如下设置参数--model-dir
:
bash
--model-dir damo/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-onnx
- 设置端口号
--port
:
bash
--port <port number>
- 设置服务端启动的推理线程数
--decoder-thread-num
:
bash
--decoder-thread-num <decoder thread num>
- 设置服务端启动的IO线程数
--io-thread-num
:
bash
--io-thread-num <io thread num>
- 关闭SSL证书:
bash
--certfile 0
springboot集成funasr示例
bash
样例代码中如注入接口,调用改为自己的即可,我只提供了主要逻辑方法,uri改为自己的
依赖
bash
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<!-- 引入org.json所需依赖 -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20240303</version>
</dependency>
</dependencies>
配置
bash
spring:
application:
name: java_http_client
server:
port: 18081
parameters:
model: "offline" #离线模型为例
hotWords: "{\"自定义\":20,\"热词\":20,\"设置\":30}"
fileUrl: "E:/work/project/gitee/mycloud/funasr/src/main/resources/upload"
serverIpPort: "ws://192.168.1.101:10095"
controller
bash
@GetMapping("/z2")
public void z2() throws Exception {
WebSocketClient client = new StandardWebSocketClient();
client.doHandshake(
new WebSocketHandler() {
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
// todo 注入自己的接口调用方法即可
recognitionService.z2(session);
// 处理连接后保存session
}
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
// 在这里处理接收到的消息
if (message instanceof TextMessage) {
String receivedMessage = ((TextMessage) message).getPayload();
System.out.println("Received message from server: " + receivedMessage);
// 在这里处理接收到的消息
}
}
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
// 异常处理
System.err.println("handleTransportError: " + exception.getMessage());
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
System.out.println("WebSocket connection closed with status: " + closeStatus);
}
@Override
public boolean supportsPartialMessages() {
return false;
}
}, null, new URI("ws://192.168.1.101:10095"));
}
实现方法
bash
@Service
public class RecognitionServiceImpl implements RecognitionService {
@Value("${parameters.model}")
private String model;
@Value("${parameters.hotWords}")
private String hotWords;
@Override
public Object z2(WebSocketSession webSocketSession) throws Exception {
JSONObject configJson = new JSONObject();
configJson.put("mode", model);
configJson.put("wav_name", "test");
configJson.put("wav_format", "wav"); // 文件格式为pcm
configJson.put("is_speaking", true);
configJson.put("hotwords", hotWords);
configJson.put("itn", true);
// 发送配置参数与meta信息
webSocketSession.sendMessage(new TextMessage(configJson.toString()));
byte[] audioData;
String localFilePath = "E:\\work\\project\\gitee\\mycloud\\funasr\\src\\main\\resources\\test.wav";
try {
audioData = Files.readAllBytes(Paths.get(localFilePath));
} catch (IOException e) {
System.err.println("Error reading file: " + e.getMessage());
e.printStackTrace();
return "Error reading audio file";
}
ByteBuffer audioByteBuffer = ByteBuffer.wrap(audioData);
BinaryMessage binaryMessage = new BinaryMessage(audioByteBuffer);
webSocketSession.sendMessage(binaryMessage);
// 发送音频结束标志
JSONObject endMarkerJson = new JSONObject();
endMarkerJson.put("is_speaking", false);
webSocketSession.sendMessage(new TextMessage(endMarkerJson.toString()));
return null;
}
}
识别后返回的数据内容