FunASR WebSocket/gRPC 通信协议全解析:从离线文件转写到实时双遍(2pass)识别

📅 发布时间:2026/9/13 22:11:14
FunASR WebSocket/gRPC 通信协议全解析:从离线文件转写到实时双遍(2pass)识别
FunASR WebSocket/gRPC 通信协议全解析从离线文件转写到实时双遍2pass识别【免费下载链接】FunASROpen-source speech recognition toolkit for training, inference, streaming ASR, VAD, punctuation, speaker diarization pipelines, and OpenAI-compatible/MCP serving.项目地址: https://gitcode.com/GitHub_Trending/fun/FunASRFunASR 软件包提供了一套完整、统一的 WebSocket可扩展至 gRPC通信协议覆盖离线文件转写与实时语音识别两大场景。本文以仓库内 runtime/docs/websocket_protocol_zh.md 为骨架结合 runtime/python/websocket 下的服务端与客户端源码逐字段解析通信消息格式、参数语义、交互时序与底层实现原理。读完本文你将能够自行编写任意语言的 WebSocket 客户端接入 FunASR 服务正确完成初始化配置、音频推流、热词/ITN 设置以及识别结果的解析。协议概览一条连接两种识别模式本协议适用于 FunASR 软件包的两种核心部署形态离线文件转写把 wav、mp3、mp4 等音视频文件可长达数小时转写成带标点的文字对应部署文档 runtime/docs/SDK_tutorial_zh.md实时语音识别边说话边出字支持一句话识别offline、纯流式识别online与流式 句尾离线纠错的双遍识别2pass对应部署文档 runtime/docs/SDK_tutorial_online_zh.md。协议有一个总原则贯穿始终配置参数与 meta 信息使用 JSON 文本帧音频数据使用二进制帧bytes。客户端与服务端通过 WebSocket 的文本帧 / 二进制帧类型区分这两类消息服务端在处理消息时也据此分流见 funasr_wss_server.py文本帧走 JSON 配置解析二进制帧进入 VAD/ASR 推理管线。一、离线文件转写offline1.1 客户端 → 服务端首次通信连接建立后客户端需要发送第一条 JSON 配置消息需 json 序列化告知服务端本次会话的推理模式与参数{mode: offline, wav_name: wav_name, wav_format:pcm, is_speaking: True, hotwords:{阿里巴巴:20,通义实验室:30}, itn:True}各字段含义与取值说明如下字段说明取值 / 默认值mode推理模式固定为offline表示离线文件转写wav_name待推理音频文件名自定义标识用于在结果中区分音频任意字符串wav_format音视频文件后缀名pcm、mp3、mp4等is_speaking断句尾点标记False表示 VAD 切割点或一条 wav 结束audio_fs音频采样率当输入为 pcm 数据时必填hotwords热词数据字符串格式{阿里巴巴:20,通义实验室:30}itn是否使用逆文本正则化ITN默认Truesvs_langSenseVoiceSmall 模型语种默认autosvs_itnSenseVoiceSmall 模型是否开启标点、ITN默认True注意热词权重仅在 fst 热词服务下生效。从服务端源码看这些字段会被逐个解析并写入会话状态funasr_wss_server.pyis_speaking控制流式缓存的 final 标记hotwords会同时注入离线与在线两套 ASR 的推理参数status_dictmode则决定后续音频帧走哪条推理路径。1.2 客户端 → 服务端发送音频数据若为pcm格式直接将音频 bytes 数据发送若为mp3、mp4 等其他格式连同头部信息与音视频 bytes 数据一起发送。协议支持多种采样率与音视频格式。服务端收到二进制帧后会根据audio_fs计算帧时长并累积缓存用于 VAD 切分与离线 ASR 推理。1.3 客户端 → 服务端发送结束标志音频数据发送完毕后需要发送一条结束标志消息需 json 序列化{is_speaking: False}服务端收到is_speaking: False后会把当前会话累积的音频一次性送入离线 ASR 进行整句识别并将该帧判定为断句尾点funasr_wss_server.py 中的end_of_input分支。若配置消息中携带is_end: True服务端在完成本次推理后还会回发一条包含is_end与is_final的确认消息用于客户端可靠地判断输入已处理完毕详见 funasr_wss_server.py。1.4 服务端 → 客户端发送识别结果识别完成后服务端回发一条 JSON 消息{mode: offline, wav_name: wav_name, text: asr ouputs, is_final: True,timestamp:[[100,200], [200,500]],stamp_sents:[]}各字段含义字段说明mode固定为offline表示离线文件转写wav_name对应请求中的音频文件名text语音识别输出的文本is_final识别是否结束。在 offline 模式下该字段恒为True服务端 WebSocket 对每条音频只返回一次识别结果timestamp若 AM声学模型为时间戳模型则返回格式[[100,200], [200,500]]单位毫秒stamp_sents若 AM 为时间戳模型则返回句子级时间戳格式[{text_seg:正 是 因 为,punc:,,start:430,end:1130,ts_list:[[430,670],[670,810],[810,1030],[1030,1130]]}]stamp_sents中每个元素的字段text_seg为分词后的文本片段punc为该句标点start/end为句子起止时间毫秒ts_list为每个词的时间戳列表。服务端组装该消息的完整逻辑见 funasr_wss_server.py依次执行离线 ASR → 声纹识别SV匹配speaker_db.json输出spk_name/spk_score→ 标点恢复PUNC最终把text、timestamp、sentence_info、punc_array等字段一并封装发送。二、实时语音识别online / 2pass2.1 系统架构实时语音识别的核心是双遍2pass架构——蓝色实时层负责低延迟出字红色非实时层负责句尾纠错与标点从架构图可以看出完整数据流客户端音频流经消息队列以约 60ms 间隔缓冲进入服务端FSMN VAD实时过滤静音将非静音段约 600ms 间隔送入Paraformer 流式 ASR实时输出初步识别文字并推送回客户端VAD 检测到尾点后将完整非静音段音频交给Paraformer 非流式 ASR做二次识别再用CT-Transformer进行标点预测非实时层的结果会覆盖实时层的初步结果最终客户端收到带标点的完整文本。2.2 客户端 → 服务端首次通信{mode: 2pass, wav_name: wav_name, is_speaking: True, wav_format:pcm, chunk_size:[5,10,5], hotwords:{阿里巴巴:20,通义实验室:30},itn:True}各字段含义字段说明modeoffline一句话识别online实时语音识别2pass实时识别 句尾离线纠错wav_name待推理音频文件名wav_format音视频文件后缀名实时场景只支持 pcm 音频流is_speaking断句尾点标记VAD 切割点或一条 wav 结束chunk_size流式模型 latency 配置[5,10,5]表示当前音频 600ms、回看 300ms、前瞻 300msaudio_fs输入为 pcm 时需指定采样率hotwords热词字符串格式{阿里巴巴:20,通义实验室:30}itn是否使用 ITN默认Truesvs_langSenseVoiceSmall 模型语种默认autosvs_itnSenseVoiceSmall 模型是否开启标点、ITN默认True注意热词权重仅在 fst 热词服务下生效。关于chunk_size需要特别说明它由编码器块大小、回看块数、前瞻块数三元组构成每个块为 60ms因此[5,10,5]的感知窗口为5×60ms 300ms当前块 10×60ms 600ms回看 5×60ms 300ms前瞻整体 latency 约 600ms。仓库客户端还提供了更细粒度的--encoder_chunk_look_back默认 4与--decoder_chunk_look_back默认 0参数用于独立调节编码器/解码器的回看深度funasr_wss_client.py。2.3 客户端 → 服务端发送音频数据实时场景要求移除头部信息后直接发送 pcm bytes 数据支持的采样率为 8000需在message中指定audio_fs为 8000与 16000。服务端按照chunk_interval默认 10即 600ms/10 60ms 一个发送粒度累积音频帧满一个间隔就触发一次流式 ASR 推理funasr_wss_server.py。2.4 客户端 → 服务端发送结束标志与离线模式一致发送结束标志{is_speaking: False}2.5 服务端 → 客户端发送识别结果{mode: 2pass-online, wav_name: wav_name, text: asr ouputs, is_final: True, timestamp:[[100,200], [200,500]],stamp_sents:[]}各字段含义字段说明mode2pass-online实时识别结果2pass-offline2 遍修正识别结果wav_name待推理音频文件名text语音识别输出文本is_final识别是否结束timestamp时间戳模型返回格式[[100,200], [200,500]]msstamp_sents句子级时间戳格式同离线模式服务端对mode字段的区分逻辑值得关注funasr_wss_server.py在线推理在 2pass 模式下只发 partial 结果2pass-online在 VAD 尾点或is_speakingFalse时才触发离线整句推理2pass-offline最终客户端把两路文本拼接即可得到完整转写。三、源码级验证服务端是如何处理协议消息的协议文档描述的是应该怎么发而 funasr_wss_server.py 给出了实际怎么收的完整实现可作为协议实现者的参考蓝本消息分流ws_serve循环中isinstance(message, str)判定为 JSON 配置帧否则视为二进制音频帧funasr_wss_server.py状态管理每个 WebSocket 连接维护独立的status_dict_asr离线、status_dict_asr_online在线含cache与chunk_size、status_dict_vad、status_dict_punc四个状态字典保证多客户端会话互不干扰并发控制服务端用ThreadPoolExecutorasyncio.Semaphore对 VAD / 在线 ASR / 离线 ASR / 标点 / 声纹分别限流--concurrent_vad、--concurrent_asr_online、--concurrent_asr_offline、--concurrent_punc、--concurrent_sv默认依次为 4/4/2/1/1避免阻塞事件循环异常收敛会话级错误会被记录并在结束时通过{is_end: true, is_final: false, error: ...}告知客户端而不是静默断开funasr_wss_server.py。服务端同时加载离线 Paraformer、流式 Paraformer、FSMN-VAD、CT-Transformer 标点与声纹模型funasr_wss_server.py这就是 2pass 架构能边出字、边纠错的模型基础。四、客户端实战命令行客户端与 SDK 封装4.1 命令行客户端仓库提供开箱即用的命令行客户端 funasr_wss_client.py支持三种模式# 离线转写从麦克风 python funasr_wss_client.py --host 0.0.0.0 --port 10095 --mode offline # 离线转写从 wav.scp 文件列表 python funasr_wss_client.py --host 0.0.0.0 --port 10095 --mode offline --audio_in ./data/wav.scp --output_dir ./results # 流式识别 python funasr_wss_client.py --host 0.0.0.0 --port 10095 --mode online --chunk_size 5,10,5 # 双遍识别 python funasr_wss_client.py --host 0.0.0.0 --port 10095 --mode 2pass --chunk_size 8,8,4 --audio_in ./data/wav.scp --output_dir ./results常用参数源码定义见 funasr_wss_client.py参数说明默认值--host服务端 IP本地为localhost/0.0.0.0localhost--port服务端端口10095--modeoffline/online/2pass2pass--chunk_size5,10,5600ms8,8,4480ms5,10,5--chunk_interval发送粒度10表示 600/1060ms5表示 120ms20表示 30ms10--audio_in音频输入不传则使用麦克风需安装 PyAudioNone--audio_fs音频采样率16000--hotword热词文件每行一个如阿里巴巴 20或热词字符串空--use_itn1 开启 / 0 关闭 ITN1--thread_num并发发送线程数多文件并发压测1--output_dir结果输出目录None--ssl1 开启 wss0 关闭1--words_max_print终端最多打印字数10000--result_timeout等待服务端最终确认的秒数300.0一个值得注意的协议细节客户端从.scp读取文件时会为每个音频先发一条携带mode/chunk_size/audio_fs/wav_name/hotwords/itn的配置帧再按stride由chunk_size、chunk_interval、采样率计算切分音频循环发送二进制帧最后发送{is_speaking: False, is_end: True}并等待服务端回执funasr_wss_client.py。这就是一连接多音频的实现方式与服务端end_of_input → finish_input → 回执的逻辑一一对应。4.2 SDK 式封装Funasr_websocket_recognizer对于需要把 ASR 嵌入自身程序的场景funasr_client_api.py 提供了三步式封装# 1. 创建识别器内部自动完成首次配置帧发送与消息接收线程启动 rcg Funasr_websocket_recognizer(host127.0.0.1, port30035, is_sslTrue, mode2pass) # 2. 逐块喂入 pcm 数据返回当前识别结果 text rcg.feed_chunk(data) print(text, text) # 3. 结束会话等待并返回最终结果timeout3 秒 text rcg.close(timeout3) print(text, text)其内部实现与协议完全对齐__init__中发送包含mode/chunk_size/chunk_interval/wav_name/is_speaking的 JSON 配置帧feed_chunk用二进制帧发送音频并以消息队列轮询结果close发送{is_speaking: False}结束标志并取出队列中最后一条消息作为最终结果funasr_client_api.py。五、部署与扩展阅读离线服务一键部署、多语言客户端Python/CPP/HTML/Java与热词/时间戳模型选型见 离线文件转写部署文档在线服务部署见 实时语音识别部署文档完整服务端/客户端示例代码位于 runtime/python/websocket含 服务端、客户端、SDK 封装 及其 README协议英文版见 runtime/docs/websocket_protocol.mdC 侧 WebSocket 实现与热词文件示例见 runtime/websocketgRPC 服务端实现见 runtime/grpc。掌握上述协议后无论是自研客户端、对接第三方平台还是基于 runtime/websocket 扩展新语言 SDK都可以直接依据本文的消息格式与字段语义进行开发调试。【免费下载链接】FunASROpen-source speech recognition toolkit for training, inference, streaming ASR, VAD, punctuation, speaker diarization pipelines, and OpenAI-compatible/MCP serving.项目地址: https://gitcode.com/GitHub_Trending/fun/FunASR创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考