Skip to content

Triton 推理服务

本页速览 NVIDIA 开源的多框架、多模型、多后端推理服务器,是 LLM 与传统模型上线到生产的事实标准。本文拆解 Backend 概念、config.pbtxt、并发执行、动态批处理、模型仓库、Prometheus 指标与 KServe 集成。

Triton 推理服务

一、概念定义:把"推理引擎"变成"推理服务"

Triton Inference Server 是 NVIDIA 开源的多框架、多模型、多后端推理服务器。它的定位是:把单机推理引擎(TensorRT / ONNX Runtime / PyTorch / TensorFlow / 自定义 Python)封装成可水平扩展的 HTTP/gRPC 服务——你给它模型仓库,它给你一个生产就绪的推理 API。

理解 Triton 在推理栈里的位置:

                ┌──────────────────────────────────────────┐
                │   客户端(Web / App / 后端服务)         │
                └────────────────┬─────────────────────────┘
                                 │ HTTP / gRPC (KServe v2)

                ┌──────────────────────────────────────────┐
                │  Triton Inference Server                 │
                │  ├─ Dynamic batching                     │
                │  ├─ Concurrent model execution           │
                │  ├─ Model repository + versioning        │
                │  ├─ Metrics (Prometheus)                 │
                │  └─ Backend 抽象(TRT/ORT/PyTorch/...)  │
                └────────────────┬─────────────────────────┘
                                 │ 内部调用

        ┌────────────────────────────────────────────────────┐
        │  Backends                                           │
        │  [TensorRT] [ONNX Runtime] [PyTorch] [TF] [Python]  │
        │  [Fil] [vLLM] [TensorRT-LLM] [OpenVINO] ...         │
        └─────────────────────────────────────────────────────┘

Triton 是 TensorRTONNX RuntimeTensorRT-LLMvLLM 的"服务化外壳"——这些引擎各有专长,但都不能直接"开个端口上线"。Triton 补上的是:协议层、批处理层、模型管理层、可观测层。详见 模型服务化批处理与调度

二、Backend:插件式引擎抽象

Triton 的核心抽象是 Backend:每个 backend 是一个 C++ 或 Python 实现的"推理引擎适配器"。同一个模型仓库下,不同模型可以用不同 backend:

Backend用途备注
tensorrt加载 TensorRT engine详见 TensorRT 案例
onnxruntime加载 ONNX 模型详见 ONNX Runtime 案例
pytorch加载 TorchScript 模型用 libtorch,不依赖 Python
python任意 Python 推理逻辑via Triton Python Backend,含 GIL 限制
tensorflow加载 SavedModelTF1 / TF2
fil树模型(XGBoost / LightGBM / RAPIDS)GBDT 部署
openvinoIntel CPU/iGPU详见 OpenVINO 案例
tensorrtllmTensorRT-LLM LLM engine详见 TensorRT-LLM 案例
vllmvLLM LLM engine详见 vLLM 案例
python (decoupled)高性能 Python backendactor 模型,规避 GIL

每个 backend 接收 Triton 的"模型实例"创建请求,返回一个能跑 enqueue 的实例对象。多个模型可以并行驻留——这是 Triton 的杀手锏:同一服务进程同时跑视觉模型(TensorRT)+ LLM(TensorRT-LLM)+ GBDT(fil),共享 GPU。

三、模型仓库与 config.pbtxt

Triton 用文件系统作为模型仓库——一个目录树:

model_repository/
├── resnet50/
│   ├── config.pbtxt              ← 模型配置
│   └── 1/                        ← 版本号 1
│       └── model.plan            ← TensorRT engine
├── bert_qa/
│   ├── config.pbtxt
│   ├── 1/
│   │   └── model.onnx            ← ONNX 模型
│   └── 2/
│       └── model.onnx            ← 新版本
├── llama3-8b/
│   ├── config.pbtxt
│   └── 1/
│       └── (TRT-LLM engine 路径)
└── gbdt_ranker/
    ├── config.pbtxt
    └── 1/
        └── model.json            ← XGBoost 模型

config.pbtxt 示例

name: "resnet50"
backend: "tensorrt"
max_batch_size: 128

input [
  {
    name: "input"
    data_type: TYPE_FP32
    dims: [ 3, 224, 224 ]
  }
]
output [
  {
    name: "output"
    data_type: TYPE_FP32
    dims: [ 1000 ]
  }
]

dynamic_batching {
  preferred_batch_size: [ 4, 8, 16, 32, 64 ]
  max_queue_delay_microseconds: 50000      # 50ms 内必须凑批
  preserve_ordering: true
}

