3. 推理框架:主流推理框架对比与选型

推理框架选型,说白了就是给你的大模型找个合适的“跑鞋”。

选对了,跑得快、省力气。选错了,要么跑不动,要么烧钱。

我这些年折腾过不少框架,踩过坑,也捡过宝。今天就把几个主流框架的底裤扒一扒,给你看看它们到底几斤几两。

3.1 四大主流框架速览

目前市面上最活跃的四个框架,分别是 vLLM、TGI、TensorRT-LLM 和 llama.cpp。它们各有各的脾气。

框架 核心卖点 适用场景 硬件偏好
vLLM PagedAttention 显存管理 高并发在线推理 NVIDIA GPU
TGI HuggingFace 生态原生 快速集成、实验验证 NVIDIA GPU
TensorRT-LLM 极致推理性能 生产级高吞吐场景 NVIDIA GPU(专属)
llama.cpp CPU/边缘设备运行 本地部署、资源受限 CPU / Apple Silicon

一句话总结:vLLM 是通用首选,TGI 适合快速上手,TensorRT-LLM 是性能怪兽,llama.cpp 是边缘救星。

3.2 框架深度对比

3.2.1 vLLM:显存管理的艺术

vLLM 最让我佩服的,是它的 PagedAttention 机制。这玩意儿借鉴了操作系统的虚拟内存分页思想。

传统推理时,KV Cache 是连续分配的。一旦请求长度变化,就会产生大量碎片。vLLM 把 KV Cache 切成固定大小的“页”,按需分配。显存利用率直接拉满。

我在项目中遇到过这种情况:用原生 Transformers 跑 13B 模型,并发 8 个请求就 OOM 了。换成 vLLM,同样的显存,并发 32 个请求还能稳如老狗。这差距,你想想看。

# vLLM 部署示例
from vllm import LLM, SamplingParams

llm = LLM(model="meta-llama/Llama-2-7b-chat-hf",
          tensor_parallel_size=1,
          gpu_memory_utilization=0.9)

params = SamplingParams(temperature=0.7, max_tokens=512)
outputs = llm.generate(["请解释什么是PagedAttention"], params)
print(outputs[0].outputs[0].text)

我的习惯:gpu_memory_utilization 我一般设 0.85-0.9,留点余量给模型加载和临时计算。设太高容易在长序列时崩掉。

3.2.2 TGI:HuggingFace 的亲儿子

TGI(Text Generation Inference)是 HuggingFace 官方出的。它的优势在于和 Transformers 库无缝衔接。

如果你已经在用 HuggingFace 的模型和 pipeline,切到 TGI 几乎零成本。它内置了连续批处理、张量并行、Flash Attention 等优化。

但说实话,TGI 的性能上限不如 vLLM 和 TensorRT-LLM。我做过压测,同样条件下 TGI 的吞吐比 vLLM 低 20%-30%。

它更适合快速验证想法,或者团队里全是 HuggingFace 生态用户的情况。

# TGI 启动命令
docker run --gpus all -p 8080:80 \
    ghcr.io/huggingface/text-generation-inference:latest \
    --model-id meta-llama/Llama-2-7b-chat-hf \
    --num-shard 1 \
    --max-total-tokens 4096

3.2.3 TensorRT-LLM:NVIDIA 的核武器

TensorRT-LLM 是 NVIDIA 官方出的。它把模型编译成高度优化的引擎,性能是四个框架里最强的。

我曾在 A100 上做过对比:TensorRT-LLM 的推理延迟比 vLLM 低 40%,吞吐高 50%。代价是什么?编译时间长,模型兼容性差,调试起来想骂娘。

嗯,这里要注意。TensorRT-LLM 只支持 NVIDIA GPU,而且每个模型版本都要重新编译。如果你模型迭代频繁,这成本你得算进去。

我曾经踩过的坑:有一次为了压榨性能,我把 TensorRT-LLM 的精度从 FP16 降到 INT8。结果模型输出质量明显下降,用户投诉率飙升。后来我学乖了:精度优化一定要做 A/B 测试,别只看延迟指标。

# TensorRT-LLM 构建引擎(简化版)
# 先转换权重
python convert_checkpoint.py --model_dir llama-7b \
    --output_dir ./tllm_checkpoint \
    --dtype float16

# 再构建引擎
trtllm-build --checkpoint_dir ./tllm_checkpoint \
    --output_dir ./engine_output \
    --max_batch_size 64 \
    --max_input_len 2048 \
    --max_output_len 512

3.2.4 llama.cpp:边缘设备的救星

llama.cpp 是个异类。它用 C++ 实现,主打 CPU 推理和量化。没有 GPU?没关系。内存只有 8GB?也能跑。

它的核心是 GGUF 格式的量化模型。4-bit 量化后,70B 模型能压到 35GB 左右,普通工作站就能跑。

我建议你在以下场景考虑它:

  • 本地开发环境,没有 GPU
  • 边缘设备,比如树莓派、手机
  • 隐私敏感场景,数据不能出本地
