前言

推理工程最酷的一点是,与许多学术新研究需要数年甚至数十年才被工业界采用的行业不同,新论文中的技术在短短几个月甚至几周内就应用在了生产环境中。

从研究到生产之间存在一道需要跨越的鸿沟,而工业界中一些最受瞩目的推理工程工作就来自于弥合这道鸿沟。

推理工程的一个核心原则是:你在推理系统中引入的约束条件越多,就能获得越好的性能。这一原则在本文中依然适用,比如解耦技术,它允许你将单个引擎约束到预填充和解耦阶段。

使用这些模型性能技术时,要记住一个新原则:你的流量越大,能做的性能优化就越多(同时保持合理的单位经济性)。在更多 GPU 上实现更高的模型并行度、KV 感知路由、动态解耦,只有在你拥有大量 GPU(通常是多个节点)、以垂直扩展和水平副本方式为同一个模型提供服务时才有意义。

现实世界的流量会打破约束。但有了足够的流量规模,你就可以随着时间推移调整系统,以适配不断变化的使用特性。调优推理引擎、推测算法和模型服务器的参数不是一次性工作。相反,无论是通过迭代部署还是运行时动态调整,你都可以持续提升推理系统的性能。

找到技术和配置的正确组合需要耐心地实验。比如一位推理工程师在做一个代码自动补全模型时,最终通过手写脚本尝试了77 种不同配置,才找到一个非直观的方案,让客户模型的 TPS 翻倍。

让推理优化更加复杂的是,技术之间有时相辅相成,有时互不兼容。例如,量化 KV 缓存可以缓解解耦的瓶颈,但增大批处理大小会减少可用于推测的计算量。推理工程师的目标始终是创建一组平衡的优化方案,使其整体效果大于各部分之和。

本文介绍五类关键的推理加速应用研究:量化、投机加码、缓存、并行、解耦。在每一节中,请特别注意使用每种技术的推荐场景,以及每种技术可能带来的潜在瓶颈或权衡。

量化

量化可以提升延迟(包括 TTFT 和 TPS)、提高系统吞吐量,并为解耦、投机加码、前缀缓存等其他优化提供更大空间,使其效果更加显著。但一旦出错,量化会显著降低模型的输出质量。

模型在训练时,权重、激活值和其他组件都以某种原生数值格式表示。通常是 BF16 或 FP16,不过训练中 8 位和 4 位原生精度也越来越流行。

训练后量化PTQ通过将模型权重和其他数值从原生格式转换为更低精度的格式来工作。精度减半可以在推理的两个阶段都提升性能:

预填充:计算密集型的预填充现在运行在低精度张量核心上,FLOPS 翻倍。

解码:内存密集型的解码现在每个数值加载的数据量减半,实际上使内存带宽翻倍。

使用量化数据确实会引入开销,因此从 16 位降到 8 位并不会线性地快两倍。实际中,单级精度降低通常能为 LLM 带来 30%~50% 的性能提升。

量化的难点在于,它有降低模型输出质量的风险。量化有可能在支撑推理的计算过程中引入精度误差。

精度误差会随着时间累积。看一下对不同精度的 π 进行平方和立方会发生什么:

π 精度

π 平方

π 立方

3.14159

9.869588

31.006198

3.14

9.8596

30.959144

3

9

27

量化的大部分工作都围绕着防止精度误差最小化误差对最终模型输出的影响这两点展开。

1. 数值格式

量化引入了一系列新的重要术语和缩写。最需要了解的是常见数值格式:

名称

缩写

nvidia gpu首次支持架构

64 位浮点

FP64

Fermi (2010)

32 位浮点

FP32

Kepler (2012)

16 位浮点

FP16

Pascal (2016)

脑浮点 16 位

BF16

Ampere (2020)

8 位浮点

FP8

Hopper (2022)

混合精度 FP8

MXFP8

Blackwell (2024)

8 位整数

INT8

Pascal (2016)

6 位浮点

FP6

Blackwell (2024, 实验性)

4 位浮点

FP4

Blackwell (2024)

混合精度 FP4

MXFP4

Blackwell (2024)

NVIDIA FP4

NVFP4

Blackwell (2024, 专有)

4 位整数

INT4

Turing (2018)

最大的数值格式 FP64(双精度)仅用于高精度科学计算,不用于 AI 训练或推理。FP32 有时用于训练,但几乎不用于推理。FP64 在到2026年初仍偏实验性,不过 AMD GPU 正在快速采用该格式。

这就剩下16 位、8 位、4 位精度作为推理的主要格式。数值格式包含:

精度:表示单个数值所用的比特数。例如,FP16 使用 16 位。

类型:这些比特被解释为整数(无小数)还是浮点数(带小数)。

