状态:草稿(2026-10-06),这是一篇原理文章。 原理说明基于各模型的官方资料(文末有链接)及常规推理理论,核对所使用的数字是笔者在 第 20 篇中实际测得的值。计算公式为了解现象进行了简化,每一节都说明了哪些部分经过了验证、哪些部分属于推测。 编写规则:以实测数据为基础,未能测得的数据标记为“未实测”。
目录
- 1. 一目了然:各组件决定时间的方式各有不同
- 2. 对话大模型:每生成一个 Token 就要完整读取一次模型
- 3. 语音合成:重复生成所需的补丁数量
- 4. 流式语音识别:计算过的内容不再重复计算
- 5. 串联起来:各组件的瓶颈类型各不相同
- 6. 面试可能会问的问题
- 外部依据:通过论文和官方资料确认的内容
- 未确认的内容
- 参考资料
- 确认的版本与日期
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) | 服务器测量 |
- 使用了上限的 66%。 其余部分可能分配给了注意力机制读取的 KV 缓存、还原量化区间的计算、逐层启动内核的间隔等,但未分解各项具体占比(推测)。
- 输入处理是生成的 8.2 倍(700 ÷ 85.6)。这与原理推导的方向一致,因此即使输入较长,第一个 Token 也不会明显延迟。相反,较长的回答会与 Token 数量成正比地延迟。不过,67个 Token 较短,其中混入了每个请求所需的固定成本。按长度测量输入的值可在下文的“输入处理受计算能力限制,短输入输出较慢”中查看。
- 量化会直接体现在速度上。 如果将同一模型设为 16-bit,则权重约为 25GB(130亿参数 × 2字节,计算得出),因此相同公式下的上限会降至 905 ÷ 25 ≈ 36 tok/s,即降至三分之一以下。由于它甚至无法放入该 GPU 的 24GB 内存中,因此 4-bit 不是一种选择,而是一个前提。未测量该模型的 16-bit 速度(未实测,计算得出)。当用小模型将精度减半时,带来的收益比计算预期的要小(1.54倍而非 1.7倍)(见下文直接验证),因此 4-bit 与 16-bit 之间的差距很有可能小于计算值。
- 思考 Token 也会以相同的速度生成。 在第 20 篇的思考中,全部用于思考的 80 个 Token 的响应耗时约 1.0 秒(与 80 ÷ 85.6 ≈ 0.93秒相符)。在语音对话中,如果模型使用 N 个思考 Token,用户就会听到 N ÷ 85 秒的沉默。必须关闭思考功能的原因不是靠直觉,而是通过计算得出的。
直接验证:用大小和精度不同的模型确认上限
由于上述核对中的带宽值取自规格说明,因此无法确认上限本身是否正确。为此,我们在单张 8GB 级 GPU 上 首先直接测量带宽,并用相同方法测量了大小和精度不同的四个模型的生成速度(vLLM 0.31.0,单并发请求,生成 128 个 Token 的 5 次中位数)。
- GPU 仅读取带宽: 250GB/s(用 PyTorch 读取大张量并求和,中位数),复制 227GB/s
- fp16 矩阵乘法 4096³: 31.8 TFLOPS(中位数)
| 模型 | 加载的权重 | 生成速度 | 权重 × 速度 | 占实测带宽的比例 |
|---|---|---|---|---|
| 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 期间完整读取一次权重计算得出的。
- 原理是正确的。 无论模型大小如何,“权重 × 速度”都聚集在带宽附近(86~98%)。这意味着决定速度的不是参数数量,而是需要读取的字节数。
- 将精度减半的效果比计算预期的要小。 将 1.7B 从 bf16 改为 fp8 时,权重变小了 1.7 倍(3.46GB 对比 2.04GB,计算得出),但速度只提升了 1.54 倍(68.8 对比 105.7)。从每个 Token 花费的时间来看,除了读取时间外,每个 Token 还额外花费了 0.4~1.3ms(计算得出:1 ÷ 速度 − 权重 ÷ 250GB/s)。推测其中包含了注意力机制、逐层内核启动以及还原 8-bit 值的计算,但未分解各项具体占比(推测)。
- 24GB 级 GPU 的带宽也用相同方法进行了测量。 仅读取带宽为 905GB/s(约为规格说明书中所知约 936GB/s 的 97%),12B 4-bit 模型的生成速度 × 权重(85.6 × 7.0)约为 599GB/s,占测得带宽的 66% 。也就是说,前面用规格值计算出的 64% 用实测值算出来也几乎是同样的 66%。这说明差异并非由假设带宽引起,而它比 8GB 级 GPU 的 vLLM 结果(86~98%)更低,无法归因于是引擎(llama.cpp 与 vLLM)、4-bit 格式(分段还原计算)还是模型结构的差异导致的(未确认)。在同款 GPU 上用两个引擎测试同一模型是遗留的工作。
并发请求增加时速度没有变慢的原因与局限性
读取权重的成本与请求数量无关,仅需一次,因此如果将多个请求合并处理(连续批处理),就可以分摊读取成本。在第 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秒) |
- 在 1024 个 Token 以上时速度会趋于稳定。 这分别比相同模型的生成速度(69、53 tok/s)快约 127 倍和约 65 倍。经计算换算,1.7B 模型去除嵌入层后的参数量为 1.4B,因此 8,730 tok/s 约为 24 TFLOPS(2 × 1.4B × 8,730);4B 模型为 3.6B,因此 3,438 tok/s 约为 25 TFLOPS。这两个模型的矩阵乘法吞吐量实测值均为 31.8 TFLOPS 的 75%~80% 左右,因此“输入处理受限于计算能力”这一原理与数据完全吻合。
- 对于较短的输入,每个 Token 的成本较高。 在 256 个 Token 下,1.7B 的速度降低了约 35%,4B 的速度降低了约 9%。这是因为在短输入中,每次请求产生的固定成本分摊到每个 Token 上的比例较少,因而显得很高。语音对话的输入通常较短,因此上述 12B 测得的 700 tok/s(67 个 Token)也应当结合这一影响来理解。
- 最初的测量结果是错误的,我们通过将其与计算极限进行对比才发现了这一点。 起初我们重复发送相同的句子,结果 4B 达到了约 91,000 tok/s。这相当于约 660 TFLOPS(2 × 3.6B × 91,240),是 GPU 无法达到的数值。这是由于命中了前缀缓存(Prefix Cache)而没有计算输入导致的;关闭缓存后,用每次请求不同的输入重新测量,便得到了上表。仅通过将测量值与硬件极限进行对比,就能排查出这种错误。
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(不含韩语) |
- 参数量少 5 倍以上,内存少 9 倍,但速度相近。 这与“决定时间的不是参数量,而是‘所需生成的步数 × 每步成本’”这一解释相符。不过,这两个模型是在不同的 GPU 上进行测量的,且未能确认 Magpie 的帧比例,因此无法像 VoxCPM2 那样计算每帧的时间(未确认)。
- 官方的首次发声延迟(H100 上为 47ms 等)是以流式传输为标准的。 测量中使用的是整句合成后接收的方式,因此无法用相同的数字进行比较。
- 韩语在此环境中未能正常生成(第 20 篇 3-2)。未能确认这是结构问题还是配置问题。
流式合成减少首字延迟的原理
由于是从前往后逐个生成 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 解码器组成。以下两个因素会产生延迟:
- 帧长。 编码器将声音缩减 8 倍,使得一个编码器帧为 80ms (以每 10ms 提取一次特征的常规设置标准为准,模型卡中的 Chunk 大小 80ms 与此解释相符)。
- 右侧上下文(前瞻量)。 为了确定当前帧的含义,我们希望 稍微靠后的帧也能被看到。必须等待该帧到达,因此前瞻量就是延迟本身。
模型通过 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% |
- 从 80ms 到 320ms,字错率从 4.3% 小幅优化至 3.9%,此后保持不变。 这意味着在这 12 个合成语音中,超过 320ms 的上下文并没有提供更多帮助。即便将延迟缩短至最短的 80~160ms,准确率损失也仅为 0.4~0.3 个百分点。由于是合成语音,声音清晰这一点可能让这一结果显得过于乐观。
- 1,120ms 时的 11.3% 无法解释。 这是由于有一个语音输出了空结果,且重复测了两遍结果都一样。模型卡的韩语 FLEURS 字错率反而在 1.12 秒设置下最低(7.12%),因此我们的数值与模型卡方向相反。用真人朗读的 30 句韩语 FLEURS 重新测试时,无论 Chunk 大小如何,空结果均为 0 个,且字错率稳定在 5.6%~6.2%(第 20 篇 4-3 节),因此该现象并非模型的普遍属性,似乎仅出现在 12 个合成语音样本中。原因未进行分解。
5. 串联起来看:各组件的瓶颈类型各不相同
| 组件 | 瓶颈类型 | 优化方向 |
|---|---|---|
| 语音识别 | 计算(与新帧数成正比),非常轻量 | 几乎无需调整 |
| 对话 LLM | 内存带宽 | 减小权重(量化)、更宽带宽的 GPU、关闭思考 |
| 语音合成 | 按顺序生成帧的循环 | 流式传输、短语优先、调整重复次数 |
这就是 20 篇中单轮计算合成占 60~85% 的原因。语音识别的计算量很轻,而 LLM 已经用到了带宽上限的 66%,进一步压榨的空间很小,只有合成处于 「根据音频长度重复」 的结构,因此句子越长,耗时呈线性增长。
6. 面试常见问题
- 如何估算 LLM Token 生成速度的上限? 用内存带宽除以权重字节数。4-bit 12B 模型测得的带宽为 905 GB/s ÷ 7.0 GB ≈ 129 tok/s,实测为 85.6 tok/s(占 66%)。
- 为什么同一模型的输入处理比生成快得多? 输入只需读取一次权重,多个 Token 即可复用,因此受限于计算能力;而生成时每个 Token 都需要重新读取权重,因此受限于带宽(1.7B 模型中为 8,730 对 69 tok/s)。
- 如果将请求数增加到 16 个,单个请求会变慢多少? 在四个小模型上仅变慢 8~14%,而总吞吐量提高了约 14~15 倍。这是因为分摊了读取权重的开销。
- 如何对测量值产生怀疑并进行验证? 与硬件极限进行对比。输入处理速度达到 91,000 tok/s 超出了 GPU 的计算能力上限,由此推断出命中了前缀缓存。
- 为什么量化对提升速度也有帮助? 权重字节数减少,带宽上限就会相应提高。4-bit 约为 16-bit 的 3.5 倍(计算值)。在小模型中,将 16-bit 转换为 8-bit 时,计算性能提升了 1.7 倍,而实测提升了 1.54 倍,收益因每个 Token 的固定开销而有所减少。
- 缓存感知流式语音识别与缓冲方式有何不同? 不会重新编码重叠的窗口,而是将各层的表示保留在缓存中,使每个帧只需计算一次。分块大小为(右侧上下文 + 1)× 80ms。
- 如何在自回归语音合成中减少首字延迟? 通过流式传输,在生成最初几帧后立即播放。播放速度必须慢于合成速度(实时系数 < 1)才不会卡顿。
外部依据:通过论文和官方资料确认的内容
本文的数值均为直接测量值,原理部分与以下资料进行了对比。外部数值因模型、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 和部分模型卡访问受限,故改用其他副本或论文阅读,未公开资料的数值均未使用。
未确认的内容
- 66% 与 86~98% 存在差异的原因。 两个 GPU 的带宽都是直接测量的,但 24GB 级使用的是 llama.cpp 的 4-bit 模型,8GB 级使用的是 vLLM 的 bf16·fp8 模型,引擎和格式有所不同。必须在同一 GPU 上用两个引擎运行同一模型才能区分。
- 66% 中剩下的 34% 流向了哪里。 未对 KV 缓存读取、注意力机制、核函数间隙进行细分。
- VoxCPM2 每帧 76ms 的明细、减少扩散重复次数的效果,以及 0.23 秒固定开销的本质。
- 流式合成的首字时间和流式语音识别的实际确定延迟。 测试中未采用流式路径。
- 12B 模型的 16-bit 速度(37 tok/s 为计算值)。 在小模型中,精度带来的影响小于计算值。
- 并发请求超过 16 个的区间。 计算受限的转变点(bf16 约 130 个,fp8 约 64 个)为计算值,未经测量。
- 输入处理中短输入固定开销的本质。 未能剖析 256 Token 时速度下降的原因(请求处理、核函数启动等)。
- 与其他推理引擎的对比。 直接验证仅使用了 vLLM 一种引擎,未与上述 12B 测试(llama.cpp)的引擎保持一致。
- 对模型结构的说明沿用了官方文档的描述,未阅读论文原文。
参考资料
- Nemotron Speech ASR 的缓存感知流式说明:https://huggingface.co/blog/nvidia/nemotron-speech-asr-scaling-voice-agents
- Nemotron 3.5 ASR 模型卡:https://huggingface.co/nvidia/nemotron-3.5-asr-streaming-0.6b
- VoxCPM:https://github.com/OpenBMB/VoxCPM
- Magpie TTS 说明:https://huggingface.co/blog/nvidia/magpie-tts-multilingual-voice-agents
- 本系列的第 20 篇(实测)、第 8 篇(KV 缓存大小计算)、第 4 篇(vLLM 内部)
确认的版本与日期
截至 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。