优化方法将应用于真实模型。将一个标准的基于PyTorch的图像分类模型转换为高度优化的TensorRT引擎。基线版本和优化版本都将被部署到Triton推理服务器上,并仔细测试其性能差异。此练习巩固了从训练产物到可投入生产的高性能推理服务的整个流程。前提条件要完成此练习,您需要一个安装了NVIDIA GPU、Docker和NVIDIA Container Toolkit的系统。这使得Docker容器能够访问GPU。所有模型优化和提供服务都将在容器化环境中执行,以确保可复现性。首先,从NVIDIA NGC仓库拉取最新的Triton推理服务器容器。此容器包含Triton、所有必要的CUDA库以及一个包含常用深度学习框架的Python环境。docker pull nvcr.io/nvidia/tritonserver:24.05-py3注意: 版本标签(例如,24.05-py3)会随时间变化。您可以在Triton的NVIDIA NGC目录页面上找到最新的可用标签。步骤 1:准备基线模型和模型仓库Triton从一个名为模型仓库的特殊结构目录中提供模型服务。每个模型都有其自己的子目录,其中包含模型文件和一个config.pbtxt文件,该文件告知Triton如何提供模型服务。我们首先为PyTorch的基线ResNet-18模型创建一个模型仓库。创建目录结构:mkdir -p triton_repo/resnet18_pytorch/1保存PyTorch模型: 创建一个名为export_model.py的Python脚本,用于下载预训练的ResNet-18模型并以TorchScript格式保存,Triton可以直接执行此格式的模型。# export_model.py import torch import torchvision.models as models # 加载预训练的ResNet-18模型 model = models.resnet18(weights=models.ResNet18_Weights.IMAGENET1K_V1) model.eval() model.cuda() # 将模型移动到GPU # 创建一个示例输入张量 # 形状必须与模型预期的一致:(批量大小, 通道数, 高度, 宽度) dummy_input = torch.randn(1, 3, 224, 224, device="cuda") # 使用TorchScript跟踪模型 traced_model = torch.jit.trace(model, dummy_input) # 保存跟踪后的模型 traced_model.save("triton_repo/resnet18_pytorch/1/model.pt") print("PyTorch模型已保存到 triton_repo/resnet18_pytorch/1/model.pt")运行脚本:python export_model.py。创建配置文件: 现在,在triton_repo/resnet18_pytorch/中创建config.pbtxt文件。此文件定义了模型的元数据。# triton_repo/resnet18_pytorch/config.pbtxt name: "resnet18_pytorch" backend: "pytorch" max_batch_size: 64 input [ { name: "INPUT__0" data_type: TYPE_FP32 dims: [ 3, 224, 224 ] } ] output [ { name: "OUTPUT__0" data_type: TYPE_FP32 dims: [ 1000 ] } ] instance_group [ { count: 1 kind: KIND_GPU } ]您的模型仓库现在应具有以下结构:triton_repo/ └── resnet18_pytorch/ ├── 1/ │ └── model.pt └── config.pbtxt步骤 2:对基线PyTorch模型进行基准测试模型仓库准备就绪后,启动Triton服务器并将其指向您的模型仓库。docker run --rm --gpus all -p 8000:8000 -p 8001:8001 -p 8002:8002 \ -v $(pwd)/triton_repo:/models \ nvcr.io/nvidia/tritonserver:24.05-py3 tritonserver --model-repository=/modelsTriton将启动并加载resnet18_pytorch模型。为了对其进行基准测试,我们使用Triton的perf_analyzer工具,该工具也包含在容器中。打开一个新的终端并运行以下命令,以在新容器内(连接到服务器网络)执行perf_analyzer。docker run --rm --net=host nvcr.io/nvidia/tritonserver:24.05-py3 \ perf_analyzer -m resnet18_pytorch --concurrency-range 1:16 -u localhost:8001此命令使用从1到16的递增客户端并发级别测试模型。稍等片刻,您将看到一个汇总表。注意吞吐量(infer/sec)和p99延迟值。对于未优化的ResNet-18,您可能会看到类似以下的内容:***提示*** 请求并发数: 16 客户端: 请求计数: 2174 吞吐量: 271.5 infer/sec p99延迟: 62105 usec这是我们的性能基线。让我们看看能将其提升多少。步骤 3:使用TensorRT优化模型现在我们将PyTorch模型转换为TensorRT引擎。此过程会应用多项优化,包括层融合、精度校准以及针对我们特定GPU的内核自动调优。创建一个新的Python脚本optimize_model.py来执行转换。您需要首先安装torch-tensorrt库:pip install torch-tensorrt。# optimize_model.py import torch import torch_tensorrt # 加载已保存的TorchScript模型 model = torch.jit.load("triton_repo/resnet18_pytorch/1/model.pt") model.eval().cuda() # 使用TensorRT编译模型 # 我们启用FP16精度以获得显著加速 trt_model = torch_tensorrt.compile(model, inputs=[ torch_tensorrt.Input( min_shape=(1, 3, 224, 224), opt_shape=(8, 3, 224, 224), # 典型批量大小 max_shape=(64, 3, 224, 224), # 与配置中的max_batch_size匹配 dtype=torch.float32) ], enabled_precisions={torch.float16} # 启用FP16 ) # 保存TensorRT引擎 torch.jit.save(trt_model, "triton_repo/resnet18_trt/1/model.plan") print("TensorRT引擎已保存到 triton_repo/resnet18_trt/1/model.plan")在运行脚本之前,为新模型创建目录:mkdir -p triton_repo/resnet18_trt/1。然后,执行脚本:python optimize_model.py。步骤 4:配置和部署TensorRT模型优化后的模型需要自己的配置文件。主要区别是将backend更改为tensorrt,并将模型文件名为model.plan。创建TensorRT的config.pbtxt: 在triton_repo/resnet18_trt/config.pbtxt创建文件。# triton_repo/resnet18_trt/config.pbtxt name: "resnet18_trt" backend: "tensorrt" max_batch_size: 64 input [ { name: "INPUT__0" data_type: TYPE_FP32 dims: [ 3, 224, 224 ] } ] output [ { name: "OUTPUT__0" data_type: TYPE_FP32 dims: [ 1000 ] } ] instance_group [ { count: 1 kind: KIND_GPU } ] # 启用动态批处理以更好地利用GPU dynamic_batching { preferred_batch_size: [8, 16] max_queue_delay_microseconds: 100 }请注意dynamic_batching块的添加。这个Triton功能将单个推理请求组合成一个更大的批次,以更好地充分利用GPU,这是提高吞吐量的一种常见策略。验证模型仓库结构: 您的模型仓库现在应包含两个模型。digraph G { rankdir=TB; node [shape=folder, style=rounded, fontname="Arial"]; edge [arrowhead=none]; "triton_repo" -> {"resnet18_pytorch" "resnet18_trt"}; "resnet18_pytorch" -> {"config.pbtxt_py" "v1_py"}; "config.pbtxt_py" [label="config.pbtxt"]; "v1_py" [label="1"]; "v1_py" -> "model.pt"; "resnet18_trt" -> {"config.pbtxt_trt" "v1_trt"}; "config.pbtxt_trt" [label="config.pbtxt"]; "v1_trt" [label="1"]; "v1_trt" -> "model.plan"; }``` > 部署仓库现在同时包含基线PyTorch模型和优化的TensorRT引擎,可以直接进行比较。3. 重新启动Triton: 如果您的Triton服务器(来自步骤2)仍在运行,请停止它(Ctrl+C)。然后,使用相同的命令重新启动。它现在将检测并加载resnet18_pytorch和resnet18_trt模型。步骤 5:对优化模型进行基准测试和比较最后,再次运行perf_analyzer,但这次针对新的resnet18_trt模型。docker run --rm --net=host nvcr.io/nvidia/tritonserver:24.05-py3 \ perf_analyzer -m resnet18_trt --concurrency-range 1:16 -u localhost:8001您应该会看到性能的显著提升。输出可能如下所示:***提示*** 请求并发数: 16 客户端: 请求计数: 13010 吞吐量: 1625.3 infer/sec p99延迟: 10015 usec让我们将结果可视化。吞吐量大幅增加,p99延迟显著降低。{"data":[{"x":["基线 (PyTorch)","优化 (TensorRT)"],"y":[271,1625],"type":"bar","name":"吞吐量","marker":{"color":"#339af0"}},{"x":["基线 (PyTorch)","优化 (TensorRT)"],"y":[62,10],"type":"bar","name":"p99延迟","yaxis":"y2","marker":{"color":"#ff922b"}}],"layout":{"title":{"text":"性能比较:基线模型 vs. TensorRT模型"},"xaxis":{"title":{"text":"模型版本"}},"yaxis":{"title":{"text":"吞吐量 (推理/秒)","color":"#339af0"}},"yaxis2":{"title":{"text":"p99延迟 (毫秒)","color":"#ff922b"},"overlaying":"y","side":"right"},"legend":{"x":0.05,"y":0.95},"barmode":"group"}}原始PyTorch模型和TensorRT优化版本之间的吞吐量和p99延迟比较。延迟以毫秒(ms)为单位。这个实操练习显示了一种标准且有效的生产模型部署流程。通过将标准框架模型转换为像TensorRT这样的专用推理引擎,并使用像Triton这样的高级服务器提供服务,您可以获得数量级的性能提升。这个过程是构建经济高效且响应迅速的AI服务,以满足严格SLO要求的基础。