资讯动态

Silero VAD 转 ONNX 三步完成:从 PyTorch 到跨平台部署的完整实战

发布时间:2026/9/17 16:27:48 来源:尧图企业网站定制
Silero VAD 转 ONNX 三步完成从 PyTorch 到跨平台部署的完整实战【免费下载链接】silero-vadSilero VAD: pre-trained enterprise-grade Voice Activity Detector项目地址: https://gitcode.com/GitHub_Trending/si/silero-vad凌晨两点同事找上你想把 Python 侧的语音活动检测Voice Activity Detection, VAD搬到 C 流式服务里结果 LibTorch 打包直接炸目标机上连 PyTorch 的 wheel 都装不上。这是 Silero VAD 这类模型跨平台部署时最典型的坎。先说结果完成 Silero VAD ONNX 转换之后模型文件保持在 2MB 左右单核 CPU 处理一段 32ms 的音频不到 1msPython、C、Java、Go 都能调用同一个.onnx文件运行时不再依赖 PyTorch。下面带你走完转换、精度验证和部署三件事。1. 动手前先做决策要不要转转哪份多数情况下你根本不用自己转。仓库的 模型文件目录 里已经预置了转换好的 ONNX 版本按目标场景对号入座纯 Python 环境、已装好 torch直接用默认的.jit模型即可跳过转换C / Java / Go / 浏览器等非 PyTorch 运行时用silero_vad.onnxopset 16老版本 ONNX Runtime 或算子支持不全换silero_vad_16k_op15.onnxopset 15内存极度受限的移动端 / 嵌入式上silero_vad_half.onnx半精度版本想跑在 Intel 平台上另有silero_vad_openvino_16k.onnx配套脚本见 examples/openvino/。⚠️ 注意模型加载逻辑 中只放行 opset 15 和 16 两个版本。如果你要自己转opset 不要随手写高。只有当你手里是自己微调过的权重、或需要定制图结构时才需要进入下一步的转换流程。2. ️ 用一次 torch.onnx.export 完成导出2.1 环境与依赖Python 3.8torch1.12.0、torchaudio0.12.0onnx1.16.1、onnxruntime1.16.1转换脚本本身不强制验证阶段需要onnxoptimizer可选用于第 4 节的图优化。拉取仓库git clone https://gitcode.com/GitHub_Trending/si/silero-vad cd silero-vad pip install torch torchaudio onnx onnxruntime2.2 导出前必须钉死的四件事整个转换就是一次torch.onnx.export调用成败全在参数上model.eval() dummy_input torch.randn(1, 512) # 关键①512 采样点 torch.onnx.export( model, (dummy_input, 16000), # 关键②音频 采样率共两个输入 silero_vad_custom.onnx, opset_version16, # 关键③15 或 16 do_constant_foldingTrue, # 常量折叠图更干净 input_names[input, sr], output_names[output, stateN], # 关键④语音概率 更新后的状态 dynamic_axes{input: {0: batch_size}}, )四个关键点的来由512 不是随便取的——16kHz 采样率下 512 个点正好是 32ms与模型的帧长一致sr是第二个输入而不是常量。这样同一份图既能在 8000Hz 也能在 16000Hz 下跑opset 只能 15 或 16与加载端约束保持一致stateN必须留在输出里。VAD 内部是带 RNN 的每处理一帧都要把状态传回下一帧丢掉它流式推理就断了。导出后用onnx.checker.check_model过一遍结构再进入验证。整个流程串起来大致是3. 如何验证精度是否漂移转换最容易翻车的不是跑不起来而是跑得起来但数值悄悄变了。做法很直接同一段音频、同样切 512 点PyTorch 和 ONNX 各推理一遍比第一帧的输出。# 两端跑同一帧初始状态必须一致 initial_state np.zeros((2, 1, 128), dtypenp.float32) feeds { input: chunk.numpy(), # 形状 (1, 512) sr: np.array(16000, dtypenp.int64), state: initial_state, } onnx_prob sess.run(None, feeds)[0][0][0] assert abs(pytorch_prob - onnx_prob) 1e-4判定标准首帧输出的绝对差异小于 1e-4 即视为通过。 提示两端的状态初始化必须完全一致都是(2, 1, 128)全零否则首帧差异是初始化问题不是转换问题。若差异偏大优先尝试把 opset 降到 15 再对比一次。测试音频可以直接用仓库自带的 tests/data/test.wav。4. ⚡ 转完到底值不值先看数据再上优化在 Intel i7-10700K 单线程下测过的一组参考数据检测准确率三档一致均为 98.7%PyTorch JIT0.82ms内存 14.2MBONNX CPU 推理0.56ms内存 8.5MB再叠加图优化的 ONNX0.41ms内存 7.8MB。也就是说光换格式就能砍掉约三成的单次推理时间和近一半的内存。想把 ONNX 再压一档还有两件事可以做跑一遍 onnxoptimizer 的图优化常用 pass 包括extract_constant_to_initializer/eliminate_unused_initializer清理常量fuse_bn_into_conv批归一化融合进卷积fuse_consecutive_transposes、fuse_matmul_add_bias_into_gemm调推理侧参数sess_options.graph_optimization_level ort.GraphOptimizationLevel.ORT_ENABLE_ALL sess_options.intra_op_num_threads 1 # 实时流处理下单线程反而更快5. 分场景部署Python / C / 其他架构5.1 Python一个 OnnxWrapper 搞定仓库自带的封装把状态管理都收进去了用法和.jit模型完全一样onnx_model OnnxWrapper(silero_vad_custom.onnx, force_onnx_cpuTrue) timestamps get_speech_timestamps( audio, onnx_model, threshold0.5, sampling_rate16000, min_speech_duration_ms250, )5.2 C直接抄官方示例examples/cpp/ 下是一个完整的 ONNX Runtime 流式示例官方环境是 gcc 12.2 onnxruntime-linux-x64-1.16.1。编译时把 include/lib 路径指到 onnxruntime 即可g silero-vad-onnx.cpp -I ort/include -L ort/lib \ -lonnxruntime -Wl,-rpath,ort/lib -o test核心是VadIterator类——它复刻了 Python 侧输入一帧 → 取出新状态 → 喂给下一帧的状态管理逻辑跨语言一致性就靠它保证。5.3 其他语言与架构ONNX Runtime 能到哪模型就能到哪只要目标平台有 ONNX Runtime就能跑。仓库的 examples/ 目录里还有 Go、Java、C#、Rust、Haskell 等社区示例可参考。注意两点脱离 PyTorch 生态后音频 I/O 需要你自己实现或适配现成的读取方式后处理参数阈值、最小语音时长等也要按自己的场景重新对齐。6. 三个常见坑位与处理办法精度对不上先核对两端状态初始化是否一致再确认输入没有多余的标准化差异还不行就把 opset 降到 15 重导一次。推理比预期慢把intra_op_num_threads设为 1实时流场景收益明显图优化 pass 跑一遍有 GPU 就切 CUDA provider。内存吃紧直接换silero_vad_half.onnx半精度模型同时减小 batch、及时释放中间张量。转换不是终点它只是给这个 2MB 的模型发了一张出圈许可证——从此 Python 之外的每个运行时拿到的都是同一份行为一致的检测能力。【免费下载链接】silero-vadSilero VAD: pre-trained enterprise-grade Voice Activity Detector项目地址: https://gitcode.com/GitHub_Trending/si/silero-vad创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价