缩放因子:将数值从低精度格式映射回高精度格式的乘数。

这些属性共同决定了一种数值格式表示推理所用数值的两个关键因素:

动态范围:格式能表示的最低值与最高值之间的差。

粒度:沿单个缩放因子被量化的参数或其他数值的数量。

动态范围对无损低精度推理至关重要。16 位可以表示 65536 个不同值,而 8 位只能表示 256 个不同值。动态范围是这些值的分布 —— 即可表示的最小值与最大值之间的差。

动态范围解释了为什么浮点格式比整数格式更适合推理。浮点格式有三个属性:

符号位:表示数字正负的单个比特。

指数位:一组比特合起来表示指数因子。

尾数位:一组比特合起来表示乘以 2 的指数次方后的基值。

E4M3 格式的 FP8 数字表示它有 4 位指数、3 位尾数,剩下 1 位是符号位。整数格式只有符号位和数值位。

:浮点数值格式除符号位外,同时拥有指数位和尾数位

浮点数中的指数使其拥有更高的动态范围,能更好地表示极大和极小的数值。这一点很重要,因为异常值在推理中意义重大,而浮点格式能在量化后更好地保留异常值。

在浮点格式中,每种精度都有多种选择,比如 FP4、MXFP4、NVFP4。这些格式在粒度上不同,即沿单个缩放因子被量化的数值数量。

量化可以应用在不同级别:

张量级别:为整个 QKV 张量计算单个缩放因子。

通道级别:为张量内每个特征向量计算不同缩放因子。

分块级别:在每个特征向量内,将向量切分为 N 个数值的块,为每个块计算缩放因子。

粒度越细,抹平异常值的风险越低,质量保留越好。但是,粒度越细,存储和应用缩放因子带来的开销就越大。

Blackwell 支持的 MXFP8、MXFP4 等新数值格式是微缩放格式,每 32 个参数计算一个分块缩放因子,降低这些低动态范围格式的质量损失。

NVIDIA 的 4 位格式 NVFP4 提供比 MX 格式更细的粒度,块大小为 16,并附带 32 位全局缩放因子,进一步缓解 4 位格式带来的质量下降。

微缩放格式的代价是:小块缩放因子也必须存在内存中,略微降低量化带来的性能收益。此外,张量和分块缩放因子都需要被应用,引入少量计算开销。Blackwell GPU 通过在张量核心中应用缩放因子抵消了这部分开销。

虽然本系列文章重点是数据中心的推理工程,但量化是本地 / 边缘推理(尤其是大模型)的核心主题。GGUF 是存储模型的二进制格式,也是 Hugging Face 上分发高度量化模型的最流行选择,个人研究者和公司能把 DeepSeek 这类巨型模型压缩到苹果电脑等消费硬件上运行。

这些量化策略通过动态量化对抗质量下降:模型的某些层或组件保留原始精度,其他部分则被量化到低至 1 比特精度的整数。动态格式表示它们的平均精度,这就是为什么你会看到 Unsloth 这类微调实验室流行的 1.58 比特量化。

尽管这些动态量化是工程上的惊人成就,且非常适合本地推理,但生产环境的推理工程师应坚持使用浮点格式—— 整数格式因动态范围不足,不适合对质量敏感的工作负载。

相反,8 位浮点格式(FP8、MXFP8)通常是提升性能且不牺牲质量的最佳点。FP4 前景广阔,尤其是能提供更高粒度精度的 NVFP4 格式,但 FP8 和 MXFP8 提供最大的灵活性,尤其在量化 KV 缓存时。

2. 量化方法

模型参数越多,对量化就越不敏感,因为每个单独参数的重要性越低。不过,即使是非常大的模型,谨慎量化也至关重要。

量化可以在训练期间或训练后进行:

量化感知训练QAT:同时训练权重和计算缩放因子,确保最终收敛的权重在指定精度下准确。

训练后量化PTQ:通过计算缩放因子,将训练完成的模型权重转换为新精度,并通过校准保留精度。

虽然有些实验室发布使用量化感知训练的模型(如 MXFP4 的 GPT-OSS、INT4 的 Kimi K2 Thinking),但使用开源模型的推理工程师只能进行训练后量化,因为他们使用的是已完成训练的权重。

主流的训练后量化工具是NVIDIA TensorRT Model Optimizer (ModelOpt),这是一个开源库,同时支持剪枝、蒸馏、稀疏性。ModelOpt 输出兼容所有推理引擎(vLLM、SGLang、TensorRT-LLM)。

选定精度后,进行训练后量化前需要做两个决策:

  1. 模型的哪些部分(权重、激活、KV 缓存、注意力)需要量化?
  2. 哪种数值格式能提供合适的动态范围和粒度?

