当前位置: 首页 > news >正文

cuda编程笔记(22)-- NVIDIA Triton Inference Server

Triton Inference Server 是什么

  • 全称:NVIDIA Triton Inference Server(以前叫 TensorRT Inference Server)。

  • 作用:在生产环境里 统一部署和管理推理任务,不用每个模型自己写推理服务。

  • 特点:

    • 支持 多框架(TensorRT, PyTorch, TensorFlow, ONNX Runtime, JAX, RAPIDS…)。

    • 支持 多 GPU / 多模型调度,提升 GPU 利用率。

    • 提供 HTTP/gRPC 接口,方便接入后端系统。

    • 内置 动态 batch、并发执行、模型 ensemble 等性能优化机制。

一句话总结:TensorRT 是推理引擎,Triton 是推理服务平台。

Triton 的核心功能

  1. 多框架支持

    • TensorRT / ONNX Runtime / PyTorch TorchScript / TensorFlow SavedModel 都能直接加载。

  2. 多模型管理

    • 一个 Triton 实例可以同时管理成百上千个模型。

    • 支持 热加载(不用停服务就能更新模型)。

  3. 动态批处理 (Dynamic Batching)

    • 自动把多个小请求合并成一个大 batch,提高 GPU 吞吐。

    • 比如在线服务场景,很多用户发来 batch=1 请求,Triton 能拼接成 batch=32 一次跑完。

  4. 模型 Ensemble Pipeline

    • 可以把多个模型串起来(预处理 → 主模型 → 后处理),由 Triton 内部调度。

    • 类似数据流图,减少客户端调用复杂度。

  5. 多实例 & 并发执行

    • 一个模型可以开多个实例,跑在不同 GPU / stream 上,支持并行执行。

  6. 推理请求接口

    • HTTP/REST 和 gRPC 两种接口,方便后端系统调用。

Triton 和 TensorRT 的关系

  • TensorRT:底层推理引擎,做 算子融合、精度优化 (FP16/INT8)、内存调度,提升单模型单 GPU 性能。

  • Triton:在 TensorRT 之上做 服务化和调度,负责 多模型管理、batch 合并、并发调度

可以理解为:

  • TensorRT = 单个模型的“赛车引擎”。

  • Triton = 把一堆赛车调度在赛道上高效跑起来的“车队管理系统”。

Triton 的工作流程(简化版)

模型存放在 Model Repository(本地文件夹 / 云存储)。

模型的存放必须是这个结构;有一个模型名的文件夹,里面有一个模型配置文件config;还有一个1文件夹(必须叫这个),有一个引擎文件(可以是onnx或者plan),但是文件名必须是model

models/├── resnet50/│   ├── 1/│   │   └── model.plan   # TensorRT 引擎文件│   └── config.pbtxt     # 模型配置文件

启动 Triton Server(Docker 常用)。

单看可能看不懂,后面会有具体例子

docker run --gpus=all -v /path/to/models:/models nvcr.io/nvidia/tritonserver:23.10-py3 tritonserver --model-repository=/models

客户端发请求(HTTP/gRPC)。

不管客户端是啥类型,可以往这个Triton Server发送请求,获得推理后的结果。

下载使用Triton

操作系统用Linux;肯定要有GPU;推荐用docker,之后的使用都是在docker上的。如果不用docker,很多配置不一定对的上,将会更加麻烦。

拉取Triton镜像

docker pull nvcr.io/nvidia/tritonserver:23.10-py3

构造文件夹

models/├── resnet50/│   ├── 1/│   │   └── model.onnx   # TensorRT 引擎文件│   └── config.pbtxt     # 模型配置文件

这个模型可以去网上找,但是我去网上找发现动态batch匹配不了,干脆直接用python生成一个了

import torch
import torch.nn as nn
import torchvision.models as models
import os# -----------------------------
# 1. 创建目录
# -----------------------------
model_dir = "/home/huangxy/models/resnet50/1"
os.makedirs(model_dir, exist_ok=True)# -----------------------------
# 2. 初始化 ResNet50
# -----------------------------
resnet50 = models.resnet50(pretrained=True)
resnet50.eval()  # 推理模式# -----------------------------
# 3. 定义动态 batch 输入
# -----------------------------
# Triton要求输入 shape: [B, 3, 224, 224],B 动态
dummy_input = torch.randn(1, 3, 224, 224)  # batch=1 占位
dynamic_axes = {'gpu_0/data_0': {0: 'batch_size'},     # 输入第0维动态'gpu_0/softmax_1': {0: 'batch_size'}  # 输出第0维动态
}# -----------------------------
# 4. 导出 ONNX
# -----------------------------
onnx_path = os.path.join(model_dir, "model.onnx")
torch.onnx.export(resnet50,dummy_input,onnx_path,input_names=['gpu_0/data_0'],output_names=['gpu_0/softmax_1'],dynamic_axes=dynamic_axes,opset_version=17,        # 最新 ONNX opsetdo_constant_folding=True
)print(f"ONNX 模型已生成: {onnx_path}")

config文件可以参考这个

