会议记录一直是从业者绕不开的低效环节:录音回听、手动标记发言人、再从中提取待办事项,整个过程消耗的时间可能接近会议本身。OpenAI 开源的 Whisper 模型让语音识别不再是障碍,但要把 Whisper 真正用到会议上,还需要解决流式音频切割、说话人归属和纪要生成三个问题。本文将这三部分串成一条可落地的链路,并给出核心代码。

实时转录并不是把整段录音一次性丢给模型,而是把不断到来的音频流按固定时间窗切块后持续识别。这个思路看似简单,但直接切块会出现单词截断、说话人切换错位等问题,所以需要在工程上做额外处理。
实时转录的音频缓冲与分片
Whisper 模型本身更适合处理 30 秒左右的音频片段。会议录音如果长达一小时,直接调用 transcribe 会占用大量内存,而且必须等整段录完才能出结果。实时方案通常维护一个环形缓冲区,每当累积到 10 秒音频就取出一块交给模型。块与块之间保留 1 到 2 秒重叠,能有效避免句尾最后一个词被切断。
下面的代码使用 faster-whisper 处理单个音频文件,这是实时方案的基础。实际流式场景中可以把 meeting_0001.wav 换成每 10 秒保存一次的临时切片文件。
from faster_whisper import WhisperModel
model = WhisperModel("small", device="cpu", compute_type="int8")
segments, info = model.transcribe(
"meeting_0001.wav",
language="zh",
vad_filter=True,
vad_parameters=dict(min_silence_duration_ms=500)
)
for segment in segments:
print(f"[{segment.start:.2f}s - {segment.end:.2f}s] {segment.text}")
这里启用了 VAD 过滤,让模型跳过静音区域,可以减少无效推理。对于会议场景,VAD 参数需要根据会议室底噪调整。如果环境里有空调或键盘声,把 min_silence_duration_ms 设得太小会导致频繁分段,反而增加延迟。
另一个容易被忽略的点是时间戳对齐。分片推理得到的是片段内的时间戳,需要加上该片段在整段录音中的偏移量。重叠部分还要做去重,否则同一句话会出现在两条记录里。常见做法是只保留重叠区域内首次出现的完整词,后续片段从非重叠边界继续拼接。
说话人分离与文本对齐
会议记录只有逐字稿是不够的,必须知道每句话是谁说的。Whisper 不负责说话人识别,需要额外引入说话人分离模型。常用的 pyannote.audio 可以把录音切分成若干语音活动段,并为每段标注 SPEAKER_00、SPEAKER_01 这样的临时身份。
from pyannote.audio import Pipeline
pipeline = Pipeline.from_pretrained(
"pyannote/speaker-diarization-3.1",
use_auth_token="YOUR_HF_TOKEN"
)
diarization = pipeline("meeting_0001.wav")
for turn, _, speaker in diarization.itertracks(yield_label=True):
print(f"{turn.start:.1f}s - {turn.end:.1f}s {speaker}")
说话人分离的结果与 Whisper 的文本段并不天然对齐,因为两套模型对语音边界的判断不同。简单做法是取每个 Whisper 文本段的中点时间,再判断它落在说话人分离结果的哪个区间内。对于短句和抢话场景,中点法可能出现归属错误,但多数会议记录中已经够用。
如果需要更精确的说话人身份,可以先用语音片段提取声纹特征,再与参会者的注册声纹做比对,把 SPEAKER_00 映射成真实姓名。这个步骤属于说话人识别,和说话人分离是两个概念,项目实施前需要区分清楚。
会议纪要生成:从逐字稿到结构化输出
拿到带说话人标签的逐字稿后,下一步是生成会议纪要。这里不建议把所有内容直接丢给通用模型,那样容易得到一段没有重点的复述。更好的做法是设计提示词,让模型先识别议题,再按议题归并讨论内容,最后提取结论和待办事项。
prompt = """
你是一名会议助理,请根据以下会议逐字稿生成会议纪要。
要求:
1. 用中文输出
2. 先列出本次会议讨论的议题
3. 每个议题后给出关键结论
4. 从内容中提取待办事项,包括负责人和截止时间
5. 原文未明确的信息一律标注为未明确
会议逐字稿:
{transcript}
"""
这段提示词把任务拆成了四个部分:议题、结论、待办和未明确项。这样生成结果更容易保持结构稳定,也不会在原文没有信息时自行编造负责人。对于技术团队,还可以在提示词中要求模型保留技术名词原文,避免翻译造成歧义。
如果逐字稿过长,超过大模型上下文窗口,可以先按 15 分钟或 4000 字做切分,对每个分片生成局部摘要,再对局部摘要做全局合并。二次合并时只输入摘要而不是完整逐字稿,能显著降低成本,同时保留足够信息用于最终纪要。
本地部署优化与常见坑
Whisper 模型有多个尺寸。会议转写对准确率要求较高时,small 在中文场景下能取得不错的平衡,medium 或 large-v3 更稳但更慢。若使用 GPU,可以搭配 faster-whisper 的 float16 推理;若只有 CPU,int8 是更务实的选择,延迟会高一些,但离线场景通常可接受。
实时转录的瓶颈往往不在模型推理,而在音频采集和文件读写。可以先把麦克风采集的 PCM 数据写入内存队列,由后台线程定期切片,避免磁盘 IO 阻塞主流程。同时不要在每次切片时重新加载模型,模型应在进程启动时初始化一次,常驻内存。
常见坑包括:采样率不一致导致转录结果变差,录音设备默认可能是 44.1kHz 而 Whisper 内部需要 16kHz;VAD 静音判断过严会吞掉轻声发言;说话人分离模型需要 Hugging Face 授权令牌,未配置时会在加载阶段直接报错。逐一检查这些点,能减少大部分现场问题。