这些决策将量化从一个二元选择变成了围绕性能与质量的一系列权衡。

模型的不同组件对量化的敏感度不同。降低更敏感组件的精度,质量下降风险更高。敏感度从低到高依次为:

权重:特别是线性层,对量化最不敏感。

激活:激活函数的中间输出,对量化敏感度中等。注意:激活函数本身几乎不量化,因为它们在模型权重中占比极小。

KV 缓存:注意力计算的缓存结果,对量化敏感度中等。

注意力:模型的注意力层,对量化高度敏感,尤其是 softmax 等计算。

在每个组件内部,你可以更有选择性地进行量化。

即使是通常最不敏感的线性层和激活,输入输出层等早期和晚期层也可能保留原始精度,因为这些层对量化更敏感。

量化权重和激活能直接提升性能,而KV 缓存量化还能增强前缀缓存、解耦等技术的效果。KV 缓存是宝贵资源,量化后推理引擎可以在内存中存储更多内容,读取速度更快。

但是,每个token的 KV 缓存会被后续所有token使用。这意味着量化引入的精度误差会逐token累积

误差累积正是注意力层量化风险最高的原因。注意力不仅对动态范围极度敏感,而且每次注意力计算都依赖之前所有注意力计算的结果。在数千tokens的序列中,这些误差会快速累积。

除了最激进的量化方案,softmax 等函数都会保留原始精度运行。

:量化风险:权重和激活低,KV 缓存中,注意力高

温和的低精度推理方法是使用 FP8 这类高动态范围格式(尽可能用微缩放格式如 MXFP8),谨慎量化部分线性层、激活值,以及常用的 KV 缓存数值。即使使用这些高动态范围格式,注意力层组件也几乎不量化。

3. 衡量质量影响

生产可用量化的标准是:无感知质量损失。量化模型后,必须全面测试其输出质量与原始精度版本的对比。

检查量化后模型质量的三种方法:

困惑度:计算量化模型的困惑度分数,与原始模型对比。

智能基准:运行 MMLU、SWE-bench 等标准智能基准,对比原始分数。

自定义评估:在量化模型上运行产品专属评估套件,与原始权重对比。

在每种情况下,你都希望分数差异小到可以视为噪声。LLM 是非确定性的,因此分数每次运行都会略有浮动。

最简单的质量检查是困惑度。困惑度不会让模型生成输出,而是给模型预期输出序列,计算模型预测这些token的似然值。

困惑度越高,代表模型对序列越 “意外”—— 这不是一个预测token的模型应有的表现。量化后,你希望困惑度增幅极小

更全面的质量检查依靠公开智能基准,或者更好的是,匹配你真实场景的领域专属评估。在评估中,你希望质量分数下降极小

全面了解量化影响的最佳方式是:运行全部三类检查,并与原始模型进行严格对照。

记住,量化是一个尺度,不是二元选择。你可以通过量化到 FP8 而非 FP4,或者只量化模型更少组件(如仅权重),在降低质量风险的同时获得部分性能提升。

如果你在高度敏感领域工作,不能承担模型质量风险,也没关系:本文介绍的除量化技术外的所有其他技术在质量上都是无损的。

投机解码

LLM 推理的解码阶段是一个自回归过程,token一次生成一个。解码的瓶颈是内存带宽,在低到中等批处理大小下,计算资源会因为等待权重从内存读取而闲置。

投机解码利用这些空闲计算资源,尝试在目标模型的单次前向传播中生成多个tokens。如果推理引擎能在每次内存权重往返中生成 2 个、3 个甚至更多令牌,每秒生成的令牌数会大幅提升。投机解码只提升 TPS/ITL,不提升 TTFT

投机解码有多种算法,机制通用:

  1. 草稿模型生成一个或多个草稿token。
  2. 目标模型(你要加速的底层模型)对这些tokens进行验证,检查是否与模型自身生成结果一致。
  3. 目标模型接受所有合法草稿tokens,并自行生成一个额外token,完成前向传播。

这样每次前向传播(解码循环迭代)能生成 N+1 个tokens,N 是被接受的草稿tokens数。

生成草稿token不是免费的,需要计算和内存。但是,目标模型验证草稿token比生成原始token快得多。想象一下数独游戏:解题很难,但检查答案是否正确非常容易。对目标模型来说,生成token就像解数独,验证草稿token就像检查已完成的数独。

任何投机解码策略的性能提升取决于三个因素:

草稿token成本:生成一个草稿token所需时间。

草稿序列长度:每次前向传播生成的草稿token数。

token接受率:被目标模型接受的草稿token百分比。

草稿序列早期的token接受率很高,但越往后可靠性越低。

:投机解码从草稿token生成与验证,到前缀接受并生成后续token

