机器学习数学基础专题【左扬精讲】—— 大模型推理与部署:从 PyTorch 到 ONNX / TensorRT / vLLM

机器学习数学基础专题【左扬精讲】—— 大模型推理与部署:从 PyTorch 到 ONNX / TensorRT / vLLM

训练只是大模型落地的第一步。

训练好的模型要真正服务于用户,必须经过推理优化与部署:用 ONNX 跨平台导出,用 TensorRT 做 GPU 极致加速,用 vLLM 处理高吞吐在线服务。

本文从推理基础出发,讲解大模型推理的核心挑战(KV Cache、量化、批处理)、主流部署框架的设计思路,以及如何为不同场景选择最合适的技术栈。

本文所有代码片段均为通用 PyTorch 2.x / ONNX / TensorRT / vLLM 写法,可在对应版本环境中运行验证

本文涉及的核心框架:
  torch.onnx            ← PyTorch 模型导出 ONNX
  onnxruntime          ← ONNX 模型推理引擎
  tensorrt / torch_tensorrt ← NVIDIA GPU 极致推理加速
  vllm                 ← 高吞吐 LLM 在线服务框架
  bitsandbytes         ← 模型量化(INT8 / INT4)
  torch.compile        ← PyTorch 2.0 原生图优化

推理优化 ONNX TensorRT vLLM 量化 KV Cache PagedAttention Continuous Batching 模型导出 部署 torch.compile

学习重点提示

★ 必须掌握

  • 必须掌握:推理与训练的核心区别 — 推理不需要梯度,专注低延迟和高吞吐
  • 必须掌握:KV Cache 的作用 — 避免每生成一个 token 都重新计算历史 attention
  • 必须掌握:ONNX 导出的基本流程 — torch.onnx.export + onnxruntime 验证
  • 必须掌握:vLLM 的 PagedAttention 解决了 LLM 推理的核心瓶颈

★ 建议掌握

  • 建议掌握:INT8 / INT4 量化的精度-性能权衡
  • 建议掌握:torch.compile 的图捕获与算子融合
  • 建议掌握:Continuous Batching 提升 GPU 利用率

本文目录

  1. 一、推理与训练的本质区别 — What & Why
  2. 二、KV Cache:自回归推理的核心优化
  3. 三、ONNX:跨框架模型导出
  4. 四、TensorRT:NVIDIA GPU 极致优化
  5. 五、torch.compile:PyTorch 原生图优化
  6. 六、量化:INT8 / INT4 的精度-性能权衡
  7. 七、vLLM 与 PagedAttention:高吞吐 LLM 服务
  8. 八、部署框架选型指南
  9. 九、常见问题 FAQ(20 组)
  10. 十、Roadmap 后续预告

一、推理与训练的本质区别 — What & Why

What — 推理和训练的核心区别是什么?

训练需要前向传播 + 反向传播 + 参数更新,追求最小化损失;推理只需要前向传播,追求低延迟、高吞吐、低显存。两者对硬件、精度、优化方向的需求完全不同。

Why — 为什么不能直接用训练代码做推理?

问题一:训练保留计算图是为了反向传播

训练时所有中间变量都保留(用于 backward),推理不需要这些,可以大幅节省显存。

问题二:训练用 fp32 保证精度,推理可以用更低精度

推理对数值误差的容忍度更高,可以用 INT8、INT4 量化加速。

问题三:训练是批处理的,推理是逐请求的

训练每个 batch 一次处理多个样本,推理每个请求独立处理,延迟敏感。

没有推理优化会发生什么?

  • 显存占用高,单卡只能跑几个并发请求。
  • 延迟高,用户等待时间过长。
  • GPU 利用率低,单次请求用不满算力。
How — 推理优化的三大方向
# 方向 1: 关闭梯度
  with torch.no_grad():
      outputs = model(inputs)
  
  # 方向 2: 切换到 eval 模式
  model.eval()
  
  # 方向 3: 量化
  model_int8 = torch.quantization.quantize_dynamic(
      model, {torch.nn.Linear}, dtype=torch.qint8
  )
  
  # 方向 4: 图编译优化
  model = torch.compile(model, mode="reduce-overhead")

这四个优化可以叠加使用,逐层提升推理性能

二、KV Cache:自回归推理的核心优化

What — KV Cache 是什么?

自回归 LLM 生成时,每个新 token 都依赖之前所有 token 的 K 和 V。在没有 KV Cache 的情况下,每生成一个 token 都要重新计算整段历史的 K 和 V,计算量是 O(n^2)。有了 KV Cache,已生成的 K 和 V 被缓存,每步只需计算新 token 的 K 和 V,复杂度降至 O(n)。

Why — 为什么 KV Cache 如此重要?

