Skip to content

第4课时:模型部署与推理加速

当你在手机上用通义千问生成旅行攻略、在浏览器里和 GPT 讨论论文时,你可能没意识到:
这些看似“轻盈流畅”的体验,其实背后是一场精密的“系统工程”—— 大模型不是直接跑起来的,而是经过层层优化后“飞”起来的

这一课,我们将探索模型如何通过部署与推理加速,真正走出实验室、走进现实世界

本课将聚焦三大核心方向:

  1. 推理引擎架构:vLLM 与 PagedAttention 的底层机制;
  2. 吞吐优化技术:Continuous Batching、Speculative Decoding(投机采样)、KV Cache 量化;
  3. 部署量化策略:AWQ、GPTQ、SmoothQuant 的原理对比与精度分析。

通俗语言 + 数学公式 + 工业界真实部署案例,带你从“会跑”走向“跑得又快又稳”。


1. 为什么需要推理加速?——从“能跑”到“跑得快、跑得起”

1.1 大模型的“三高”困境

一个典型的 70 亿参数(7B)大语言模型(如 LLaMA-2-7B、Qwen-7B)在默认 FP32 精度下:

  • 高内存占用:仅模型权重就需约 28 GB(7B × 4 字节);
  • 高计算量:生成 1 个 token 需做数十亿次浮点运算(FLOPs);
  • 高延迟:在普通 A10 GPU 上,首次响应可能需 2–5 秒,无法满足交互式需求。

这导致一个问题:模型虽强,但“用不起、等不及”

💡 举个生活化的例子:
预训练相当于让一个博士读遍天下书;
而推理加速,则是帮他配一副眼镜、买一辆电动车、再给他装个导航——
不是让他变聪明,而是让他更高效地服务大众

1.2 部署目标的三角权衡

在工业界,推理部署的目标通常围绕三个维度权衡:

维度 描述 优先级场景
延迟(Latency) 单请求响应时间 聊天机器人、实时翻译
吞吐量(Throughput) 单位时间处理请求数 批量摘要、API 服务
成本(Cost) 单 token 的计算/电力/硬件开销 大规模在线服务、边缘设备

优化的本质,是在精度损失可接受的前提下,在这三者之间找到最佳平衡点。


2. 推理加速的核心思想:压缩 + 并行 + 融合

推理加速不是单一技术,而是一套“组合拳”。其核心可归纳为三大策略:

  1. 压缩(Compression):减少模型规模与计算量;
  2. 并行(Parallelism):提升硬件利用率;
  3. 融合(Fusion):减少内存访问与调度开销。

下面我们逐层展开,从最基础、最有效的量化开始。


3. 量化(Quantization)——精度换效率的“性价比之王”

3.1 什么是量化?

量化是将模型中高精度的浮点数(如 FP32、FP16)转换为低精度的整数(如 INT8、INT4)的技术。 alt text

🧠 关键洞察
大模型在推理时,不需要训练时那么高的数值精度
大量研究表明,权重和激活值的分布高度集中,低比特表示足以保留关键信息。

3.2 量化数学原理

假设原始浮点值 \(x \in [x_{\min}, x_{\max}]\),我们希望将其映射到 \(b\)-bit 整数(如 \(b=8\),范围 \([0, 255]\))。

线性量化公式: $$ x_q = \text{round}\left( \frac{x - x_{\min}}{x_{\max} - x_{\min}} \cdot (2^b - 1) \right) $$

  • \(x\):原始浮点数值;
  • \(x_{\min}, x_{\max}\):该张量(或通道)中所有元素的最小值和最大值;
  • \(b\):目标整数位宽(如 4 表示 INT4,8 表示 INT8);
  • \(2^b - 1\)\(b\)-bit 无符号整数的最大值(如 INT8 为 255);
  • \(\text{round}(\cdot)\):四舍五入取整;
  • \(x_q\):量化后的整数值。

反量化(用于计算): $$ \tilde{x} = x_{\min} + \frac{x_q}{2^b - 1} \cdot (x_{\max} - x_{\min}) $$