一旦单个草稿token被判定错误,序列中所有后续tokens也会被拒绝。

使用投机解码很有趣,因为很多因素会影响token接受率。最重要的是温度—— 更高的温度会产生更难预测的token分布,降低投机解码效果。但即使是主题这类简单因素,如果用于投机的草稿模型或附加head在数学上比历史更熟练,也会对接受率产生影响。

投机解码的另一个限制是,它在计算资源空闲的低批处理大小下最有用。在更高批处理大小下,计算资源过于饱和,无法承担验证开销,投机必须动态关闭。

每种投机算法以不同方式处理这些权衡,正确实现适合场景的算法能显著提升 TPS。

1. 草稿 - 目标投机解码

投机解码的原始方法使用两个模型:

草稿模型:生成投机草稿token的附加模型。

目标模型:原始模型,现在除了普通解码外还验证草稿token。

配置草稿 - 目标投机解码时,最重要的决策是使用哪个草稿模型。好的草稿模型应具备高token接受率,同时运行资源消耗极小。

草稿模型通常是与目标模型同系列的更小模型,因为它们共享分词器和行为。经验法则:草稿模型的参数规模应至少比目标模型小 10 倍。微调或蒸馏可以通过让小模型学习更像目标模型的行为,提升token接受率。

如果你希望快速开箱即用,不需要任何训练或微调,草稿 - 目标投机解码是不错的选择。

但是,其他投机算法通常能提供更好的性能。草稿 - 目标引入了所有投机解码方法中最大的开销。尽管草稿模型很小,但推理引擎必须在内存中存储草稿模型的权重、激活值和 KV 缓存,并将计算周期用于草稿模型预填充。此外,草稿模型和目标模型必须协调运行,避免资源竞争,不过 TensorRT-LLM 等推理引擎会处理这种模型编排。

2. Medusa

Medusa 是最早替代草稿 - 目标投机解码的方法之一。Medusa 通过微调目标模型,使其在每次前向传播中生成额外token,解决了运行草稿模型带来的复杂性和开销。

为 Medusa 微调模型意味着嫁接额外的解码头到模型上。普通 LLM 架构只包含单个解码头,而 Medusa 会增加 2~4 个头,生成连续的草稿tokens。

与草稿 - 目标投机解码一样,草稿token会在下一次前向传播中验证。

Medusa 在草稿token数量和接受率上仍然受限,如今在生产中使用并不广泛。不过,Medusa 启发了 EAGLE 等更流行的技术。

:Medusa head在目标模型生成的token之上,各自生成一个草稿token

3. EAGLE

使用现成预训练模型作为草稿模型的主要问题是:Qwen 0.5B 这类模型被设计为在廉价硬件上运行的优秀独立 LLM,而不是在 B200 上生成投机草稿token。这些草稿模型运行效率低,接受率相对较低。

EAGLE提供了一种替代方案:一个从零开始训练的专用草稿模型,生成最多8 个草稿tokens(是 Medusa 的两倍多),且接受率非常高。

在推理过程中,LLM 会以隐藏状态形式在各层之间累积大量关于预测token的上下文信息。传统草稿模型无法访问这些信息。

EAGLE 是一个以隐藏状态为输入、生成推测token为输出训练的草稿模型。具体来说,它训练于三组隐藏状态:早期层、中层、后期层各一组。EAGLE 通常小于 10 亿参数,在增加训练数据时扩展性良好。

:EAGLE 推测模型以隐藏状态为输入,输出草稿token

实际使用中,在 TensorRT-LLM 等推理引擎上使用 EAGLE 时,实现通常很简单:训练后创建 EAGLE,单序列推测。

EAGLE 可以附加到与目标模型相同的模块(PyTorch 类)上,因此每次前向传播都会同时在目标模型和 EAGLE 推测器上运行推理。这种统一流水线解决了草稿 - 目标解码的另一个问题:需要多次 CPU 往返编排草稿和目标模型。

EAGLE 是具备训练 EAGLE head知识和能力的推理工程师的通用首选推测算法,并得到推理引擎的良好支持。与其他推测技术一样,为提升延迟采用 EAGLE 需要降低批处理大小,从而降低吞吐量、增加成本。

4. N-gram 推测与 Lookahead 解码

N-gram 推测使用与其他投机方法类型不同的机制。它没有草稿模型

相反,在生成 KV 缓存的同时,推理引擎会构建一个N-gram 字典。N-gram 字典将单个起始token映射到观察到的 N 个tokens序列(N-gram)。

:N-gram 字典将前缀映射到可能的后缀,特别适用于代码这类约束性语言