对于 2048 token 的输入,KV Cache 可以让推理速度提升约 10~20 倍,显存占用增加有限(线性而非平方增长)。它是所有现代 LLM 推理框架的基础。

没有 KV Cache 会发生什么?

  • 生成长文本时延迟指数级增长,无法实时响应。
  • GPU 算力浪费在重复计算上,单次请求吞吐极低。
  • 长上下文场景几乎不可用。
How — KV Cache 在 HuggingFace Transformers 中
from transformers import AutoModelForCausalLM, AutoTokenizer
  
  model = AutoModelForCausalLM.from_pretrained("gpt2").cuda().eval()
  tokenizer = AutoTokenizer.from_pretrained("gpt2")
  
  inputs = tokenizer("Hello, my name is", return_tensors="pt").to("cuda")
  
  # use_cache=True 启用 KV Cache(默认 True)
  outputs = model.generate(
      **inputs,
      max_new_tokens=50,
      use_cache=True,
      do_sample=False,
  )
  
  print(tokenizer.decode(outputs[0]))

HuggingFace Transformers 在 generate() 中默认启用 KV Cache。对于自回归生成,必须设置 use_cache=True 否则会非常慢

三、ONNX:跨框架模型导出

What — ONNX 是什么?

Open Neural Network Exchange (ONNX) 是一个开放的模型表示格式,由 Meta 和微软联合发起。它定义了一个标准的计算图,可以在不同框架(PyTorch、TensorFlow、JAX)之间互转模型,并在不同硬件(CPU、GPU、NPU)上运行。

Why — 为什么需要 ONNX?

问题一:训练和部署框架不同

训练通常用 PyTorch,部署可能用 TensorFlow、CoreML、TensorRT。直接转换代价巨大。

问题二:硬件多样性

CPU 服务器、移动端、边缘设备的推理引擎不同。ONNX 提供统一的中间表示。

问题三:算子优化

ONNX Runtime 在底层做了大量算子融合、量化、并行化优化,比原始 PyTorch 推理更快。

没有 ONNX 会发生什么?

  • 每个部署平台都要重新实现推理代码。
  • 无法利用 ONNX Runtime 的优化能力。
How — PyTorch 模型导出 ONNX
import torch
  from transformers import AutoModelForCausalLM
  
  model = AutoModelForCausalLM.from_pretrained("gpt2").eval()
  dummy_input = torch.zeros(1, 8, dtype=torch.long)  # batch=1, seq=8
  
  # 导出 ONNX
  torch.onnx.export(
      model,
      (dummy_input,),
      "gpt2.onnx",
      input_names=["input_ids"],
      output_names=["logits"],
      dynamic_axes={
          "input_ids": {0: "batch", 1: "sequence"},
          "logits": {0: "batch", 1: "sequence"},
      },
      opset_version=17,
  )

关键参数:dynamic_axes 声明动态维度(batch 和 sequence),否则模型只能接受固定大小输入。opset_version=17 是当前稳定版本,支持大部分 Transformer 操作。

四、TensorRT:NVIDIA GPU 极致优化

What — TensorRT 是什么?

TensorRT 是 NVIDIA 开发的 GPU 推理优化引擎。它通过算子融合、内核自动调优、量化、内存优化等手段,在 NVIDIA GPU 上达到极致推理性能。

Why — 为什么 TensorRT 比 ONNX Runtime 更快?

TensorRT 针对特定 GPU 架构(Ampere、Hopper 等)做内核自动调优,选择最优的 CUDA kernel 组合。它支持层融合(Conv + BN + ReLU 融合为一个 kernel)、动态 tensor 内存分配、FP16/INT8 量化等优化手段。

How — PyTorch 模型用 TensorRT 加速
import torch_tensorrt
  
  # 加载模型
  model = MyModel().eval().cuda()
  
  # 编译为 TensorRT 引擎
  trt_model = torch_tensorrt.compile(
      model,
      inputs=[
          torch_tensorrt.Input(
              min_shape=[1, 8],
              opt_shape=[16, 512],
              max_shape=[32, 1024],
              dtype=torch.float32,
          )
      ],
      enabled_precisions={torch.float16},  # 使用 fp16
  )
  
  # 推理
  with torch.no_grad():
      output = trt_model(input_tensor)

torch_tensorrt 是 PyTorch 官方的 TensorRT 集成。它接受 PyTorch 模型直接编译,省去了手动转换 ONNX 的步骤

五、torch.compile:PyTorch 原生图优化

What — torch.compile 是什么?

torch.compile 是 PyTorch 2.0 引入的图编译优化。它在第一次前向传播时捕获计算图,然后通过算子融合、内存优化、并行化等手段加速后续执行。

Why — 为什么 torch.compile 比 eager mode 快?

Eager mode 下每个 PyTorch 操作都立即执行 CUDA kernel,开销巨大。torch.compile 把多个小操作融合为一个 CUDA kernel,大幅减少 kernel launch 开销和内存访问次数。

