TT Lab
博客

한국어 English 日本語 中文

开始
博客

博客

用数字验证语音对话的原理:解码看内存带宽,合成看帧数,流式看缓存

状态:草稿(2026-10-06),这是一篇原理文章。 原理说明基于各模型的官方资料(文末有链接)及常规推理理论,核对所使用的数字是笔者在 第 20 篇中实际测得的值。计算公式为了解现象进行了简化,每一节都说明了哪些部分经过了验证、哪些部分属于推测。 编写规则:以实测数据为基础,未能测得的数据标记为“未实测”。

目录

1. 一目了然:各组件决定时间的方式各有不同

第 20 篇的值是“花了多少时间”,而这篇文章探讨的是“为什么会花这么多时间”。

组件 决定时间的因素 原理预测值 实测值 一致性
对话大模型,Token 生成 每个 Token 从内存中读取整个权重的时间 上限约 129 tok/s(基于测得的带宽) 85.6 tok/s 上限的 66%
对话大模型,输入处理 计算量 远快于生成 700 tok/s(67个 Token),1024个 Token 以上时约为计算上限的 75~80% 一致,短输入较慢
生成速度的带宽上限 权重字节数 × 速度 ≤ 带宽 测得带宽 250GB/s 四个模型中占 86~98% 一致
语音合成(VoxCPM2) 需要生成的补丁(步数)数量 音频 1秒 = 6.25个补丁(一个补丁 = 160ms 的量) 每秒 0.475秒,每补丁约 76ms 通过计算连接,与论文结构一致
流式语音识别 区块 = 帧数 × 80ms 5 种区块 与显卡的 5 个值核对一致 一致

2. 对话大模型:每生成一个 Token 就要完整读取一次模型

原理

Transformer 要计算下一个 Token,必须完整使用每一层的权重一次。如果只有一个请求,每个权重只需进行一两次乘法运算便结束,GPU 的计算单元处于闲置状态, 从内存加载权重的速度(内存带宽) 决定了时间。因此,Token 生成速度的理论上限如下。

초당 토큰 수 ≤ 메모리 대역폭 ÷ 가중치 바이트 수

相反,处理输入(提示词)的阶段会同时计算几十个 Token,因此多个 Token 会重复使用相同的权重,此时计算能力是瓶颈。这就是同一模型下输入处理比生成快得多的原因。

核对

项目 值 出处
GPU 内存带宽 约 905GB/s(24GB 级消费级 GPU,仅读取合计,重复 3 次 903~905) 直接测量(用 PyTorch 进行读取 1GiB 张量的测试)。复制(读取+写入)为 865GB/s。规格说明书中的约 936GB/s 是依赖记忆的值,故不采用
权重(4-bit QAT) 7.0GB 通过公开 API 确认模型文件大小
理论上限 905 ÷ 7.0 ≈ 129 tok/s 计算
测得的生成速度 85.6 tok/s(每 Token 11.6ms) 第 20 篇测量,与服务器日志测得的一致
效率 85.6 ÷ 129 ≈ 66% 计算
输入处理速度 700 tok/s(67个 Token 耗时 95.7ms) 服务器测量

直接验证:用大小和精度不同的模型确认上限

由于上述核对中的带宽值取自规格说明,因此无法确认上限本身是否正确。为此,我们在单张 8GB 级 GPU 上 首先直接测量带宽,并用相同方法测量了大小和精度不同的四个模型的生成速度(vLLM 0.31.0,单并发请求,生成 128 个 Token 的 5 次中位数)。

模型 加载的权重 生成速度 权重 × 速度 占实测带宽的比例
0.6B, bf16 1.12GiB 180.4 tok/s 217GB/s 87%
1.7B, bf16 3.22GiB 68.8 tok/s 238GB/s 95%
1.7B, fp8 1.90GiB 105.7 tok/s 216GB/s 86%
4B, fp8 4.32GiB 52.7 tok/s 244GB/s 98%

权重大小为服务器日志中的加载内存,“权重 × 速度”是假设生成每个 Token 期间完整读取一次权重计算得出的。

并发请求增加时速度没有变慢的原因与局限性

