Triton Inference Server 是 NVIDIA 开源的推理服务框架——提供请求排队、模型管理、多模型并发、GPU 调度。用 Triton 做推理服务部署是 GPU 场景的标准做法。对于昇腾场景,CANN 社区维护的 triton-inference-server-ge-backend 仓库提供了 Triton 的 CANN backend,让 Triton 可以管理昇腾 NPU 上的推理。


Triton 为什么适合推理服务

Triton 是一个推理服务框架——它解决的不是"怎么推理",而是"怎么把推理做成服务":

  • 请求排队:并发请求到来时,Triton 自动排队和 Batch
  • 模型管理:多模型加载/卸载、版本管理、动态加载
  • 并发调度:多 GPU/多 NPU 的请求分发
  • Metrics:请求延迟、吞吐、GPU 利用率等监控指标

不用 Triton 的话,这些功能需要自己实现——每个公司写一套类似的推理服务框架。Triton 提供了一套标准化的方案。


GE Backend 如何接入昇腾

Triton 通过 backend 机制对接不同的硬件。GPU 用 tensorrt backend 或 onnxruntime backend。昇腾用 ge backend——triton-inference-server-ge-backend 把 Triton 的请求转发到 CANN 的 AscendCL 接口。

Triton 请求
  ↓
GE Backend:
  1. 接收 Triton 的推理请求(输入 Tensor)
  2. 加载 OM 模型(如果还没加载)
  3. 调用 AscendCL 执行推理(aclmdlExecute)
  4. 把结果封装回 Triton 的响应格式
  ↓
CANN Runtime → 昇腾 NPU

部署配置示例(config.pbtxt):

name: "llama_model"
backend: "ge"
max_batch_size: 8
input [
  {
    name: "input_ids"
    data_type: TYPE_INT64
    dims: [-1]
  }
]
output [
  {
    name: "logits"
    data_type: TYPE_FP32
    dims: [-1, 32000]
  }
]
parameters: [
  {
    key: "om_model_path"
    value: { string_value: "/models/llama.om" }
  }
]

Triton 加载 llama_model 时读到 backend: "ge"——自动加载 GE Backend 的 .so 文件。推理请求来到时 GE Backend 调 aclmdlExecute


Runtime 如何调度推理请求

GE Backend 对 Triton 请求的处理流程:

// GE Backend 的推理执行(简化)
Status GeBackend::Execute(const std::vector<Tensor>& inputs,
                           std::vector<Tensor>* outputs) {
    // 1. 拿到当前请求的 OM 模型
    auto model = GetModel(model_name_);
    
    // 2. 从 Triton 的输入 Tensor 转为 AscendCL Dataset
    aclmdlDataset* input_set = aclmdlCreateDataset();
    for (auto& input : inputs) {
        // 创建 Device Buffer 并拷贝输入数据
        void* dev_buf = aclrtMalloc(input.ByteSize(), ...);
        aclrtMemcpy(dev_buf, ..., input.Data(), ..., H2D);
        aclmdlAddDatasetBuffer(input_set, aclCreateDataBuffer(dev_buf, ...));
    }
    
    // 3. 调用推理——同步模式
    model.Execute(input_set, output_set);
    
    // 4. 结果拷回 Host,封装成 Triton 的输出格式
    for (int i = 0; i < output_set.Size(); i++) {
        void* host_buf = malloc(output_set[i].Size());
        aclrtMemcpy(host_buf, ..., output_set[i].Data(), ..., D2H);
        outputs->push_back(Tensor(host_buf, ...));
    }
}

注意这里用的是同步模式 aclmdlExecute——Triton 的业务逻辑通常不需要异步推理的复杂流水线编排,同步模式更简单。


大模型服务部署链路

一个完整的 LLaMA 推理服务部署:

外部分层 API(gRPC / HTTP)
  ↓
Triton Inference Server
  ↓ GE Backend
CANN AscendCL
  ↓ Runtime/GE
昇腾 NPU(单卡或 8 卡张量并行)

部署步骤:

  1. LLaMA checkpoint → ONNX → ATC → OM
  2. 编写 config.pbtxt,指定 backend=ge 和 OM 路径
  3. 启动 Triton:tritonserver --model-repository=/models
  4. 客户端发 gRPC 请求

多卡张量并行的场景中,GE Backend 支持自动张量切分——OM 模型编译时指定 --tp_size=8,Triton 的推理请求自动分发到 8 张 NPU 上。


实际吞吐分析

在 1×Ascend 910 上用 Triton + GE Backend 部署 LLaMA-7B:

配置Batch=1 延迟Batch=4 延迟Batch=8 延迟最大吞吐
直接 AscendCL 推理78ms145ms220ms36 req/s
Triton GE Backend82ms152ms228ms35 req/s

Triton 引入的额外延迟约 4-7ms(请求序列化、Triton 内部调度、Backend 调用开销)。吞吐基本持平,Triton 的 Batch 编排策略在并发场景下反而可能比自行管理更高。

Triton 的真正价值不在单次推理速度——它的价值在并发管理和运维能力上:请求排队、超时控制、模型热加载、Prometheus 监控。对于生产环境的推理服务部署,这些功能跟推理速度一样重要。

GE Backend 的多模型管理

Triton 支持在同一个进程中管理多个模型。每个模型可以独立配置 backend、Batch 策略、并发度。

GE Backend 的多模型管理在底层使用不同的 om_model_path 加载不同的 OM 文件。每个模型有独立的 GE 上下文——模型 A 的图优化不影响模型 B。但多个模型共享同一个 Runtime 进程——显存池和通信域是共用的。

# 两个模型共享同一个 Triton 实例
name: "bert_model"
backend: "ge"
parameters: [{ key: "om_model_path"; value: { string_value: "/models/bert.om" } }]

name: "llama_model"  
backend: "ge"
parameters: [{ key: "om_model_path"; value: { string_value: "/models/llama.om" } }]
# 两个模型独立加载,共享显存池

GE Backend 的性能监控

GE Backend 集成了 Triton 的 Metrics 上报接口。Triton 的 Prometheus 端点可以查到每个模型的推理延迟、请求数、出错数、GPU/NPU 利用率。对运维团队来说——不需要额外接入监控系统,Triton 自带的全套指标已经在运行了。

参考仓库

triton-inference-server-ge-backend

cann-recipes-infer 推理参考

更多推荐