随着 LLMs 在各行各业的应用,如何在保证模型性能的前提下实现高效推理已成为重点挑战之一。

前言

主流的 LLMs 在算法架构上基于 transformer 的 decoder-only 架构,核心任务是 next token prediction,在推理过程中,模型需要依次生成每个 token,这种自回归生成的特点会增加推理延迟。并且从参数量上模型可分为不同规模,即使是小模型,其对计算资源和内存资源也有较高要求。

为了应对这些挑战,学术界和工业界提出了多种优化方案。本文将介绍了若干 LLMs 的推理加速相关的关键技术。如有错误或不准确之处,欢迎指正。

正文

推理阶段概述

推理阶段是模型接收输入并产生输出的过程。与训练阶段不同,推理阶段不需要计算梯度和更新参数,只需要完成前向传播计算。

在推理过程中,由于自回归生成的特点,模型需要逐个生成 token。这导致处理的序列长度会不断增加。例如:

  • 输入长度为 1000 tokens,需要生成 100 个新 tokens,那么实际计算的序列长度为: 1000 + 1001 + … + 1100 = 106050 个 tokens
  • 每个新 token 都需要与之前所有 token 计算注意力

在典型的 decoder-only 架构中,有多层 decoder block,每个 token 在推理时都要依次通过这些 block。每个 block 包含 3 个主要计算模块:Self-AttentionFFN、Layer Normalization(保证数值稳定性的基础,下文忽视)。

image
image

其模块的执行阶段可分为 prefill 阶段与 decode 阶段:

  1. Prefill:模型需计算与存储 所有输入的 kv cache

    1. 特点:
      1. 计算密集场景:计算复杂度为 O(n2),n*n 的矩阵运算,但可利用硬件的并行处理能力加快
      2. 显存密集场景:占用显存随序列长度增长
    2. 模块:
      1. Self-Attention: 需要计算所有输入 token 之间的注意力分数,生成并存储所有 token 的 K、V 到 cache 中
      2. FFN: 对所有输入 token 执行 FFN 计算
  2. Decode:复用已缓存的 kv,只需计算新 token

    1. 特点:
      1. 计算稳定:向量计算,每个 token 的计算量为 O(n),1*n 的向量计算,延迟主要来自顺序依赖,难以并行化
      2. 显存增长稳定
    2. 模块:
      1. Self-Attention: 只需为新 token 生成 Q,复用已缓存的 K、V,计算新 token 的注意力分数
      2. FFN: 只对新生成的 token 执行 FFN 计算

Demonstration of the prefilling stage (a) and decoding stage (b)

image
image

Illustration of the memory variation through time (latency) during

image
image

推理过程中性能指标包括:

  • TTFT(Time-To-First-Token):首 token 的生成时间,主要衡量 Prefill 阶段性能。
  • TPOT(Time-Per-Output-Token):生成每个 token 的时间,主要衡量 Decode 阶段性能。

通过一个实际的例子来理解推理过程,query:”最近发生了哪些与 Deepseek R1 相关的实践”

Prefill 阶段:

  1. Self-Attention:“发生”、“实践” 会与 “Deepseek R1” 产生比较高的关注度,产生 n * n 的注意力矩阵
  2. FFN:会在大量已学习知识中,查找到关于 Deepseek 的 pretrain 知识
  3. 结果:输出第一个概率最高的 token

Decode 阶段:

  1. Self-Attention:用生成的 新 token q 去理解输入的 kv ,发现问的是实践,理解需要实践的相关知识
  2. FFN:会在大量已学习知识中,找到实践的相关知识
  3. 结果:输出后续概率最高的 token

综上,推理阶段的关键开销:

  1. 计算成本:
    1. Prefill 要处理所有输入,输入与计算量成平方关系;
    2. 模型参数量越来越大;
    3. Decode gpu 计算量低
  2. 存储成本:
    1. KV Cache 与输入序列的长度成正比,需要在显存中保存所有历史 token 的 K/V
    2. FNN 存储开销大,参数量预计占比 70% 以上
  3. IO 成本:decode 每次只生成一个 token,但要反复调用模型

技术总览

针对这些挑战,业界从不同阶段提出了优化方案:

image
image

数据层面

输入压缩