读取权重的成本与请求数量无关,仅需一次,因此如果将多个请求合并处理(连续批处理),就可以分摊读取成本。在第 20 篇中,同时发送 2 个请求时首字延迟为 0.206秒,4 个请求时中位数为 0.352秒。由于该服务器只开放了 2 个槽位,4 个请求时是 2 个一组排队的值,因此这不是一个能清晰展示批处理收益的实验。

为此,我们将上述四个模型的槽位开放至 16 个,并增加并发请求数来测量总吞吐量(每个请求生成 128 个 Token,3 次中位数)。

并发请求 0.6B bf16 1.7B bf16 1.7B fp8 4B fp8
1 180 69 106 53
4 670 264 405 205
16 2,484 1,007 1,544 775
16个时是 1个时的多少倍 13.8倍 14.6倍 14.6倍 14.7倍
16个时单个请求的速度 155(86%) 63(91%) 97(91%) 48(92%)

单位是总吞吐量(tok/s),最后两行根据上表计算得出。请求增加了 16 倍,但单个请求仅变慢了 8~14%,总吞吐量几乎达到了 14~15 倍。分摊权重读取成本的原理得到了完美体现。

这种收益结束的临界点仅通过计算进行了估计。由于每个 Token 对每个参数进行 2 次运算,根据测得的算力吞吐量(31.8 TFLOPS)和测得的带宽(250GB/s),当 bf16 的并发请求超过约 130 个、fp8 超过约 64 个时,瓶颈会转变为计算限制(计算,忽略了注意力机制和 KV 缓存读取的简化模型)。由于本次只开放到了 16 个,因此未确认该临界点(未实测),并且 16 个并发时的 4B 模型算力也仅为测得上限的约 18%(2 × 3.6B × 775 ≈ 5.6 TFLOPS),依然处于带宽受限的区域。

输入处理受计算能力限制,短输入输出较慢

输入处理使用相同的服务器,关闭前缀缓存,并通过每次请求不同的随机输入进行测量。

输入长度 1.7B bf16 4B fp8
256个 Token 5,709 tok/s(45ms) 3,129 tok/s(82ms)
1,024个 Token 8,634 tok/s(119ms) 3,438 tok/s(298ms)
2,048个 Token 8,730 tok/s(235ms) 3,365 tok/s(609ms)
3,500个 Token 8,244 tok/s(425ms) 3,182 tok/s(1.10秒)

3. 语音合成:重复生成所需的 Patch 数量

原理

两个合成模型都不会一次性输出声音,而是从前往后逐个生成 较短的单位(VoxCPM2 为 160ms 的 Patch,Magpie 为编解码器帧) (自回归)。因此,时间与音频长度成正比,且句子开头包含与长度无关的固定成本。第 20 篇中拟合出的 12 点公式正是这种形态。

합성 시간 ≈ 0.475 × 오디오 길이(초) + 0.23초

VoxCPM2:每个 Patch 76ms

根据 VoxCPM2 技术报告,该模型不使用离散 Token,而是通过扩散和自回归来生成 连续的潜在表示(Latent Representation) 的结构。它将语音压缩为每秒 25 个潜在帧(40ms),并将 4 个帧打包成 一个 Patch,每次生成一个 Patch。因此,自回归的一步相当于 160ms 的音频,即每秒 6.25 步。将这个数字与测量结果结合起来看,如下所示。