其中 \(\tilde{x}\) 是近似值,用于后续矩阵乘法等操作。

🔍 注意:实际系统中常使用对称量化(zero-point=0)或非对称量化(含 zero-point),以更好拟合分布。

3.3 量化类型与演进

类型 说明 代表方法
PTQ(Post-Training Quantization) 训练后直接量化,无需再训练 GGUF、bitsandbytes
QAT(Quantization-Aware Training) 训练时模拟量化,精度更高 TensorFlow QAT
AWQ(Activation-aware Weight Quantization) 仅量化“不重要”权重,保留关键通道 Liu et al., 2023
GPTQ(Group-wise Quantization) 按通道分组量化,减少误差传播 Frantar et al., 2022

业界趋势
对于 7B–70B 级别模型,4-bit AWQ/GPTQ 已成为主流,在几乎无损精度下实现 3–4 倍显存节省


4. 推理引擎架构详解:vLLM 与 PagedAttention

4.1 KV Cache 的内存瓶颈

alt text 在自回归生成中,KV Cache 随上下文长度线性增长。以 LLaMA-2-7B 为例:

  • 每 token KV ≈ 16 KB(32 heads × 128 dim × 2 × FP16);
  • 32k 上下文 → 512 MB / 请求
  • 并发 16 请求 → >8 GB,且需连续内存分配

传统实现使用 torch.cat 动态拼接,导致严重内存碎片和拷贝开销。

4.2 PagedAttention:虚拟内存式 KV 管理

vLLM 借鉴操作系统分页机制,将 KV Cache 划分为固定大小 Block(默认 16 tokens/block)。

关键机制:

  • 每个请求维护一个 Page Table:逻辑块 → 物理块映射;
  • 全局 Block Pool:预分配显存池,支持动态分配/回收;
  • 注意力计算通过索引表拼接逻辑连续、物理非连续的块。

注意力计算不变性:

\[ \text{Attention}(Q, K, V) = \text{Softmax}\left(\frac{QK^\top}{\sqrt{d}}\right)V \]
  • \(Q \in \mathbb{R}^{1 \times d}\):当前 token 的 Query 向量;
  • \(K \in \mathbb{R}^{T \times d}\):历史所有 token 的 Key 矩阵;
  • \(V \in \mathbb{R}^{T \times d}\):历史所有 token 的 Value 矩阵;
  • \(d\):每个注意力头的维度(如 128);
  • \(T\):当前上下文长度(即已生成 token 数 + 输入长度)。

PagedAttention 不修改公式,仅优化内存布局,实现零拷贝、高利用率


5. 吞吐优化三大核心技术

5.1 Continuous Batching(连续批处理)

问题

传统批处理要求所有请求同时开始、同时结束,但真实请求:

  • 到达时间随机;
  • 生成长度差异大(10 vs 1000 tokens)。

→ GPU 大量时间空闲。

解决方案

  • 动态调度器:实时监控请求状态;
  • 仅对 active 请求批处理:batch size 动态变化;
  • GPU 始终满载,吞吐提升 10–20 倍。

实测(LLaMA-2-7B):HuggingFace 7 req/s → vLLM 170 req/s

5.2 Speculative Decoding(投机采样)

核心思想

“用小模型猜,大模型验”——用廉价计算替代昂贵计算。

算法流程

  1. 草稿模型(如 100M)生成 \(k\) 个候选 token;
  2. 目标模型(如 LLaMA-7B)一次性验证所有候选;
  3. Token Acceptance Rule
\[ m = \max \left\{ i : \frac{p_t(x_{t+i} \mid x_{<t+i})}{p_d(x_{t+i} \mid x_{<t+i})} \geq u_i \right\}, \quad u_i \sim \mathcal{U}(0,1) \]
  • \(t\):当前生成步;
  • \(x_{<t+i}\):截至第 \(t+i-1\) 个 token 的上下文;
  • \(x_{t+i}\):第 \(t+i\) 个候选 token;
  • \(p_t(\cdot \mid \cdot)\):目标大模型(如 LLaMA-3)的条件概率;
  • \(p_d(\cdot \mid \cdot)\):草稿小模型(如 llama-160m)的条件概率;
  • \(u_i\):从均匀分布 \(\mathcal{U}(0,1)\) 中采样的随机数;
  • \(m\):最大被接受的索引(从 0 开始);
  • 最终接受前 \(m+1\) 个 token。

  • 接受前 \(m+1\) 个 token。

