作者​:昇腾实战派
知识地图​:https://blog.csdn.net/Lumos_Lovegood/article/details/161601003

摘要

模型服务化是将训练好的模型包装成一个可以通过网络访问的标准化服务的过程。将模型部署在一个专门的服务中,而其他的程序不需要关心模型所有的细节,只需要通过网络协议(HTTP/gRPC) 发送数据并且接收预测结果即可。

Triton Inference Server 是一个开源的高性能推理服务框架,支持 TensorFlow、PyTorch、ONNX 等多种模型,并可在 GPU、CPU 和 NPU 等异构硬件上高效运行。它通过动态批处理、多实例并发和统一接口实现高吞吐与低延迟,适合在大规模生产环境中部署和管理模型。

Triton 服务化框架

在这里插入图片描述

使用说明

  1. 准备一个基于Triton格式的model repository
    Triton NPU基于Triton的Python Backend进行适配,triton21.09版本之后自带Python Backend,镜像标签中以-py3 结束。
    可以参考Triton官方样例了解相关特性。
    Triton规定了model_repository实现时的目录结构,以下是一个model repository目录结构的样例:

    model_repository/
    ├── model1
    │   ├── 1
    │   │   └── model.py
    │   └── config.pbtxt
    └── model2
        ├── 1
        │   └── model.py
        └── config.pbtxt
    ​
    
    • model_repository/
      Triton 的模型仓库根目录,可以包含多个模型。
    • model/*
      每个子文件夹表示一个模型,文件夹名即为模型名称MODEL_REPO(部署时用这个名字来调用)。
    • version 子目录(如 1/, 2/
      • 表示模型的版本号(必须是整数)。
      • Triton 可以同时管理多个版本(例如线上推理用 v1,灰度测试用 v2)。
    • model.pymodel.onnx 等文件都放在对应的版本目录下。
    • config.pbtxt
      每个模型必须有的配置文件,用来告诉 Triton 输入输出张量类型、形状、batching 方式等。
    • 启动 Triton server
      /opt/tritonserver/bin/tritonserver --model-repository=${MODEL_REPO}
      ​
      
  2. 关于model.py、config.pbtxt文件实现说明
    Python backend 中,model.py 是模型的推理逻辑实现文件,必须定义以下类和方法:

    import triton_python_backend_utils as pb_utils
    
    class TritonPythonModel:
        def initialize(self, args):
            """
            模型初始化逻辑(类似构造函数)
            - args: dict,包含 model_repository 路径、model 名称、version 等信息
            - 这里可以加载模型权重、初始化依赖库等
            """
            pass
    
        def execute(self, requests):
            """
            推理核心函数
            - requests: list,包含多个 inference request(可能是 batch)
            - 必须返回 list of pb_utils.InferenceResponse
            - 调用后端的模型进行推理,后端模型可以使用`.om`计算图文件,也可以使用torchair的适配等等,只要是能正常在NPU上推理的模型均可
            """
            responses = []
            for request in requests:
                # 获取输入张量
                in_tensor = pb_utils.get_input_tensor_by_name(request, "INPUT_NAME")
                in_numpy = in_tensor.as_numpy()
    
                # 模型计算逻辑(这里可以调用 PyTorch、TensorFlow、NumPy)
                out_numpy = in_numpy + 1  # 示例逻辑
    
                # 构造输出
                out_tensor = pb_utils.Tensor("OUTPUT_NAME", out_numpy)
                responses.append(pb_utils.InferenceResponse(output_tensors=[out_tensor]))
            return responses
    
        def finalize(self):
            """
            资源清理逻辑(类似析构函数)
            - 在模型卸载时调用
            - 可以释放 GPU/CPU 资源,关闭文件句柄
            """
            pass
    • 必须实现 TritonPythonModel 类,并包含 initializeexecutefinalize 方法。
    • 输入输出的名字和类型 必须和 config.pbtxt 中保持一致。
    • 执行逻辑完全由使用者控制,可以调用深度学习框架或自定义算法。

    config.pbtxt 是一个 protobuf 格式的配置文件,主要定义:

    基本结构
    name: "model1"                 # 模型名称,必须与文件夹名一致
    backend: "python"              # 后端类型(Python 模型用 python)
    max_batch_size: 8              # 最大 batch 大小(0 表示不支持 batching)
    
    input [
      {
        name: "INPUT_NAME"
        data_type: TYPE_FP32       # 输入数据类型 (FP32, INT64 等)
        dims: [ 224, 224, 3 ]      # 输入维度,实际triton会自动增加batch维度,即: [ batchsize, 224, 224, 3 ] 
      }
    ]
    
    output [
      {
        name: "OUTPUT_NAME"
        data_type: TYPE_FP32
        dims: [ 1000 ]             # 输出维度,同上,实际维度为[ batchsize, 1000 ]
      }
    ]
    
    dynamic_batching {
      preferred_batch_size: [4,8]
      max_queue_delay_microseconds: 1000
    }
    
    instance_group [
      {
        kind: KIND_CPU             # 运行设备 (KIND_GPU / KIND_CPU)
        count: 1                   # 实例数(可以部署多个副本以提升并发)
      }
    ]
    ​
    
    关键字段说明
    • name​: 模型名称,必须与文件夹名一致。
    • backend​: 使用的后端(Python backend 就写 "python")。
    • max_batch_size​: 最大 batch 大小。设为 >0 时 Triton 可以自动合并请求,提高吞吐量。
    • input/output​:
      • 定义输入输出张量的名字、类型、维度。
      • 这里的 name 必须和 model.py 中的输入输出一致。
    • instance_group​: 定义运行的设备类型(GPU/CPU/NPU)和实例数。我们目前只能通过Python backend 在 Triton中调用昇腾CANN,所以在此处要写作KIND_CPU, Triton负责在CPU进程中调用NPU API
    • dynamic_batching​: Triton 会把多个到达的请求在服务端合并,拼凑成一个大batch(通过设定的max_batch_sizepreferred_batch_size确定)提高吞吐量。

独特特性

  • 动态批处理:服务端合并请求为batch,送给后端模型一次性处理

    | 特性 | 模型自身 batch | Triton 组 batch |
    | :--------------------------- | --------------------------------- | ------------------------------------------------------ |
    | 谁负责收集样本? | 你在代码里自己准备好 | Triton 在服务端自动合并多个 request |
    | 客户端需不需要关心 batch? | 需要(你要自己准备 batch 输入) | 不需要(随便发单条请求,Triton 会拼 batch) |
    | 提升性能方式 | 单个 request 内部的并行 | 多个 request 融合成更大的 batch,提高 GPU/CPU 利用率 |
    | 灵活性 | 受限于调用方,必须一次性收集好 | 面向多用户 / 高并发场景,自动调度更好 |

    triton的组batch相当于把收集batch数据这个过程交给了服务方,更加适用于多客户端并发场景。

  • 并发模型 | 多实例:可以为同一个后端模型启动多个实例,提高并行度并自动实现更加灵活的负载分配,对于NPU,也就是可以通过Python backend并发调用NPU提高利用率

  • 模型组合:可以将多个模型 | 预处理、中间模型、后处理串联组合,由Triton统一调用并且进行内部的数据流转控制,简化复杂的流水线部署(tokenizer -> encoder -> decoder)

  • 序列批处理:可以保证请求按顺序被处理(即使在batching中),可以保证多个请求的对话不混乱。Triton服务接收请求的时候会自动维护一个RequestContext,建立数据与客户端的关系,并且按照请求的先后维护好这个顺序。在triton服务推理过程中也会保护顺序。最后拆分结果,并且按照RequestContext中的对应关系发送回客户端。

性能调优与验证

perf_analyzer 是Triton自带的一个压测与性能分析工具,可以模拟不同配置下的客户端请求,并且统计模型的性能表现。
支持HTTP/gRPC协议

  • 启动方式
    perf_analyzer -m model1 \ # 指定模型名称,与config.pbtxt中的name一致
                   --concurrency-range 1:16 \ # 并发请求数量的范围,1:16表示并发从1到16逐步测试
                   --input-data zero \ # 输入数据为全零张量(常用),除此之外还有random和file(真实数据)
                   --shape INPUT_NAME:1,224,224,3 # 需要与config.pbtxt中定义的维度一致
    		--protocol HTTP # 默认HTTP,可以选择gRPC
    ​
    

整体工作流程

  1. 客户端请求发送到 Triton。
  2. Triton 根据 config.pbtxt 知道模型输入输出规格,解析请求。
  3. 请求进入对应模型的 model.pyexecute()
  4. model.py 处理输入张量,生成输出张量。
  5. Triton 将结果打包成响应返回给客户端。

特别说明

Triton-npu服务化时,NVML以及CUDA等报错信息可以安全忽略:

  • 本服务采用纯 Python backend 实现,不依赖 NVIDIA 生态组件
  • 报错源于底层驱动对 GPU 相关库的兼容性检查,不影响 NPU 的实际计算功能
  • 核心推理流程通过昇腾 CANN 框架执行,与报错模块无实际关联
Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