ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

FunASR 流式 Paraformer 实战指南:工业预训练模型的实时语音识别、微调训练与 ONNX 导出全流程

FunASR 流式 Paraformer 实战指南:工业预训练模型的实时语音识别、微调训练与 ONNX 导出全流程 FunASR 流式 Paraformer 实战指南工业预训练模型的实时语音识别、微调训练与 ONNX 导出全流程【免费下载链接】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导读本文围绕 FunASR 开源仓库中examples/industrial_data_pretraining/paraformer_streaming目录下的官方指南系统讲解流式 Paraformerparaformer-zh-streaming即speech_paraformer_asr_nat-zh-cn-16k-common-vocab8404-online从模型推理、接口参数、实时/非实时识别到工业数据微调训练、多机多卡训练、日志监控、模型测试再到 ONNX 导出与验证的完整闭环。读者读完本文后将能够直接用命令行或 Python API 完成流式 ASR 的实时解码、基于自有 JSONL 数据微调流式模型、按需导出 ONNX 并做量化验证为生产环境的低延迟语音识别落地提供可复制的实战方案。说明文中所有相对路径均以 FunASR 仓库根目录为起点原文档中的外部链接已转换为仓库内可直达的路径。一、模型推理1.1 快速使用流式 Paraformer 的推理有两种方式命令行适合快速冒烟验证Python API推荐适合集成进业务代码。命令行方式调用funasr modelparaformer-zh vad_modelfsmn-vad punc_modelct-punc inputasr_example_zh.wav其中paraformer-zh是 FunASR 在 model_zoo 中注册的模型别名组合 VAD 与标点模型后即可对任意时长音频做整段输入 → 文本输出的端到端识别。Python 代码调用推荐from funasr import AutoModel model AutoModel(modelparaformer-zh) res model.generate(inputhttps://isv-data.oss-cn-hangzhou.aliyuncs.com/ics/MaaS/ASR/test_audio/vad_example.wav) print(res)AutoModel会自动从模型仓库下载模型并完成推理输入既支持本地 wav 路径也支持 URL。1.2 接口说明AutoModel 定义model AutoModel(model[str], device[str], ncpu[int], output_dir[str], batch_size[int], hub[str], **kwargs)参数类型默认值说明modelstr—模型仓库 中的模型名称或本地磁盘中的模型路径devicestrcuda:0指定 GPU 推理默认 gpu0若为cpu则使用 CPU 推理ncpuint4设置 CPU 内部操作并行性的线程数output_dirstrNone若设置则指定输出结果的保存路径batch_sizeint1解码时的批处理样本个数hubstrmsms表示从 ModelScope 下载模型hf表示从 Hugging Face 下载**kwargsdict—config.yaml中的所有参数均可直接在此指定例如 VAD 模型的最大切割长度max_single_segment_time6000毫秒AutoModel 推理res model.generate(input[str], output_dir[str])input支持多种形态的输入wav 文件路径例如asr_example.wavpcm 文件路径例如asr_example.pcm此时需要指定音频采样率fs默认 16000音频字节流例如来自麦克风的字节数据wav.scpKaldi 样式 wav 列表格式为wav_id \t wav_path例如asr_example1 ./audios/asr_example1.wav asr_example2 ./audios/asr_example2.wav使用wav.scp输入时必须设置output_dir以保存输出结果音频采样点numpy.ndarray例如audio, rate soundfile.read(asr_example_zh.wav)支持 list 形式的 batch 输入[audio_sample1, audio_sample2, ..., audio_sampleN]fbank 输入支持组 batchshape 为[batch, frames, dim]类型为torch.Tensor。output_dir默认为None**kwargs可传入与模型相关的推理参数例如beam_size10、decoding_ctc_weight0.1。1.3 更多用法介绍非实时语音识别离线from funasr import AutoModel # paraformer-zh is a multi-functional asr model # use vad, punc, spk or not as you need model AutoModel(modelparaformer-zh, vad_modelfsmn-vad, vad_kwargs{max_single_segment_time: 60000}, punc_modelct-punc, # spk_modelcam ) wav_file f{model.model_path}/example/asr_example.wav res model.generate(inputwav_file, batch_size_s300, batch_size_threshold_s60, hotword魔搭) print(res)注意事项通常模型输入时长限制在 30s 以下组合vad_model后支持任意时长音频输入这一能力不局限于 paraformer 模型所有音频输入模型均适用model相关的参数可以直接在AutoModel定义中指定与vad_model相关的参数通过vad_kwargsdict 类型指定类似地还有punc_kwargs、spk_kwargsmax_single_segment_timeVAD 模型最大切割音频时长单位为毫秒 msbatch_size_s启用动态 batch表示 batch 中总音频时长单位为秒 sbatch_size_threshold_s当 VAD 切割后的音频片段时长超过该阈值时将 batch_size 强制设置为 1单位为秒 s。长音频 OOM 排查建议显存占用与音频时长呈平方关系增长遇到 OOM 可按三种场景对症下药a) 推理起始阶段显存主要取决于batch_size_s适当减小该值可降低显存占用b) 推理中间阶段遇到 VAD 切割出的长音频片段总 token 数小于batch_size_s仍出现 OOM可适当减小batch_size_threshold_s使超过阈值的片段强制 batch 为 1c) 推理快结束阶段即使强制 batch 为 1 仍 OOM可适当减小max_single_segment_time让 VAD 切割出的音频片段更短。实时语音识别流式from funasr import AutoModel chunk_size [0, 10, 5] #[0, 10, 5] 600ms, [0, 8, 4] 480ms encoder_chunk_look_back 4 #number of chunks to lookback for encoder self-attention decoder_chunk_look_back 1 #number of encoder chunks to lookback for decoder cross-attention model AutoModel(modelparaformer-zh-streaming) import soundfile import os wav_file os.path.join(model.model_path, example/asr_example.wav) speech, sample_rate soundfile.read(wav_file) chunk_stride chunk_size[1] * 960 # 600ms cache {} total_chunk_num int(len((speech)-1)/chunk_stride1) for i in range(total_chunk_num): speech_chunk speech[i*chunk_stride:(i1)*chunk_stride] is_final i total_chunk_num - 1 res model.generate(inputspeech_chunk, cachecache, is_finalis_final, chunk_sizechunk_size, encoder_chunk_look_backencoder_chunk_look_back, decoder_chunk_look_backdecoder_chunk_look_back) print(res)参数含义chunk_size为流式延时配置[0,10,5]表示上屏实时出字粒度为10*60600ms未来信息为5*60300ms[0,8,4]对应 480ms 出字粒度、240ms 未来信息每次推理输入为600ms音频采样点数为16000*0.6960输出为该片段对应的文字最后一个语音片段必须设置is_finalTrue以强制输出最后一个字encoder_chunk_look_backencoder 自注意力回看的 chunk 数decoder_chunk_look_backdecoder 交叉注意力回看的 encoder chunk 数。这一流式解码流程在源码层面有完整对应实现。examples/industrial_data_pretraining/paraformer_streaming/demo.py给出了可直接运行的完整示例模型 ID 为iic/speech_paraformer_asr_nat-zh-cn-16k-common-vocab8404-online底层由 funasr/models/paraformer_streaming/model.py 中的ParaformerStreaming类驱动inference()按chunk_stride_samples int(chunk_size[1] * 960)切分音频model.py通过cache字典跨 chunk 保存 encoder、decoder、frontend 及prev_samples状态init_cache并调用encode_chunk→calc_predictor_chunk→cal_decoder_with_predictor_chunk逐块产出 token最终由sentence_postprocess拼接文本。语音端点检测非实时from funasr import AutoModel model AutoModel(modelfsmn-vad) wav_file f{model.model_path}/example/vad_example.wav res model.generate(inputwav_file) print(res)VAD 模型输出格式为[[beg1, end1], [beg2, end2], .., [begN, endN]]其中begN/endN表示第 N 个有效音频片段的起始点/结束点单位为毫秒。语音端点检测实时from funasr import AutoModel chunk_size 200 # ms model AutoModel(modelfsmn-vad) import soundfile wav_file f{model.model_path}/example/vad_example.wav speech, sample_rate soundfile.read(wav_file) chunk_stride int(chunk_size * sample_rate / 1000) cache {} total_chunk_num int(len((speech)-1)/chunk_stride1) for i in range(total_chunk_num): speech_chunk speech[i*chunk_stride:(i1)*chunk_stride] is_final i total_chunk_num - 1 res model.generate(inputspeech_chunk, cachecache, is_finalis_final, chunk_sizechunk_size) if len(res[0][value]): print(res)流式 VAD 的输出格式有 4 种情况单位均为毫秒时间从起始点开始的绝对时间[[beg1, end1], [beg2, end2], .., [begN, endN]]同离线 VAD 的完整输出结果[[beg, -1]]只检测到起始点[[-1, end]]只检测到结束点[]既没有检测到起始点也没有检测到结束点。标点恢复from funasr import AutoModel model AutoModel(modelct-punc) res model.generate(input那今天的会就到这里吧 happy new year 明年见) print(res)ct-punc是纯文本输入的标点恢复模型可直接对 ASR 输出的无标点文本做后处理。时间戳预测from funasr import AutoModel model AutoModel(modelfa-zh) wav_file f{model.model_path}/example/asr_example.wav text_file f{model.model_path}/example/text.txt res model.generate(input(wav_file, text_file), data_type(sound, text)) print(res)fa-zh通过同时输入音频sound与文本text为每个字对齐时间戳。更多用例可参考 examples/industrial_data_pretraining 目录下的其他官方示例。二、模型训练与测试流式 Paraformer 同样支持在工业数据上做全量训练与微调finetune下文给出完整的命令、参数与数据组织方式。2.1 快速开始命令行执行用于快速测试不推荐funasr-train modelparaformer-zh train_data_set_listdata/list/train.jsonl valid_data_set_listdata/list/val.jsonl output_dir./outputs log.txt 脚本执行可多机多卡推荐进入流式 paraformer 示例目录直接运行仓库自带的微调脚本cd examples/industrial_data_pretraining/paraformer_streaming bash finetune.sh # log_file: ./outputs/log.txt仓库内的 finetune.sh 是流式模型的完整微调入口它做了四件事指定模型model_name_or_model_diriic/speech_paraformer_asr_nat-zh-cn-16k-common-vocab8404-online既支持自动下载也支持git clone到本地后传本地路径用scp2jsonl把train_wav.scp/train_text.txt与val_wav.scp/val_text.txt转成训练所需的train.jsonl/val.jsonl自动推导 GPU 数量并组装torchrun分布式参数--nnodes ${WORLD_SIZE:-1}、--master_addr ${MASTER_ADDR:-127.0.0.1}、--master_port ${MASTER_PORT:-26669}等调用../../../funasr/bin/train_ds.py启动训练日志输出到./outputs/log.txt。脚本还默认引入../../ds_stage1.json作为 DeepSpeed 配置train_conf.use_deepspeedfalse可关闭。2.2 详细参数介绍funasr/bin/train.py \ model${model_name_or_model_dir} \ train_data_set_list${train_data} \ valid_data_set_list${val_data} \ dataset_conf.batch_size20000 \ dataset_conf.batch_typetoken \ dataset_conf.num_workers4 \ train_conf.max_epoch50 \ train_conf.log_interval1 \ train_conf.resumefalse \ train_conf.validate_interval2000 \ train_conf.save_checkpoint_interval2000 \ train_conf.keep_nbest_models20 \ train_conf.avg_nbest_model10 \ optim_conf.lr0.0002 \ output_dir${output_dir} ${log_file}各参数说明modelstr模型名字模型仓库中的 ID此时脚本会自动下载模型到本地或本地已经下载好的模型路径train_data_set_liststr训练数据路径默认为 jsonl 格式格式示例见 data/listvalid_data_set_liststr验证数据路径默认为 jsonl 格式示例同上dataset_conf.batch_typestrexample默认表示按固定样本数 batchlength或token表示动态组 batchbatch 总长度或 token 数为batch_sizedataset_conf.batch_sizeint与batch_type搭配。batch_typeexample时表示样本个数batch_typelength/token时表示样本长度单位fbank 帧数1 帧 10ms或文字 token 个数train_conf.max_epochint100默认训练总 epoch 数train_conf.log_intervalint50默认打印日志的间隔 step 数train_conf.resumeintTrue默认是否开启断点重训train_conf.validate_intervalint5000默认训练中做验证测试的间隔 step 数train_conf.save_checkpoint_intervalint5000默认训练中模型保存间隔 step 数train_conf.avg_keep_nbest_models_typestracc默认保留 nbest 的标准为 acc越大越好loss表示按 loss越小越好保留train_conf.keep_nbest_modelsint500默认配合avg_keep_nbest_models_type按验证集 acc/loss 保留最佳的 n 个模型其余删除以节约存储train_conf.avg_nbest_modelint10默认按验证集 acc/loss 对最佳的 n 个模型做参数平均train_conf.accum_gradint1默认梯度累积train_conf.grad_clipfloat10.0默认梯度截断train_conf.use_fp16boolFalse默认开启 fp16 训练以加快速度optim_conf.lrfloat学习率output_dirstr模型保存路径**kwargsdictconfig.yaml中的所有参数均可直接指定例如过滤 20s 以上长音频dataset_conf.max_token_length2000单位fbank 帧数或文字 token 个数。流式模型训练时的网络结构在 funasr/models/paraformer_streaming/template.yaml 中有完整定义可作为理解参数影响的底层依据model: ParaformerStreamingmodel_conf中ctc_weight: 0.0、lsm_weight: 0.1、predictor_weight: 1.0、sampling_ratio: 0.75等控制损失组合与采样比例编码器为SANMEncoderChunkOptchunk_size: [12, 15]、stride: [8, 10]、encoder_att_look_back_factor: [4, 4]、decoder_att_look_back_factor: [1, 1]与推理侧encoder_chunk_look_back4、decoder_chunk_look_back1一一对应解码器为ParaformerSANMDecoder预测器为CifPredictorV2threshold: 1.0、tail_threshold: 0.45前端为WavFrontendOnline16kHz、80 维 mel、lfr_m: 7, lfr_n: 6dataset_conf中默认batch_type: example, batch_size: 1并可通过max_token_length过滤超长样本。2.3 多 GPU 训练单机多 GPUexport CUDA_VISIBLE_DEVICES0,1 gpu_num$(echo $CUDA_VISIBLE_DEVICES | awk -F , {print NF}) torchrun --nnodes 1 --nproc_per_node ${gpu_num} \ ../../../funasr/bin/train.py ${train_args}--nnodes表示参与的节点总数--nproc_per_node表示每个节点上运行的进程数。多机多 GPU在主节点上假设 IP 为 192.168.1.1端口为 12345使用 2 个 GPUexport CUDA_VISIBLE_DEVICES0,1 gpu_num$(echo $CUDA_VISIBLE_DEVICES | awk -F , {print NF}) torchrun --nnodes 2 --node_rank 0 --nproc_per_node ${gpu_num} --master_addr 192.168.1.1 --master_port 12345 \ ../../../funasr/bin/train.py ${train_args}在从节点上假设 IP 为 192.168.1.2需确保MASTER_ADDR与MASTER_PORT与主节点一致并运行同样命令export CUDA_VISIBLE_DEVICES0,1 gpu_num$(echo $CUDA_VISIBLE_DEVICES | awk -F , {print NF}) torchrun --nnodes 2 --node_rank 1 --nproc_per_node ${gpu_num} --master_addr 192.168.1.1 --master_port 12345 \ ../../../funasr/bin/train.py ${train_args}--nnodes表示参与的节点总数--node_rank表示当前节点 id--nproc_per_node表示每个节点上运行的进程数通常为 GPU 个数。2.4 准备数据jsonl 格式参考 data/list 下的示例文件。可以通过scp2jsonl指令从wav.scp与text.txt生成。wav.scp与text.txt的准备过程如下train_text.txt左边为数据唯一 ID需与train_wav.scp中的 ID 一一对应右边为音频标注文本ID0012W0013 当客户风险承受能力评估依据发生变化时 ID0012W0014 所有只要处理 data 不管你是做 machine learning 做 deep learning ID0012W0015 he tried to think how it could betrain_wav.scp左边为数据唯一 ID需与train_text.txt中的 ID 一一对应右边为音频文件路径本地路径或 URL 均可BAC009S0764W0121 https://isv-data.oss-cn-hangzhou.aliyuncs.com/ics/MaaS/ASR/test_audio/BAC009S0764W0121.wav BAC009S0916W0489 https://isv-data.oss-cn-hangzhou.aliyuncs.com/ics/MaaS/ASR/test_audio/BAC009S0916W0489.wav ID0012W0015 https://isv-data.oss-cn-hangzhou.aliyuncs.com/ics/MaaS/ASR/test_audio/asr_example_cn_en.wav生成指令生成 train.jsonl 与 val.jsonl# generate train.jsonl and val.jsonl from wav.scp and text.txt scp2jsonl \ scp_file_list[../../../data/list/train_wav.scp, ../../../data/list/train_text.txt] \ data_type_list[source, target] \ jsonl_file_out../../../data/list/train.jsonl可选非必需如果需要从 jsonl 反向解析出 wav.scp 与 text.txt# generate wav.scp and text.txt from train.jsonl and val.jsonl jsonl2scp \ scp_file_list[../../../data/list/train_wav.scp, ../../../data/list/train_text.txt] \ data_type_list[source, target] \ jsonl_file_in../../../data/list/train.jsonl仓库的 finetune.sh 已内置scp2jsonl转换步骤直接执行脚本即可完成数据准备。2.5 查看训练日志查看实验 logtail log.txt [2024-03-21 15:55:52,137][root][INFO] - train, rank: 3, epoch: 0/50, step: 6990/1, total step: 6990, (loss_avg_rank: 0.327), (loss_avg_epoch: 0.409), (ppl_avg_epoch: 1.506), (acc_avg_epoch: 0.795), (lr: 1.165e-04), [(loss_att, 0.259), (acc, 0.825), (loss_pre, 0.04), (loss, 0.299), (batch_size, 40)], {data_load: 0.000, forward_time: 0.315, backward_time: 0.555, optim_time: 0.076, total_time: 0.947}, GPU, memory: usage: 3.830 GB, peak: 18.357 GB, cache: 20.910 GB, cache_peak: 20.910 GB [2024-03-21 15:55:52,139][root][INFO] - train, rank: 1, epoch: 0/50, step: 6990/1, total step: 6990, (loss_avg_rank: 0.334), (loss_avg_epoch: 0.409), (ppl_avg_epoch: 1.506), (acc_avg_epoch: 0.795), (lr: 1.165e-04), [(loss_att, 0.285), (acc, 0.823), (loss_pre, 0.046), (loss, 0.331), (batch_size, 36)], {data_load: 0.000, forward_time: 0.334, backward_time: 0.536, optim_time: 0.077, total_time: 0.948}, GPU, memory: usage: 3.943 GB, peak: 18.291 GB, cache: 19.619 GB, cache_peak: 19.619 GB指标解释rankGPU idepoch、step、total step当前 epoch、step 与总 step 数loss_avg_rank当前 step 所有 GPU 的平均 lossloss/ppl/acc_avg_epoch当前 epoch 截止当前 step 的总平均 loss/ppl/accepoch 结束时最后一个 step 即为 epoch 总平均推荐使用 acc 指标lr当前 step 的学习率[(loss_att, ...), (acc, ...), (loss_pre, ...), (loss, ...), (batch_size, ...)]当前 GPU 上的具体指标对应流式模型的注意力损失、准确率、predictor 损失等total_time单个 step 总耗时GPU, memory分别表示模型使用/峰值显存、模型缓存使用/峰值显存。TensorBoard 可视化tensorboard --logdir /xxxx/FunASR/examples/industrial_data_pretraining/paraformer/outputs/log/tensorboard然后在浏览器中打开 http://localhost:6006/ 查看 loss/acc 曲线。2.6 训练后模型测试有 configuration.json假定训练模型路径为./model_dir如果该目录下生成了configuration.json只需把推理时model参数从模型名改为模型路径即可。从 shell 推理python -m funasr.bin.inference model./model_dir input${input} output_dir${output_dir}从 Python 推理from funasr import AutoModel model AutoModel(model./model_dir) res model.generate(inputwav_file) print(res)无 configuration.json 时如果模型路径中没有configuration.json需要手动指定配置文件路径与模型权重路径python -m funasr.bin.inference \ --config-path ${local_path} \ --config-name ${config} \ init_param${init_param} \ tokenizer_conf.token_list${tokens} \ frontend_conf.cmvn_file${cmvn_file} \ input${input} \ output_dir${output_dir} \ device${device}参数说明config-path实验中保存的config.yaml所在目录可从实验输出目录中查找config-name配置文件名一般为config.yaml支持 yaml 与 json 格式如config.jsoninit_param需要测试的模型参数一般为model.pt可自行指定具体模型文件tokenizer_conf.token_list词表文件路径一般在config.yaml中已有指定无需手动设置仅当config.yaml中路径不正确时需要手动指定frontend_conf.cmvn_filewav 提取 fbank 时用到的 cmvn 文件同上一般config.yaml已指定路径不正确时才需手动指定。其他参数与前述推理参数一致完整示例可参考离线版 examples/industrial_data_pretraining/paraformer/infer_from_local.sh。三、模型导出与测试流式 Paraformer 支持导出为 ONNX便于在 runtime/python/onnxruntime 等运行时上部署。3.1 从命令行导出funasr-export modelparaformer quantizefalse仓库内的 export.sh 给出了流式模型的完整导出命令可指定typeonnx、quantizefalse、devicecpu并支持从模型仓库 ID 或本地路径两种方式导出export HYDRA_FULL_ERROR1 modeliic/speech_paraformer_asr_nat-zh-cn-16k-common-vocab8404-online python -m funasr.bin.export \ model${model} \ typeonnx \ quantizefalse \ devicecpu3.2 从 Python 导出from funasr import AutoModel model AutoModel(modelparaformer) res model.export(quantizeFalse)对应流式模型的 Python 导出脚本 export.py 如下from funasr import AutoModel model AutoModel( modeliic/speech_paraformer_asr_nat-zh-cn-16k-common-vocab8404-online, ) res model.export(typeonnx, quantizeFalse) print(res)从源码结构看流式模型的导出由 funasr/models/paraformer_streaming/model.py 中的export()方法实现内部调用export_meta.export_rebuild_model完成模型重建与 ONNX 转换。3.3 测试 ONNX# pip3 install -U funasr-onnx from funasr_onnx import Paraformer model_dir damo/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-pytorch model Paraformer(model_dir, batch_size1, quantizeTrue) wav_path [~/.cache/modelscope/hub/damo/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-pytorch/example/asr_example.wav] result model(wav_path) print(result)通过funasr-onnx包加载导出后的模型支持batch_size与quantize参数即可在脱离 PyTorch 的环境下完成推理验证。更多例子请参考 runtime/python/onnxruntime 目录下的官方样例。结语本文完整覆盖了 FunASR 流式 Paraformer 的三大环节推理含流式 chunk 解码、VAD、标点、时间戳等组合能力、训练与测试数据准备、参数详解、多机多卡、日志监控、本地模型加载以及ONNX 导出与验证。官方指南中的每一步都可以在仓库内找到对应的脚本与源码实现流式解码逻辑见 funasr/models/paraformer_streaming/model.py模型结构配置见 template.yaml端到端示例脚本见 examples/industrial_data_pretraining/paraformer_streaming 目录下的demo.py、finetune.sh、export.sh。参照本文即可将流式 Paraformer 快速落地到实时会议转写、语音助手、直播字幕等低延迟场景。【免费下载链接】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),仅供参考
返回列表