Skip to content

大模型(LLMs)推理加速篇

整理自:AiGC面试宝典 日期:2024年8月11日


1. 推理过程分哪些阶段?

推理会分成 PrefillDecoding 两个阶段。

📝通俗解释:可以把大模型推理比作一场接力赛。Prefill阶段就像起跑前的准备阶段,需要一次性处理用户的全部输入;而Decoding阶段则像接力跑,每次只生成一个字(token),然后把这个字放回输入中继续跑,直到比赛结束。

1.1 Prefill(输入理解与初始化)阶段

Prefill 阶段需要计算整个 prompt 的自注意力。具体流程如下:

  1. Tokenize(向量化):将用户输入的文本转换为向量,这一过程约占整个 Prefill 阶段 10% 的时间;
  2. Computing(计算):进行真正的 Prefill 计算,这一过程约占 80% 的时间;
  3. Sampling(采样):根据模型输出生成下一个词,约占 10% 的时间;
  4. Return(返回):将结果返回给用户,约占 2%~5% 的时间。

📝通俗解释:Tokenize就像把文字翻译成机器能读懂的语言;Computing是真正的思考过程;Sampling是从可能的答案中选一个最合适的;Return是把结果展示给用户。

1.2 Decoding(递归推理与解码输出)阶段

每生成一个 token 就要计算一次。模型理解了初始序列之后便会开始逐词预测后续文本。

  • Computing:约占 80% 的时间
  • Sampling:约占 10% 的时间
  • Detokenize(解码):将生成的向量转换回文本,约占 5% 的时间
  • Return:将结果返回给用户

📝通俗解释:Decoding阶段就像打字时输入法的联想功能——你打出第一个字,模型猜测下一个最可能是什么字,然后继续猜测,直到完成整个句子。这个阶段不需要Tokenize,因为输入已经是向量形式了。


2. 推理性能的评价指标

2.1 Throughput(吞吐量)

当系统负载达到最大时,单位时间内能够执行多少个 decoding,即生成多少个字符。

📝通俗解释:吞吐量就像餐厅的翻台率——在高峰期一小时能接待多少桌客人。输入和输出越长,翻台率(吞吐量)自然越低。

2.2 First Token Latency(首字延迟)

用户完成 Prefill 阶段需要多长时间,也就是系统生成第一个字符所需的响应时间。

📝通俗解释:这就像你问服务员一个问题,他思考多久才给出第一个字。理想情况下,希望这个时间小于2-3秒,否则用户会觉得响应太慢。

2.3 Latency(延迟)

每一个 decoding 阶段需要的时长,反映大模型每生成一个字符的间隔时间。

📝通俗解释:这就像打字时每个字出现的间隔时间。希望延迟小于50毫秒,这样一秒钟能生成20个字符,体验比较流畅。

2.4 QPS(每秒请求数)

一秒钟能够处理多少个用户的请求。

📝通俗解释:QPS就像餐厅一秒钟能接多少单。有的顾客点完就走(生成内容短),有的要等很久(生成内容长),所以即使吞吐量很高,QPS也可能提不上去。


3. 当前优化模型最主要技术手段有哪些?

3.1 KVCache

在 decoding 阶段需要计算当前 token 和之前所有已生成 token 的 attention,前面的 token 的 KV 值在每轮 decoding 中都被重复计算,因此可以将它们存下来,每轮只需要计算当前 token 的 KV 值即可。

📝通俗解释:就像做数学题时把中间结果记在草稿纸上,不用每次都重新算。KVCache就是模型的"草稿本",把之前算过的注意力结果存起来,下次直接用。

3.2 分布式推理

主要有三种主流方式:

  • 数据并行(DataParallel):每个 GPU 都包含完整模型,各负责一部分数据的推理
  • 流水线并行(PipelineParallel):将模型纵向拆分,每 GPU 只负责部分层
  • 张量并行(TensorParallel):将模型横向拆分,每层计算由多个 GPU 合作完成

📝通俗解释:数据并行就像把同一道题复印给多个人同时做;流水线并行就像工厂流水线,每个人只做一道工序;张量并行就像把一道复杂数学题拆成多部分同时计算。

3.3 流水线处理

让 Tokenize、Fast Sample 和 Detokenize 这些过程与模型计算并行执行,尽可能让 GPU 利用率占满。

📝通俗解释:就像厨房里洗菜、切菜、炒菜可以同时进行,不用等一道菜完全做好才开始下一道。

3.4 动态批处理

在第二个请求进入时,将其 Prefill 阶段与第一个请求的 Decoding 阶段混合处理,形成 Merge Step。

📝通俗解释:就像银行柜台服务——当第一个客户在等待办理业务时,可以让第二个客户先填表(Prefill),两件事同时进行,效率更高。

3.5 低比特量化

使用精度更低的单位(如 INT8、INT4、FP8)来表示模型权重或中间变量,以节省空间和加速推理。

  • 训练时量化(QAT):需要重新训练,效果好但成本高
  • 训练后量化(PTQ):直接量化预训练好的模型,成本低

📝通俗解释:就像把高清照片压缩成低分辨率——占用空间小了,但细节可能损失一点。INT4适合小批量(batch≤4),INT8/FP8适合大批量服务场景。

3.6 System Prompt 缓存

对于相同 System Prompt 的请求,将其 Key 和 Value 缓存在 GPU 显存中,后续请求直接加载而无需重复计算。

📝通俗解释:就像客服背熟了的常见问题答案,不用每次客户问都重新思考,直接调取已有的答案就行。

3.7 预测生成长度