在尽可能降低性能影响的前提下,压缩输入的文本,裁剪低质信息,从而提升性能,细分工作:

  1. LLMLingua Series:训练小模型对原始 prompt 进行裁剪压缩
    image
    image
    image
    image
    其思路是将压缩过程转化为一个词元分类问题,即决定每个词元是保留还是舍弃。任务模型是通过大模型蒸馏出数据集后,训练一个小模型来执行。
    image
    image
    另一些在 rag 场景的压缩工作:
  2. RECOMP:将检索到的文档压缩成文本摘要来提高语言模型的性能,同时减少计算成本。

    image
    image
  3. xRAG:通过模态融合的方式将文档的 embedding 直接投影到 LLMs 的表示空间中

    image
    image
  4. 常规的 RAG、Rerank:适用于信息密集型场景,选择高相关的内容,避免 garbage in garbage out

    image
    image

    不相关段落对于 RAG 效果的影响 https://arxiv.org/pdf/2410.05983

输出规划

在尽可能降低性能影响的前提下,提升长文本输出的并行度,从而提升性能,细分工作:

  1. SOT:SOT 提出一种意图理解后并行输出的思路,对答案生成大纲,然后针对大纲中的每一个点再并行生成,从而提高了线性解码的性能,但对应不同点之间存在依赖的场景,无法很好的解决。所以基于此,又额外训练了个 router model 去判断是否存在依赖,存在依赖则不进行并行解码。

    image
    image
    image
    image
  2. SGD:在 SOT 的基础上更进一步,将依赖关系抽象成 DAG(有依赖的点 存在连线;没有依赖的点独立),所以可以更进一步提升效果。

    image
    image

模型层面

模型结构优化
  1. Attention 优化:核心是减少 KV Cache 以及核函数的运算,

    补一下苏神的解答:为什么降低 KV Cache 的大小如此重要?众所周知,一般情况下 LLM 的推理都是在 GPU 上进行,单张 GPU 的显存是有限的,一部分我们要用来存放模型的参数和前向计算的激活值,这部分依赖于模型的体量,选定模型后它就是个常数;另外一部分我们要用来存放模型的 KV Cache,这部分不仅依赖于模型的体量,还依赖于模型的输入长度,也就是在推理过程中是动态增长的,当 Context 长度足够长时,它的大小就会占主导地位,可能超出一张卡甚至一台机(8 张卡)的总显存量。在 GPU 上部署模型的原则是:能一张卡部署的,就不要跨多张卡;能一台机部署的,就不要跨多台机。这是因为“卡内通信带宽 > 卡间通信带宽 > 机间通信带宽”,由于“木桶效应”,模型部署时跨的设备越多,受设备间通信带宽的的“拖累”就越大,事实上即便是单卡 H100 内 SRAM 与 HBM 的带宽已经达到了 3TB/s,但对于 Short Context 来说这个速度依然还是推理的瓶颈,更不用说更慢的卡间、机间通信了。所以,减少 KV Cache 的根本目的是实现在更少的设备上推理更长的 Context,从而实现更快的推理速度以及更低的推理成本。

    1. MHA(Multi-Head Attention):最基础的多头注意力机制,每个注意力头都有独立的 Q、K、V 参数矩阵。虽然可以充分捕获不同特征维度的信息,但需要存储所有头的 KV Cache,存储开销较大。
    2. MQA(Multi-Query Attention): 在计算注意力时,共享的 K/V 会被广播到每个注意力头,然后每个头仍然使用自己独立的 Q 与共享的 K/V 计算注意力分数。KV Cache 大小减少为原来的 1/h (h 是头数)。但共享 KV 可能会限制模型捕获多样化特征的能力。
    3. GQA(Grouped-Query Attention): MQA 和 MHA 的折中方案,将注意力头分成若干组,同一组内的头共享 KV。相比 MQA 能保持更好的模型性能,同时相比 MHA 显著减少了 KV Cache。代表作:DeepSeek V1LLaMa 3.1Qwen2
    4. MLA(Multi-head Latent Attention): 是 DeepSeek V2 通过引入隐变量的一种新型的注意力机制。它通过压缩键 (Key) 和值 (Value) 到一个低维隐式空间,显著减少了 KV 缓存的大小。与标准注意力机制相比,据称可减少约 93.3% 的 KV 缓存。
      image
      image
      image
      image
  2. MOE(Mixture-of-Expert):高效的 FFN 设计,将 FFN 拆解成一个 gate network 与 多个 expert,每个 token 只分配给若干个 experts 进行计算,可以显著减少缓存、IO 开销,该思路起源于 1991 年的论文 Adaptive Mixture of Local Experts。 从 Mistral 的 Mixtral 8x7B 开始,在 24 年 moe 已成为各大模型的主流趋势,以 deepseek 为代表,三个版本的 paper 都是沿着更专业、更极致 的 moe 架构演进。其中的难点有:token 分配的问题、专家学识不精等。

    image
    image
    image
    image