# llama.cpp 命令行推理
./main -m models/llama-2-7b.Q4_K_M.gguf \
    -p "请用中文解释什么是量化" \
    -n 256 \
    -t 8 \
    --temp 0.7

3.3 框架选型策略

选框架不是选美,得看你的实际场景。我总结了一个决策流程,画成图给你看。

推理框架选型决策流程 开始选型 是否有 NVIDIA GPU? 是 极致性能还是快速部署? 极致性能 TensorRT-LLM 快速部署 vLLM 否 llama.cpp 或 TGI 💡 说明: vLLM 和 TGI 可互相替代,性能 vLLM 更优,集成 TGI 更简单。 TensorRT-LLM 适合稳定模型,llama.cpp 适合无 GPU 场景。

选型时,我建议你按这个顺序问自己:

  1. 有没有 GPU? 没有 → llama.cpp。有 → 继续。
  2. 要极致性能? 是 → TensorRT-LLM。否 → 继续。
  3. 要快速上线? 是 → TGI。否 → vLLM。
  4. 模型是否稳定? 频繁换模型 → vLLM/TGI。固定模型 → TensorRT-LLM。

3.4 框架部署与配置

部署框架,说白了就是配参数。配好了是神器,配不好是累赘。

3.4.1 通用配置要点

参数 说明 我的建议值
max_num_seqs 最大并发请求数 GPU 显存 / 单请求显存 × 0.8
max_model_len 模型最大上下文长度 根据业务需求,别设太大
gpu_memory_utilization 显存利用率 0.85 - 0.9
tensor_parallel_size 张量并行度 单卡 1,多卡按卡数

我的习惯:max_model_len 别贪心。设 4096 够用就别设 8192。每多一倍长度,显存消耗翻倍。我见过有人设 32768,结果 8 张 A100 只跑了 2 个并发。

3.4.2 vLLM 部署实战

vLLM 部署最简单,一行命令搞定。

# 启动 OpenAI 兼容 API 服务
python -m vllm.entrypoints.openai.api_server \
    --model meta-llama/Llama-2-7b-chat-hf \
    --port 8000 \
    --max-model-len 4096 \
    --gpu-memory-utilization 0.9 \
    --tensor-parallel-size 1

客户端调用:

import openai

client = openai.OpenAI(base_url="http://localhost:8000/v1", api_key="none")
response = client.chat.completions.create(
    model="meta-llama/Llama-2-7b-chat-hf",
    messages=[{"role": "user", "content": "你好"}],
    max_tokens=256
)
print(response.choices[0].message.content)

3.4.3 TensorRT-LLM 部署实战

TensorRT-LLM 部署分两步:构建引擎 + 启动服务。

# 第一步:构建引擎(耗时较长)
trtllm-build --checkpoint_dir ./tllm_checkpoint \
    --output_dir ./engine \
    --max_batch_size 32 \
    --max_input_len 2048 \
    --max_output_len 512 \
    --gemm_plugin float16

# 第二步:启动 Triton 推理服务
docker run --gpus all -p 8001:8001 -p 8002:8002 -p 8003:8003 \
    -v /path/to/engine:/models \
    nvcr.io/nvidia/tritonserver:24.01-trtllm-python-py3 \
    tritonserver --model-repository=/models

我曾经踩过的坑:TensorRT-LLM 的引擎构建时间,7B 模型大概 10 分钟,70B 模型可能要 1 小时以上。而且不同 CUDA 版本编译出来的引擎不兼容。我建议你统一团队的环境,用 Docker 固定 CUDA 和 TensorRT 版本。

3.4.4 llama.cpp 部署实战

llama.cpp 部署最简单,下载二进制就能跑。

# 下载量化模型
wget https://huggingface.co/TheBloke/Llama-2-7B-GGUF/resolve/main/llama-2-7b.Q4_K_M.gguf

# 启动 HTTP 服务
./server -m llama-2-7b.Q4_K_M.gguf \
    --host 0.0.0.0 \
    --port 8080 \
    --n-gpu-layers 0 \
    --ctx-size 4096

如果机器有 GPU,可以加 --n-gpu-layers 参数把部分层卸载到 GPU。

# 使用 GPU 加速(Apple Silicon 或 NVIDIA)
./server -m llama-2-7b.Q4_K_M.gguf \
    --n-gpu-layers 35 \
    --ctx-size 4096

3.5 框架选型总结

最后,我用自己的血泪史给你几个建议:

  • 别盲目追求性能。 TensorRT-LLM 性能最强,但维护成本也最高。团队小、迭代快,选 vLLM 更划算。
  • 量化不是万能的。 4-bit 量化能省 4 倍显存,但模型质量会下降。关键业务场景,至少用 FP16。
  • 留足余量。 显存利用率别设 0.95,留 10% 给突发流量和长序列。
  • 先跑通,再优化。 我见过太多人一上来就折腾 TensorRT-LLM,结果一周没跑通。先用 vLLM 跑通流程,再考虑优化。

一句话送给你:框架是工具,不是目的。你的目标是低成本、高质量地服务用户。选那个让你睡得着觉的框架。