@YichiZ03: https://x.com/YichiZ03/status/2078588932191895976

X AI KOLs Timeline 工具

摘要

MOSS-TD是一个说话人感知的ASR系统,在SGLang-Omni服务栈中进行了优化,能够在单张H100上以约49秒转录38分钟的多说话人音频,并支持16个会议的并发处理。

https://t.co/SbM1XD8dAf
查看原文
查看缓存全文

缓存时间: 2026/07/20 13:26

优化ASR模型以转录90分钟多说话人音频

概述

MOSS-TD 是一个说话人感知的 ASR(自动语音识别)系统:它不仅将语音转换为文本,还能识别出谁在说话以及说话的时间,适用于长达约 90 分钟的录音。贡献者将 MOSS-TD 集成到 SGLang-Omni 服务栈中,在此过程中修正了正确性问题,并叠加了一系列性能优化。关键成果:在单张 H100 上,一段 38 分钟的多说话人会议经过处理后,输出一份带有说话人标签和时间戳的转录文本,耗时约 49 秒——这比单纯听完录音的第一分钟还要快。如果同时运行 16 个这样的会议,同一 GPU 每秒处理约 97.5 秒的音频。本文档的其余部分将介绍这些数字背后的工程技术。

ASR 模型基础

ASR 输入音频波形,输出文本。MOSS-TD 采用“音频 LLM”设计:Whisper 风格的编码器将音频转换为连续嵌入,FFN 适配器将这些嵌入投影到仅解码器 LLM 的令牌空间中,然后 LLM 自回归地生成转录文本——包括说话人标签和时间戳。

整个流水线分三个阶段:

  • 编码器 — 将波形转换为 80 维对数梅尔频谱图,经过 24 层 Whisper Transformer 处理,通过合并相邻帧进行 4 倍下采样,再经过 FFN 适配器(Linear → SiLU → Linear → LayerNorm,4096→1024)投影为 LLM 嵌入空间中的连续嵌入向量。

  • LLM 预填充 — 这些嵌入替换提示中的占位令牌,Qwen3 处理整个提示以构建其 KV 缓存——对于短音频是一次前向传播,对于长音频则分为多个 4096 令牌的块(详见下文)。

  • 自回归解码 — Qwen3 逐个令牌生成转录文本,包括 [S01]/[S02] 等说话人标签和时间戳,直到遇到结束符。

组件规格
模型架构MossTranscribeDiarizeForConditionalGeneration
音频编码器Whisper 编码器(24 层,d_model=1024)
适配器FFN:Linear→SiLU→Linear→LayerNorm,4096→1024
文本解码器Qwen3(28 层,hidden=1024,GQA 16/8)
输出带说话人标签和起止时间戳的转录文本
端点/v1/audio/transcriptions

长音频的分块预填充

一段 90 分钟的录音可能产生数万个编码后的令牌。一次性预填充所有这些令牌会长时间占用 GPU 并导致激活内存激增——而且由于预填充和解码共享同一个调度循环,其他正在进行的请求的解码会在这段时间内全部停止。分块预填充避免了这个问题:它将序列拆分为每块 4096 个令牌,每个调度步骤处理一个块,并在其间穿插其他请求的解码步骤。代价是长请求本身的预填充会稍晚完成(分布在更多调度轮次中),但换来的是有界的解码停顿,以及共享 GPU 的其他请求的流畅处理。当请求处于分块预填充过程中时,流式输出会被完全抑制,因此中间内部状态不会泄漏出来像是转录文本。

ASR 与 TTS 对比

ASR 和 TTS 在 SGLang-Omni 中共享大部分服务机制——相同的 OmniScheduler、CUDA graph 处理、KV 缓存管理和连续批处理,并且两者都是带有 LLM 主干的自回归模型(MOSS-TD 和 MOSS-TTS 都恰好使用 Qwen3 是巧合——主干选择因模型而异)。它们真正不同的地方在于编码内容、生成内容以及流水线形状:

维度ASR (MOSS-TD)TTS (Higgs / MOSS-TTS)
音频表示连续特征(mel → 编码器隐藏状态)离散编解码令牌(RVQ 多码本)
数据流音频 → 文本文本 → 音频
音频解码器/声码器不需要——输出是纯文本需要用于重建波形
典型输入长度非常长(MOSS-TD 可处理约 90 分钟)短(参考语音:数秒)
流水线阶段单阶段(编码器 + LLM)多阶段(编码器 → AR 引擎 → 声码器)
流式输出增量文本输出流式音频 + 流式声码器

由于 ASR 从不涉及声码器,其工程挑战转移到了其他地方:长输入将真正的优化工作推向了自回归解码循环和长序列内存管理,而不是音频重建质量。关于 TTS 方面的故事,请参阅姊妹文章《优化 TTS 推理》(tts-optimization.md)。