模型压缩

模型压缩旨在通过降低模型复杂度(包括参数量、计算量和内存占用)来减少资源开销,在尽可能保持模型性能的前提下提升推理效率。其中一些代表性的措施有:

image
image
1. 量化:量化是降低模型权重和激活的精度,大多数模型都以 32 或 16 位精度进行训练,其中每个参数和激活元素占用 32 或 16 位内存(单精度浮点),显然,可以尝试使用更少的位来表示权重。 常见的方法有训练后量化,模型训练完直接转换数值精度,操作简单但精度可能下降;还有量化感知训练,训练时模拟量化效果,让模型提前适应低精度,精度损失更小。收益除了大幅减少模型体积外,也能提高计算速度。在 prefill 阶段 重点量化激活值量化;在 decode 阶段 重点量化权重。
image
image
  1. 知识蒸馏:知识蒸馏是将大模型(教师模型)的知识转移到小模型(学生模型)中的压缩方法。常见方法有训练后蒸馏,直接用教师模型生成数据训练学生模型,可以在保持大部分性能的同时将模型压缩至原来的 40-60%。

    image
    image
  2. 减枝:通过移除模型中不重要的连接或结构来压缩模型。常见方法有结构化剪枝(移除整层或整个头)和非结构化剪枝(移除单个权重),可以在性能损失较小的情况下减少 30-50% 的参数量。

  3. 低秩分解:将大的权重矩阵分解成若干个小矩阵的乘积,从而减少参数量和计算量。常见方法有 SVD 分解和 LoRA 等。其中 LoRA 通过在原始权重旁增加低秩矩阵来实现参数高效微调,已成为主流的模型压缩方法之一。
解码优化

推理阶段最耗时的部分是自回归生成过程,解码优化旨在通过并行化或预测等方式来加速 token 生成。其中一些代表性的措施有:

  1. 推测解码 (Speculative Decoding):一种用于自回归大模型的创新解码技术,旨在提高解码效率,同时不影响输出的质量。这种方法的核心思想包括使用一个较小的模型(Draft Model)来有效地预测几个后续 token,然后使用大模型并行验证这些预测。该方法旨在使大模型能够在单个推理通常所需的 a 时间范围内生成多个 token。

    image
    image
  2. 跳跃式解码:代表工作 SGLang,核心思想是通过分析文本结构的确定性特征,在生成过程中跳过可预测的部分。它不需要逐个 token 地生成,而是能够在确定性很强的位置直接跳转到下一个需要推理的位置,从而大幅提升生成效率。

    image
    image
  3. 约束性解码:代表工作 Outlines,Outlines 通过将 JSON Schema 转换成正则表达式,然后基于该正则表达式构建有限状态机(FSM, Finite State Machine),然后在生成过程中实时过滤 token,确保输出始终符合预定义的格式要求。这种方式特别适合需要严格控制输出格式的场景。

    image
    image
  4. 结构化解码:代表工作 Guidance,创新点在于将生成任务分为固定结构和动态内容两类,并采用不同的处理策略。通过识别文本中的模板部分,可以显著减少需要实际生成的内容量,从而提高整体效率。

    image
    image

系统层面

KV Cache

KV Cache 在 LLM 推理过程中占用了大量访存带宽,这使得 KV Cache 的压缩优化成为 LLM 推理领域的研究热点。目前主要有两种压缩技术路线:

  1. 稀疏化压缩通过减少保留的关键 token 数量来实现压缩。例子:
    1
    2
    3
    4
    原始输入:
    [T1, T2, T3, ..., T128K] // 128K tokens 的 prompt
    稀疏化后:
    [T1, T512, T1024, ..., T128K] // 仅保留 1024 个关键 tokens
  2. 量化压缩在保持 token 数量不变的情况下,降低数据精度。例子: 这两种方法各有特点,但都致力于在保证模型性能的前提下,降低内存占用并提升推理速度。稀疏化适合处理超长文本输入,而量化则是一种普适性的优化方案。 KV Cache 优化的过程:
    image
    image
PagedAttention

传统推理框架采用静态显存分配策略:按照 batch_size × max_seq_len 预分配固定大小的显存块,这导致显存利用率低下。

