说话人日志:识别音频中谁在何时说话

FreeGuideOnline 最新 2026-06-19

什么是说话人日志

说话人日志(Speaker Diarization),也常被称为声纹分割聚类,回答了一个基础却实用的问题:音频中谁在什么时候说话。与单纯识别讲话内容(语音识别)不同,它专注于辨别“谁”在发声,并将每个片段与对应的说话人关联起来。这项技术是构建对话分析系统、会议记录工具、呼叫中心质检与智能助理的核心组件。

一个完整的说话人日志系统,输入是一段包含多人交替发言的音频,输出则是带有说话人标签的时间轴,通常格式为:

[00:00.00 – 00:03.50] 说话人 A
[00:03.52 – 00:07.10] 说话人 B
[00:07.12 – 00:12.40] 说话人 A
...

注意,系统并不需要事先知道说话人是谁,它自动区分出“有几个不同的人”并分配匿名标签(如 Speaker_0、Speaker_1)。当与声纹识别(Speaker Recognition)相结合时,可以为标签赋予真实姓名。

说话人日志的核心流程

经典的说话人日志系统通常包含以下四个核心步骤,每个步骤都可以由传统信号处理方法或深度学习模型完成。

1. 语音活动检测

语音活动检测(Voice Activity Detection,VAD)用于判断哪段时间轴上有语音,筛除静音、噪声等非语音片段。这是后续步骤的基础,直接决定了待处理音频段的纯净程度。现代 VAD 多采用轻量级神经网络,在帧级别进行“语音/非语音”二分类。

2. 声学特征提取

在检测到的语音片段上,系统将原始波形转换为适合建模的声学特征。最常用的特征是梅尔频率倒谱系数(MFCC),它模仿了人耳对不同频率的感知特性。近年来,基于深度说话人嵌入(Deep Speaker Embedding)的方法成为主流,例如使用 x-vector、d-vector 或 ECAPA-TDNN 模型提取固定维度的向量,该向量可以紧凑地表征说话人的声纹特性。

3. 说话人分割与聚类

这是说话人日志中最为关键的环节,又可以细分为两种实现路径:

  • 先分割再聚类:将语音按照固定长度切成小段,提取每个小段的说话人嵌入,然后使用聚类算法(如 K-means、谱聚类、层次凝聚聚类 AHC)将这些小段归并为属于同一说话人的簇。AHC 结合贝叶斯信息准则(BIC)的变体曾是工业界标配。
  • 端到端日志系统:利用序列到序列模型直接预测每帧属于哪个说话人。例如基于编码器-解码器-吸引子(EEND-EDA)的架构,可以同时处理重叠语音,不再显式依赖分离的聚类步骤。这类方法对重叠说话场景更友好,但对训练数据要求较高。

4. 后处理与重叠语音处理

聚类结果可能存在短暂的错误切换或孤立短片段,需要通过中值滤波、重分割技术等进行平滑。对于两人同时讲话的重叠区域,传统聚类方法容易出现漏标或误标。专门的目标说话人语音活动检测(Target-Speaker VAD)重叠语音检测模块可以识别并分离这些难例,进一步优化最终结果。

动手实践:用 Python 实现一个简易说话人日志系统

下面我们使用 pyannote.audio 这个开源工具包,快速搭建一个可用的说话人日志流水线。pyannote.audio 基于 PyTorch,提供了预训练模型,在学术和工业界都有广泛应用。

环境准备

pip install pyannote.audio

你将需要一个 Hugging Face 账号来接受模型使用协议,并使用令牌访问模型。在代码中设置环境变量或通过 huggingface-cli 登录。

执行说话人日志

假设你有一段名为 meeting.wav 的音频文件。

from pyannote.audio import Pipeline

# 加载预训练的说话人日志流水线
pipeline = Pipeline.from_pretrained(
    "pyannote/speaker-diarization-3.1",
    use_auth_token="YOUR_HF_TOKEN"
)

# 对音频进行日记分析
diarization = pipeline("meeting.wav")

# 输出结果
for turn, _, speaker in diarization.itertracks(yield_label=True):
    print(f"start={turn.start:.1f}s stop={turn.end:.1f}s speaker_{speaker}")

输出示例:

start=0.5s stop=2.3s speaker_SPEAKER_00
start=2.8s stop=5.1s speaker_SPEAKER_01
start=5.4s stop=9.8s speaker_SPEAKER_00