name: "resnet50"
platform: "onnxruntime_onnx"#这里用的onnx,所以这么写,用.plan、.pt啥的就不是这么写了
max_batch_size: 8 #大于0代表接受动态batch推理input [{name: "gpu_0/data_0"#这个得和模型设置的一样data_type: TYPE_FP32dims: [3,224,224]#这是resnet的输入维度(不包括batch)}
]output [{name: "gpu_0/softmax_1"#这个也是data_type: TYPE_FP32dims: [1000]#输出维度也不包括batch}
]

启动docker里的Triton

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

--gpus=all

所有可见的 GPU 分配给容器。
(相当于容器里的 Triton 能使用宿主机的 GPU 进行推理。)

--rm

容器退出后自动删除,不保留历史。
(方便测试,避免到处都是旧容器残留。)

-it

  • -i:交互模式(保持 STDIN 打开)

  • -t:分配一个伪终端
    👉 合起来就是让你能看到 Triton 的日志,并能 Ctrl+C 停止。

-v ~/models:/models

宿主机的 ~/models 目录 挂载到容器内的 /models 路径。
这样 Triton 就能读到你放在宿主机的模型。

比如你在宿主机放 /home/huangxy/models/resnet50/1/model.onnx
容器里能直接访问 /models/resnet50/1/model.onnx

-p 8000:8000 -p 8001:8001 -p 8002:8002

端口映射,把容器内的 Triton 服务暴露给宿主机:

  • 8000 → HTTP endpoint

  • 8001 → gRPC endpoint

  • 8002 → Prometheus metrics

你在本机访问 http://localhost:8000/v2/health/ready 就能检查服务。

nvcr.io/nvidia/tritonserver:23.10-py3

我们之前下载的镜像

tritonserver --model-repository=/models

这是容器启动后运行的命令:

  • tritonserver:启动 Triton 推理服务

  • --model-repository=/models:指定模型仓库目录(刚才挂载的 /models

这条命令的效果是:

  • 启动一个带 GPU 的临时 Triton 容器

  • 把你本地的 ~/models 映射进去

  • 在 8000(HTTP)、8001(gRPC)、8002(Metrics)端口暴露服务

  • 并用 /models 目录里的模型仓库启动 Triton

客户端发送请求测试

import numpy as np
import requests
import json# Triton HTTP endpoint (模型推理接口地址)
# 格式: http://<host>:8000/v2/models/<model_name>/infer;这是http的请求推理的路径,gRPC会有不同
# 这里模型名是 "resnet50",端口 8000 是 Triton HTTP 服务
TRITON_URL = "http://localhost:8000/v2/models/resnet50/infer"# ====== 构造输入数据 ======
# 创建一个随机输入,模拟 1 张图片
# ResNet50 的输入格式是 [batch, channel, height, width]
batch_size = 1
input_data = np.random.rand(batch_size, 3, 224, 224).astype(np.float32)# Triton HTTP 请求体
payload = {"inputs": [{# 输入名字必须和模型配置 (config.pbtxt / onnx graph) 一致"name": "gpu_0/data_0",# 输入数据的形状,必须与模型要求一致"shape": list(input_data.shape),# 数据类型,对应 Triton 的 FP32"datatype": "FP32",# 数据展平为一维数组,并转为 Python 列表"data": input_data.flatten().tolist()}],"outputs": [{"name": "gpu_0/softmax_1"}]
}# ====== 发送 HTTP POST 请求给 Triton ======
response = requests.post(TRITON_URL, json=payload)
# ====== 解析响应 ======
if response.status_code == 200:# Triton 返回的结果是 JSON 格式result = response.json()# 输出张量数据,转成 numpy 数组output_data = np.array(result['outputs'][0]['data'])# 打印输出形状 (这里应该是 [1000],对应 ImageNet 分类)print("Output shape:", output_data.shape)# 打印概率最大的前 5 个类别索引print("Top-5 indices:", output_data.argsort()[-5:][::-1])
else:print("Error:", response.status_code, response.text)

输出结果:

Output shape: (1000,)
Top-5 indices: [610 549 783 446 892]

这样就完成了一个远程推理的过程

http://www.dtcms.com/a/407616.html

相关文章:

  • 怎么知道网站是否被百度收录软件开发工具有哪些
  • 伦理治理进入程序化攻坚阶段
  • 经典网站赏析永久使用免费虚拟主机
  • 【跟我学YOLO】YOLO26:YOLO Vision 2025 最新发布的端到端视觉 AI 新突破
  • 什么网站百度收录好最新国家大事时政新闻
  • 怎么做网站手机版辅助设计软件有哪些
  • Model Context Protocol (MCP)详解与Spring Boot集成实战
  • 珠海h5模板建站网站建设考试卷a卷
  • 豆包Seedream 4.0创意玩法大赏:开启AI绘画新纪元
  • 算法基础篇(5)前缀和
  • 手机网站宽度多少合适网站开发行业代码
  • 了解一下Ubuntu上搭建的ROS环境
  • 博客网站搭建网站建设需要资质么
  • 泰安市景区建设网站阿里巴巴企业网站怎么做
  • 网站采用什么字体wordpress get_pages()
  • 禁用内核模块,是否需要执行脚本 $ sudo update-initramfs -u $ sudo update-grub ?
  • 建站最好的公司排名织梦cms源码
  • 渲染 Python 中用 LaTeX 语法定义的数学公式 - 环境准备
  • 做教育业网站wordpress最漂亮的主题
  • 上海快速网站建设wordpress推广浏览插件
  • JVM-垃圾回收
  • [数据结构]ST表(markdown重制版)
  • 深圳网站建设saote网站建设项目登记表
  • STL 基础概念
  • dw做旅游网站毕业设计模板下载适合代码新手做的网站
  • 为什么公司网站打不开网页链接制作生成
  • 网站制作模板过程开发app的网站有哪些
  • 原来两个std::vector可以直接进行相等判断的吗?
  • 电子工程基础原理与应用指南(初学者版)电子工程入门:三极管与MOS管全解析
  • Rust/C/C++ 混合构建 - 用Bazel构建Rust与C