🌟 效果

  • 吞吐提升 2–3 倍
  • xAI(Grok)Meta 用于线上服务;
  • Medusa:在主模型加多预测头,无需额外小模型。

5.3 KV Cache Quantization

动机

KV Cache 占比随上下文增长而升高(32k 时 >50%)。

方法

alt text

这张图片对比了正常神经网络推理流程(图 a)与量化神经网络推理流程(图 b),直观展示了“量化”如何在保持精度的前提下大幅降低计算和存储开销。

  • INT8 对称量化: $$ K_q = \text{round}\left( \frac{K}{s_K} \right), \quad s_K = \frac{\max(|K|)}{127} $$

  • \(K \in \mathbb{R}^{T \times d}\):原始 FP16 Key 矩阵;

  • \(|K|\):对 \(K\) 中每个元素取绝对值;
  • \(\max(|K|)\)\(K\) 中绝对值的最大值;
  • \(s_K\):缩放因子(scale),用于归一化;
  • \(K_q\):量化后的 INT8 矩阵;
  • 127:INT8 有符号整数的最大正值(范围 [-128, 127])。

  • FP8:H100 硬件加速,动态范围更大。

精度影响:MMLU 下降 <0.2%(几乎无损)
显存节省:KV Cache 减半 → 吞吐提升 1.3–1.5 倍


6. 高级量化策略深度对比

6.1 问题根源:权重分布异质性

LLaMA-2-7B 的 FFN 层中:

  • 95% 通道\(|w| < 1.0\)
  • 5% 通道\(|w| > 5.0\)(“异常值”)

→ 均匀量化会因异常值拉低整体精度。

6.2 AWQ(Activation-aware Weight Quantization)

下图是AWQ的核心示意图,它通过分析模型在少量校准数据上的激活分布,识别出对输出影响最大的“重要通道”(salient channels),并仅对不敏感的权重进行量化,从而在保持高精度的同时实现高效压缩。

alt text

  • 核心:通过少量校准数据(~128 样本)分析激活分布,识别重要通道;
  • 操作:引入通道缩放因子 \(\alpha\),仅量化不敏感通道: $$ W_{\text{quant}} = \text{Quantize}(W \odot \alpha) \oslash \alpha $$

    • \(W \in \mathbb{R}^{d_{\text{in}} \times d_{\text{out}}}\):原始权重矩阵;
    • \(\alpha \in \mathbb{R}^{d_{\text{out}}}\):每输出通道一个的缩放因子(向量);
    • \(\odot\):按列(输出通道)的逐元素乘法(即 \(W_{:,j} \cdot \alpha_j\));
    • \(\oslash\):按列的逐元素除法;
    • \(\text{Quantize}(\cdot)\):对缩放后的权重进行 INT4 量化;
    • 该变换是等效的,不改变 \(XW\) 的输出(若量化无损)。
  • 精度:INT4 下 MMLU 损失 <1%

  • 支持:vLLM、AutoGPTQ、TGI

6.3 GPTQ(Group-wise Post-Training Quantization)

  • 核心:按权重列分组(如 128 元素/组),组内独立量化;
  • 优化:贪心逐层 + Hessian 信息校正误差;
  • 优势:无需激活数据,仅需权重;
  • 工具AutoGPTQ

算法原理

GPTQ 的核心思想是将量化视为一个逐列最优回归问题。对于每一列权重 \(W_{:j}\),它寻找最优的量化值 \(Q_{:j}\),使得量化前后该列对输出的影响最小:

\[ \min_{Q_{:j}} \| W_{:j} - Q_{:j} \|_{H}^2 = (W_{:j} - Q_{:j})^\top H (W_{:j} - Q_{:j}) \]

