训练一个前沿模型可能需要花费数亿美元并耗时数月。但一旦该模型被生产出来,它就只是一堆静止在内存中的巨大数字集合。模型本身并不知道如何执行任何操作。那么,幕后究竟发生了什么让模型“活”过来?这个过程被称为推理(Inference)。如今的大多数现代聊天机器人、代码助手和智能体应用背后,都是推理技术在支撑。

与仅发生一次的训练不同,每当有人向模型发送消息时就会触发推理过程。经过训练的模型是一组静态的权重或专用数字,它们在训练过程中被调整以表示信息。推理则是将该经过训练的模型应用于新输入并产生某种输出的过程。令人惊讶的是,随着时间推移,推理的成本通常高于训练成本,因为它会在每次请求时重复发生。

随着时间的推移,尽可能高效地提供服务模型以降低成本变得愈发关键。今天我们将深入了解提示词与响应之间真正发生的事情,以及如何使该服务过程尽可能快速且廉价。管理推理的软件被称为推理引擎(Inference Engine)。它的职责是将一堆权重转化为能够可靠、快速且大规模地服务请求的东西。

这意味着它需要调度传入的请求,管理 GPU 资源,并决定如何协同处理工作负载。如果你听说过 vLLM、Ollama 或 Llama.cpp,这些都是推理引擎的例子。让我们看看当你向大型语言模型发送消息时会发生什么。大多数推理引擎提供一个标准的 OpenAI 兼容端点,这意味着无论后端运行的是哪个模型,你都可以使用相同的请求格式来发送查询。

当你有一个旨在调用某个模型的构建应用,并希望在不重写任何代码的情况下轻松替换另一个模型时,这非常有用。但在该请求进入数据中心之前,我们需要将其转换为模型可以理解的格式。这个过程称为分词(Tokenization)。将文本分解为令牌,这些令牌可能是整个单词、单词的一部分或某些标点符号,并将每个令牌映射到一个任意的令牌 ID。

模型实际上并不“看到”这些单词,它只看到一串 ID。尽管这一步几乎不消耗处理功率,但它决定了你的提示词成本多少,因为它是按令牌构建的。拥有更大词汇量的模型可以使用更少的令牌更高效地表示文本,但更大的词汇量会在训练过程中增加计算开销。你的请求需要在物理硬件上进行处理。

在大多数情况下,这种硬件位于数据中心内。一旦你的请求到达数据中心,它将通过 API 密钥或令牌进行身份验证,这证明你有权使用这些 GPU 资源。接下来,你会被路由到特定的硬件上。推理路由器会查看你的提示词、其长度以及包含的内容,并将其路由到当时最适合你请求的可用硬件上。

然而,你的请求并非唯一传入的请求,逐个将请求通过模型处理就像面包店一次只用工业烤箱烤一个糕点一样。这会浪费大量的 GPU 资源,并严重降低系统的吞吐量(即系统一次能承载的请求数量)。批处理将请求分组在一起,以便 GPU 将它们作为一个更大、更高效的工作单元进行处理。

并非所有请求的处理时间都相同,因此现代引擎使用连续批处理(Continuous Batching)。一旦一个请求完成,另一个请求就会立即填补其位置。这样 GPU 就能始终保持接近满负荷的运行状态。调度程序将处理此批处理过程,并将你的请求路由到执行实际计算和生成响应的硬件上。让我们深入探讨最后这一步。

LLM 推理包含两个不同的阶段:预填充(Prefill)和解码(Decode)。一旦你的请求到达模型,它便进入预填充阶段。在预填充中,模型一次性读取整个提示词并建立对其的理解,同时构建所谓的键值缓存(KV Cache)。这是模型迄今为止所读取内容的运行记忆。

如果没有它,对于每个想要输出的令牌,模型都必须重新处理整个对话过程。这就是为什么随着对话变长,你的体验不会呈指数级变慢的原因。这一步是计算密集型的(Compute-bound),意味着它需要巨大的并行数学运算爆发,因此其速度受限于硬件能同时支持多少原始计算量。

接下来,该 KV 缓存被传递到解码阶段。在解码中,模型一次生成一个令牌的响应。在解码的每一步中,模型执行前向传播(Forward Pass),并在其词汇表中的每个令牌上产生一个概率分布。本质上,这是一个潜在下一个令牌的排名列表。

一旦从分布中选择一个令牌,它就会被附加到序列末尾,然后整个过程随着每个生成令牌的产生而重新开始。每个令牌都依赖于之前的令牌,并且在每一步中,模型还必须参考整个 KV 缓存以记住它在预填充阶段学到的信息。

这一步是内存带宽受限的(Memory bandwidth-bound),意味着其速度不受限于它能做多少数学运算,而是受限于数据从内存中移动的速度。预填充需要原始计算能力,而解码则需要快速的内存访问。这也是两个常见基准测试数字的来源:首令牌时间(TTFT)是指用户收到第一个令牌所需的时间。

这有效地显示了你的预填充步骤花费了多长时间。以及词元间延迟(ITL),这是用户收到令牌之间的时间间隔。这本质上显示了你的解码阶段的每一步花费了多长时间。结合起来,这些构成了人们所说的 LLM 延迟的大部分含义。推理是静态训练模型实际生成响应的方式。

每个请求都被调度到批处理中以保持硬件在处理不均匀请求时的忙碌状态。请求被路由到硬件,经过计算密集型的预填充阶段和内存带宽受限的解码阶段。结合起来,这就是位于训练模型和用户可实时使用的产品之间的机械装置。请在评论区提出任何后续问题,或告诉我你已经在优化推理栈的哪个部分。