instance_group [
  {
    kind: KIND_GPU
    count: 2                                # 2 个并发实例
    gpus: [ 0 ]
  }
]

parameters: {
  key: "workspace_size"
  value: { string_value: "1073741824" }    # 1 GB workspace
}

关键字段:

  • max_batch_size:最大 batch,决定单次请求 batch 上限
  • dynamic_batching:动态批处理配置(详见下一节)
  • instance_group:模型实例数与 GPU 分配
  • parameters:backend 特定参数

版本管理

Triton 用目录 1/2/ 表示模型版本,可通过 --model-version-policy=all / specific: 1,2 / latest: 2 控制。生产实践:

  1. 新版本先放 2/config.pbtxt 里设 version_policy: latest:2
  2. 灰度(10% 流量)通过客户端选择版本号实现;
  3. 完整切换后再删 1/
  4. 一定要保留上一版本以备回滚。

四、并发模型执行:多实例并行

Concurrent Model Execution 让同一模型可以驻留多个 instance 并行跑:

请求 A ──┐
         ├──→ [Instance 1 on GPU 0] → 响应 A
请求 B ──┤
         ├──→ [Instance 2 on GPU 0] → 响应 B
请求 C ──┘
  • kind: KIND_GPU:跑在 GPU 上
  • count: N:N 个实例(受 GPU SM 资源约束)
  • gpus: [0, 1]:分配到哪些 GPU

实例越多 → 并发吞吐越高,但单实例 SM 资源减少 → 单请求延迟可能上升。实例数 = 单请求延迟 × 并发吞吐的权衡,详见 延迟与吞吐

LLM 场景下,TensorRT-LLM / vLLM backend 内部已经做了 PagedAttention + continuous batching,单实例吞吐极高——通常不需要多实例(反而抢资源)。

五、Dynamic Batching:把零散请求凑成批

Dynamic batching 是 Triton 的招牌功能:客户端零散请求在服务器端"等一小段时间"凑成批,一次 forward

T=0ms:   请求 A (batch=1)
T=2ms:   请求 B (batch=1)
T=5ms:   请求 C (batch=1)
T=10ms:  凑到 3 个 → 一次 forward batch=3 → 响应 A,B,C
T=50ms:  即使没凑够,强制开跑(max_queue_delay)

关键参数:

  • preferred_batch_size: [4, 8, 16, 32, 64]:凑到这些大小就立刻开跑
  • max_queue_delay_microseconds: 50000:最长等 50 ms
  • preserve_ordering: true:保证响应顺序与请求一致(LLM 推荐开)

动态批处理的取舍

  • 凑批越大 → 吞吐越高,但延迟上升(请求等凑批);
  • max_queue_delay 越小 → 延迟越低,但凑批小;
  • 视觉 / NLP 分类:max_queue_delay = 50 mspreferred = [8, 16, 32] 通常是好起点;
  • LLM:dynamic batching 通常不适用,因为 continuous batching(详见 vLLM / TensorRT-LLM)已经做了 iteration-level 凑批。

六、协议与客户端

Triton 支持两种协议:

  • HTTP / REST:JSON,易调试
  • gRPC:protobuf,性能高,生产推荐
python
# Python 客户端
import tritonclient.http as httpclient

client = httpclient.InferenceServerClient(url="localhost:8000")

# 检查模型就绪
assert client.is_model_ready("resnet50")

# 推理
inputs = [httpclient.InferInput("input", [1, 3, 224, 224], "FP32")]
inputs[0].set_data_from_numpy(input_array)

outputs = [httpclient.InferRequestedOutput("output")]

response = client.infer("resnet50", inputs, outputs=outputs)
result = response.as_numpy("output")

Triton 兼容 KServe v2 协议(详见 模型服务化),所以可以直接被 KServe / Seldon Core / BentoML 等上层框架调用。

七、Metrics 与可观测

Triton 内置 Prometheus 格式的 metrics endpoint:

GET http://localhost:8002/metrics

关键指标:

Metric含义
nv_inference_request_success成功请求数
nv_inference_request_failure失败请求数
nv_inference_request_duration请求总耗时(含排队)
nv_inference_infer_duration实际推理耗时
nv_inference_queue_duration排队等待时间
nv_inference_exec_count模型执行次数
nv_gpu_memory_used_bytesGPU 显存使用

Grafana 模板 Triton 官方有现成的(详见 Awesome 集合避坑指南)。

上线必看的指标

  1. queue_duration 90 百分位 > 100 ms → 凑批过激,降 preferred_batch_size;
  2. infer_duration / request_duration 比值 < 0.5 → 凑批/序列化开销过大,换 gRPC;
  3. failure 增长 → 多半是 OOM 或超时,看 GPU memory;
  4. 不同模型实例的 exec_count 严重不均 → 流量不均,考虑多实例或 LB。