How — torch.compile 的使用
import torch
  
  # 一行代码启用图编译
  model = torch.compile(model, mode="reduce-overhead")
  
  # 推理
  with torch.no_grad():
      output = model(input)

mode 可选值包括 "default""reduce-overhead""max-autotune"。后者会做激进的算子调优,第一次编译会显著变慢,但推理时性能最优

六、量化:INT8 / INT4 的精度-性能权衡

What — 量化是什么?

量化是把 fp32/fp16 的权重和激活值映射到 INT8 或 INT4 的低精度表示。显存占用减少 2~8 倍,计算加速 2~4 倍,但会引入量化误差。

Why — 为什么不全部用 INT4?

问题一:精度损失

INT4 的表示范围只有 16 个值,对于 LLM 的大权重矩阵,会损失严重精度,导致 perplexity 飙升。

问题二:训练 vs 推理的精度容忍度不同

训练对精度极其敏感,必须 fp32;推理可容忍 1~3% 的精度下降以换取显著性能提升。

问题三:硬件支持

INT8 推理在大多数 GPU 上有原生加速;INT4 需要特定架构(Hopper)和 kernel 支持。

没有量化会发生什么?

  • 显存占用高,单卡只能装下小模型。
  • 吞吐量受限于显存带宽,而非计算单元。
How — 使用 bitsandbytes 做 INT8 / INT4 量化
from transformers import AutoModelForCausalLM
  import bitsandbytes as bnb
  
  # INT8 量化
  model = AutoModelForCausalLM.from_pretrained(
      "facebook/opt-6.7b",
      load_in_8bit=True,
      device_map="auto",
  )
  
  # INT4 量化(QLoRA 训练)
  model = AutoModelForCausalLM.from_pretrained(
      "facebook/opt-6.7b",
      load_in_4bit=True,
      bnb_4bit_quant_type="nf4",
      bnb_4bit_compute_dtype=torch.bfloat16,
      device_map="auto",
  )

bitsandbytes 提供了 INT8 和 NF4 量化方案。NF4(4-bit NormalFloat)是为正态分布权重设计的特殊数据类型,比普通 INT4 精度更好

七、vLLM 与 PagedAttention:高吞吐 LLM 服务

What — vLLM 是什么?

vLLM 是 UC Berkeley 开发的 LLM 推理和服务框架。它的核心创新是 PagedAttention,借鉴操作系统的虚拟内存分页思想,解决了 LLM 推理中的 KV Cache 内存碎片化问题。

Why — 为什么传统推理框架吞吐低?

问题一:KV Cache 的连续分配

传统框架(如 HuggingFace Transformers)为每个请求预分配连续的 KV Cache 空间。不同请求长度差异大,导致严重碎片,浪费显存。

问题二:批处理效率低

传统静态 batching 要等所有请求完成才能开始下一批,GPU 利用率忽高忽低。

问题三:vLLM 的解决方案

PagedAttention 把 KV Cache 切分成固定大小的"页",类似操作系统管理内存。请求完成即释放页,显存可以立即被其他请求复用。Continuous Batching 让完成的请求立即被新请求替换,GPU 始终满载。

没有 PagedAttention 会发生什么?

  • 显存浪费严重,单卡并发请求数极少。
  • GPU 利用率低,吞吐量仅为 vLLM 的 1/5~1/10。
How — vLLM 的部署方式
# 安装:pip install vllm
  
  from vllm import LLM, SamplingParams
  
  # 启动 LLM 服务
  llm = LLM(
      model="meta-llama/Llama-2-7b-hf",
      tensor_parallel_size=1,
      gpu_memory_utilization=0.9,
      max_num_batched_tokens=8192,
  )
  
  # 推理
  prompts = ["Hello, my name is", "The capital of France is"]
  sampling_params = SamplingParams(temperature=0.8, top_p=0.95, max_tokens=100)
  
  outputs = llm.generate(prompts, sampling_params)
  for output in outputs:
      print(f"Prompt: {output.prompt!r}")
      print(f"Generated: {output.outputs[0].text!r}")

vLLM 一行代码即可启动高性能 LLM 服务。它内置了 Continuous Batching、PagedAttention、Tensor Parallel 等所有优化

八、部署框架选型指南

场景推荐框架理由
在线 LLM 服务(高吞吐) vLLM PagedAttention + Continuous Batching
NVIDIA GPU 极致优化 TensorRT 硬件级内核优化
跨平台部署(CPU + GPU) ONNX Runtime 统一模型格式
PyTorch 快速优化 torch.compile 零代码改造
边缘设备(手机、嵌入式) ONNX + 量化 小体积、低功耗
大批量离线推理 DeepSpeed-Inference 张量并行 + 量化