这个 N-gram 字典包含输入文本中的常见序列,在预填充阶段首次构建。解码时,生成的token被送入字典,任何可用后缀都会被选为草稿token。在下一次前向传播中,目标模型正常验证这些草稿tokens。

N-gram 推测相比 EAGLE 的优势是序列可以长得多。EAGLE 能以不错的接受率生成约 8 个草稿tokens,而 N-gram 序列可以超过 10 个tokens。

但是,N-gram 的接受率只在模型输出内容与输入高度相似时才高。N-gram 推测主要用于代码补全、代码修改等场景,语法可预测、输出与输入高度接近。在这个特定领域内,它轻松超越 EAGLE。

与 N-gram 推测类似的方法是Lookahead 解码,它在推理过程中生成 N-gram 来填充字典。Lookahead 解码比 N-gram 推测更通用,因为它不那么依赖高度重复的上下文,但需要额外计算生成 N-gram。

所有投机解码算法都旨在减少生成完整输出序列所需的总前向传播次数,提升整体延迟,特别是解码阶段单用户的每秒token数。N-gram 推测在代码补全等任务中表现出色,而 Lookahead 解码在计算资源富余的系统中更通用。

缓存

在预填充阶段,推理引擎为输入序列构建KV 缓存(每个token的键值存储)。然后在解码阶段为每个新生成的token更新 KV 缓存。由于推理是自回归的,每个新token的值都依赖序列中之前所有tokens的值。

所有推理引擎默认按请求使用 KV 缓存。如果没有 KV 缓存,LLM 推理会慢得无法忍受,因为每个后续token都需要重新计算序列中所有先前值。

但是,工程师可以通过在请求之间复用 KV 缓存(而不是仅在一个推理序列内使用),从 KV 缓存中获得更大价值。

1. 前缀缓存与 KV 缓存复用

看下面两个提示词(在大多数分词器中各包含 4 个tokens):

:两个 4 个 tokens 的序列,拥有 2 个 tokens 匹配前缀

默认情况下,推理引擎必须对每个提示词的全部 4 个tokens运行预填充。但两个提示词的前两个tokens “Weather in” 构成共享前缀。

使用前缀缓存,你可以复用第一个请求的 KV 缓存,通过跳过前两个tokens的预填充、直接读取已有 KV 缓存,提升第二个请求的 TTFT。

当你看到按tokens付费的 API 对 “缓存命中” 的输入tokens收费低于 “缓存未命中” tokens,原因就在于此 —— 复用缓存tokens几乎不消耗计算和时间。作为推理工程师,你可以应用相同原则,降低延迟、提升吞吐量(从而省钱)。

节省两个tokens不会对 TTFT 产生重大影响,但前缀缓存可以在特定领域跳过数千tokens的预填充:

复杂系统提示:智能体、面向客户的聊天机器人、RAG 框架、工具调用通常在每次调用时使用冗长复杂的系统提示。

代码补全:代码补全、代码生成等编程功能需要传递数千行相同代码作为共享上下文。

文档与检索:文档摘要、问答、检索都会在用户提示前添加重复上下文。

多轮对话:普通对话会在对话模板中重复所有历史消息,每轮对话都能从前缀缓存中节省更多时间。

前缀缓存从序列开头一直工作到第一个不重复token。天气示例中的第四个token(问号)在两个输入序列中都相同,但前缀在第一个不同token处结束,因此第四个token不会从缓存读取。

因为前缀在第一个唯一token处结束,你的上下文工程决定了 TTFT 节省量。换一种提示方式:

:两个 4 个 tokens的序列,无前缀匹配;第一个token不同,即使后面三个都相同也没用

这里前缀缓存完全没有节省,因为两个序列的第一个token不同,即使后续所有tokens都相同也不能使用前缀缓存。

要利用前缀缓存,请确保新异tokens尽可能放在上下文末尾

前缀缓存是 KV 缓存复用的主流形式,因为 LLM 是自回归的。每个token都会影响后续所有tokens,因此单个新异token会改变模型内部对序列其余部分的表示,即使在人类看来序列是相同的。

不过,围绕其他类型 KV 缓存复用的研究正在积极进行,以克服这一限制。缓存任意中间序列需要校正位置嵌入,并选择性地重新计算 KV 条目以保持输出质量。CacheBlend、LMCache 等工具支持非前缀序列,扩展了 KV 缓存复用的可能性。

2. KV 缓存存储位置

KV 缓存非常宝贵,但占用大量内存,而 GPU 的 VRAM 有限。

你可以配置推理引擎为 KV 缓存分配多少内存。例如,在 TensorRT-LLM 中,你可以设置:

:为 KV 缓存分配空闲 GPU 内存是运行推理引擎时的关键配置决策