其中 \(H\) 是 Hessian 矩阵的近似(通过对校准数据的输入激活计算 \(H = XX^\top\)),用于衡量每个权重元素对最终输出的影响程度。

算法流程

  1. 收集校准数据:用少量样本(通常 128 条)前向传播,累积各层的 Hessian 近似 \(H\)
  2. 逐列贪心量化:对每一列权重,选择使 Hessian 加权误差最小的量化值;
  3. 误差传播校正:量化完一列后,将量化误差传播到剩余未量化列: $$ W_{:, \text{rest}} \leftarrow W_{:, \text{rest}} - \frac{W_{:j} - Q_{:j}}{H_{jj}^{-1}} H_{j, \text{rest}}^{-1} $$
  4. 分组处理:为减少误差累积,将权重按 128 列分组,组内共享量化参数。

与 AWQ 的对比

维度 GPTQ AWQ
是否需要校准数据 是(计算 Hessian) 是(计算激活分布)
量化策略 逐列贪心 + 误差校正 通道缩放 + 均匀量化
推理开销 低(量化后纯 INT4 推理) 低(量化后纯 INT4 推理)
量化速度 较慢(需逐列优化) 较快(通道级缩放)
精度表现 略优(误差校正更精细) 略逊但差距极小

6.4 SmoothQuant

  • 核心:通过缩放矩阵 \(S\) 平滑激活与权重分布: $$ XW = (XS)(S^{-1}W) $$

    • \(X \in \mathbb{R}^{B \times d_{\text{in}}}\):输入激活矩阵;
    • \(W \in \mathbb{R}^{d_{\text{in}} \times d_{\text{out}}}\):权重矩阵;
    • \(S \in \mathbb{R}^{d_{\text{in}} \times d_{\text{in}}}\):对角缩放矩阵,\(S_{ii} = s_i > 0\)
    • \(XS\):缩放后的激活,动态范围更小;
    • \(S^{-1}W\):缩放后的权重,异常值被抑制;
    • 该变换是等效的,输出不变。
  • 优势:支持 INT8 全量化(权重+激活);

  • 代表应用:NVIDIA TensorRT-LLM

为什么需要 SmoothQuant?

大语言模型(如 LLaMA、OPT)的激活分布中存在显著的异常值(Outliers)——某些通道的激活值远超其他通道(可达 10-100 倍)。这些异常值使得激活难以直接量化为 INT8(量化步长过大,导致非异常通道精度严重损失)。

SmoothQuant 的洞察是:激活的异常值与权重的异常值在通道维度上高度相关。通过将这些"难度"从激活侧迁移到权重侧,可以让两侧都变得"易于量化"。

缩放因子的计算

缩放因子 \(s_i\) 按通道计算,核心公式为:

\[ s_i = \left( \frac{\max(|X_i|)}{\max(|W_i|)} \right)^\alpha \]

其中:

  • \(\max(|X_i|)\):第 \(i\) 通道激活绝对值的最大值(在校准集上统计);
  • \(\max(|W_i|)\):第 \(i\) 通道权重绝对值的最大值;
  • \(\alpha \in [0, 1]\)平滑强度超参数,控制难度迁移的比例:
  • \(\alpha = 0\):不迁移,激活承担全部难度;
  • \(\alpha = 1\):完全迁移,权重承担全部难度;
  • \(\alpha = 0.5\):均分难度(常用默认值)。

