推理引擎选择:ONNX Runtime、TensorRT、vLLM、llama.cpp 的对比与选型
说实话,做模型部署这几年,我踩过最多的坑就是「选错推理引擎」。
你想想看,模型训好了,精度也达标了,结果上线时发现推理速度慢得像蜗牛,或者显存直接爆掉——这种体验,我经历过太多次了。
今天咱们就把市面上最主流的四个推理引擎掰开揉碎聊一聊。ONNX Runtime、TensorRT、vLLM、llama.cpp,它们各自擅长什么,又有什么致命短板。
先画一张图,理清思路
我个人习惯在做技术选型前,先画一张框架图。这样脑子里的脉络就清晰了。
ONNX Runtime:通用性最强的「瑞士军刀」
先聊聊 ONNX Runtime。我个人觉得,它是入门部署的首选。
为什么?因为它支持的框架太多了。PyTorch、TensorFlow、Keras 训练出来的模型,都能转成 ONNX 格式,然后用 ONNX Runtime 跑。
核心优势:
- 跨平台支持:Windows、Linux、macOS、甚至移动端
- 多硬件后端:CPU、GPU、NPU、甚至 FPGA
- 框架无关:一次导出,到处运行
我在项目中遇到过这样一个场景:客户要求模型同时跑在 Windows 服务器和 Linux 边缘设备上。当时我第一反应就是用 ONNX Runtime。模型转一次 ONNX,两边都能用,省了不少事。
不过它也有短板。说白了,ONNX Runtime 追求的是「通用性」,所以在特定硬件上的极致优化不如专用引擎。比如在 NVIDIA GPU 上,它就跑不过 TensorRT。
我的建议:如果你需要快速验证部署方案,或者目标平台比较杂,选 ONNX Runtime 准没错。但如果你追求极致性能,那就得往下看了。
TensorRT:NVIDIA GPU 上的「性能怪兽」
说到 TensorRT,我脑海里就两个字:快,但折腾。
TensorRT 是 NVIDIA 自家的推理优化引擎。它能把模型做层融合、精度校准、内存优化,最终跑出惊人的速度。
我记得有一次做视频检测项目,模型用 ONNX Runtime 跑是 30ms 一帧,换成 TensorRT 优化后直接降到 8ms。那种感觉,怎么说呢,就像换了台新电脑。
TensorRT 的核心优化手段:
- 层融合:把多个小算子合并成一个,减少 kernel 启动开销
- 精度校准:支持 FP16、INT8、甚至 INT4 量化
- 动态张量:支持可变输入尺寸,不用重新构建引擎
但这里有个坑——TensorRT 的构建过程很慢。尤其是第一次构建引擎时,可能要花几分钟甚至更久。我曾经在客户现场演示时,就因为引擎构建超时,场面一度很尴尬。
避坑指南:我曾经在生产环境中吃过亏——TensorRT 的 INT8 量化需要校准数据集。如果校准数据分布和实际数据不一致,精度会掉得很厉害。建议先跑一遍 FP16,确认没问题再上 INT8。
另外,TensorRT 只支持 NVIDIA GPU。如果你用的是 AMD 或者 Intel 的卡,那就只能绕道了。
vLLM:大语言模型的「显存救星」
这两年大模型火了,vLLM 也跟着火了起来。它专门为 LLM 推理设计,核心创新是 PagedAttention。
你想想看,传统推理引擎在处理 LLM 时,显存利用率其实很低。因为 KV Cache 是动态分配的,但传统方式会预先分配一大块连续内存,导致大量碎片浪费。
vLLM 的 PagedAttention 借鉴了操作系统的虚拟内存管理思路。它把 KV Cache 分成固定大小的「页」,按需分配,按需回收。这样一来,显存利用率能提升 2-4 倍。
vLLM 的亮点:
- PagedAttention 显存管理,支持更大的 batch size
- 连续批处理(Continuous Batching),请求来了就处理,不用等
- 支持多种量化方式:GPTQ、AWQ、SqueezeLLM
- 兼容 OpenAI API 接口,迁移成本低
我在做 LLM 服务部署时,对比过 vLLM 和普通的 Hugging Face 推理。同样的 7B 模型,vLLM 的吞吐量能高出 3-5 倍。这个差距,说实话,挺震撼的。
但 vLLM 也不是万能的。它目前主要支持 decoder-only 的 LLM 架构(比如 LLaMA、GPT)。如果你用的是 encoder-decoder 模型(比如 T5),那支持就没那么好了。
我的建议:如果你要部署 LLaMA、Qwen、ChatGLM 这类大模型做在线服务,vLLM 基本是首选。但如果是小模型或者非 LLM 场景,就别用它了,杀鸡焉用牛刀。
llama.cpp:边缘设备的「轻量之王」
最后聊聊 llama.cpp。这个项目很有意思,它最初是为了在 MacBook 上跑 LLaMA 模型而生的。
llama.cpp 的核心思路是:用纯 C++ 实现,不依赖 CUDA、不依赖 Python,甚至不需要 GPU。它把模型量化成 GGUF 格式,在 CPU 上就能跑出不错的速度。
我记得有一次出差,客户那边只有一台没有 GPU 的旧服务器。他们想跑一个 13B 的模型做文本生成。我当时就用 llama.cpp 把模型量化到 4-bit,然后直接在 CPU 上跑。虽然速度比不上 GPU,但至少能用了。
llama.cpp 的特点:
- 纯 C++ 实现,无外部依赖
- 支持多种量化级别:Q2_K、Q3_K、Q4_K、Q5_K、Q6_K、Q8_0
- 支持 CPU、Metal(Apple Silicon)、CUDA、Vulkan
- 内存占用极低,4-bit 量化后 7B 模型只需约 4GB 内存
不过,llama.cpp 的缺点也很明显。它主要针对 LLaMA 系列模型优化,对其他架构的支持有限。而且它的 API 比较底层,如果你想做复杂的服务化部署,可能需要自己封装一层。
避坑指南:我曾经在树莓派上试过 llama.cpp,结果发现 7B 模型跑一个 token 要好几秒。嗯,这玩意儿还是更适合笔记本或者服务器级别的 CPU。边缘设备的话,建议用 1B-3B 的小模型。
选型对比:一张表说清楚
说了这么多,咱们用一张表总结一下。这样你选型时直接对照着看就行。
| 维度 | ONNX Runtime | TensorRT | vLLM | llama.cpp |
|---|---|---|---|---|
| 适用场景 | 通用推理、多平台 | NVIDIA GPU 极致优化 | LLM 在线服务 | CPU/边缘设备 |
| 硬件要求 | CPU/GPU/其他 | 仅 NVIDIA GPU | GPU(推荐大显存) | CPU(可加 GPU) |
| 模型类型 | 几乎所有模型 | CNN/Transformer | Decoder-only LLM | LLaMA 系列为主 |
| 量化支持 | FP16/INT8 | FP16/INT8/INT4 | GPTQ/AWQ | GGUF 多级量化 |
| 部署难度 | 低 | 中高 | 中 | 低 |
| 推理速度 | 中等 | 极快 | 快(LLM 场景) | 中等(CPU 场景) |
| 社区活跃度 | 高 | 高 | 高 | 高 |
我的选型建议
说了这么多,到底怎么选?我根据自己的经验,给你几个判断标准:
- 看硬件:只有 NVIDIA GPU?优先考虑 TensorRT。没有 GPU?llama.cpp 是你的朋友。硬件杂?ONNX Runtime 最稳妥。
- 看模型:大语言模型?vLLM 或者 llama.cpp。CNN 或者小 Transformer?TensorRT 或者 ONNX Runtime。
- 看场景:在线服务要求高吞吐?vLLM 的连续批处理很香。边缘设备要求低功耗?llama.cpp 的 CPU 推理是王道。
- 看团队:团队对 CUDA 优化不熟?别碰 TensorRT,先拿 ONNX Runtime 跑起来再说。
最后说一句:没有完美的推理引擎,只有最适合你当前场景的引擎。我个人的习惯是,先拿 ONNX Runtime 快速验证可行性,然后根据性能瓶颈再切换到专用引擎。这样既不会耽误进度,也不会错过优化空间。
公众号:蓝海资料掘金营,微信deep3321