语音识别:docker部署FunASR以及springboot集成funasr

内容摘选自: 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;
    }

}

识别后返回的数据内容

相关推荐
好像是个likun2 分钟前
使用docker拉取镜像很慢或者总是超时的问题
运维·docker·容器
AskHarries2 小时前
Spring Cloud OpenFeign快速入门demo
spring boot·后端
玖疯子2 小时前
介绍 Docker 的基本概念和优势,以及在应用程序开发中的实际应用。
docker
暴富的Tdy2 小时前
【快速上手Docker 简单配置方法】
docker·容器·eureka
isolusion3 小时前
Springboot的创建方式
java·spring boot·后端
Karoku0663 小时前
【k8s集群应用】kubeadm1.20高可用部署(3master)
运维·docker·云原生·容器·kubernetes
Yvemil73 小时前
《开启微服务之旅:Spring Boot Web开发举例》(一)
前端·spring boot·微服务
saynaihe5 小时前
安全地使用 Docker 和 Systemctl 部署 Kafka 的综合指南
运维·安全·docker·容器·kafka
星河梦瑾5 小时前
SpringBoot相关漏洞学习资料
java·经验分享·spring boot·安全
G_whang6 小时前
centos7下docker 容器实现redis主从同步
redis·docker·容器