如果你在一块 180GB VRAM 的 B200 上运行,模型权重和缓冲区用了 100GB,这会将剩余 VRAM 的 80%(即 64GB)分配给 KV 缓存。

一旦分配空间用尽(而且很快会用尽),你就必须开始删除已保存的 KV 缓存,增加未来请求缓存未命中的概率。

为了获得更多 KV 缓存空间,可以从 VRAM 卸载到其他就近存储。KV 缓存可以存储在四个位置,按 GPU 带宽从高到低排序:

级别

内存类型

近似速度

近似容量

G1

设备内存(GPU VRAM)

每秒 TB 级

几十到几百 GB

G2

主机内存(CPU RAM)

每秒几十到几百 GB

几百 GB 到 TB 级

G3

本地 SSD

5~10 GB/s

TB 级

G4

网络 SSD

每秒 GB 级

几十 TB

GB200 等型号配备 CPU 和高速互联,非常适合 KV 缓存卸载。

NVIDIA Dynamo 通过KVBM(KV 块管理器)支持 KV 缓存卸载。KVBM 提供 API,用于在不同内存级别之间移动 KV 缓存块。通常,你希望将最常使用的块放在高带宽内存中,不常用的块可以放到慢速存储,直到需要时再读取。

3. 缓存感知路由

在生产环境中,推理服务会有多个副本,传入流量会在副本间分配。通常,流量路由基于每个副本的繁忙程度。

如果你的推理服务大量使用前缀缓存,路由逻辑需要为此调整。进行长时间对话聊天或多次询问代码库问题的用户,应尽可能将请求路由到同一个副本,以便获得缓存命中,请求更快、成本更低。

:缓存感知路由基于 KV 缓存分配流量,而非简单地在副本间均分请求

另一种选择是使用 G4 级别的网络存储构建跨副本的全局 KV 缓存。路由仍然重要 —— 拥有 G1 级别热缓存的副本会比从 G4 读取的副本更快处理请求 —— 但全局缓存确保所有副本最终都能访问任何预计算序列,并且在节点循环或自动扩缩容下线时不会丢失缓存序列。

4. 长上下文处理

“长上下文”这个说法在定义上有点同义反复:当序列生成的 KV 缓存大到在推理中引发问题时,它就成为 “长上下文”。

根据模型、硬件、引擎和流量的不同,这些问题在超过 32K、64K 或 128K tokens等常见阈值后开始出现。在性能基准测试中,务必发送超长输入序列,测试推理服务对长上下文请求的处理能力。

基础模型一直在使用 RoPE 等缩放技术,解锁更长、更准确的上下文窗口。但支持这些升级后的上下文窗口会给推理带来新挑战。

考虑到 KV 缓存,注意力方程随序列长度线性增长。在长序列下,注意力可能成为 VRAM 的主要消耗者 —— 而 VRAM 正是解码的瓶颈。

虽然滑动窗口注意力、压缩注意力、稀疏注意力等方法在逐个模型基础上提供了解决方案,但优化标准注意力算法有通用方法:

FlashAttention:一系列优化的注意力内核,以更少的内存读写计算注意力。

PagedAttention:一种内存管理技术,将 KV 缓存存储在固定大小的页面中,减少碎片和重复。

分块预填充:将长输入序列切分成块的策略,可以在资源允许时与解码同时运行,避免长序列压垮推理引擎。

但是,如果经过这些优化后,你仍然需要超过单块 GPU 所能提供的 VRAM 来存储 KV 缓存怎么办?你需要跨多 GPU 并行推理

模型并行

目前市面上所有前沿 LLM 都大到无法在单块 GPU 上运行批处理推理。尽管 GPU 越来越大,模型也越来越大,而且这一趋势没有逆转的迹象。

在 FP8 精度下,加载 10 亿(1B)参数模型权重大约需要 1GB VRAM。对于 DeepSeek-V3.1 这类 6710 亿(671B)参数的模型,仅模型权重就会让单块 B200 GPU 直接报 OOM(Out Of Memory,内存不足)错误。

仅仅勉强把模型权重塞进 VRAM 是不够的。在 4 块 B200 GPU(720GB VRAM)上,理论上可以加载 DeepSeek 权重。但没有剩余空间留给 KV 缓存(通常在加载权重后占用 80% 以上的剩余 VRAM),4 块 B200 无法以任何合理序列长度或批处理大小为 DeepSeek 提供服务。

相反,需要整整 8 块 B200 的一个节点来为 DeepSeek 这种规模的模型提供真实生产流量。你可以通过精度、参数数量、预期 KV 缓存分配的乘积估算模型所需最小 GPU 数量。

:计算推理所需 VRAM 后,向上取整到下一个可用实例大小,确定最小 GPU 数量

