# LLM模型推理入门

- URL: https://www.yidoo.xyz/llm-inference-introduction
- 作者: 核动力蜗牛
- 发布时间: 2024-07-27
- 更新时间: 2024-07-27
- 分类: LLM技术内幕
- 标签: llm, LLM推理优化

# 概述

随着生成式 AI 的迅速发展，大语言模型（LLM）的推理性能和成本已成为其大规模应用的关键障碍。LLM 推理是指利用仅解码器的 Transformer 模型生成词元（token），其中大多数挑战及其解决方案都源于这一特定架构和用例。

本文将深入探讨 LLM 推理过程的两个阶段：预填充阶段（Prefilling）和解码阶段（Decoding），并详细介绍如何通过算法创新和系统优化来提升 LLM 的推理效率。具体内容包括：

1. **LLM 推理基础知识**：介绍 Transformer 架构及其关键组件，如自注意力机制、多头注意力机制和前馈网络。同时，详细说明从输入词元到生成输出词元的预填充阶段和解码阶段的推理过程。
2. **LLM 推理优化方向**：探讨通过算法创新和系统优化来提升 LLM 推理效率的方法，包括优化解码算法、优化架构设计和模型压缩等。
3. **LLM 推理性能指标**：介绍衡量 LLM 推理性能的关键指标，如每秒请求数（RPS）、首字输出时间（TTFT）和字符间延迟（ITL）等。

# 术语解释

- **词元（Token）**：在自然语言处理中，词元是文本数据的最小单位。它可以是一个词、一部分词、一个字符，或者是一个子词。词元化是将文本拆分成这些最小单位的过程，以便于计算机处理和分析。
- **预填充阶段（Prefilling）**：在 LLM 推理过程中，预填充阶段是指模型在收到输入序列后，生成第一个输出词元之前的计算过程。
- **解码阶段（Decoding）**：解码阶段是指在预填充阶段生成第一个词元后，模型通过迭代生成后续词元的过程，直到生成结束标志或达到最大序列长度。
- **自注意力机制（Self-Attention Mechanism）**：Transformer 模型中的一种机制，通过计算输入序列中不同部分的重要性，使模型能够在生成过程中聚焦于输入序列的不同部分。
- **前馈网络（Feed-Forward Network, FFN）**：Transformer 模型中的组件，包含两个线性变换和一个非线性激活函数，能够增加模型的非线性表达能力。
- **多头注意力机制（Multi-Head Attention）**：Transformer 模型中的一种机制，通过在不同的表示空间中同时关注输入序列的不同部分，提高模型的表现力。
- **位置编码（Position Encoding）**：在 Transformer 模型中，位置编码为序列中的每个词元添加位置信息，使模型能够识别输入序列中的相对位置关系。
- **量化（Quantization）**：通过减少表示模型权重和激活值的比特位数来降低计算成本和内存占用的一种技术。
- **模型并行（Model Parallelism）**：一种将模型的不同部分分配到多个设备上并行计算的方法，用于加速推理过程。
- **数据并行（Data Parallelism）**：一种将不同的数据样本分配到多个设备上并行处理的方法，用于提高处理速度。
- **网络剪枝（Network Pruning）**：通过移除模型中不重要的参数来减少模型大小和计算需求的一种技术。

# LLM 推理基础知识

## Transformer 介绍

