什么是 LLM 推理

·

文章大纲

1. 什么是大模型

点击后可快速跳到对应章节

当你打开 AI 聊天的网页,输入问题,按下发送,不一会儿对面就开始“哒哒哒”地逐字给你回复了。在 AI 时代,我们不能只停留在“会用”上,起码得稍微懂点它背后的原理。在这篇文章里,我就来和大家聊聊,看看大模型推理这玩意儿,到底是怎么一回事(本文仅从整个 pipeline 的角度做一个综述,涉及到的具体细节之后的文章中再谈)。

1. 什么是大模型

在一切开始之前,先简要介绍一下大模型:大模型是基于 Transformer 架构的深度神经网络。

接下来我将逐步介绍文本如何被计算、数据如何流动。

2. 分词和词嵌入

文本本身是不能被计算的,那么首先需要把文本转化为计算机能理解的数学表示——高维向量。

  • 第一步:将输入的文本进行分词,即将一段文本按照给定方式划分成词元(Token)——词元是大模型中定义的自然语言文本的基本单位。一个词元对应一个整数,所有词元构成一个词表。
  • 第二步:分词之后,将词元从整数映射到高维空间的向量。

3. 位置编码

自注意力机制是无法记录词元先后顺序,故引入位置编码这个概念来记录先后顺序。

4. Decoder only Transformer 架构

带有位置信息的向量序列依次穿过所有堆叠的解码器块。

5. 推理的 Prefill 和 Decode

大模型的推理过程通常分为两个截然不同的阶段:

  • Prefill:当大模型接收到你输入的 prompt 时,它需要先“理解”这些上下文。在这个阶段,模型会将输入的所有 Token 一次性并行输入到 Transformer 中进行前向传播计算。因为是并行计算,这个阶段能极大地发挥 GPU 矩阵乘法的并行算力。计算完成后,模型会输出第一个生成的词(First Token),并且会计算出输入序列的 Key 和 Value 向量(为下一步做准备)。这一步是计算密集型。
  • Decode:当你看到屏幕上的字一个一个蹦出来时,模型正处于 Decode 阶段。大模型的生成是自回归(Autoregressive)的,这意味着它每次只能生成一个词元,并且生成下一个词元时,需要依赖之前输入的所有内容加上刚刚生成的所有词元。因为每次只能算一个词元,无法像 Prefill 那样大规模并行,所以这个阶段的速度相对较慢。这一步是 IO 密集型。

6. KV Cache

既然 Decode 阶段每次生成新词都需要看前面的所有词,就意味着前面词的注意力(Attention)需要被重复计算无数次,为了避免这种巨大的算力浪费,KV Cache 应运而生。

在 Transformer 的自注意力计算中,每个 Token 都会映射成 Query (Q)、Key (K) 和 Value (V)。

  • 在生成新词时,我们只需要当前最新 Token 的 Q 去和之前所有 Token 的 K 匹配计算注意力分数,再乘以之前所有 Token 的 V。
  • 因此,我们可以把之前所有 Token 的 K 和 V 缓存(Cache)在显存里。每次生成新词,只需计算新词的 Q、K、V,然后把新的 K 和 V 追加到缓存中。

总结来说,KV Cache 就是一种“以空间换时间”的策略,通过消耗显存来大幅降低重复计算。

7. 量化

面对动辄几十亿、几百亿甚至上千亿的大模型参数,如果使用标准的半精度浮点数(FP16/BF16,每个参数占 2 字节)存储,往往需要极其庞大的显存。比如 70B 的模型仅仅是权重就需要约 140GB 显存,这使得个人电脑甚至单张高端服务器显卡都无法运行。

量化(Quantization) 就是给模型“瘦身”的技术。它将模型权重(甚至激活值)从 16 位浮点数压缩到 8 位整数(INT8)甚至 4 位整数(INT4)。

  • 优势: 显存占用成倍降低,同时由于读取的数据量变小,极大缓解了 Decode 阶段的访存带宽瓶颈,推理速度显著提升。
  • 代价: 会带来精度损失。

8. 端到端推理流程

将以上所有概念串联起来,一次完整的对话推理流程如下:

  1. 用户输入:输入一段自然语言文本(Prompt)。
  2. 分词(Tokenization):分词器将文本切分成计算机能看懂的 Token IDs。
  3. 词嵌入与位置编码(Embedding & Positional Encoding):将 Token IDs 转换为高维向量,并注入位置信息,让模型知道词的先后顺序。
  4. 预填充(Prefill):模型并行处理所有输入向量,计算并缓存下它们的 KV Cache。最终输出一个概率分布,并采样出生成的第一个预测词(First Token)。
  5. 反分词与展示(Detokenization & Streaming):将刚刚生成的 Token ID 转换回人类可读的文字,立刻在屏幕上展示给用户(这就是你看到的第一字)。
  6. 解码循环(Decode Loop):
    • 将刚刚生成的 Token 作为新的输入。
    • 利用已有的 KV Cache,仅计算新 Token 的 Q、K、V。
    • 新 Token 的 Q 与缓存中所有的 K(包含自身)计算注意力,生成下一个词。
    • 更新 KV Cache,将新词转为文字流式展示给用户(“哒哒哒”的打字效果)。
  7. 结束条件:不断重复步骤 6,直到模型生成了特殊的结束符(EOS Token)或达到了设定的最大长度,推理结束。

9. 大模型推理框架

在实际的生产环境中,我们通常不会手写推理代码,而是使用成熟的推理框架来处理并发、内存分配和极致优化。主流的推理框架包括:

  • vLLM:目前最流行的开源推理框架之一,首创了 PagedAttention 技术,像操作系统管理内存分页一样管理 KV Cache,极大提升了系统的吞吐量。
  • TensorRT-LLM:NVIDIA 官方推出的推理库,对自家 GPU 底层做了极致优化,性能天花板极高,但部署相对复杂。
  • TGI (Text Generation Inference):HuggingFace 开发的框架,与 HF 生态集成极好,开箱即用。
  • Llama.cpp:专为 CPU 和边缘设备(如 Mac、手机端)优化的纯 C++ 框架,使得在消费级硬件上跑大模型成为可能。

10. 性能监测

要评估一个大模型推理服务的好坏,我们通常会关注以下几个核心指标:

  • 首字延迟 (TTFT - Time To First Token):从用户点击发送到看到第一个字出现的时间。它主要反映了网络延迟和模型 Prefill 阶段的耗时。
  • 每个输出词元时间 (TPOT - Time Per Output Token):生成第一个词之后,后续每个词生成的平均时间。它反映了 Decode 阶段的速度。
  • 吞吐量 (Throughput):服务器每秒钟能生成的所有 Token 总数(Tokens/s)。这是衡量推理框架并发处理能力的最重要指标。
  • 显存占用 (VRAM Usage):监控权重、KV Cache 和上下文长度对显存的消耗,防止 OOM (Out of Memory) 崩溃。