时间消耗分析:性能剖析

在进行任何更改之前,团队在单张 H100(开启 CUDA graphs,bf16)上对 MOSS-TD 进行了性能剖析,以观察时间到底花在哪里。

音频长度并发数编码器LLM 预填充自回归解码
5 秒118.9%14.7%76.4%
5 秒420.0%22.3%57.7%
5 秒1638.2%29.7%32.1%
60 秒14.0%2.1%94.0%
60 秒45.0%4.6%90.4%
60 秒1613.7%9.5%76.8%
20 分钟14.7%0.8%94.5%
20 分钟49.2%1.9%88.9%
20 分钟1611.6%2.6%85.7%

两点突出:对于长音频且并发数为 1 时,解码占用超过 94% 的总时间,几乎全部的优化潜力都在这里;对于短音频且并发数为 16 时,编码器和预填充合计占比 68%,因此编码器侧的工作也值得做。

优化策略

大量优化工作复用了已为 TTS 服务构建的基础设施,并针对 ASR 更简单的流水线(无声码器、无多码本采样)进行了适配——CUDA graphs、异步解码和编码器缓存再次出现。

编码器

  • CUDA Graph. 由于 Whisper 编码器始终处理固定的 30 秒窗口(音频被切分为 30 秒的块,最后一块填充),每个块都具有相同的形状——因此编码器按每个请求的块数(默认最多 8 块,约 4 分钟音频)进行分桶,每个桶捕获自己的 CUDA graph,以消除每次调用的内核启动开销。

  • Torch Compile(可选启用). 作为 CUDA graph 的替代方案,torch.compile(self.whisper_encoder, dynamic=False) 在顶部增加了内核融合。默认的编译模式被有意跳过:reduce-overhead 模式管理自己的内部 CUDA graphs,这些图会与同一进程中运行的解码侧 CUDA graphs 冲突。这会牺牲第一次调用(每桶一次编译)的速度,以换取更稳定的稳态吞吐量,对于编码器密集、高并发、短音频的工作负载值得开启。

  • LRU 缓存. 编码器的输出对于给定输入是确定性的,因此输出被缓存在 CPU 上(最多 64 个条目,4 GB),以波形哈希为键;缓存命中时完全跳过编码器,并将缓存的嵌入异步复制回 GPU。与 TTS 不同(相同的参考语音经常在多个提示中重复使用),ASR 输入在生产环境中通常是唯一的——因此此缓存对重试、A/B 测试不同解码设置以及本地开发更有效,生产环境命中率不高。

自回归解码

  • CUDA Graph. 解码批量大小被填充到固定桶(1、2、4、8…),每次生成一个令牌时重放捕获的 CUDA graph——与 TTS 解码使用的技术相同。

  • 异步解码. 与 TTS 使用的一步超前技巧相同:启动当前解码步骤的 GPU 工作,同时并行处理上一步的主机侧工作(设备到主机拷贝、完成检查、分发结果)。批量大小为 1 时退化为同步执行,因为没有足够的主机侧工作来使重叠有意义。两个交替的固定主机缓冲区确保 GPU 的异步写入和 CPU 的读取不会竞争。这在高并发下显著提升了吞吐量,同一更改还修复了由超前机制超出范围导致的 KV 缓存槽泄漏。

  • 流式输出. 转录文本通过 SSE 在生成时流式输出,受三条规则约束:令牌按请求缓冲,默认在 50 毫秒窗口后刷新(第一个令牌立即输出,结束符始终强制刷新);所有流式输出在请求处于分块预填充时被抑制,因此中间状态永远不会看起来像转录文本;如果缓冲的令牌中途包含多字节 UTF-8 字符,则刷新会等待下一个令牌完成该字符。

批量推理

在编码器侧,不同长度的梅尔频谱图被对齐,以便多个请求可以共享一次批处理 Whisper 前向传播。在 LLM 侧,多个请求的令牌序列被打包到共享批次中,用于预填充和解码,从而在并发负载下保持高 GPU 利用率。

基准测试结果

基准测试使用了两个私有多说话人数据集,涵盖输入长度范围:

  • Movies(movies800times)—— 800 个短对话片段,每个约 12 秒。
  • AISHELL-4 Long(aishell4_long)—— 20 个长会议录音,每个约 38 分钟。

两个数据集均为私有许可;请联系 MOSS 团队获取访问权限。

这里关注两个指标:RTF(实时因子)是处理时间除以音频时长——小于 1 表示快于实时。audio_s/s 是每秒壁钟时间处理的音频秒数,这真正反映了批处理带来的吞吐量提升。