当前主流的 LLM 比如 OpenAI 的 GPT 系列、Meta 的 Llama 系列还有如 OPT、BLOOM、Mistral 等等，其核心是基于自注意力机制的 Transformer 架构，该机制允许模型在做出预测时对输入数据的不同部分的重要性进行权重计算。
![50126873c9b4cc08075b9b7569fad2b6.png](https://www.yidoo.xyz/images/50126873c9b4cc08075b9b7569fad2b6.png)

### 自注意力机制

在 Transformer 模型中，自注意力机制通过线性变换计算输入序列 X 的查询 Q、键 K 和值 V。自注意力分数计算公式如下：
![d8cfaa70e35f51b3a9b7b1598eb9801f.png](https://www.yidoo.xyz/images/d8cfaa70e35f51b3a9b7b1598eb9801f.png)
其中 dk 是键的维度。该机制使模型能够对输出的每个元素聚焦于输入序列的不同部分，从而捕捉输入序列中不同位置之间的复杂依赖关系。

### 前馈网络（FFN）

Transformer 的每一层中都包含前馈网络（FFN），显著增加了计算强度。FFN 通常由两个线性变换和一个非线性激活函数（通常是 ReLU）组成，公式如下：
![98849921f82cfa67ffeae1afa53fedde.png](https://www.yidoo.xyz/images/98849921f82cfa67ffeae1afa53fedde.png)
其中 W1, W2, b1, b2 是可学习参数。FFN 引入了必要的非线性，使模型能够学习更复杂的模式。每个 Transformer 层在多头注意力（MHA）聚合输入的不同部分的信息后，FFN 会独立地处理这些聚合信息。

### Transformer 其他组件

Transformer 模型还包括其他关键组件，如位置编码（position encoding），它为序列中的每个标记添加位置信息；多头注意力机制（multi-head attention），允许模型在不同的表示空间中关注序列的不同部分。这些组件共同作用，使得 Transformer 模型能够捕捉广泛的语言上下文和细微差别，在各种 NLP 任务中设立了新的基准。

## LLM 推理过程：预填充 + 解码

在介绍完 Transformer 结构之后，我们来看下 Decoder-Only 的模型如何进行模型推理。为简单起见，我们假设一次只处理一个序列（即批处理大小为 1）。在下图中，我描述了一个简单的基于 Transformer 的解码器的主要层，用于从一系列输入词元中生成输出词元。
![64cf1aff9e2d2268ed84863ee8061889.png](https://www.yidoo.xyz/images/64cf1aff9e2d2268ed84863ee8061889.png)
需要注意的是，解码器本身并不会输出词元，而是输出 logit（其数量与词汇表大小相同）。输出 logit 的最后一层通常被称为语言模型头（Language Model Head）或 LM 头。将 logit 转换为词元是通过一种启发式算法来完成的，这种算法通常被称为解码策略（decoding strategy），也叫做词元搜索策略（token search strategy）或生成策略（generation strategy）。解码策略的目的是在保持文本连贯性和合理性的同时，提高生成结果的质量和多样性。

简单起见，我们假设解码策略是模型的一部分，这些接受词元序列作为输入，并返回相应输出词元的实体通常被称为执行引擎或推理引擎。

如果要生成多个词元呢？使用基于 Transformer 的解码器，从一个输入文本序列（称为 prompt）中生成文本（称为 completion）通常包含以下步骤：

1. 将模型权重加载到 GPU。
2. 在 CPU 上对输入文本进行分词，并将文本序列词元传输到 GPU。
3. 利用模型运行输入词元，输出第一个词元（预填充阶段）。![95929907ee2d494122fb567c71f8354d.png](https://www.yidoo.xyz/images/95929907ee2d494122fb567c71f8354d.png)
4. 将生成的词元添加到输入的词元序列中，然后作为新的输入，生成下一个词元，直到生成停止词元（比如 EOS）或者到达预先配置的最大序列长度（解码阶段）。![116069ddc1872cc38d452d8553246796.png](https://www.yidoo.xyz/images/116069ddc1872cc38d452d8553246796.png)
5. 将生成的词元传输到 CPU，并进行逆词元化（de-tokenization）获得生成的文本。![7665c92128328629e11f4b777deb1176.png](https://www.yidoo.xyz/images/7665c92128328629e11f4b777deb1176.png)
   上述介绍了最基础的 LLM 推理过程，目前也有一些更为先进的技术，流程上可能会有所不同。

## LLM 性能评估指标

### Prefill 性能评估指标：TTFT

**TTFT（Time To First Token），表示生成第 1 个 token 所用的时间，这是 prefill 阶段的重要评估指标之一**。 在实践中，我们一般会人为设置一个**TTFT SLO（Service Level Objective）**，这个指标是我们给系统提的要求，只有系统达到了这个指标，我们才认为它的性能达标了。举例来说，**假设我们定 P90 TTFT SLO = 0.4s**，那么这意味着我们对该系统的要求是：“90%的 request 的 TTFT 值都必须<=0.4”

### Decode 性能评估指标：TPOT

**TPOT（Time Per Output Token），产出每一个 response token 所用的时间，这是 decode 阶段的重要评估指标之一**。 同样，**我们也有一个 TPOT SLO 指标**，这是人为给系统定下的性能要求。

# LLM 推理优化方向

在《Towards Efficient Generative Large Language Model Serving: A Survey from Algorithms to Systems》论文中，将现有的 LLM 推理优化的方向分成两类：

- 算法创新（Algorithmic Innovation）：算法创新主要集中在改进和优化模型本身的推理过程，以提高效率和降低计算复杂度。
- 系统优化（System optimizations）：系统优化则侧重于在硬件和系统层面上进行改进，以提升整体推理效率。

![f46bb2e230b0b0e5b06e8ddc88b810e6.png](https://www.yidoo.xyz/images/f46bb2e230b0b0e5b06e8ddc88b810e6.png)

## 算法创新

这些创新旨在优化大型语言模型（LLM）的推理过程，以提高效率、减少计算复杂度，并在不显著降低性能的情况下减小模型的计算资源需求。

### 优化解码算法（Decoding Algorithm）

#### 非自回归解码（Non-autoregressive Decoding）

- **基本概念**：传统的自回归解码方法一次生成一个输出标记，依赖于前一个标记。这种方法计算复杂度高，速度较

慢。非自回归解码试图并行生成多个输出标记，从而提高解码速度。

- **实现方法**：通过假设输出标记之间的某种独立性来进行并行解码。常见的方法包括用半自回归解码来部分解决输出质量下降的问题，或者通过块并行解码来预测多个未来位置的标记。

#### 推测性解码（Speculative Decoding）

- **基本概念**：推测性解码通过提前生成多个可能的输出并并行验证这些输出，从而提高解码效率。
- **实现方法**：使用一个较小的草稿模型（参数更少）快速生成多个预测，然后通过原始模型进行验证。如果预测错误，可以回退到正确的生成路径。这种方法增加了并行性而不改变最终输出。

#### 提前退出（Early Exiting）

- **基本概念**：利用模型的多层架构，在浅层模型能够自信地做出预测时提前终止计算，从而减少不必要的计算。
- **实现方法**：在模型的浅层添加内部分类器，并在满足特定条件时提前输出结果。这种方法适用于计算量较小的简单推理请求。

#### 级联推理（Cascade Inference）

- **基本概念**：根据输入的复杂程度选择适当规模的模型，以减少不必要的计算开销。
- **实现方法**：采用一组不同规模的模型，并根据输入的复杂度自适应选择合适的模型进行推理。例如，对于简单的输入，可以使用较小的模型；对于复杂的输入，则使用完整的大模型。

![876bb60d76a7c86ee03d15d8afc891fc.png](https://www.yidoo.xyz/images/876bb60d76a7c86ee03d15d8afc891fc.png)

### 优化架构设计（Architecture Design）

#### 配置缩减（Configuration Downsizing）

- **基本概念**：通过减少模型参数或层数来降低计算成本。
- **实现方法**：使用浅层编码器或解码器、权重共享、缩小词汇表等方法来减小模型尺寸。尽管这种方法可能会影响性能，但通过适当调整可以在性能和效率之间找到平衡。

#### 注意力机制简化（Attention Simplification）

- **基本概念**：自注意力机制计算复杂度高（O(𝐿²)，其中 𝐿 是序列长度），简化注意力机制可以显著减少计算复杂度。
- **实现方法**：使用稀疏化、核化和分解等技术来简化注意力计算。例如，滑动窗口注意力、哈希注意力和稀疏注意力等方法，通过减少计算量来提高效率。

#### 激活共享（Activation Sharing）

- **基本概念**：在不同层之间共享中间激活值，以提高计算效率。
- **实现方法**：观察不同层的注意力矩阵分布相似性，重用这些注意力矩阵以减少计算成本。多查询注意力（MQA）和组查询注意力（GQA）等方法，通过共享键和值向量来减少内存带宽需求。

#### 条件计算（Conditional Computing）

- **基本概念**：稀疏激活的专家混合模型（MoE）通过根据输入选择性激活部分专家网络，减少计算和内存需求。
- **实现方法**：使用特定路由机制（如任务级路由）来选择激活不同的专家网络，只对相关的专家进行计算，从而提高效率。

#### 循环单元（Recurrent Unit）

- **基本概念**：循环神经网络（RNN）及其变体（如 LSTM 和 GRU）在处理序列数据时具有显著优势，尤其是在捕捉长距离依赖关系方面。然而，传统的 RNN 在处理长序列时可能会遇到梯度消失或爆炸的问题。尽管 Transformer 模型在很大程度上解决了这些问题，但一些研究仍然尝试使用循环单元来替代 Transformer 模块，以在推理过程中实现线性计算和内存复杂度。
- **实现方法**：RWKV 模型结合了 RNN 和 Transformer 的优点，利用线性递归单元（LRU）在推理过程中实现线性复杂度。RWKV 通过引入递归机制，使模型在每个时间步只需要线性计算，从而大幅减少计算量和内存占用。

### 模型压缩（Model Compression）

#### 知识蒸馏（Knowledge Distillation）

- **基本概念**：训练一个较小的学生模型，使其从大型教师模型中学习，从而在保持性能的同时减少计算需求。
- **实现方法**：通过教师模型的监督信息训练学生模型，使其在较少参数的情况下达到类似的性能。常见的知识蒸馏方法包括白盒蒸馏和黑盒蒸馏。

#### 网络剪枝（Network Pruning）

- **基本概念**：移除模型中不重要的参数以减少模型大小和计算需求。
- **实现方法**：采用结构化剪枝方法（如去除特定的注意力头和 MLP 参数）和非结构化剪枝方法（如随机去除参数）来压缩模型。近年来的研究表明，网络剪枝可以显著减少模型的计算量而不显著影响性能。

这些算法创新方法，通过优化模型结构和推理过程，可以显著提高大型语言模型的推理效率，使其更适用于实际应用中的各种场景。

## 系统优化（System Optimizations）

系统优化主要集中在硬件和系统层面，通过改进底层实现和资源管理，提高大型语言模型（LLM）推理的效率。以下是几种主要的系统优化方法：

### 低位量化（Low-bit Quantization）

- **基本概念**：使用较少的比特位（如 INT8 或 INT4）来表示模型权重和激活值，从而减少内存消耗并加速推理。
- **实现方法**：
    - 量化感知训练（QAT）：在训练过程中引入量化，通过模拟低精度运算来调整模型参数，使其在低精度下仍能保持较高性能。这种方法在训练阶段需要更多的计算资源，但可以在推理阶段显著提高效率。
    - 训练后量化（PTQ）：在模型训练完成后对其进行量化，将模型权重和激活值的精度降低到 INT8 或 INT4。PTQ 方法不需要重新训练模型，因此更适用于已经训练好的模型。通过自定义 CUDA 内核或编译器优化，实现低精度计算，显著提升推理效率。

### 并行计算（Parallel Computation）

- **基本概念**：并行计算通过在多个处理器或设备上分配计算任务，加速推理过程。
- **实现方法**：
    - **模型并行（Model Parallelism）**：将模型的不同部分分配到多个设备上并行计算，如张量模型并行和流水线模型并行。
    - **数据并行（Data Parallelism）**：将不同的数据样本分配到多个设备上并行处理。
    - **分布式推理（Decentralized Inference）**：利用多个分散的节点协作处理推理任务，适用于地理分布的硬件资源。

### 内存管理（Memory Management）

- **基本概念**：有效的内存管理对于减少推理过程中内存占用和提升效率至关重要。
- **实现方法**：
    - **动态 KV 缓存管理**：通过细粒度的内存管理机制减少 KV 缓存的内存使用，如 vLLM 中的分页注意力和 SpecInfer 中的树注意力。
    - **内存碎片管理**：在复杂的解码场景中，通过精细的内存管理机制减少内存碎片。

### 请求调度（Request Scheduling）

- **基本概念**：高效的请求调度可以最大化资源利用率，保证响应时间在延迟服务级别目标（SLO）内。
- **实现方法**：
    - **动态批处理（Dynamic Batching）**：通过批处理请求提高硬件利用率。
    - **迭代级调度（Iteration-level Scheduling）**：根据请求的长度和复杂度进行调度，如 Orca 中的先到先服务（FCFS）和 FastServe 中的预处理机制。

### 内核优化（Kernel Optimization）

- **基本概念**：内核级优化通过提升模型推理过程中关键操作的性能，提高整体推理效率。
- **实现方法**：
    - **内核融合（Kernel Fusion）**：将多个计算内核融合为一个内核，以减少内存访问和内核启动的开销。
    - **定制注意力机制（Tailored Attention）**：为注意力计算定制优化内核，如 cuDNN 的融合多头注意力内核和 FlashDecoding 的块级并行注意力计算。
    - **采样优化（Sampling Optimization）**：优化采样算法，提高生成质量和效率，如 LightSeq 中的层次化实现。
    - **变长序列处理（Variable Sequence Length Processing）**：

减少填充和优化批处理，提高对变长序列的处理效率，如 Packing technique 和 Ragged tensor。 - **自动编译（Automatic Compilation）**：使用自动化编译工具优化模型在不同硬件平台上的执行效率，如 TVM、MLIR、JAX、OpenAI Triton。

这些系统优化方法通过改进底层硬件利用和资源管理，显著提高了大型语言模型的推理效率，使其在实际应用中更加高效和可靠。

# LLM 推理性能指标

下面是 Anyscale 公司，在 llmperf 工具中采用的一些推理性能测试指标：

- **每分钟完成请求数**（RPS，Requests Per Second）：衡量模型在一定时间内能处理的请求数量，反映了并发处理能力。
- **首字输出时间**（TTFT，Time to First Token）：从接收到请求到输出第一个字符的时间，表示初始响应速度。
- **字符间延迟**（ITL，Inter-Token Latency）：连续生成字符之间的平均时间，影响生成文本的流畅性和速度。
- **端到端延迟**（End-to-End Latency）：从请求发出到完成整个响应的时间，总体响应速度的体现。
- **每次典型请求的成本**（Cost per Typical Request）：综合考虑性能指标的成本效率。

# 参考资料

- [Towards Efficient Generative Large Language Model Serving: A Survey from Algorithms to Systems](https://arxiv.org/abs/2312.15234)
- [LLM Inference Series: 2. The two-phase process behind LLMs’ responses | by Pierre Lienhart | Medium](https://medium.com/@plienhar/llm-inference-series-2-the-two-phase-process-behind-llms-responses-1ff1ff021cd5)
- [Reproducible Performance Metrics for LLM inference](https://www.anyscale.com/blog/reproducible-performance-metrics-for-llm-inference#quantitative-performance-metrics-for-llms)
