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?

  1. 显存安全:涉诈录音有时长达几分钟。如果不做 VAD,直接送入 Transformer,序列长度过长会导致 OOM (Out Of Memory)
  2. 并行效率merge_vad=True 可以将多个短片段合并成一个 Batch 送入模型,比完全去掉 VAD 后串行处理长音频更高效。
  3. 噪音过滤: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,推理效率和速度翻倍,针对普通话,转写结果无明显差异,方言等会不一样,有时会更好,有时不如全精度的。

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