4. 模型推理框架:Triton Inference Server部署、vLLM与TensorRT-LLM对比、推理优化策略

模型训练完了,怎么让它跑起来?

这个问题,我当年刚入行时觉得很简单——写个Flask接口,load模型,predict就完事了。结果呢?第一个线上事故就教会了我:推理框架选不对,后面全是坑

今天咱们聊聊三个主流方案:Triton、vLLM、TensorRT-LLM。它们各有脾气,选对了事半功倍。

4.1 Triton Inference Server:企业级推理的“瑞士军刀”

Triton是NVIDIA开源的推理服务器。它最大的特点就是啥都能跑——TensorFlow、PyTorch、ONNX、TensorRT,甚至自定义后端。我习惯叫它“万能插座”。

4.1.1 部署实战

部署Triton其实不复杂。核心就三步:准备模型仓库、写配置文件、启动服务。

第一步:模型仓库结构

model_repository/
├── bert_onnx/
│   ├── 1/
│   │   └── model.onnx
│   └── config.pbtxt
├── resnet50_trt/
│   ├── 1/
│   │   └── model.plan
│   └── config.pbtxt
└── ensemble_model/
    ├── 1/
    └── config.pbtxt

每个模型一个文件夹,版本号用数字表示。嗯,这里要注意:版本号必须从1开始,不然Triton会找不到模型。

第二步:配置文件

name: "bert_onnx"
platform: "onnxruntime_onnx"
max_batch_size: 32
input [
  {
    name: "input_ids"
    data_type: TYPE_INT64
    dims: [128]
  }
]
output [
  {
    name: "output"
    data_type: TYPE_FP32
    dims: [768]
  }
]
dynamic_batching {
  preferred_batch_size: [4, 8, 16]
  max_queue_delay_microseconds: 100
}

这里有个坑:dynamic_batching一定要配。我曾经有个项目没配这个,结果并发一上来,GPU利用率只有20%。配了之后直接飙到85%。

第三步:启动服务

docker run --gpus all -p 8000:8000 -p 8001:8001 -p 8002:8002 \
  -v /path/to/model_repository:/models \
  nvcr.io/nvidia/tritonserver:23.10-py3 \
  tritonserver --model-repository=/models

端口8000是HTTP,8001是gRPC,8002是Prometheus监控。我个人习惯用gRPC,性能比HTTP好30%左右。

小技巧: 启动时加个 --model-control-mode=explicit,可以手动控制模型加载。这样上线新模型时不用重启服务。

4.2 vLLM vs TensorRT-LLM:大模型推理的“双子星”

大模型火了之后,vLLM和TensorRT-LLM成了最热门的两个框架。它们都针对Transformer做了极致优化,但思路完全不同。

对比维度 vLLM TensorRT-LLM
核心优化 PagedAttention + 连续批处理 图优化 + 内核融合 + 量化
易用性 ⭐️⭐️⭐️⭐️⭐️(开箱即用) ⭐️⭐️⭐️(需要编译)
吞吐量 高(动态批处理) 极高(静态图优化)
延迟 中等 低(首token延迟更优)
模型支持 LLaMA、ChatGLM、Qwen等 LLaMA、GPT、BLOOM等
量化支持 FP16、INT8 FP16、INT8、INT4、FP8

你看,vLLM胜在简单,TensorRT-LLM胜在极致性能。怎么选?

我个人经验:快速验证用vLLM,生产压榨用TensorRT-LLM。有个项目,我们用vLLM三天就上线了,后来换成TensorRT-LLM,吞吐量又提了40%。

4.2.1 vLLM部署示例

from vllm import LLM, SamplingParams

# 加载模型
llm = LLM(model="meta-llama/Llama-2-7b-chat-hf",
          tensor_parallel_size=2,
          gpu_memory_utilization=0.9)

# 配置采样参数
sampling_params = SamplingParams(
    temperature=0.7,
    top_p=0.9,
    max_tokens=512
)

# 推理
outputs = llm.generate(["请介绍一下深度学习"], sampling_params)
print(outputs[0].outputs[0].text)

就这么几行代码,一个7B模型就跑起来了。你想想看,以前用HuggingFace的transformers,同样的模型,吞吐量差5倍不止。

4.2.2 TensorRT-LLM部署示例

TensorRT-LLM就麻烦一些,需要先编译模型:

# 1. 下载模型权重
git lfs clone https://huggingface.co/meta-llama/Llama-2-7b-chat-hf

# 2. 编译TensorRT引擎
python build.py --model_dir ./Llama-2-7b-chat-hf \
                --dtype float16 \
                --use_gpt_attention_plugin float16 \
                --use_gemm_plugin float16 \
                --max_batch_size 32 \
                --max_input_len 2048 \
                --max_output_len 512 \
                --output_dir ./trt_engines/llama_7b

# 3. 运行推理
python run.py --engine_dir ./trt_engines/llama_7b \
              --tokenizer_dir ./Llama-2-7b-chat-hf \
              --max_output_len 512 \
              --input_text "请介绍一下深度学习"
注意: 编译TensorRT引擎时,max_batch_sizemax_input_lenmax_output_len这三个参数一旦确定就不能改了。我建议设大一点,比如max_batch_size设64,虽然编译慢点,但后面灵活。

4.3 推理优化策略:从“能用”到“好用”

框架选好了,模型能跑了,但离“好用”还差得远。我总结了一套优化策略,按优先级排序:

4.3.1 批处理优化

说白了就是让GPU一次干更多活。Triton的dynamic_batching、vLLM的continuous batching都是干这个的。

我曾经遇到一个场景:用户请求的输入长度差异很大,短的几十个token,长的上千。如果等长填充,浪费严重。后来用了vLLM的动态批处理,吞吐量直接翻倍。

4.3.2 量化压缩

模型太大?量化一下。从FP16降到INT8,模型大小减半,速度提升30%,精度损失不到1%。

TensorRT-LLM支持INT4量化,我试过把LLaMA-13B从26GB压到7GB,还能跑出不错的效果。当然,量化后一定要做精度验证,不然上线后出问题就麻烦了。

4.3.3 KV Cache优化

大模型推理时,KV Cache占显存大头。vLLM的PagedAttention就是解决这个问题的——像操作系统的虚拟内存一样,按需分配。

我建议:监控KV Cache的命中率。如果命中率低于80%,说明批处理策略有问题,需要调整。

4.3.4 请求调度

请求来了,先处理谁?

  • FCFS(先来先服务):简单,但长请求会阻塞短请求
  • 最短作业优先:延迟低,但可能饿死长请求
  • 带权重的调度:给VIP用户更高优先级

我个人习惯用混合策略:短请求优先,但给长请求设置超时保护。这样既保证了响应速度,又不会让长请求一直等。

核心总结: 推理优化不是一锤子买卖。先跑起来,再监控,再优化。我见过太多团队花一个月调优,结果上线后发现瓶颈在别的地方。记住:先测量,再优化

4.4 避坑指南

最后分享几个我踩过的坑:

  • 显存泄漏:Triton的Python后端容易泄漏,建议用C++后端或者定期重启
  • 模型版本管理:别用latest标签,用具体版本号。不然回滚时哭都来不及
  • 预热:新模型上线前,先发几个请求预热。不然第一个请求延迟会很高
  • 监控:一定要监控GPU利用率、显存、请求延迟。我习惯用Prometheus + Grafana

好了,这一章就到这里。下一章咱们聊聊模型服务的高可用架构——怎么让推理服务7x24小时不宕机。