SpeakerLM 技术全解:端到端 SDR 大模型的架构设计与工程落地
SpeakerLM最大的贡献在于它把“声纹识别”变成了一种“阅读理解”任务——LLM 看着声纹 Embedding 的提示,听着音频,结合上下文逻辑来判断是谁在说话。复现路线图下载和ERes2NetV2预训练模型。准备。构建包含的数据集。编写 Projector 网络(简单的 MLP+CNN 即可)。按照1/3 概率混合策略进行微调训练。博主注:目前 SpeakerLM 的官方代码尚未完全开源,但
SpeakerLM 技术全解:端到端 SDR 大模型的架构设计与工程落地
摘要:在多人会议转写和语音分析领域,“谁说了什么”(SDR)一直是“老大难”问题。传统的级联系统(VAD+聚类+ASR)误差累积严重,无法利用语义信息。
2025年发布的 SpeakerLM 提出了一种端到端的“大一统”方案:利用多模态大模型(LLM)统一建模声纹、语音和文本。本文将从模型架构原理到工程实现细节(数据构造、Prompt设计、训练策略)进行全方位拆解,为开发者提供一份可复现的技术方案。
第一部分:为什么选择 SpeakerLM?(背景与架构)
1.1 传统方案 vs. SpeakerLM
在工程实践中,解决 SDR 任务通常有两种路径:
-
传统级联路径 (Cascade Pipeline):
-
Audio -> VAD -> Embedding提取 -> 聚类(Clustering) -> ASR -> 对齐 -
痛点:聚类算法(如 Spectral Clustering)是“瞎”的,它听不懂“大家好,我是主持人”这种语义信息;且 VAD 切错了,后面全错。
-
-
SpeakerLM 端到端路径 (E2E Pipeline):
-
[Audio + Speaker Prompts] -> LLM -> Text with Speaker Tags -
优势:LLM 同时利用声纹相似度(听声识人)和上下文语义(逻辑推理)来判断说话人,鲁棒性极强。
-
1.2 模型核心组件选型
SpeakerLM 采用 Encoder-Adapter-LLM 架构,各组件均选用了目前的 SOTA 模型:
| 模块 | 模型选型 | 作用 |
|---|---|---|
| Audio Encoder | SenseVoice-large | 阿里开源的强力语音编码器,支持多语言,能提取细粒度的语音特征。 |
| Speaker Encoder | ERes2NetV2 | 来自 3D-Speaker 项目,专门用于提取高区分度的声纹 Embedding (d=192)。 |
| Projector | Transformer (2-layers) + CNN | 将 Audio/Speaker 特征映射对齐到 LLM 的维度 (d=4096)。 |
| LLM Backbone | Qwen2.5-7B-Instruct | 基座模型,具备极强的指令遵循(Instruction Following)能力。 |
第二部分:核心算法与工程实现
2.1 独创的“灵活注册机制” (Flexible Registration)
这是 SpeakerLM 的灵魂。为了适应真实业务中“有时知道谁参会,有时不知道”的情况,工程上需要实现三种数据流。
核心逻辑代码复现(伪代码)
在训练数据加载器(Dataloader)中,我们需要实现如下动态采样逻辑 :
import random def build_training_sample(audio_clip, speakers_ground_truth, all_speaker_pool): """ 动态构建训练样本,模拟三种注册场景 """ prob = random.random() # --- 场景 1: Match-Regist (精准匹配) --- # 概率 < 1/3: 就像会议系统,已知参会人名单 if prob < 0.33: mode = "Match-Regist" registered_list = speakers_ground_truth # --- 场景 2: No-Regist (盲分模式) --- # 概率 1/3 ~ 2/3: 完全未知,让模型自己聚类 elif prob < 0.66: mode = "No-Regist" registered_list = [] # 清空注册列表 # --- 场景 3: Over-Regist (抗干扰/过注册) --- # 概率 > 2/3: 名单里混入了不在场的人,训练模型抗幻觉 else: mode = "Over-Regist" # 1. 取出真实说话人 true_spks = speakers_ground_truth # 2. 随机从数据库采样 1~50 个干扰说话人 num_distractors = random.randint(1, 50) distractors = random.sample(all_speaker_pool, num_distractors) # 3. 混合并打乱顺序 registered_list = true_spks + distractors random.shuffle(registered_list) # 构建最终 Prompt prompt = construct_prompt_template(mode, registered_list) return prompt, audio_clip
2.2 Prompt 模板工程设计
Prompt 是驱动 LLM 工作的指令。我们需要将文本指令和声纹 Embedding 拼接在一起。
工程模板如下:
<|im_start|>system You are a helpful assistant.<|im_end|> <|im_start|>user # 如果是 Match/Over 模式,插入声纹信息 Registered Speaker Embeddings: <Speaker_ID_A> <start>Embedding_Tensor_A<end>; <Speaker_ID_B> <start>Embedding_Tensor_B<end>; ... # 任务指令 Transcribe by roles. (PS: There are no specific requirements about the speaker order.) # 输入语音 <start>Input_Audio_Features<end><|im_end|> <|im_start|>assistant
实现细节:
-
Special Tokens:需要向 Tokenizer 添加
<start>和<end>标记,告诉 LLM 中间包裹的是非文本的模态特征。 -
Embedding 映射:声纹 Embedding (192维) 必须先过一个 Linear Layer 变成 (4096维) 才能拼接到 Prompt 中。
第三部分:训练与数据工程指南
3.1 数据准备 (Data Preparation)
要复现 SpeakerLM,你需要构建一个包含以下字段的 JSON 数据集:
{
"key": "session_123",
"wav_path": "/data/wavs/session_123.wav",
"text_label": "Speaker A: Hello world. Speaker B: Hi there.",
"speakers": [
{
"spk_id": "Speaker A",
"embedding_wav": "/data/enroll/spk_a.wav" // 用于提取声纹的参考音频
},
{
"spk_id": "Speaker B",
"embedding_wav": "/data/enroll/spk_b.wav"
}
]
}
3.2 两阶段训练策略 (Two-Stage Training)
为了防止 LLM 遗忘文本知识,训练必须分步进行 :
-
Stage 1: ASR 预热 (SpeakerLM-ASR)
-
数据:纯 ASR 数据(如 WenetSpeech, GigaSpeech),量级通常在 10k+ 小时。
-
Prompt:
Transcribe the speech. -
目的:让 Projector 学会把音频变成 LLM 能懂的 Token,此时不引入声纹注册。
-
-
Stage 2: SDR 核心训练 (SpeakerLM)
-
数据:Diarization 数据(如 MagicData-RAMC, AISHELL-4),包含精确的说话人轮替标签。
-
Prompt:启用上述的
Match/No/Over混合采样策略。 -
关键 Trick:Over-Regist 数据的比例要足够(论文建议 1/3),否则模型很容易在推理时把 Prompt 里提到的人强行分配台词,哪怕他没说话。
-
第四部分:推理与部署 (Inference)
在实际业务部署时,针对长会议音频,建议采用滑动窗口 (Sliding Window) 策略:
-
分块:将长音频切分为 30s 或 60s 的片段。
-
全局声纹池:如果是已知说话人会议,构建全局的
Match-RegistPrompt。 -
流式处理:
-
将当前窗口音频 + 全局声纹 Prompt 输入 SpeakerLM。
-
LLM 输出当前片段的
Speaker: Text结果。 -
拼接文本。
-
总结与展望
SpeakerLM 最大的贡献在于它把“声纹识别”变成了一种“阅读理解”任务——LLM 看着声纹 Embedding 的提示,听着音频,结合上下文逻辑来判断是谁在说话。
复现路线图:
-
下载 SenseVoice-large 和 ERes2NetV2 预训练模型。
-
准备 Qwen2.5-7B-Instruct。
-
构建包含
<Audio, Enroll_Audio, Text>的数据集。 -
编写 Projector 网络(简单的 MLP+CNN 即可)。
-
按照 1/3 概率混合策略进行微调训练。
博主注:目前 SpeakerLM 的官方代码尚未完全开源,但在 ModelScope 的
3D-Speaker和FunAudioLLM仓库中可以找到其核心组件的实现。建议先关注这些项目,利用本文提供的架构图自行搭建 MVP 版本。
论文概括
论文标题:SpeakerLM:基于多模态大语言模型的端到端多功能说话人日志与识别系统
(SpeakerLM: End-to-End Versatile Speaker Diarization and Recognition with Multimodal Large Language Models)
1. 摘要 (Abstract)
原文译意: 说话人日志与识别(SDR)任务旨在预测音频片段中“谁在什么时间说了什么”,这是会议转写和对话系统等真实多说话人场景中的关键任务。现有的 SDR 系统通常采用级联管道(Cascade pipeline),即分别进行说话人日志(Diarization)和自动语音识别(ASR)。这种方法存在两个主要局限性:一是缺乏对文本和音频上下文的联合建模;二是级联导致的误差传播问题。 为了解决这些限制,我们推出了 SpeakerLM,这是一个统一的多模态大语言模型,能够以端到端的方式联合执行说话人日志(SD)和语音识别(ASR)。 此外,为了适应多样化的真实场景,我们在 SpeakerLM 中引入了一种灵活的说话人注册机制(Speaker Registration Mechanism),使其能够在不同的注册设置下工作。 实验表明,SpeakerLM 展现了强大的数据扩展能力和泛化能力,在域内和域外的公共基准测试中均优于最先进的级联基线模型。
2. 核心模型架构 (Model Architecture)
SpeakerLM 采用经典的 Encoder-Projector-LLM 架构,具体组件如下:
-
语音编码器 (Audio Encoder):
-
使用预训练的 SenseVoice-large 编码器。
-
作用:提供强大的音频表征,擅长多语言识别和音频事件检测。
-
-
音频投影器 (Audio Projector):
-
由一个随机初始化的 2 层 Transformer 和一个 CNN 层组成。
-
作用:将音频特征对齐到 LLM 的维度。
-
-
声纹提取器 (Embedding Extractor):
-
使用预训练的 ERes2NetV2 模型(来自 3D-Speaker 项目)。
-
作用:提取具有判别性的声纹特征,对于识别“谁是谁”至关重要。提取出的 Embedding 会经过一个线性层(Linear Layer)进行维度对齐。
-
-
大语言模型基座 (LLM Backbone):
-
使用 Qwen2.5-7B-Instruct。
-
作用:利用其强大的指令遵循和通用语言理解能力,处理复杂的多说话人任务。
-
3. 核心创新:灵活的说话人注册机制 (The Flexible Speaker Registration Mechanism)
这是论文最硬核的部分。为了让模型适应各种情况(比如:不知道谁在说话、知道部分人、或者名单里有不在场的人),作者设计了三种模式,并在训练中混合使用。
三种注册模式
-
无注册 (No-Regist)
-
含义:不提供任何声纹信息,让模型自己盲分(Blind Diarization)。
-
Prompt 模板:
You are a helpful assistant. Transcribe by roles. <start>语音路径<end>
-
-
匹配注册 (Match-Regist)
-
含义:提供当前音频中所有说话人的声纹信息(类似于会议签到,知道谁会说话)。
-
Prompt 模板:列出每个人的 ID 和对应的声纹 Embedding。
-
-
过注册 (Over-Regist)
-
含义:提供的声纹名单中包含了“干扰项”(即不在场的人)。
-
目的:训练模型辨别“谁在场,谁不在场”,防止模型产生幻觉。
-
训练策略 (Training Strategy)
在训练过程中,每个 Batch 的数据会随机分配一种模式,以强制模型学会所有能力:
-
< 1/3 概率:使用 Match-Regist(标准匹配)。
-
1/3 ~ 2/3 概率:使用 No-Regist(移除所有注册信息)。
-
> 2/3 概率:使用 Over-Regist(随机从其他会话中抽取 1 到 50 个说话人作为干扰项加入 Prompt)。
4. Prompt 设计细节 (Prompts for LLMs)
论文公开了具体的 Prompt 构建方式,这对于复现至关重要。
场景假设:
-
实际说话人:Mike, Lucy, Jack
-
干扰说话人(不在场):Andy, Rose, Frank
LLM Prompt 示例 (Over-Regist 模式):
System: You are a helpful assistant.
User: Registered Speaker Embeddings: Mike
<start>path to Mike's embedding<end>; Lucy<start>path to Lucy's embedding<end>; Jack<start>path to Jack's embedding<end>; Andy<start>path to Andy's embedding<end>; Rose<start>path to Rose's embedding<end>; Frank<start>path to Frank's embedding<end>;Transcribe by roles.
<start>path to the multi-speaker speech<end>(PS: Andy, Rose, and Frank are over-registered speakers.)
模型输出 (Output): 模型会直接输出带说话人标签的文本,例如:
Mike: Hello everyone. Lucy: Hi Mike.
5. 训练流程 (Training Pipeline)
SpeakerLM 采用了 多阶段训练 (Multi-Stage Training) 策略:
-
第一阶段:SpeakerLM-ASR
-
任务:纯 ASR(自动语音识别)。
-
数据:使用纯语音数据。
-
Prompt:
Transcribe the speech. -
目的:让音频编码器和 LLM 对齐,确保模型能听懂内容。
-
-
后续阶段:SpeakerLM (SDR)
-
任务:SDR(日志 + 识别)。
-
数据:使用带有说话人标签的真实对话数据。
-
操作:引入上述的三种注册机制(No/Match/Over-Regist),联合训练模型识别说话人身份和内容的对应关系。
-
6. 结论 (Conclusion)
SpeakerLM 是首个能够执行 SDR 任务的音频-文本多模态大模型。它通过统一的架构整合了语音内容理解和说话人感知建模。特别是其提出的说话人注册机制,使得模型能够灵活处理未知、部分已知或包含干扰项的说话人场景,解决了现有系统需要精确预注册的痛点。实验证明,该方法不仅在性能上超越了传统的级联系统,还具备极强的鲁棒性。
更多推荐



所有评论(0)