项目 数值
生成 1 秒音频所需的步数(Patch) 6.25
生成 1 秒音频所需的时间(测量斜率) 0.475 秒
单个步(Patch)所需时间 0.475 ÷ 6.25 ≈ 76ms
服务器配置的扩散迭代次数 10(inference_timesteps=10(在服务器代码中确认)
单次扩散所需时间(上述 76ms 除以 10) 约 7.6ms(上限。每步的时间包含一个语言模型步骤和解码,根据论文,每个扩散阶段还包含计算两次扩散模块的无分类器引导(CFG),因此实际每次的数值可能更小)

这意味着每个步骤中执行 一个语言模型步骤和 10 次扩散的成本是 76ms。在该结构中,可以预期减少扩散迭代次数会带来几乎成正比的速度提升。我们未测试减少迭代次数后的速度和质量(未实测)。固定成本 0.23 秒在论文中也未找到依据。论文中的实时系数是包含固定成本的挂钟时间(Wall-clock time),因此长度越长越接近斜率,但没有任何资料说明这个 0.23 秒究竟是句子编码、参考语音处理、解码器初始化还是服务器包装器(Wrapper)中的哪一项,且未进行分解(未确认)。

官方说明称该模型支持流式生成(generate_streaming),技术报告(表 11)显示,在使用单张消费级高端 GPU(24GB 级别)运行 PyTorch 实现时,实时系数为 0.30(峰值 VRAM 约 8GB);使用推理引擎(Nano-vLLM)时为 0.13。我们测得的斜率 0.475 比论文中的 0.30 慢约 1.6 倍,但无法区分这是由于 GPU 类型、以整句合成方式返回的服务器运行方式还是包装器开销导致的(未确认)。VRAM(6,600~6,900MiB)与论文中的约 8GB 处于相同范围。

Magpie TTS:一次生成两帧

Magpie TTS Multilingual 是一个拥有 3.64 亿参数的编码器-解码器 Transformer 模型。官方说明的核心有两点。 帧堆叠(Frame Stacking)是指解码器在一个步骤中同时预测两个音频帧,从而将迭代次数减半的方法; 局部 Transformer(Local Transformer)是一个小型模块,用于微调这样生成的帧之间的依赖关系,以恢复因减少帧数而下降的质量。这相当于生成相同长度声音所需的解码器步数减半。

项目 VoxCPM2 Magpie TTS
参数量 约 20 亿 约 3.64 亿
生成方式 通过扩散和自回归生成连续潜在表示 通过自回归生成编解码器帧(每两帧一组)
GPU 内存(实测) 约 6,600~6,900MiB 约 750MiB
实时系数(实测) 0.494~0.582,中位数为 0.521 0.447~0.541,中位数为 0.466(不含韩语)

流式合成减少首字延迟的原理

由于是从前往后逐个生成 Patch,因此无需等待整句话结束, 只要第一个 Patch 一生成 就可以开始播放(VoxCPM2 报告解释其结构是将生成的 Patch 直接转换为声音)。直到发出第一个声音的时间从“整句合成时间”(第 20 篇测量值:1.2~2.1 秒)缩短到了“每句固定成本与第一个 Patch 的时间”(0.23 秒 + 0.08 秒,约 0.3 秒)。这只是计算结果,并未在测量所用的服务器上进行测试。由于播放速度慢于合成速度(实时系数 0.5),因此还需要后续声音不会中断这一前提条件。

4. 流式语音识别:计算过的内容绝不重复计算

原理

语音识别模型 Nemotron 3.5 ASR 由 24 层 FastConformer 编码器和 RNNT 解码器组成。以下两个因素会产生延迟:

  1. 帧长。 编码器将声音缩减 8 倍,使得一个编码器帧为 80ms (以每 10ms 提取一次特征的常规设置标准为准,模型卡中的 Chunk 大小 80ms 与此解释相符)。
  2. 右侧上下文(前瞻量)。 为了确定当前帧的含义,我们希望 稍微靠后的帧也能被看到。必须等待该帧到达,因此前瞻量就是延迟本身。

模型通过 att_context_size = [왼쪽, 오른쪽] 来确定这两者。左侧 56 帧是记忆过去 4.48 秒(56 × 80ms)的量,右侧决定了 Chunk。每次处理的 Chunk 长度为 (右侧 + 1) × 80ms。

att_context_size 计算:(右侧 + 1) × 80ms 模型卡的 Chunk 值 一致
[56, 0] 1 × 80 = 80ms 80ms 一致
[56, 1] 2 × 80 = 160ms 160ms 一致
[56, 3] 4 × 80 = 320ms 320ms 一致
[56, 6] 7 × 80 = 560ms 560ms 一致
[56, 13] 14 × 80 = 1,120ms 1.12 秒 一致

这五个数值均与模型卡中的表格相符,因此可以认为“Chunk = (右侧上下文 + 1) × 80ms”这一解释是正确的。

缓存的作用

以往的流式方式(缓冲区方式)是将最近的声音切割成重叠的窗口,每次都从头开始重新编码。这相当于对重叠区间进行了多次计算。而缓存感知方式则是 将所有自注意力层和卷积层的编码器表示存储在缓存中,当有新声音到来时,仅计算新帧并更新缓存。正如官方说明所述,每个帧都恰好被处理一次。其结果是,计算量不再与声音长度成正比,而是与 新输入的长度成正比。吞吐量为厂商提供的数据:多语言 3.5 模型卡指出,在单张 H100 上,80ms Chunk 设置下支持约 240 个并发流(缓冲区方式基准 Parakeet 1.1B 约为 14 个),1.12 秒设置下支持约 2,400 个(基准约 400 个);而英文专属模型的 NVIDIA 博客则指出在 320ms Chunk 下支持 560 个流(由于是两个模型的值,切勿混淆阅读)。“直到确定结果的中位数为 24ms”是英文模型博客中合作伙伴流水线的值。在作者的实验环境中未能复现。

RNNT 解码器的结构是每输出一个编码器帧就输出一个字符(或表示“尚无”的空白符号),因此字符会随着帧的输入源源不断地输出。这样一来,在讲话结束之前结果就已经流式输出,讲话结束后只需确定最后的 Chunk 即可。

增大 Chunk 大小会提高准确率吗?

由于右侧上下文越长,模型能够看到越多的未来信息并进行判断,因此通常准确率会上升,同时延迟也会增加。如果将不同 Chunk 大小的设置应用于相同的 12 个语音并测量平均字错率(CER),结果如下(这是将设置应用于整个文件的近似值,并非实际流式传输)。

Chunk 80ms 160ms 320ms 560ms 1,120ms
平均字错率 4.3% 4.0% 3.9% 3.9% 11.3%

5. 串联起来看:各组件的瓶颈类型各不相同

组件 瓶颈类型 优化方向
语音识别 计算(与新帧数成正比),非常轻量 几乎无需调整
对话 LLM 内存带宽 减小权重(量化)、更宽带宽的 GPU、关闭思考
语音合成 按顺序生成帧的循环 流式传输、短语优先、调整重复次数

这就是 20 篇中单轮计算合成占 60~85% 的原因。语音识别的计算量很轻,而 LLM 已经用到了带宽上限的 66%,进一步压榨的空间很小,只有合成处于 「根据音频长度重复」 的结构,因此句子越长,耗时呈线性增长。

6. 面试常见问题

外部依据:通过论文和官方资料确认的内容

本文的数值均为直接测量值,原理部分与以下资料进行了对比。外部数值因模型、GPU 和负载而异,未进行直接对比,仅判定了 结构和方向的一致性。

主题 资料与确认位置 确认的内容与条件 与本文的关系
解码的内存限制 Pope 等, 「Efficiently Scaling Transformer Inference」, arXiv 2211.05102, 第 2 节。Yuan 等, 「LLM Inference Unveiled: Survey and Roofline Model Insights」, arXiv 2402.16363, 第 3.1.1 节 当批处理和上下文较小时,读取权重的时间占主导地位;当批处理较大时,转变为计算受限。即使压缩权重,在计算受限区间内时间也不会减少(Llama-2-13b,上下文 1,024) 支持。 与第 2 节原理相同。未找到将「上限 = 带宽 ÷ 权重字节」公式写成一行的论文,本文公式为去除了 KV 读取项的简化版
带宽利用率 Databricks 技术博客 「LLM Inference Performance Engineering: Best Practices」(2023-10-12) 在批处理为 1 时,模型带宽利用率(MBU)为:2×H100 60%,4×A100-40GB 55%(TensorRT-LLM,张量并行)。随着批处理增大而降低 有限支持。 分母是 规格书中的最高带宽,与我们 86~98%(分母为直接测得的读取带宽)的尺度不同
利用率的偏差 Chen, 「Memory-Bound but Not Bandwidth-Limited」, arXiv 2605.30571(2026 年单作者预印本,未经同行评议) 报告在批处理为 1 时,基于 PyTorch 默认路径,L4 约为 81%,H100 约为 27%,并解释原因为执行启动开销 有限支持。 在高带宽 GPU 上可能无法得出相同的达成率。我们的数值仅在 8GB 级和 24GB 级两种 GPU 上进行了验证
VoxCPM2 结构 「VoxCPM2 Technical Report」, arXiv 2606.06928, 第 3.1 节、第 3.7 节、第 4.6 节表 11 将 4 个 25Hz 潜在帧打包为一个 Patch,以 6.25Hz 进行自回归(一步 = 160ms)。每个扩散步骤计算两次扩散模块(CFG)。消费级高端 GPU(24GB 级)单张 PyTorch 实时系数 0.30,峰值 VRAM 约 8GB,推理引擎 0.13 有限支持。 长度正比结构正确。每步时间的明细和 0.23 秒的固定开销在论文中没有依据,我们的斜率 0.475 比论文慢 1.6 倍
帧堆叠 Fejgin 等 (NVIDIA), 「Frame-Stacked Local Transformers for Efficient Multi-Codebook Speech Generation」, arXiv 2509.19592, ICASSP 2026 在基于 NanoCodec(每秒 21.5 帧,8 个代码簿)的英语模型中,堆叠系数为 2 时,自回归局部 Transformer 比并行预测基准快 2.1 倍 相关。 与 Magpie 的「一次两帧」说明方法相同,但模型卡未披露是否为公开的多语言模型同款实验模型
缓存感知流式 ASR Noroozi 等, 「Stateful Conformer with Cache-based Inference for Streaming ASR」, arXiv 2312.17279, ICASSP 2024, 表 1、表 2 约 1.14 亿参数,LibriSpeech test-other,RNNT 的词错误率在预看量为 0ms 时 9.5%、240ms 时 7.8%、520ms 时 7.5%、1,360ms 时 6.3%。延迟比缓冲方式基准(RNNT 11.3%,平均延迟 2,000ms)更短且更准确 支持。 上下文越长准确率越高的趋势。论文中的「延迟」与分块大小定义不同
各分块的韩语准确率 nvidia/nemotron-3.5-asr-streaming-0.6b 模型卡(FLEURS,指定语言模式) 韩语字错误率:80ms 7.59,160ms 7.70,320ms 7.27,560ms 7.18,1.12秒 7.12(%)。分块数值 80、160、320、560、1,120ms 与 att_context_size 的(右侧+1)×80ms 相符 支持。 第 4 节表中对分块的解读与方向一致。使用人类语音 FLEURS 30 句重新测试后,韩语字错误率在分块从 1,120 到 80ms 时分别为 5.8、5.9、5.6、6.2、6.1%,与模型卡(7.12~7.70%)并不矛盾。在 12 个合成语音中仅 1,120ms 表现不佳的现象未能复现
非母语语音 McGuire, arXiv 2503.06924, 表 2、3(L2-ARCTIC 朗读语音)。Kim 等, LearnerVoice, Interspeech 2024, arXiv 2407.04280。Oh 等, ETRI Journal 42(5), 2020 在朗读语音中,Whisper large-v3 的错误率为:母语者 0.007,韩语说话者 0.033(约 4.7 倍),中文说话者 0.053,越南语说话者 0.124。韩国学习者的英语自发语音 WER 为 19.18%(与母语者对话水平相近,因此自发对话特征也是巨大因素)。旧版韩语模型中,母语者为 3.42%,非母语者为 36.74%(音节错误率) 支持。 关于合成语音数值过于乐观的表述依据。对合成语音数值乘以通用倍数的做法缺乏依据。在可获取的资料中未找到针对韩语、日语、中文学习者语音的现代模型测试

厂商数值(如模型卡的 H100 并发流等)由于条件在卡片中仅部分记录,故仅引用了趋势。由于 PNAS 和部分模型卡访问受限,故改用其他副本或论文阅读,未公开资料的数值均未使用。

未确认的内容

参考资料

确认的版本与日期

截至 2026-10-06。llama.cpp b11429, Gemma 4 12B QAT q4_0, vLLM 0.31.0(通过 Qwen3 0.6B·1.7B·4B-Instruct-2507 FP8 验证了带宽、并发性、输入处理),VoxCPM2(voxcpm 2.0.3), Nemotron 3.5 ASR Streaming 0.6B, NeMo 3.0.0。

登录后即可点赞

评论

还没有评论。

登录后即可发表评论