核心代码完整代码# codingutf-8 import os import torch import numpy as np import onnx import argparse from funasr import AutoModel import onnxruntime as ort # 通用配置 SAMPLE_RATE 16000 # 固定16kHz采样率 OPSET_VERSION 12 # 适配.NET 4.5的ONNX Runtime DEVICE cpu # 强制CPU推理和C#端一致 def export_vad_model(vad_pt_dir, onnx_save_path): 转换VAD模型speech_fsmn_vad_zh-cn-16k-common-pytorch :param vad_pt_dir: VAD模型文件夹路径包含model.pt :param onnx_save_path: 导出的ONNX路径 print(f\n 开始转换VAD模型 ) print(f源路径{vad_pt_dir}) print(f目标路径{onnx_save_path}) # 1. 加载VAD模型 vad_model AutoModel( modelvad_pt_dir, taskvad, disable_updateTrue, trust_remote_codeTrue, deviceDEVICE ) model vad_model.model model.eval() # 2. 构造模拟输入1秒音频[1, 16000] dummy_input torch.randn(1, SAMPLE_RATE, dtypetorch.float32) # 3. 导出ONNX torch.onnx.export( model, dummy_input, onnx_save_path, input_names[audio_input], output_names[vad_output], dynamic_axes{ audio_input: {1: seq_len}, vad_output: {1: seq_len} }, opset_versionOPSET_VERSION, do_constant_foldingTrue, verboseFalse ) # 4. 验证模型 onnx_model onnx.load(onnx_save_path) onnx.checker.check_model(onnx_model) # 5. 测试推理 ort_session ort.InferenceSession(onnx_save_path) test_input np.random.randn(1, SAMPLE_RATE).astype(np.float32) ort_output ort_session.run([vad_output], {audio_input: test_input}) print(fVAD模型转换完成输出形状{ort_output[0].shape}) def export_sensevoice_model(sv_pt_dir, onnx_save_path): 转换SenseVoice主模型sensevoicefp16 :param sv_pt_dir: SenseVoice模型文件夹路径包含model.pt :param onnx_save_path: 导出的ONNX路径 print(f\n 开始转换SenseVoice模型 ) print(f源路径{sv_pt_dir}) print(f目标路径{onnx_save_path}) # 1. 加载SenseVoice模型 sv_model AutoModel( modelsv_pt_dir, disable_updateTrue, trust_remote_codeTrue, deviceDEVICE, dtypetorch.float32 # 强制float32避免fp16兼容问题 ) model sv_model.model model.eval() # 2. 构造模拟输入3秒音频[1, 48000] 初始cache dummy_audio torch.randn(1, SAMPLE_RATE * 3, dtypetorch.float32) cache model.get_cache(batch_size1, deviceDEVICE) cache_tensors [v for k, v in cache.items() if isinstance(v, torch.Tensor)] dummy_inputs (dummy_audio, *cache_tensors) # 3. 构造输入名称音频cache input_names [audio_input] [fcache_{i} for i in range(len(cache_tensors))] # 4. 导出ONNX torch.onnx.export( model, dummy_inputs, onnx_save_path, input_namesinput_names, output_names[text_probs, score], dynamic_axes{ audio_input: {1: seq_len}, **{fcache_{i}: {1: seq_len} for i in range(len(cache_tensors))} }, opset_versionOPSET_VERSION, do_constant_foldingTrue, verboseFalse, keep_initializers_as_inputsFalse ) # 5. 验证模型 onnx_model onnx.load(onnx_save_path) onnx.checker.check_model(onnx_model) # 6. 测试推理简化版仅验证加载 ort_session ort.InferenceSession(onnx_save_path) test_input {audio_input: np.random.randn(1, SAMPLE_RATE).astype(np.float32)} # 补充cache输入初始化为0 for i in range(len(cache_tensors)): test_input[fcache_{i}] np.zeros_like(cache_tensors[i].numpy()) ort_output ort_session.run(None, test_input) print(fSenseVoice模型转换完成输出数量{len(ort_output)}) def main(): # 解析命令行参数默认使用你提供的路径 parser argparse.ArgumentParser(description批量转换SenseVoiceVAD模型到ONNX) parser.add_argument(--sv-dir, defaultrD:\ai\asr_sen\cyberwinmodel\sensevoicefp16, helpSenseVoice模型文件夹路径) parser.add_argument(--vad-dir, defaultrD:\ai\asr_sen\cyberwinmodel\speech_fsmn_vad_zh-cn-16k-common-pytorch, helpVAD模型文件夹路径) parser.add_argument(--sv-onnx, defaultrD:\ai\asr_sen\cyberwinmodel\sensevoice_model.onnx, helpSenseVoice ONNX保存路径) parser.add_argument(--vad-onnx, defaultrD:\ai\asr_sen\cyberwinmodel\vad_model.onnx, helpVAD ONNX保存路径) args parser.parse_args() # 检查源路径是否存在 if not os.path.exists(args.sv_dir): print(f错误SenseVoice模型路径不存在 → {args.sv_dir}) return if not os.path.exists(args.vad_dir): print(f错误VAD模型路径不存在 → {args.vad_dir}) return # 创建目标目录如果不存在 for onnx_path in [args.sv_onnx, args.vad_onnx]: onnx_dir os.path.dirname(onnx_path) if not os.path.exists(onnx_dir): os.makedirs(onnx_dir) # 执行转换 export_vad_model(args.vad_dir, args.vad_onnx) export_sensevoice_model(args.sv_dir, args.sv_onnx) print(\n 所有模型转换完成 ) print(fVAD ONNX路径{args.vad_onnx}) print(fSenseVoice ONNX路径{args.sv_onnx}) if __name__ __main__: # 安装依赖提示 print( 依赖检查 ) try: import funasr import onnxruntime except ImportError: print(请先安装依赖) print(pip install torch2.0.1 onnx1.14.0 onnxruntime1.15.1 funasr1.0.23 numpy1.24.3) # 执行主逻辑 main()东方仙盟拥抱知识开源共筑数字新生态在全球化与数字化浪潮中东方仙盟始终秉持开放协作、知识共享的理念积极拥抱开源技术与开放标准。我们相信唯有打破技术壁垒、汇聚全球智慧才能真正推动行业的可持续发展。开源赋能中小商户通过将前端异常检测、跨系统数据互联等核心能力开源化东方仙盟为全球中小商户提供了低成本、高可靠的技术解决方案让更多商家能够平等享受数字转型的红利。共建行业标准我们积极参与国际技术社区与全球开发者、合作伙伴共同制定开放协议与技术规范推动跨境零售、文旅、餐饮等多业态的系统互联互通构建更加公平、高效的数字生态。知识普惠共促发展通过开源社区、技术文档与培训体系东方仙盟致力于将前沿技术转化为可落地的行业实践赋能全球合作伙伴共同培育创新人才推动数字经济的普惠式增长阿雪技术观在科技发展浪潮中我们不妨积极投身技术共享。不满足于做受益者更要主动担当贡献者。无论是分享代码、撰写技术博客还是参与开源项目维护改进每一个微小举动都可能蕴含推动技术进步的巨大能量。东方仙盟是汇聚力量的天地我们携手在此探索硅基生命为科技进步添砖加瓦。Hey folks, in this wild tech - driven world, why not dive headfirst into the whole tech - sharing scene? Dont just be the one reaping all the benefits; step up and be a contributor too. Whether youre tossing out your code snippets, hammering out some tech blogs, or getting your hands dirty with maintaining and sprucing up open - source projects, every little thing you do might just end up being a massive force that pushes tech forward. And guess what? The Eastern FairyAlliance is this awesome place where we all come together. Were gonna team up and explore the whole silicon - based life thing, and in the process, well be fueling the growth of technology.