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 框架选型策略
选框架不是选美,得看你的实际场景。我总结了一个决策流程,画成图给你看。
选型时,我建议你按这个顺序问自己:
- 有没有 GPU? 没有 → llama.cpp。有 → 继续。
- 要极致性能? 是 → TensorRT-LLM。否 → 继续。
- 要快速上线? 是 → TGI。否 → vLLM。
- 模型是否稳定? 频繁换模型 → 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 跑通流程,再考虑优化。
一句话送给你:框架是工具,不是目的。你的目标是低成本、高质量地服务用户。选那个让你睡得着觉的框架。