八、LLM 部署:Triton + TensorRT-LLM / vLLM

LLM 推理与中小模型不同——PagedAttention、continuous batching、KV cache 管理需要专用 backend。Triton 通过 tensorrtllm backendvllm backend 支持 LLM:

TRT-LLM 部署(详见 TensorRT-LLM

models/
└── llama3-8b/
    ├── 1/
    │   ├── config.json
    │   └── engine/                     ← TRT-LLM engine
    └── config.pbtxt

config.pbtxt

backend: "tensorrtllm"
max_batch_size: 0                        # LLM 自管 batch,Triton 不要凑

input [
  { name: "text_input",      data_type: TYPE_STRING, dims: [1] },
  { name: "max_tokens",      data_type: TYPE_INT32,  dims: [1] },
  { name: "temperature",     data_type: TYPE_FP32,  dims: [1] }
]
output [
  { name: "text_output",     data_type: TYPE_STRING, dims: [1] }
]

parameters: {
  key: "TRTLLM_Batch_scheduler_policy"
  value: { string_value: "max_utilization" }
}

启动:

bash
tritonserver \
    --model-repository=/models \
    --http-port=8000 \
    --grpc-port=8001 \
    --metrics-port=8002

vLLM backend

2024 年起 Triton 也支持 vLLM backend,部署方式类似但配置更简——可以直接吃 HuggingFace 模型 ID。

九、与 KServe / Seldon Core 集成

Triton 是"单进程推理服务器",KServe / Seldon Core 是"Kubernetes 上的推理平台"。两者协同:

┌────────────────────────────────────────────────┐
│  Kubernetes                                    │
│                                                │
│  ┌──────────────────────────────────────────┐  │
│  │  KServe InferenceService                │  │
│  │  ├─ Knative Service (自动扩缩容)         │  │
│  │  ├─ 路由、入口、TLS                      │  │
│  │  └─ Container                           │  │
│  │     └─ tritonserver (本节主题)          │  │
│  └──────────────────────────────────────────┘  │
│                                                │
└────────────────────────────────────────────────┘
  • KServe:负责 K8s 上的部署、扩缩容、流量管理、canary 灰度
  • Triton:负责单 Pod 内的推理 + 凑批 + 多模型管理

详见 模型服务化项目集

十、性能数据:基线参考

单台 A100 80GB 上 Triton + TensorRT-LLM 跑 Llama-3-8B FP8:

并发吞吐(tokens/s)首 token 延迟稳定延迟(per token)
115025 ms6.7 ms
8110030 ms7.3 ms
32450045 ms7.1 ms
128850090 ms15 ms
2569500180 ms27 ms

可以看到:

  • 并发 32 时吞吐 4500 tokens/s,首 token 45 ms——生产可用;
  • 并发 256 时吞吐见顶(接近显存带宽瓶颈),延迟上升——这是 显存带宽 边界。

十一、局限与边界

  1. NVIDIA 中心:虽然支持 ONNX Runtime / OpenVINO / TF backend,但优化深度不及 NVIDIA 栈;非 NVIDIA GPU 体验差。
  2. Python Backend 慢:Python backend 受 GIL 限制,性能差——重负载用 Decoupled Python Backend 或 C++ backend。
  3. 配置复杂:config.pbtxt 字段几十个,文档分散;初学者常踩坑。
  4. LLM 模型仓库管理:LLM engine 路径与版本管理比单文件模型复杂,需要 CI 配合。
  5. 多模型共享 GPU 时容易 OOM:实例数配置不当会 OOM,需要测试 + 监控。
  6. 开源版本缺企业特性:如多副本共享模型仓库、A/B 测试、自动金丝雀等需要 KServe 等上层框架补充。

十二、与同类对比

方案与 Triton 的关系
TorchServePyTorch 官方,PyTorch 生态深度好;后端少、性能差
TF ServingTF 官方,TF 生态深度好;与 TorchServe 类似的局限
BentoMLPython 优先,开发体验好;后端少、企业特性需自配
KServe不是 Triton 竞争者,是上层平台;Triton 是 KServe 的 runtime 之一
Seldon Core同 KServe,是上层平台
OpenVINO Model Server详见 OpenVINO,Intel 中心但功能类似
vLLM servervLLM 自带 OpenAI 兼容 server,单 LLM 场景比 Triton 轻量;多模型混合走 Triton
Candle / candle-coreRust 生态,简洁但生态小

十三、可继续追踪

参考资料