全部產品
Search
文件中心

Platform For AI:Triton Inference Server鏡像部署

更新時間:Dec 24, 2025

Triton Inference Server是一個適用於深度學習與機器學習模型的推理服務引擎,支援將TensorRT、TensorFlow、PyTorch或ONNX等多種AI架構的模型部署為線上推理服務,並支援多模型管理、自訂backend等功能。本文為您介紹如何通過鏡像部署的方式部署Triton Inference Server模型服務。

部署服務:單模型

1. 準備模型與設定檔

在OSS儲存空間中建立模型儲存目錄,並根據模型儲存目錄格式要求配置模型檔案與設定檔。具體操作請參見管理目錄

每個模型目錄下都至少包含一個模型版本目錄和一個模型設定檔:

  • 模型版本目錄:包含模型檔案,且必須以數字命名,作為模型版本號碼,數字越大版本越新。

  • 模型設定檔:用於提供模型的基礎資訊,通常命名為config.pbtxt

假設模型儲存目錄在oss://examplebucket/models/triton/路徑下,模型儲存目錄的格式如下:

triton
└──resnet50_pt
    ├── 1
    │   └── model.pt
    ├── 2
    │   └── model.pt
    ├── 3
    │   └── model.pt
    └── config.pbtxt

其中:config.pbtxt 為設定檔,檔案內容樣本如下:

name: "resnet50_pt"
platform: "pytorch_libtorch"
max_batch_size: 128
input [
  {
    name: "INPUT__0"
    data_type: TYPE_FP32
    dims: [ 3, -1, -1 ]
  }
]
output [
  {
    name: "OUTPUT__0"
    data_type: TYPE_FP32
    dims: [ 1000 ]
  }
]

# 使用GPU推理
# instance_group [
#   { 
#     kind: KIND_GPU
#   }
# ]

# 模型版本配置
# version_policy: { all { }}
# version_policy: { latest: { num_versions: 2}}
# version_policy: { specific: { versions: [1,3]}}

config.pbtxt檔案中關鍵配置說明如下:

參數

是否必選

描述

name

預設為模型儲存目錄名。如果指定了名稱,也必須與模型儲存目錄名稱保持一致。

platform/backend

platform與backend至少配置一項:

  • platform:用於指定模型架構。常用的模型架構套件含:tensorrt_plan、onnxruntime_onnx、pytorch_libtorch、tensorflow_savedmodel、tensorflow_graphdef等。

  • backend:用於指定模型架構或使用Python代碼自訂推理邏輯。

    • 可指定的模型架構與platform完全一樣,只是設定的名稱不同,架構套件含:tensorrt、onnxruntime、pytorch、tensorflow等。

    • 使用Python代碼自訂推理邏輯,具體操作,請參見部署服務:使用backend

max_batch_size

用於指定模型請求批處理的最大數量,若不開啟批處理功能,則將該項設定為0。

input

用於指定以下屬性:

  • name:輸入資料的名稱。

  • data_type:資料類型。

  • dims:維度。

output

用於指定以下屬性:

  • name:輸入資料的名稱。

  • data_type:資料類型。

  • dims:維度。

instance_group

當資源配置中有GPU資源時,預設使用GPU進行模型推理,否則預設使用CPU。您也可以通過配置instance_group參數,來顯式指定模型推理使用的資源,配置格式如下:

instance_group [
   { 
     kind: KIND_GPU
   }
 ]

其中kind可配置為KIND_GPUKIND_CPU

version_policy

用於指定模型版本,配置樣本如下:

version_policy: { all { }}
version_policy: { latest: { num_versions: 2}}
version_policy: { specific: { versions: [1,3]}}
  • 不配置該參數:預設載入版本號碼最大的模型版本。樣本中resnet50_pt模型會載入模型版本3。

  • all{}:表示載入該模型所有版本。樣本中resnet50_pt會載入模型版本1、2和3。

  • latest{num_versions:}:例如配置為num_versions: 2,樣本中resnet50_pt會載入最新的2個模型版本,即版本2和3。

  • specific{versions:[]}:表示載入指定版本。樣本中resnet50_pt會載入模型版本1和3。

