工程发布于 2026-02-12·约 11 分钟阅读
在手机上做说话人分离:深度复盘
我们如何在 4 瓦功耗预算下实时端到端做说话人分离——并且不上传一帧音频。
问题
说话人分离回答的是"谁在什么时候说话"。它把一堵文字墙变成一段对话。没有分离,"那就发吧"无名无姓;有分离,它落到一个具体的名字头上,变成一项行动项。
流水线
- VAD(语音活动检测) —— 给后面所有环节把门。只在真有语音时花算力。我们的 VAD 是一个 200 KB 的 CNN,作用于 log-mel 特征,每 10 毫秒跑一次。
- 说话人嵌入 —— 每段有声片段提取一个 192 维定长向量。我们用蒸馏到 12 MB int8 的 ECAPA-TDNN 系模型。
- 在线聚类 —— 带回归修正的层次聚类。新证据会更新旧标签。
- 平滑 —— 400 毫秒以内的短切换会被合并,防止 UI 闪烁。
移动端难在哪
- 嵌入模型要小到能和 ASR 模型、LLM 摘要在同一内存预算里并存。
- 聚类必须增量——不能每一步都把整场会议重聚。我们用一个恒定内存的在线层次聚类,用余弦距离。
- UI 不能因为回头修标签而闪。我们用 200 ms 的交叉淡入替代直接换字。
- 多人重叠说话破坏"单标签"假设。我们给这种区域贴上主导说话人,并把片段标记为"overlap",让下游摘要降权。
我们最后落到的方案
12 MB 嵌入模型,6 秒更新窗口的流式聚类算法,以及一个用动画切换标签、不再跳变的转写视图。在 iPhone 15 Pro 上端到端首标签延迟中位数 950 ms,Pixel 8a 上 1.6 s。
仍然难的地方
- "声音像"——同音域、同口音、同性别——会让嵌入在头 30 秒左右搞混。我们在 UI 里以"还在学习声音"的提示告知用户。
- 嘈杂房间里的串音会急剧退化。我们在尝试一个端侧的微型分离前置阶段。