在许多情况下,即使是 GPT-OSS 这类中等模型,你也希望使用超过最低要求的 GPU 数量,以支持更大的 KV 缓存,实现更好的单用户延迟。

但是,所有这些都要求推理能高效地从单卡扩展到多卡。并行推理扩展的限制是GPU 间通信开销

【模型推理系列-3】模型推理硬件加速器-GPU

系列-3中详细介绍了 GPU 之间的不同互联:节点内的 NVLink 和 NVSwitch,节点间的 InfiniBand。

虽然 NVLink 和 InfiniBand 提供高带宽,但它们的速度远低于 VRAM。由于解码受内存带宽限制,多 GPU 推理必须精心设计,避免 GPU 间通信成为瓶颈。这一研究领域称为拓扑感知并行

推理中有三种主要模型并行形式:

流水线并行(PP):将模型层切分到不同 GPU。

张量并行(TP):将每层内的张量切分到不同 GPU。

专家并行(EP):将 MoE 模型的整个专家分片到不同 GPU。

每种并行方式都有其权衡:

方法

机制

缺点

PP

每个 GPU 处理前向和反向传播的一个阶段

不推荐,延迟和利用率差,分步流水线

TP

矩阵乘法等计算密集型操作跨 GPU 拆分

需要 GPU 间同步,不适合多节点

EP

每个专家在单个 GPU 内运行,专家内推理速度快

需要 GPU 间路由访问多个专家,更适合吞吐量

张量并行通常最适合单节点内低延迟模型推理,专家并行提升 MoE LLM 的吞吐量。流水线并行仅用于多节点推理。

此外,上下文并行等数据并行策略会跨设备拆分计算。这些策略在 LLM 推理中很少见,但对视频生成至关重要。

1. 低延迟张量并行

张量并行应作为多 GPU 模型推理的默认方案。它同时支持 Llama 405B 等稠密模型和目前主导开源模型生态的 MoE 模型。

:张量并行在 GPU 间拆分权重,有效共享 VRAM 资源,快速运行大模型

张量并行将模型的每一层拆分(与流水线并行保留完整层不同),并将层片段分布到分配的 GPU 上。每层中,读取权重内存和执行矩阵乘法的开销由多个 GPU 共享。

:对于混合专家模型,每个专家通过张量并行跨多 GPU 运行

但是,每层的结果需要以归约方式合并为单个输出,然后才能计算下一层。在具备高带宽节点内 NVLink 和 NVSwitch 的节点中,这种通信开销被最小化。

增加张量并行度能提升单用户 TPS(假设模型足够大、序列足够长,通信开销不会超过更快的前向传播,大多数前沿模型都满足)。

2. 高吞吐量专家并行

专家并行将专家干净地分到不同 GPU。在一个 128 专家的模型上以 EP8 跨 8 块 GPU 运行,每个 GPU 托管 16 个完整专家。

:专家并行在单个 GPU 上运行每个专家,每个 GPU 托管多个专家

专家并行提升系统总吞吐量,使推理更具可扩展性、成本更低。单个专家独立处理token,每个token耗时相同,但系统整体能处理更多并发token。

许多部署混合使用TP+EP,同时获得两种优势。

:该部署对注意力使用 TP,对稀疏 MoE 层使用 EP

专家并行比张量并行需要更少的 GPU 间通信。专家路由器(决定每个token激活哪些专家)被复制到每个 GPU,因为它是模型中相对较小的组件。GPU 间通信仅用于token在专家间传递,但与 TP 不同,它不需要收集每层结果。

由于通信开销更低,EP 能很好地扩展到多节点部署和互联带宽有限的系统。

3. 多节点推理

如果你在服务超大规模模型、高精度、支持数百万令牌输入序列,或只是想尽可能快地运行推理,可能需要超过 8 块 GPU。

GPU 被设计为跨节点协同工作,多节点训练多年来一直是开发前沿模型的标准。但多节点推理带来了新挑战:

基础设施:如何可靠地申请两个或更多互联 GPU 节点,并跨云厂商构建抽象?

并行:如何在速度远低于 NVLink 的 InfiniBand 上有效通信?

:InfiniBand 通过高带宽节点间互联支持超过 8 块 GPU 的多节点推理

InfiniBand 为拓扑感知并行带来了新问题。张量并行通常需要过多的 GPU 间通信,不适合多节点推理。相反,你有两种在 InfiniBand 上运行良好的选择:

  1. 对于稠密模型,节点内用张量并行,节点间用流水线并行(如 TP8PP2)。
  2. 对于 MoE 模型,也可以尝试专家并行(如 EP16),因为通信开销比张量并行低。

对于 MoE 模型,TP8PP2通常提供更低的单用户延迟,EP16提供更高的系统总吞吐量。