九、常见问题 FAQ(20 组)

FAQ 常见问题解答

Q1. 推理和训练的根本区别是什么?

推理不需要反向传播,专注低延迟和高吞吐。推理只用前向传播,可以关闭梯度、降低精度、量化模型。

Q2. 什么是 KV Cache?

缓存已生成 token 的 Key 和 Value,避免重复计算。它是 LLM 自回归推理的核心优化,可让生成速度提升 10~20 倍。

Q3. ONNX 是什么?

Open Neural Network Exchange,开放的模型交换格式。让模型在不同框架和硬件之间互转,是工业部署的事实标准。

Q4. ONNX 和 TensorRT 有什么区别?

ONNX 是模型格式,TensorRT 是推理引擎。ONNX 提供跨平台的中间表示,TensorRT 在 NVIDIA GPU 上做极致优化。

Q5. 什么是 PagedAttention?

vLLM 提出的 KV Cache 内存管理方案。借鉴操作系统的虚拟内存分页,把 KV Cache 切分成固定大小页,解决碎片化问题

Q6. 为什么量化能加速推理?

低精度计算更快、显存占用更少。INT8 比 fp32 快 2~4 倍,显存少 4 倍。GPU 的 Tensor Core 对低精度有原生支持。

Q7. INT8 量化会损失精度吗?

通常有 1~3% 的精度下降。对于分类、生成任务影响较小,但对回归、数值敏感任务影响较大。

Q8. 为什么需要 torch.compile?

减少 CUDA kernel launch 开销。eager mode 每个操作都启动一次 kernel,compile 后多个操作融合为一次 kernel。

Q9. vLLM 比 HuggingFace 快多少?

通常 5~20x 吞吐提升。vLLM 的 PagedAttention 解决显存碎片,Continuous Batching 提升 GPU 利用率。

Q10. 什么是 Continuous Batching?

动态批次管理。完成的请求立即被新请求替换,GPU 始终满载。传统静态 batching 必须等所有请求完成才能开始下一批。

Q11. ONNX 导出的常见错误?

动态 shape、动态控制流、自定义算子。导出时需要声明 dynamic_axes,自定义算子需要用 onnx-script 包装。

Q12. 什么是动态 batching?

按请求动态合并批次。新请求到来时立即加入当前批次,无需等待。Continuous Batching 是动态 batching 的一种。

Q13. 如何选择 batch size?

在延迟预算内尽量大。大 batch 提升吞吐但增加延迟。建议通过 profiling 找到延迟-吞吐的最佳平衡点。

Q14. 什么是 speculative decoding?

用小模型预生成 token,大模型一次性验证。可以在不损失精度的前提下加速 2~3 倍。vLLM、TensorRT-LLM 都支持。

Q15. TensorRT-LLM 是什么?

NVIDIA 针对 LLM 优化的 TensorRT 扩展。提供了针对 Transformer 的高级优化(KV Cache 优化、PagedAttention、量化),比通用 TensorRT 更适合 LLM。

Q16. 推理时为什么要用 eval 模式?

关闭 Dropout 和 BatchNorm 的训练行为。推理需要稳定的输出,eval 模式禁用 Dropout 并固定 BatchNorm 的统计量。

Q17. 什么是 prefill 和 decode 阶段?

LLM 推理的两个阶段。Prefill 处理整个 prompt 一次性计算 K/V,decode 逐 token 生成。两者计算模式不同,常用不同并行策略。

Q18. 模型量化的常见方法?

训练后量化(PTQ)和量化感知训练(QAT)。PTQ 在训练后直接量化,简单但精度损失大;QAT 在训练中模拟量化,精度更好但复杂。

Q19. 为什么 ONNX 模型比 PyTorch 模型小?

因为 ONNX 只保存计算图和权重。PyTorch 模型保留 Python 对象和调试信息,文件通常大几倍。

Q20. 如何部署多模态模型?

分别导出图像、文本编码器,再用 ONNX 拼接。多模态模型的部署更复杂,常需要 Triton Inference Server 等专门的推理服务器。

全篇总纲

  • 1 个核心优化:KV Cache 把推理复杂度从 O(n^2) 降到 O(n)
  • 1 个跨平台标准:ONNX 是模型交换的事实格式
  • 1 个 NVIDIA 极致方案:TensorRT 提供硬件级推理优化
  • 1 个 LLM 服务框架:vLLM 用 PagedAttention 解决显存碎片
  • 3 个加速手段:torch.compile(编译)/ 量化(精度)/ vLLM(批处理)

十、Roadmap 后续预告

后续预告

  • 第 11 篇:深度学习模型评估与基准测试
  • 第 12 篇:模型微调与对齐(PEFT / LoRA / RLHF)
posted @ 2026-07-13 19:44  左扬  阅读(31)  评论(0)    收藏  举报