1
2
3
4
5
6
7
// 传统静态分配
预分配显存大小 = 4(batch_size) × 2048(max_seq_len) × 2(bytes/token)
实际使用情况:
- 请求 1: 使用 256 tokens
- 请求 2: 使用 512 tokens
- 请求 3: 使用 128 tokens
结果:大量显存空间被浪费
vllm 借鉴操作系统的虚拟内存分页思想,提出了 PagedAttention 技术,实现 KV Cache 显存的动态分配。
1
2
3
4
5
6
// PagedAttention 动态分配
显存页大小 = 16KB
请求 1: 动态分配 2 页 (32KB)
请求 2: 动态分配 4 页 (64KB)
请求 3: 动态分配 1 页 (16KB)
优势:按需分配,提高显存利用率
这种动态管理机制让显存资源得到更高效的利用,特别适合处理长度变化较大的多请求场景。

image
image
Perfix Cache

传统 PagedAttention 的局限:KV Cache 只能在单个请求内复用,无法跨请求共享,这在多轮对话场景下效率不高。 例子:

1
2
3
4
5
6
7
8
// 传统方式
对话轮次 1:
Prompt: "你好,请介绍下北京"
→ 计算完整的 KV Cache

对话轮次 2:
Prompt: "你好,请介绍下北京的故宫"
→ 重新计算 KV Cache(即使包含大量重复内容)
Prefix Caching 优化:通过缓存系统提示和历史对话的 KV Cache,实现跨请求复用,降低首次 Token 生成时间(TTFT)。 SGLang 提出的 RadixAttention 通过三个关键步骤实现自动 KV Cache 复用:

  1. 缓存保留
    1
    2
    3
    请求完成后:
    KV Cache → 保留在 GPU 显存
    Token 序列 → 存入 RadixTree
  2. 前缀匹配
    1
    2
    3
    4
    5
    6
    7
    新请求:"你好,请介绍下北京的故宫"

    RadixTree 匹配

    命中:"你好,请介绍下北京"的 KV Cache

    仅需计算新增部分:"的故宫"
  3. 缓存管理
    1
    2
    3
    4
    策略:LRU(最近最少使用)
    当显存不足时:
    - 识别最久未使用的 KV Cache
    - 优先释放这部分显存
    这种优化特别适合多轮对话等场景,可以显著提升模型响应速度和资源利用效率。
其他

系统层面还有诸多优化手段,如张量并行、流水线并行、分布式推理等。由于这些优化方案涉及较为复杂的系统架构设计,在此不做展开讨论。感兴趣的读者可以参考相关技术文档深入了解。


结束语

通过对 LLMs 推理加速技术的深入探讨,我们可以看到:

  1. 技术架构与挑战
    • 推理过程分为 Prefill 和 Decode 两个主要阶段
    • 核心挑战:
      • 计算成本:输入规模、参数量、自回归特性
      • 存储成本:KV Cache、FFN 参数存储
      • IO 成本:频繁模型调用
  2. 优化方案(多层次技术栈)
    • 数据层面优化:
      • 输入压缩:LLMLingua、RECOMP、xRAG 等
      • 输出规划:SOT、SGD 等并行输出技术
    • 模型层面优化:
      • 结构优化:注意力机制(MHA、MQA、GQA、MLA)、MOE 架构
      • 模型压缩:量化、知识蒸馏、减枝、低秩分解
      • 解码优化:推测解码、跳跃式解码、约束性解码等
    • 系统层面优化:
      • KV Cache 优化:稀疏化压缩、量化压缩
      • PagedAttention:动态显存管理
      • Prefix Cache:跨请求 KV 复用 随着 LLMs 在各领域的应用不断扩大,推理加速技术也在持续演进。从早期的简单优化到现在的多层次综合优化方案,技术在不断突破。这些优化技术的发展使得 LLMs 能够更高效地服务于实际应用场景,为 AI 应用的普及奠定了重要基础。未来,随着硬件技术的进步和算法的创新,我们有望看到更多突破性的推理加速方案。

参考资料:

  1. A Survey on Efficient Inference for Large Language Models 帮助很大,推荐
  2. Model Compression and Efficient Inference for Large Language Models: A Survey
  3. Mastering LLM Techniques: Inference Optimization
  4. AI 大模型推理过程和优化技术
  5. How to make LLMs go fast
  6. 异度部落格
  7. 详细谈谈 DeepSeek MoE 相关的技术发展
  8. 缓存与效果的极限拉扯:从 MHA、MQA、GQA 到 MLA
  9. A Survey on Model Compression for Large Language Models

转载本站文章请注明作者和出处 SimonAKing,请勿用于任何商业用途。