除非你的模型和 KV 缓存大到必须多节点推理,否则这可能不是额外硬件的最佳使用方式。你通常最好将额外节点用于副本水平扩展,或解耦服务。

解耦

解耦结合了推理工程中的三个重要思想:

1. 预填充是决定 TTFT 的计算密集型过程,而解码是决定 TPS 的内存密集型过程。

2. 专业化能提升从内核选择到推理引擎参数调优的所有环节性能。

3. 如果能避免低带宽互联带来的瓶颈,你可以在多 GPU 甚至多节点上有效扩展模型服务。

当预填充和解码在高流量下运行在同一节点时,它们相互干扰的概率更高。理想情况下,预填充使用更多计算资源,解码使用更多内存,两者可以高效共存。但是,在更大批处理和更多计算密集型优化下,预填充和解码会开始竞争资源。

1. 解耦工作原理

解耦(或称解耦服务)是将预填充和解码分离到不同 GPU / 节点上的独立引擎的思想。

解耦将 LLM 推理变为三步流程:

1. 预填充引擎接收输入序列,生成 KV 缓存并计算第一个token。

2. 预填充引擎通过硬件互联将 KV 缓存发送到解码引擎。

3. 解码引擎计算所有后续tokens。

条件解耦中,请求首先发送到解码引擎,它会检查输入序列是否已缓存或足够短,可以本地处理:

:解耦分配预填充工作节点生成第一个token,解码工作节点生成后续tokens

  1. 如果是,解码引擎本地处理预填充,跳过解耦。
  2. 如果否,解码引擎将请求转移到预填充引擎进行解耦服务。

条件解耦更适合真实世界流量。

解耦的另一个优势是,通过独立的预填充和解码引擎,你可以分别优化每个引擎,进而优化整个系统。例如,计算密集型的预填充引擎需要的 TP 比内存密集型的解码引擎更低。

2. 何时使用解耦

解耦非常强大,但需要多 GPU 和额外工程工作。仅在以下情况下使用解耦:

  1. 你服务大流量,根据模型大小,每天 1 亿~10 亿tokens起。
  2. 你服务大型模型,至少 100B 参数。
  3. 你的流量是预填充密集型,输入序列长。

如果条件 1 或 2 不满足,你可能在额外硬件上浪费钱,性能提升极小。如果条件 3 不满足,你最好用额外 GPU 水平扩展副本,因为解码引擎对短序列或前缀缓存命中更高效。

解耦的绝佳用例是在代码编辑器中服务前沿 LLM,许多开发者同时传入大量多样的代码块作为上下文。大量tokens、以预填充为主、万亿参数 LLM,是解耦的教科书式工作负载。

3. 基于 NVIDIA Dynamo 的动态解耦

Dynamo 为解耦提供生产就绪支持,具备处理异构真实流量的灵活性。

Dynamo 提供开发者工具和预构建优化,支持解耦:

  • 预填充队列,在所有预填充引擎饱和时保存请求。
  • 稳健的条件解耦支持,基于前缀缓存后 ISL 阈值和预填充队列大小路由预填充。
  • 基于 NIXL 的高效 KV 从预填充传输到解码引擎,当引擎有不同 TP 配置时,使用内核转置 KV 块布局。

这些功能共同实现动态解耦:预填充和解码引擎数量可在运行时配置,并随传入流量变化动态调整。

解耦不需要预填充与解码引擎 1:1 比例。尽管用单个预填充引擎和单个解码引擎解释解耦很简单,但真实系统会有多个。

预填充和解码引擎数量写作 xPyD,例如 5P3D 表示 5 个预填充引擎和 3 个解码引擎协同服务单个模型部署。

随着系统变复杂,潜在瓶颈会增多。解耦中,新瓶颈是预填充队列长度。不要让队列过大,既要为解码引擎本地预填充设置合理阈值,也要在运行时调整 xPyD,在需要时为预填充分配更多资源。

解耦的另一个潜在瓶颈是高负载下解码引擎的KV 缓存不足。通过量化和 KV 缓存卸载增加 KV 缓存可用空间。

  学习资源推荐

如果你想更深入地学习大模型,以下是一些非常有价值的学习资源,这些资源将帮助你从不同角度学习大模型,提升你的实践能力。

一、全套AGI大模型学习路线

AI大模型时代的学习之旅:从基础到前沿,掌握人工智能的核心技能!​

因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获取

二、640套AI大模型报告合集

这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示

​因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获取

三、AI大模型经典PDF籍

随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。

因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获取

四、AI大模型商业化落地方案

作为普通人,入局大模型时代需要持续学习和实践,不断提高自己的技能和认知水平,同时也需要有责任感和伦理意识,为人工智能的健康发展贡献力量。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