2. 部署Triton Inference Server服務

  1. 登入PAI控制台,在頁面上方選擇目標地區,並在右側選擇目標工作空間,然後單擊進入EAS

  2. 模型線上服務(EAS)頁面,單擊部署服務,然後在情境化模型部署地區,單擊Triton部署

  3. Triton部署頁面,配置以下關鍵參數,其他參數配置說明,請參見自訂部署

    參數

    描述

    服務名稱

    自訂佈建服務名稱。

    模型配置

    在本方案中,配置類型選擇Object Storage Service,將OSS配置為步驟1中已準備的模型所在的OSS儲存路徑,例如oss://example/models/triton/

  4. (可選)啟用gRPC。預設情況下,服務僅在8000連接埠上開啟HTTP服務。如需支援gRPC調用,單擊頁面右側的切換為自訂部署,進行如下修改:

    • 修改環境資訊地區的連接埠號碼為8001。

    • 服務功能 > 進階網路下啟用GRPC。

  5. 參數配置完成後,單擊部署

部署服務:多模型

EAS部署多模型服務的方式與部署單模型服務相同,您只需建立如下所示的多個模型儲存目錄即可,服務會載入所有的模型,並部署在同一個服務中。具體部署方式請參見部署服務:單模型

triton
├── resnet50_pt
|   ├── 1
|   │   └── model.pt
|   └── config.pbtxt
├── densenet_onnx
|   ├── 1
|   │   └── model.onnx
|   └── config.pbtxt
└── mnist_savedmodel
    ├── 1
    │   └── model.savedmodel
    │       ├── saved_model.pb
    |       └── variables
    |           ├── variables.data-00000-of-00001
    |           └── variables.index
    └── config.pbtxt

部署服務:使用backend

backend是模型推理計算的具體實現部分,它既可以調用現有的模型架構(如TensorRT、ONNX Runtime、PyTorch、TensorFlow等),也可以自訂模型推理邏輯(如模型預先處理、後處理)。

backend支援 C++、Python兩種語言,與C++相比, Python使用起來更加靈活方便,因此以下內容主要介紹Python backend的使用方式。

1. 更新模型與設定檔

以PyTorch為例,使用Python backend自訂模型的計算邏輯,模型目錄結構樣本如下:

resnet50_pt
├── 1
│   ├── model.pt
│   └── model.py
└── config.pbtxt