为每个请求预测所需的生成长度,提前分配连续显存空间。

📝通俗解释:就像租房时预估自己要住多久,提前租好相应大小的房子,不用住一段时间再临时找更大的。

3.8 Flash Attention

利用 GPU 分级缓存(SRAM 和 HBM),将 Attention 计算更多地放到快速的 SRAM 上,减少对慢速 HBM 的访存。

📝通俗解释:就像把常用的工具放在工作台(SRAM)上,不常用的放在仓库(HBM)里。Flash Attention把需要频繁访问的数据放在高速缓存里,速度自然快。

3.9 Paged Attention

允许生成过程中动态分配显存,灵感来自操作系统的虚拟内存和分页机制。

📝通俗解释:就像操作系统的内存管理——不需要一开始就分配连续的一大块内存,可以像拼图一样用多个小块拼出完整的内存空间,更灵活也更省内存。

3.10 精简 Attention 的 MHA/GQA/MQA 技术

  • MHA(Multi-Head Attention):传统多头注意力
  • GQA(Grouped-Query Attention):查询头分组,每组共享 Key 和 Value
  • MQA(Multi-Query Attention):所有头共享同一份 Key 和 Value

📝通俗解释:就像开会时,MHA是每个人都有自己的记录本;GQA是分组共用记录本;MQA是所有人共用一份记录本——当然记忆量减少了,但信息也可能有损失。

3.11 选择合适的硬件

根据不同负载选择合适的 GPU(如 H20、L20、A10、H800 等)或国产 AI 芯片(昇腾 910、邃思 2.0、昆仑芯 XPU 2 代等)。

📝通俗解释:就像根据不同的运输需求选择不同的交通工具——短途用小车,长途用大车,特殊货物用专业车辆。


4. 推理加速框架有哪些?都有什么特点?

4.1 FasterTransformer

NVIDIA 推出的推理加速框架,不修改模型架构而在计算层面优化:

  • 融合除 GEMM 以外的操作
  • 支持 FP16、INT8、FP8
  • 移除无用的 padding 减少计算开销

📝通俗解释:就像对汽车发动机进行调校——不改变车身结构,但通过优化点火时机、进气量等提升性能。

4.2 TurboTransformers

腾讯推出的框架,适用于 CPU 和 GPU:

  • 融合操作减少计算量
  • Smart Batching 减少 zero-padding 开销
  • 对 LayerNorm 和 Softmax 进行批处理
  • 引入模型感知分配器优化内存

📝通俗解释:就像智能排班系统——能根据每个"员工"的工作量自动安排任务,避免有人忙死有人闲死。

4.3 vLLM

基于 Paged Attention 的推理框架,详情见第5节。

4.4 Text Generation Inference

HuggingFace 推出的框架,详情见第6节。


5. vLLM 篇

5.1 vLLM 的功能有哪些?

  • Continuous Batching:迭代级别的调度机制,每次迭代 batch 大小动态变化
  • PagedAttention:受操作系统虚拟内存启发的注意力算法

📝通俗解释:Continuous Batching就像餐厅动态调整排队人数——根据忙闲程度灵活安排;PagedAttention让内存管理像拼图一样灵活。

5.2 vLLM 的优点有哪些?

  1. 推理速度最快
  2. 高吞吐量服务,支持多种解码算法(parallel sampling、beam search 等)
  3. 与 OpenAI API 兼容

5.3 vLLM 的缺点有哪些?

  1. 添加自定义模型较复杂
  2. 缺乏对适配器(LoRA、QLoRA 等)的支持
  3. 缺少权重量化功能

5.4 vLLM 离线批量推理

python
# pip install vllm
from vllm import LLM, SamplingParams

prompts = [
    "Funniest joke ever:",
    "The capital of France is",
    "The future of AI is",
]

sampling_params = SamplingParams(temperature=0.95, top_p=0.95, max_tokens=200)
llm = LLM(model="huggyllama/llama-13b")
outputs = llm.generate(prompts, sampling_params)

for output in outputs:
    prompt = output.prompt
    generated_text = output.outputs[0].text
    print(f"Prompt: {prompt!r}, Generated text: {generated_text!r}")

5.5 vLLM API Server

bash
# 启动服务
python -m vllm.entrypoints.api_server --env MODEL_NAME=huggyllama/llama-13b

# 请求示例
curl http://localhost:8000/generate \
  -d '{
    "prompt": "Funniest joke ever:",
    "n": 1,
    "temperature": 0.95,
    "max_tokens": 200
  }'

6. Text Generation Inference 篇

6.1 介绍一下 Text Generation Inference?

Text Generation Inference 是用于文本生成的 Rust、Python 和 gRPC 服务器,由 HuggingFace 开发。

6.2 Text Generation Inference 的功能有哪些?

  • 内置服务评估,监控服务器负载
  • 使用 Flash Attention 和 Paged Attention 优化推理

6.3 Text Generation Inference 的优点有哪些?

  • Docker 容器化部署,环境配置简单
  • 支持 HuggingFace 模型
  • 提供丰富的推理控制选项(精度调整、量化、张量并行、重复惩罚等)

6.4 Text Generation Inference 的缺点有哪些?

  • 缺乏对适配器的官方支持
  • 从源码编译需要 Rust 知识
  • 文档不完整

6.5 使用 Docker 运行 Web Server

bash
mkdir data
docker run --gpus all --shm-size 1g -p 8080:80 \
-v data:/data ghcr.io/huggingface/text-generation-inference:0.9 \
--model-id huggyllama/llama-13b \
--num-shard 1

整理完成

基于 MIT 许可发布