算法流程

  1. 校准阶段

    • 用少量样本(通常 128 条)前向传播,收集各层激活的逐通道最大值 \(\max(|X_i|)\)
    • 读取各层权重的逐通道最大值 \(\max(|W_i|)\)
    • 按公式计算每层的缩放因子 \(s_i\)
  2. 平滑变换

    • 激活侧:\(X' = X \cdot S\),动态范围缩小,异常值被压缩;
    • 权重侧:\(W' = S^{-1} \cdot W\),权重吸收异常值,分布更平滑。
  3. INT8 量化

    • 对平滑后的 \(X'\)\(W'\) 分别进行 INT8 线性量化;
    • 由于两侧分布都已平滑,量化误差显著降低。
  4. INT8 GEMM 推理

    • 使用 INT8 矩阵乘法计算 \(X'_q W'_q\)
    • 反量化后得到近似输出。

与 AWQ/GPTQ 的本质区别

维度 SmoothQuant AWQ / GPTQ
量化对象 权重 + 激活(全量化) 仅权重
推理精度 INT8 INT4
适用场景 严格低延迟、需全 INT8 流水线 显存受限、追求极致压缩
校准依赖 需要(统计激活分布) 需要(Hessian / 激活敏感度)
硬件友好度 极高(纯 INT8 GEMM) 高(需专用 INT4 kernel)

在 TensorRT-LLM 中的应用

NVIDIA TensorRT-LLM 将 SmoothQuant 作为 INT8 推理的标准方案: - 自动完成校准、平滑变换和 INT8 kernel 生成; - 结合 FP8 支持(H100),进一步将动态范围从 INT8 的 256 级扩展到 FP8 的指数+尾数表示; - 在 LLaMA-2-70B 上,SmoothQuant INT8 相比 FP16 显存减半、吞吐提升 1.5-2 倍,MMLU 精度损失 <0.5%

6.5 策略选择建议

场景 推荐 理由
本地部署(Mac/PC) GGUF (Q4_K_M) 无需 GPU,开箱即用
高吞吐 API 服务 AWQ + vLLM 精度高、速度快、生态成熟
超大规模(70B+) GPTQ + ExLlama 内存极致优化
NVIDIA GPU 生产 SmoothQuant + TensorRT-LLM 硬件深度优化,支持 FP8

⚠️ 注意:AWQ/GPTQ 模型不兼容,需匹配对应推理引擎。


7. 主流推理引擎对比与选型

引擎 核心技术 量化支持 硬件 适用场景
vLLM PagedAttention、Continuous Batching AWQ、GPTQ、INT8 KV NVIDIA GPU 高吞吐 API 服务
TGI FlashAttention、Tensor Parallelism AWQ、GPTQ、bitsandbytes NVIDIA/AMD/TPU HuggingFace 生态
llama.cpp GGUF、CPU+GPU hybrid GGUF (1.5–8 bit) CPU/Apple Silicon/NVIDIA/AMD 本地/边缘部署
TensorRT-LLM Kernel Fusion、FP8 SmoothQuant、AWQ NVIDIA GPU 超大规模生产

📌 最新动态

  • Hugging Face Inference Endpoints 已原生支持 GGUF;
  • llama.cpp 新增 gpt-oss MXFP4多模态OpenAI API 兼容服务器
  • vLLM 支持 Speculative DecodingFP8 KV Cache

8. 实战演练:联合优化部署 Qwen

8.1 使用 vLLM 部署

vllm serve Qwen/Qwen3-8B --tensor-parallel-size 4
上述命令将在 4 块 GPU 上使用张量并行。您应根据需求调整 GPU 的数量。 默认情况下,如果模型未指向有效的本地目录,它将从 Hugging Face Hub 下载模型文件。要从 ModelScope 下载模型,请在运行上述命令之前设置以下内容:
export VLLM_USE_MODELSCOPE=true
同时也支持使用 Python 库中的 vLLM 进行部署
from transformers import AutoTokenizer
from vllm import LLM, SamplingParams

# Initialize the tokenizer
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen3-8B")

# Configurae the sampling parameters (for thinking mode)
sampling_params = SamplingParams(temperature=0.6, top_p=0.95, top_k=20, max_tokens=32768)

# Initialize the vLLM engine
llm = LLM(model="Qwen/Qwen3-8B")

# Prepare the input to the model
prompt = "Give me a short introduction to large language models."
messages = [
    {"role": "user", "content": prompt}
]
text = tokenizer.apply_chat_template(
    messages,
    tokenize=False,
    add_generation_prompt=True,
    enable_thinking=True,  # Set to False to strictly disable thinking
)

# Generate outputs
outputs = llm.generate([text], sampling_params)

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

8.2 使用LazyLLM来部署服务

LazyLLM 原生支持了 LightLLM、LMDeploy 和 vLLM 三种大模型推理加速框架和 Infinity 嵌入模型加速框架,用户在使用时仅需通过 TrainableModule.deploy_method 指定对应的框架即可。

from lazyllm import TrainableModule, deploy

llm = TrainableModule('model_name').deploy_method(deploy.vllm)
print(llm("hello, who are you?"))
我们以 Qwen2-72B-Instruct 和它的 AWQ 量化版本为例,对比一下二者的大小及运行速度。运行BF16或FP16 的 Qwen2-72B-Instruct 模型运行需要至少144GB显存(例如2xA100-80G或5xV100-32G);运行 Int4 模型至少需要 48GB 显存(例如1xA100-80G或2xV100-32G),是原来的33%(数据来源于 Qwen 官方[魔塔社区])。

image.png

下面我们简单对比一下二者的运行速度(更严谨的情况下可以对比多次执行的差异,完整代码见GitHub链接):

import time
from lazyllm import TrainableModule, deploy, launchers

start_time = time.time()
llm = TrainableModule('Qwen2-72B-Instruct').deploy_method(
        deploy.Vllm).start()

end_time = time.time()
print("原始模型加载耗时:", end_time-start_time)

start_time = time.time()
llm_awq = TrainableModule('Qwen2-72B-Instruct-AWQ').deploy_method(deploy.Vllm).start()
end_time = time.time()
print("AWQ量化模型加载耗时:", end_time-start_time)

query = "生成一份1000字的人工智能发展相关报告"

start_time = time.time()
llm(query)
end_time = time.time()
print("原始模型耗时:", end_time-start_time)

start_time = time.time()
llm_awq(query)
end_time = time.time()
print("AWQ量化模型耗时:", end_time-start_time)
同样在 4 张 A800 卡加载和执行的速度如下所示:

原始模型加载耗时: 129.6051540374756

原始模型耗时: 13.104065895080566

AWQ量化模型加载耗时: 86.4980857372284

AWQ量化模型耗时: 8.81701111793518

LazyLLM 输出的日志信息中的 token/s 信息分别为:

INFO 03-12 19:52:50 metrics.py:341] Avg prompt throughput: 6.6 tokens/s, Avg generation throughput: 30.8 tokens/s

INFO 03-12 20:00:03 metrics.py:341] Avg prompt throughput: 6.6 tokens/s, Avg generation throughput: 41.2 tokens/s

