Skip to content

常规 ML 推理 vs. LLM 推理

Regular ML Inference vs. LLM Inference

相比常规 ML 推理,LLM 推理面临一系列独特的挑战,这也是为什么会出现 vLLM、LMCache、SGLang、TensorRT LLM 这类专门的高性能 LLM 推理引擎。接下来我们就来了解这些挑战,以及它们是如何被解决的!

连续批处理(Continuous Batching)

传统模型,比如 CNN,通常有固定尺寸的图像输入和固定长度的输出(比如一个标签),这让批处理变得很简单。

llm optimization p319 1

然而,LLM 处理的输入(也就是提示词,prompt)长度是可变的,生成的输出长度也同样可变。

llm optimization p319 2

因此,如果把多个请求打包成一批,它们完成的时间各不相同,GPU 必须等到最长的那个请求处理完,才能开始处理新的请求。这就导致了 GPU 出现空闲时间:

llm optimization p319 3

连续批处理解决了这个问题。系统不再等待整批请求全部完成,而是持续监控所有序列,一旦某个序列完成(出现 <EOS> token),就立刻把它替换成新的查询:

llm optimization p320 1

这样可以让 GPU 的处理流水线始终保持饱和,从而最大化利用率。

预填充-解码分离(Prefill-decode Disaggregation)

LLM 推理是一个两阶段的过程,这两个阶段对资源的需求存在本质差异。

  • 预填充(prefill)阶段会一次性处理输入提示词的所有 token,因此是计算密集型的。
  • 解码(decode)阶段以自回归方式逐个生成输出 token,因此对低延迟的要求很高。
  • 如果把这两个阶段放在同一批 GPU 上运行,计算密集型的预填充请求就会干扰对延迟敏感的解码请求。预填充-解码分离通过为预填充阶段和解码阶段分别分配一组专用 GPU,来解决这个问题。

llm optimization p320 2

llm optimization p321 1

相比之下,标准 ML 模型通常只有一个统一的计算阶段。

GPU 内存管理与 KV 缓存

生成一个新 token 需要用到之前所有 token 的 key 向量和 value 向量。为了避免对所有 token 反复重新计算这些向量,我们会把它们缓存起来。

llm optimization p321 2

这个 KV 缓存(KV cache)会随着对话历史的总长度线性增长。不过在很多工作流中,像系统提示词(system prompt)这样的输入会被许多请求共享,因此我们可以在所有对话中复用这些 KV 向量,从而避免重复计算:

llm optimization p322 1

话虽如此,由于 KV 缓存是以连续内存块的形式存储的,它会占用相当可观的内存,这既浪费 GPU 内存,也会导致内存碎片化:

llm optimization p322 2

Paged Attention 通过把 KV 缓存存储在不连续的内存块中、再用一张查找表来追踪这些块,解决了这个问题。这样一来,LLM 只需要加载它实际需要的那些块,而不必一次性加载全部内容。我们会在另一篇文章中详细介绍 Paged Attention。

前缀感知路由(Prefix-aware Routing)

要扩展标准 ML 模型,你只需把模型复制到多台服务器/GPU 上,再配合简单的负载均衡策略,比如轮询(Round Robin),或者把请求路由到最空闲的服务器即可。

由于每个请求都是相互独立的,这种做法完全没问题。但 LLM 严重依赖缓存(比如前面提到的共享 KV 前缀),这意味着请求之间不再是相互独立的了。如果一个新查询的共享前缀已经缓存在副本 A 上,但路由器却把它发到了更空闲的副本 B,副本 B 就不得不重新计算整个前缀的 KV 缓存。前缀感知路由正是为了解决这个问题。

llm optimization p323 1

不同的开源框架对前缀感知路由各有各的实现方式。一般来说,前缀感知路由需要路由器维护一张映射表(或者使用某种预测算法),来追踪哪些 KV 前缀当前缓存在哪些 GPU 副本上。

当新查询到来时,路由器会把它发送给已经缓存了相关前缀的那个副本。

模型分片策略(Model Sharding Strategies)

扩展一个稠密(dense)ML 模型有几种常见策略:

llm optimization p324 1

而像混合专家(MoE)这样的 LLM 架构,情况要复杂得多。

llm optimization p325 1

MoE 模型使用一种专门的并行策略,叫做专家并行(expert parallelism):把各个专家(experts)分散到不同的设备上,而注意力层则会在所有 GPU 上进行复制:

llm optimization p325 2

也就是说,每个 GPU 只保存部分专家的完整权重,而不是全部专家。这意味着每个 GPU 只处理分配给它所存储的那些专家的 token。当一个查询到来时,MoE 层中的门控网络(gating network)会根据被激活的是哪些专家,动态决定这个查询应该被送到哪个 GPU 上。这是一个复杂的内部路由问题,不能简单地用「模型复制」的思路来处理,而是需要一个足够精细的推理引擎,去管理跨分片专家池的动态计算流程。

本站内容仅供学习交流,版权归原作者所有。