FunASR + SenseVoice Small 在Nvidia上推理优化技术方案
·
1. 背景与目标
- 模型:SenseVoice Small (基于 FunASR 框架)
- 场景:大规模语音转写(涉诈识别前置处理),需处理至少 2 万条数据。
- 痛点:原始流程中 VAD 分段耗时较长,且全精度(FP32)推理显存占用高、速度慢。
- 目标:在保持识别精度的前提下,提升吞吐量(QPS),降低显存峰值。
2. 方案详解
方案一:移除 VAD 预处理 (Direct Input)
2.1 核心逻辑
默认情况下,FunASR 会先加载一个 VAD 模型将长音频切割成短片段,再逐个送入 ASR 模型。方案一直接跳过 VAD,将原始音频文件直接输入 SenseVoice。
2.2 代码实现
from funasr import AutoModel
# 初始化模型时不加载 VAD
model = AutoModel(
model=model_dir, # SenseVoice Small 路径
trust_remote_code=True,
remote_code=remote_code_py,
# vad_model=None, # 关键:不指定 vad_model 或注释掉
device=f"cuda:{gpu}", # 指定具体 GPU 卡
disable_update=True,
hub="ms" # 建议从 ModelScope 加载,避免 HuggingFace 网络问题
)
# 推理调用
res = model.generate(
input=save_file_path,
cache={},
language="zh",
use_itn=True, # 启用逆文本标准化(数字转中文等)
batch_size_s=60, # 批处理大小(秒),根据显存调整
merge_vad=False, # 因为没做 VAD,此参数无效或设为 False
)
2.3 优缺点分析
|
维度 |
优势 |
风险/劣势 |
|---|---|---|
|
速度 |
极快。省去了 VAD 模型的加载和前向计算时间。 |
如果音频极长(>30s),单次推理耗时可能增加。 |
|
显存 |
较低。无需额外加载 VAD 模型权重。 |
显存峰值不可控。若直接输入长音频,Transformer 的注意力机制会导致显存随序列长度平方级增长。 |
|
精度 |
避免了 VAD 误切导致的语义断裂。 |
对于含大量静音的音频,模型可能会产生幻觉或重复输出。 |
|
适用性 |
适合短音频(<15s)或连续性强的通话录音。 |
不适合长达数分钟且中间有大量静音的录音。 |
方案二:FP16 半精度自动混合精度推理 (AMP)
2.1 核心逻辑
利用 PyTorch 的 torch.cuda.amp.autocast 上下文管理器,在支持的算子(如 Conv, Linear)上自动使用 Float16 进行计算,不支持的算子保持 Float32。
2.2 代码实现
import torch
from funasr import AutoModel
# 1. 模型初始化:保留 VAD 但优化参数,并尝试指定 dtype
model = AutoModel(
model=model_dir,
vad_model=vad_model_dir, # 建议保留 VAD,防止长音频显存爆炸
trust_remote_code=True,
device=f"cuda:{gpu}",
disable_update=True,
# 如果 FunASR 版本支持,直接在这里设置半精度
# dtype="float16"
)
# 2. 推理函数
def optimized_infer(audio_path):
"""
结合 FP16 和优化后的 VAD 参数
"""
with torch.cuda.amp.autocast(dtype=torch.float16):
res = model.generate(
input=audio_path,
cache={},
language="zh",
use_itn=True,
batch_size_s=60, # 根据显存剩余情况动态调整,A10/V100 可设更大
merge_vad=True, # 合并 VAD 切片,减少模型调用次数
merge_length_s=15, # 合并阈值:15秒内的片段合并为一个推理请求
max_single_segment_time=30000, # VAD 最大单段时长(ms),避免切得太碎
min_silence_duration_ms=500 # 静音阈值,适当提高以减少无效分段
)
return res
为什么推荐保留 VAD?
- 显存安全:涉诈录音有时长达几分钟。如果不做 VAD,直接送入 Transformer,序列长度过长会导致
OOM (Out Of Memory)。 - 并行效率:
merge_vad=True可以将多个短片段合并成一个 Batch 送入模型,比完全去掉 VAD 后串行处理长音频更高效。 - 噪音过滤:VAD 可以剔除开头的静音和中间的长时间停顿,减少模型对噪音的误识别。
4. 性能对比预估 (基于 A10/V100 32G)
|
指标 |
原始方案 (FP32 + 默认 VAD) |
方案 1 (去 VAD) |
方案 2 (FP16 + 优化 VAD) |
推荐方案 |
|---|---|---|---|---|
|
单条耗时 |
~1.5x |
~1.0x (短音频) / ~3.0x (长音频 OOM) |
~0.6x |
~0.7x |
|
显存峰值 |
High |
Medium (短) / Crash (长) |
Low |
Low |
|
识别稳定性 |
High |
Medium (长音频易出错) |
High |
High |
|
工程复杂度 |
Low |
Low |
Medium |
Medium |
5.实测
使用方案2,推理效率和速度翻倍,针对普通话,转写结果无明显差异,方言等会不一样,有时会更好,有时不如全精度的。
更多推荐

所有评论(0)