AWQ 模型在单卡上的加载和执行耗时为:137 秒和 23 秒,也就是说,当有 4 张卡的时候,量化模型可以多处理 1.3-1.4 倍的请求。而当用户无法满足执行原模型的资源时,可以通过量化模型获得与原模型效果差异不大的生成效果(官方数据称量化模型在MMLU,CEval,IEval上的评测平均值只差0.9个点)。


9. 性能评估与调优

9.1 关键指标

指标 说明
Latency (ms/token) 单 token 生成时间
Throughput (tokens/s) 单位时间生成 token 数
Memory Usage (GB) 显存或内存占用
Accuracy Drop (%) 相比 FP16 的 MMLU/ARC 下降

9.2 调优建议

  • 延迟高 → 启用 Speculative Decoding、FlashAttention;
  • 显存爆 → 启用 PagedAttention、KV Cache 量化;
  • 精度崩 → 从 INT4 改为 INT8,或使用 AWQ/GPTQ;
  • 吞吐低 → 启用 Continuous Batching、增大 max_num_seqs。

10. 总结:推理加速的三层加速塔

层级 技术 原理 典型收益
内存层 AWQ/GPTQ、KV Cache 量化 减少 HBM 访问 显存 ↓50–75%,吞吐 ↑1.5x
调度层 PagedAttention、Continuous Batching 提升 GPU 利用率 吞吐 ↑5–20x
预测层 Speculative Decoding、Medusa 用小模型预跑 延迟 ↓2–3x