與常規的模型目錄結構相比,backend需要在模型版本目錄下新增一個model.py檔案,用於自訂模型的推理邏輯,並且設定檔config.pbtxt內容也需要做相應修改。

  • 自訂推理邏輯

    model.py檔案需要定義名為TritonPythonModel的類,並實現initialize、execute、finalize三個關鍵的介面函數。該檔案內容樣本如下:

    import json
    import os
    import torch
    from torch.utils.dlpack import from_dlpack, to_dlpack
    
    import triton_python_backend_utils as pb_utils
    
    
    class TritonPythonModel:
        """必須以 "TritonPythonModel" 為類名"""
    
        def initialize(self, args):
            """
            初始化函數,可選實現,在載入模型時被調用一次,可用於初始化與模型屬性、模型配置相關的資訊。
            Parameters
            ----------
            args : 字典類型,其中keys和values都為string 類型,具體包括:
              * model_config:JSON格式模型配置資訊。
              * model_instance_kind:裝置型號。
              * model_instance_device_id:裝置ID。
              * model_repository:模型倉庫路徑。
              * model_version:模型版本。
              * model_name:模型名。
            """
    
            # 將JSON字串類型的模型配置內容轉為Python的字典類型。
            self.model_config = model_config = json.loads(args["model_config"])
    
            # 擷取模型設定檔中的屬性。
            output_config = pb_utils.get_output_config_by_name(model_config, "OUTPUT__0")
    
            # 將Triton types轉為numpy types。
            self.output_dtype = pb_utils.triton_string_to_numpy(output_config["data_type"])
    
            # 擷取模型倉庫的路徑。
            self.model_directory = os.path.dirname(os.path.realpath(__file__))
    
            # 擷取模型推理使用的裝置,本例中使用GPU。
            self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
            print("device: ", self.device)
    
            model_path = os.path.join(self.model_directory, "model.pt")
            if not os.path.exists(model_path):
                raise pb_utils.TritonModelException("Cannot find the pytorch model")
            # 通過.to(self.device)將pytorch模型載入到GPU上。
            self.model = torch.jit.load(model_path).to(self.device)
    
            print("Initialized...")
    
        def execute(self, requests):
            """
            模型執行函數,必須實現;每次請求推理都會調用該函數,若設定了 batch 參數,還需由使用者自行實現批處理功能
            Parameters
            ----------
            requests : pb_utils.InferenceRequest類型的請求列表。
    
            Returns
            -------
            pb_utils.InferenceResponse 類型的返回列表。列表長度必須與請求列表一致。
            """
    
            output_dtype = self.output_dtype
    
            responses = []
    
            # 遍曆request列表,並為每個請求都建立對應的response。
            for request in requests:
                # 擷取輸入tensor。
                input_tensor = pb_utils.get_input_tensor_by_name(request, "INPUT__0")
                # 將Triton tensor轉換為Torch tensor。
                pytorch_tensor = from_dlpack(input_tensor.to_dlpack())
    
                if pytorch_tensor.shape[2] > 1000 or pytorch_tensor.shape[3] > 1000:
                    responses.append(
                        pb_utils.InferenceResponse(
                            output_tensors=[],
                            error=pb_utils.TritonError(
                                "Image shape should not be larger than 1000"
                            ),
                        )
                    )
                    continue
    
                # 在GPU上進行推理計算。
                prediction = self.model(pytorch_tensor.to(self.device))
    
                # 將Torch output tensor轉換為Triton tensor。
                out_tensor = pb_utils.Tensor.from_dlpack("OUTPUT__0", to_dlpack(prediction))
    
                inference_response = pb_utils.InferenceResponse(output_tensors=[out_tensor])
                responses.append(inference_response)
    
            return responses
    
        def finalize(self):
            """
            模型卸載時調用,可選實現,可用於模型清理工作。
            """
            print("Cleaning up...")
    
    重要
    • 如果使用GPU進行推理計算,此時在模型設定檔config.pbtxt中指定instance_group.kind為GPU的方式無效,需要通過model.to(torch.device("cuda")) 將模型載入到GPU,並在請求計算時調用pytorch_tensor.to(torch.device("cuda"))將模型輸入Tensor分配到GPU。您只需要在部署服務時配置GPU資源,即可使用GPU進行推理計算。

    • 如果使用批處理功能,此時在模型設定檔config.pbtxt中設定max_batch_size參數的方式無效,您需要自行在execute函數中實現請求批處理的邏輯。

    • request與response必須一一對應,每一個request都要返回一個對應的response。

  • 更新設定檔

    設定檔config.pbtxt內容樣本如下:

    name: "resnet50_pt"
    backend: "python"
    max_batch_size: 128
    input [
      {
        name: "INPUT__0"
        data_type: TYPE_FP32
        dims: [ 3, -1, -1 ]
      }
    ]
    output [
      {
        name: "OUTPUT__0"
        data_type: TYPE_FP32
        dims: [ 1000 ]
      }
    ]
    
    parameters: {
        key: "FORCE_CPU_ONLY_INPUT_TENSORS"
        value: {string_value: "no"}
    }

    其中關鍵參數說明如下,其餘配置與之前保持一致即可。

    • backend:需指定為python。

    • parameters:可選配置,當模型推理使用GPU時,可將FORCE_CPU_ONLY_INPUT_TENSORS參數設定為no,來避免推理計算時輸入Tensor在CPU與GPU之間來回拷貝產生不必要的開銷。

2. 部署服務