设置: 单张 H100 80GB,单 GPU 同地部署;MOSS-Transcribe-Diarize 采用 bf16,开启 CUDA graphs,贪心解码;服务器设置为 max_running_requests = cuda_graph_max_bs = 16,mem_fraction_static = 0.80。Movies 数据为 3 次运行的平均值;AISHELL-4 Long 每个数据点运行一次,因为每个请求是一段约 38 分钟的会议。精度在并发数 16 时测量一次(贪心解码使其与并发数无关)。

Movies——短多说话人对话(N=800)

并发数吞吐量 (req/s)RTF 均值audio_s/s延迟均值 (s)延迟 p95 (s)
14.550.02252.70.2190.500
28.400.02497.20.2380.544
414.960.027173.20.2670.610
824.900.033288.10.3210.714
1632.790.043379.50.4220.935

从并发数 1 到 16,吞吐量和 audio_s/s 均扩展约 7.2 倍(4.6→32.8 req/s;53→379 audio_s/s)。RTF 全程远低于 1(0.022→0.043,即大约 23–45 倍快于实时),平均延迟始终在亚秒级别。随着批次填满,短音频 ASR 更依赖编码器和预填充,因此每请求 RTF 逐渐上升,但总吞吐量继续攀升。

AISHELL-4 Long——长会议(N=20,每个约 38 分钟)

并发数吞吐量 (req/s)RTF 均值audio_s/s延迟均值 (s)延迟 p95 (s)
10.0210.02147.048.7771.1
20.0300.02869.764.9778.5
40.0340.04877.7110.2142.7
80.0370.08185.4184.8239.2
160.0430.12797.5291.0374.5

每个请求都是一段约 38 分钟的会议,解码占主导地位,因此每秒请求数自然低,RTF 是关键指标。单流已能将 38 分钟的会议在 约 49 秒 内转写完成(RTF 0.021,约 47 倍快于实时)。将并发数推到 16,总 audio_s/s 增加了一倍以上(47→97.5),req/s 也从 0.021 增加到 0.043;在批处理争用下,每请求延迟和 RTF 有所增长,但仍保持在 约 8 倍快于实时(RTF 0.127)——这是预期中的权衡:更高的总吞吐量以换取长音频单请求更高的延迟。

精度

在并发数 16 下使用贪心解码测量。CER 是字符错误率;cpCER 添加了最小排列对齐以计入说话人分配;Δ CER 是两者之差,归因于说话人分配错误;DER 是说话人时间戳的日志化错误率。

数据集样本数CER (%)cpCER (%)Δ CER (%)说话人时间戳 DER (%)
Movies8005.9213.127.2021.20
AISHELL-4 Long2013.7615.071.3110.25

模型使用

请参阅 MOSS-TD 操作指南以获取部署和使用说明。

后续计划

仍有若干优化工作在持续进行中:

  • 流式音频输入 — 音频到达时逐步转录,而不是等待整个片段上传完毕。
  • 分块预填充 CUDA Graph — 将分块预填充本身捕获为 CUDA graph。
  • 张量并行 — 多 GPU TP 支持,针对非常长的音频文件,其 KV 缓存可能超出单 GPU 内存。

致谢

这项工作体现了 OpenMOSS 团队与 SGLang-Omni 团队的共同努力。

MOSS 团队: 董浩宇、林政远、陈汉夫、张毅阳、高阳、费昭烨、程钦远、李仕敏、邱锡鹏。

SGLang-Omni 团队: 田逸江、景新力、柯祥瑞、郭志豪、张若一、沈立凡、曲金涛、田旭翔、李凯歌、Ratish P、蔡浩广、夏子杰、洪辰辰、叶学松、顾靖雯、邓嘉欣、罗嘉轩、卢心雨、金浩、赵辰阳、张一驰。

了解更多

  • 模型: OpenMOSS-Team/MOSS-Transcribe-Diarize
  • 服务框架: SGLang-Omni on GitHub
  • 操作指南: MOSS-TD in SGLang-Omni
  • ASR 优化路线图: tracking issue on GitHub
  • TTS 优化博客: Optimizing TTS Inference (tts-optimization.md)
  • 编码器偏差分析: The Root Cause of RL Training-Serving Skew (moss-tts-local-batch-encoder-skew.md)

相似文章

OpenMOSS-Team/MOSS-TTS-Nano-100M

Hugging Face Models Trending

MOSS-TTS-Nano是一个开源的多语言语音生成模型,仅0.1B参数,专为实时TTS设计,可直接在CPU上运行而无需GPU。由OpenMOSS团队和MOSI.AI发布,它支持简单的本地部署,用于Web服务和产品集成。

OpenMOSS-Team/MOSS-TTS-v1.5 · Hugging Face

Reddit r/LocalLLaMA

MOSS-TTS v1.5是一个更新的开源文本转语音模型,具有改进的多语言合成(支持31种语言)、更稳定的零样本语音克隆以及显式的内联停顿控制。