语音转写前怎样用 VAD 切除静音区
来源:17golang原创
时间:2026-10-17 23:46:37 371浏览 收藏
会议录音、客服语音或手机采访交给 ASR 前,先用 VAD(Voice Activity Detection,语音活动检测)找出真正有人声的区间,通常能减少无效音频和长静音带来的等待时间。稳妥做法不是把所有低能量片段直接删掉,而是先得到语音时间戳,再为每段保留少量前后上下文,最后把原始偏移一起传给转写环节。
官方地址:https://github.com/snakers4/silero-vad
如果目标只是切掉静音,先把 VAD 当成“边界检测器”,不要把它当成最终转写器。真正影响结果的是采样率、静音持续时间和边界 padding 三组参数。
- Silero VAD 常用 8 kHz 或 16 kHz 输入,先统一音频格式再检测。
- threshold 决定“像不像语音”,min_silence_duration_ms 决定何时断开,speech_pad_ms 用来保护词头词尾。
- 切段后必须保存原始 start/end;只拼接语音会让后续字幕时间轴失真。
先把采样率与 VAD 输入边界固定下来
VAD 的输入边界要比 ASR 的模型选择更早确定。以 Silero VAD 为例,官方实现支持 8000 和 16000 Hz;录音是 44.1 kHz 或 48 kHz 时,应先用音频工具重采样到目标采样率,而不是把原始采样率直接塞给检测函数。还要统一声道和张量形状,否则同一组参数在不同文件上的边界会漂移。
下面的调用只展示数据关系,不代表已经在本机执行。return_seconds=True 让时间戳直接用秒表示,后续回写 ASR 结果更直观。
import torch
# 载入官方模型与工具;实际项目应固定依赖版本并缓存模型文件
model, utils = torch.hub.load(
repo_or_dir="snakers4/silero-vad",
model="silero_vad",
trust_repo=True,
)
get_speech_timestamps, _, read_audio, _, _ = utils
SAMPLE_RATE = 16000 # 只使用模型支持的采样率
wav = read_audio("input.wav", sampling_rate=SAMPLE_RATE)
# start/end 是语音区间;阈值和边界参数应按业务录音调参
timestamps = get_speech_timestamps(
wav,
model,
sampling_rate=SAMPLE_RATE,
threshold=0.5,
min_speech_duration_ms=250,
min_silence_duration_ms=220,
speech_pad_ms=120,
return_seconds=True,
)

用三个参数控制“切得干不干净”
threshold 越高,越不容易把背景噪声当成人声,但轻声和远场说话也更可能被漏掉;min_silence_duration_ms 太小会把一句话切碎,太大又会把两句话粘在一起;speech_pad_ms 则给每个区间补边,重点保护爆破音、词头和词尾。工程上不要先追求“静音绝对为零”,应先保证关键字不被截断。
| 参数 | 解决的问题 | 调整方向 |
|---|---|---|
| threshold | 噪声误报或轻声漏检 | 噪声多时上调,远场轻声多时下调 |
| min_silence_duration_ms | 短停顿是否切段 | 对话快时减小,长句多时增大 |
| speech_pad_ms | 词头词尾被削掉 | 先保守增加,再观察 ASR 重复字 |
| max_speech_duration_s | 长段不利于转写 | 按 ASR 上下文窗口拆分,并保留偏移 |
VAD 只给出候选边界,混响、音乐、多人重叠说话和笑声都可能改变概率曲线。调参时应抽取一批真实录音,分别观察漏切、误切和重复字,而不是只用一段安静样本决定阈值。
保留上下文,再把分段交给转写模型
拿到时间戳后,不建议直接把各段首尾裁到极限。可以用 100~200 毫秒的 padding 扩展区间,并把相邻扩展后重叠的区间合并;这样既减少句首丢字,也避免 ASR 在两个片段之间失去语境。合并后的每段仍要记录原始坐标。
def expand_segments(timestamps, total_seconds, pad_seconds=0.12):
# 扩展边界并合并相交区间,避免词头词尾被硬切开
expanded = []
for item in timestamps:
start = max(0.0, item["start"] - pad_seconds)
end = min(total_seconds, item["end"] + pad_seconds)
if expanded and start

常见问题
VAD 切完后,转写结果少了句首怎么办?
先增加 speech_pad_ms 或扩展分段的前置 padding,再检查采样率和 threshold;不要一开始就把阈值调得很低。
静音切除后为什么字幕时间对不上?
通常是只保存了拼接音频,没有保存每段在原文件中的 start/end。转写结果必须带回原始偏移,再生成字幕时间轴。
VAD 能代替说话人识别吗?
不能。VAD 只判断某个时间段是否存在语音活动,不负责区分是谁在说,也不负责把多人重叠语音分离开。
这套流程的边界很清楚:VAD 负责找语音区间,padding 负责保护边界,ASR 负责识别文字,时间偏移负责把结果放回原音频。先固定输入格式,再用真实录音调三个参数,切静音才不会变成“少字但更快”的假优化。
-
284 收藏
-
387 收藏
-
328 收藏
-
426 收藏
-
147 收藏
-
318 收藏
-
413 收藏
-
390 收藏
-
461 收藏
-
262 收藏
-
158 收藏
-
199 收藏
-
119 收藏
-
147 收藏
-
219 收藏
-
433 收藏
-
297 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习