使用Python backend必須設定共用記憶體。在自訂模型部署 > JSON獨立部署填寫如下JSON配置即可實現自訂模型推理邏輯。

{
  "metadata": {
    "name": "triton_server_test",
    "instance": 1
  },
  "cloud": {
        "computing": {
            "instance_type": "ml.gu7i.c8m30.1-gu30",
            "instances": null
        }
    },
  "containers": [
    {
      "command": "tritonserver --model-repository=/models",
      "image": "eas-registry-vpc.<region>.cr.aliyuncs.com/pai-eas/tritonserver:23.02-py3",
      "port": 8000,
      "prepare": {
        "pythonRequirements": [
          "torch==2.0.1"
        ]
      }
    }
  ],
  "storage": [
    {
      "mount_path": "/models",
      "oss": {
        "path": "oss://oss-test/models/triton_backend/"
      }
    },
    {
      "empty_dir": {
        "medium": "memory",
        // 配置共用記憶體為1 GB。
        "size_limit": 1
      },
      "mount_path": "/dev/shm"
    }
  ]
}

其中:

  • name:需要自訂模型服務名稱。

  • storage.oss.path:更新為您的模型儲存目錄所在的OSS Bucket路徑。

  • containers.image:將<region>替換為當前地區,例如:華東2(上海)為cn-shanghai。

調用服務:發送服務要求

您可以通過用戶端發送請求來使用模型服務,Python程式碼範例如下:

發送HTTP請求

連接埠號碼配置為8000時,服務支援發送HTTP請求。

import numpy as np
import tritonclient.http as httpclient

# url為EAS服務部署後產生的訪問地址。
url = '1859257******.cn-hangzhou.pai-eas.aliyuncs.com/api/predict/triton_server_test'

triton_client = httpclient.InferenceServerClient(url=url)

image = np.ones((1,3,224,224))
image = image.astype(np.float32)

inputs = []
inputs.append(httpclient.InferInput('INPUT__0', image.shape, "FP32"))
inputs[0].set_data_from_numpy(image, binary_data=False)
outputs = []
outputs.append(httpclient.InferRequestedOutput('OUTPUT__0', binary_data=False))  # 擷取 1000 維的向量

# 指定模型名稱、請求Token、輸入輸出。
results = triton_client.infer(
    model_name="<model_name>",
    model_version="<version_num>",
    inputs=inputs,
    outputs=outputs,
    headers={"Authorization": "<test-token>"},
)
output_data0 = results.as_numpy('OUTPUT__0')
print(output_data0.shape)
print(output_data0)

其中關鍵參數配置說明如下:

參數

描述

url

佈建服務訪問地址,服務訪問地址需要省略http://。您可以在模型線上服務(EAS)頁面,單擊服務名稱,然後在服務詳情頁簽中單擊查看調用資訊,查看公網調用地址。

model_name

配置模型目錄名稱,例如resnet50_pt

model_version

配置實際的模型版本號碼,每次只能對一個模型版本發送請求。

headers

<test-token>替換為服務Token,您可以在公網地址調用頁簽查看Token。

發送gRPC請求

連接埠號碼配置為8001,並添加gRPC相關配置後,服務支援發送gRPC請求。

#!/usr/bin/env python
import grpc
from tritonclient.grpc import service_pb2, service_pb2_grpc
import numpy as np

if __name__ == "__main__":
    # 定義服務的訪問地址。
    host = (
        "service_name.115770327099****.cn-beijing.pai-eas.aliyuncs.com:80"
    )
    # 服務Token,實際應用中應使用真實的Token。
    token = "test-token"
    # 模型名稱和版本。
    model_name = "resnet50_pt"
    model_version = "1"
    
    # 建立gRPC中繼資料,用於Token驗證。
    metadata = (("authorization", token),)

    # 建立gRPC通道和存根,用於與伺服器通訊。
    channel = grpc.insecure_channel(host)
    grpc_stub = service_pb2_grpc.GRPCInferenceServiceStub(channel)
    
    # 構建推理請求。
    request = service_pb2.ModelInferRequest()
    request.model_name = model_name
    request.model_version = model_version
    
    # 構造輸入張量,對應模型設定檔中定義的輸入參數。
    input = service_pb2.ModelInferRequest().InferInputTensor()
    input.name = "INPUT__0"
    input.datatype = "FP32"
    input.shape.extend([1, 3, 224, 224])
     # 構造輸出張量,對應模型設定檔中定義的輸出參數。
    output = service_pb2.ModelInferRequest().InferRequestedOutputTensor()
    output.name = "OUTPUT__0"
    
    # 建立輸入請求。
    request.inputs.extend([input])
    request.outputs.extend([output])
    # 構造隨機數組並序列化為位元組序列,作為輸入資料。
    request.raw_input_contents.append(np.random.rand(1, 3, 224, 224).astype(np.float32).tobytes()) #數實值型別
        
    # 發起推理請求,並接收響應。
    response, _ = grpc_stub.ModelInfer.with_call(request, metadata=metadata)
    
    # 提取響應中的輸出張量。
    output_contents = response.raw_output_contents[0]  # 假設只有一個輸出張量。
    output_shape = [1, 1000]  # 假設輸出張量的形狀是[1, 1000]。
    
    # 將輸出位元組轉換為numpy數組。
    output_array = np.frombuffer(output_contents, dtype=np.float32)
    output_array = output_array.reshape(output_shape)
    
    # 列印模型的輸出結果。
    print("Model output:\n", output_array)

其中關鍵參數配置說明如下:

參數

描述

host

需要配置為服務訪問地址,服務訪問地址需要省略http://並在末尾添加:80。您可以在模型線上服務(EAS)頁面,單擊服務名稱,然後在服務詳情頁簽中單擊查看調用資訊,查看公網調用地址。

token

<test-token>替換為服務Token,您可以在公網地址調用頁簽查看Token。

model_name

配置模型目錄名稱,例如resnet50_pt

model_version

配置實際的模型版本號碼,每次只能對一個模型版本發送請求。

常見問題

Q:Triton部署的服務如何線上調試?

線上調試功能需要使用 JSON 格式的請求體。

初始化 HTTPClient 時設定verbose=True,即可列印請求和返回的 JSON 資料。

triton_client = httpclient.InferenceServerClient(url=url, , verbose=True)

結果樣本如下:

POST /api/predict/triton_test/v2/models/resnet50_pt/versions/1/infer, headers {'Authorization': '************1ZDY3OTEzNA=='}
b'{"inputs":[{"name":"INPUT__0","shape":[1,3,32,32],"datatype":"FP32","data":[1.0,1.0,1.0,.....,1.0]}],"outputs":[{"name":"OUTPUT__0","parameters":{"binary_data":false}}]}'

據此補充請求路徑和請求體即可進行線上調試:

image

Q:Triton部署的服務如何一鍵壓測?

請參見Q:Triton部署的服務如何線上調試?擷取請求路徑和請求體格式。

以單個資料壓測為例,操作步驟如下,更多壓測說明請參見通用情境服務壓測

  1. 壓測任務頁簽,單擊添加壓測任務,選擇已部署的Triton服務,並填寫壓測地址。

  2. 資料來源選擇單個資料,並參考如下代碼將JSON請求體轉換為Base64編碼的字串。

    import base64
    
    # 已有的 JSON 請求體字串
    json_str = '{"inputs":[{"name":"INPUT__0","shape":[1,3,32,32],"datatype":"FP32","data":[1.0,1.0,.....,1.0]}]}'
    # 直接編碼
    base64_str = base64.b64encode(json_str.encode('utf-8')).decode('ascii')
    print(base64_str)

    image

相關文檔

  • 如何基於TensorFlow Serving推理服務引擎部署EAS服務,請參見TensorFlow Serving鏡像部署

  • 您也可以開發自訂鏡像,使用自訂鏡像部署EAS服務。具體操作,請參見自訂鏡像