AI模型部署:Triton Inference Server模型部署框架简介和快速实践

前言

Triton Inference Server是由NVIDIA提供的一个开源推理框架,旨在为AI算法模型提供高效的部署和推理能力,目前已经成为主流的模型部署方案。本文对Triton Inference Server做简要介绍,并且以一个简单的线性模型为例子来实践部署。


内容摘要
  • Triton Inference Server简介
  • Docker构建Triton Inference Server环境
  • Triton Inference Server部署一个线性模型

Triton Inference Server简介

Triton Inference Server是一款开源的推理服务框架,它的核心库基于C++编写的,旨在在生产环境中提供快速且可扩展的AI推理能力,具有以下优势

  • 支持多种深度学习框架:包括PyTorch,Tensorflow,TensorRT,ONNX,OpenVINO等产出的模型文件
  • 至此多种机器学习框架:支持对树模型的部署,包括XGBoost,LightGBM等
  • 支持多种推理协议:支持HTTP,GRPC推理协议
  • 服务端支持模型前后处理:提供后端API,支持将数据的前处理和模型推理的后处理在服务端实现
  • 支持模型并发推理:支持多个模型或者同一模型的多个实例在同一系统上并行执行
  • 支持动态批处理(Dynamic batching):支持将一个或多个推理请求合并成一个批次,以最大化吞吐量
  • 支持多模型的集成流水线:支持将多个模型进行连接组合,将其视作一个整体进行调度管理

Triton Inference Server架构如下图所示,从客户端请求开始,到模型调度处理,模型仓库管理和推理,响应返回,服务状态监控等。

Triton Inference Server架构图


Docker构建Triton Inference Server环境

Triton Inference Server官方推荐使用Docker来构建环境,在Docker镜像仓库下载已经构建好tritonserver镜像
,根据cuda版本下载对应版本的镜像,版本对应关系参照。笔者cuda版本为11.2,对应下载nvcr.io/nvidia/tritonserver:21.02-py3镜像

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

启动容器并进入,它以Python3作为服务端语言,tritonserver是推理服务的启动命令

root@de4977a12c14:/opt/tritonserver# which tritonserver
/opt/tritonserver/bin/tritonserver
root@de4977a12c14:/opt/tritonserver# which python3
/usr/bin/python3

模型部署还需要一些常用的Python包,为了后续测试,我们以该镜像作为源,安装PyTorch,transformers依赖到环境中形成一个新的镜像

# vim Dockerfile 
From nvcr.io/nvidia/tritonserver:21.02-py3
Maintainer xxx
COPY ./torch-1.12.1+cu113-cp38-cp38-linux_x86_64.whl /home
RUN pip install /home/torch-1.12.1+cu113-cp38-cp38-linux_x86_64.whl -i https://pypi.tuna.tsinghua.edu.cn/simple
RUN pip install transformers==4.28.0 -i https://pypi.tuna.tsinghua.edu.cn/simple

构建新镜像triton_server:v1

docker build -t triton_server:v1 .


使用Triton Inference Server部署一个线性模型

本节实践使用Triton Inference Server部署一个线性模型成为一个API服务,包含PyTorch线性模型训练,Triton模型仓库构建,模型推理配置构建,服务端代码构建,服务端启动,客户端服务调用这六个步骤。

(1)PyTorch线性模型训练

我们使用PyTorch的nn.Linear直接构建一个线性层,舍去训练部分,直接使用初始化的权重保存为一个模型文件

import torch
import torch.nn as nn

model = nn.Linear(3, 1)
nn.init.xavier_normal_(model.weight.data)

torch.save(model, "./pytorch_model.bin")


(2)Triton模型仓库构建

Triton Inference Server将模型统一放置在一个目录下进行管理,该目录下每个记录了模型的名称,配置,后端代码,模型文件等,我们创建该目录为model_repository,并且在其下创建一个线性模型目录,命名为linear,该命名是自定义的,但是在后续的配置文件和请求中要保持命名统一。

mkdir model_repository
cd model_repository
mkdir linear


(3)模型推理配置构建

进入linear目录,创建一个文件夹命名为1,代表是linear的第一个版本,将步骤1中训练得到PyTorch模型文件放置在1目录的linear目录下

mkdir 1
cd 1
mkdir linear
cd linear
mv /home/model/pytorch_model.bin ./

回到1目录下创建模型的推理配置文件命名为config.pbtxt,所有版本共用该配置,配置如下

# vim config.pbtxt
name: "linear"
backend: "python"

max_batch_size: 4
input [
  {
    name: "x"
    data_type: TYPE_FP32
    dims: [ 3 ]
  }
]
output [
  {
    name: "y"
    data_type: TYPE_FP32
    dims: [ 1 ]
  }
]

该配置定义了模型的输入和输出,在此做简要的说明

  • name:模型名称,必须和步骤二中的文件名一致
  • max_batch_size:一个批次下的最大大小,4代表一次请求最大推理4条样本
  • input:模型的输入信息,array格式,其中每个输入是一个json格式
  • input-name:一个输入的名称,该名称自定义,但是在服务端代码必须和其保持一致
  • input-data_type:一个输入的数据类型,本例中采用32位浮点
  • input-data_dims:一个输入的维度,代表一条样本的维度,若max_batch_size不为0,它和max_batch_size一起构成了最终的输入大小,本例中最终输入最大是[4, 3]的矩阵,若max_batch_size为0,则dims就是最终的维度

此处输入的x维度为3,和我们训练PyTorch模型时的nn.Linear(3, 1)保持对应。


(4)服务端代码构建

如果使用Python作为后端,Triton以Python脚本的形式来允许模型,这个Python脚本默认命名为model.py,此时服务端代码负责读取模型,并且在其中实现数据的前处理,模型推理,后处理的逻辑。Triton Inference Server提供了服务端代码模板TritonPythonModel,只需要略微修改即可,本例的服务端代码如下

import os

os.environ['PYTORCH_CUDA_ALLOC_CONF'] = 'max_split_size_mb:32'

os.environ['TRANSFORMERS_CACHE'] = os.path.dirname(os.path.abspath(__file__)) + "/work/"
os.environ['HF_MODULES_CACHE'] = os.path.dirname(os.path.abspath(__file__)) + "/work/"

import json

# triton_python_backend_utils is available in every Triton Python model. You
# need to use this module to create inference requests and responses. It also
# contains some utility functions for extracting information from model_config
# and converting Triton input/output types to numpy types.
import triton_python_backend_utils as pb_utils
import sys
import gc
import time
import logging
import torch
import numpy as np

gc.collect()
torch.cuda.empty_cache()

logging.basicConfig(format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s',
                    level=logging.INFO)


class TritonPythonModel:
    """Your Python model must use the same class name. Every Python model
    that is created must have "TritonPythonModel" as the class name.
    """

    def initialize(self, args):
        """`initialize` is called only once when the model is being loaded.
        Implementing `initialize` function is optional. This function allows
        the model to intialize any state associated with this model.

        Parameters
        ----------
        args : dict
          Both keys and values are strings. The dictionary keys and values are:
          * model_config: A JSON string containing the model configuration
          * model_instance_kind: A string containing model instance kind
          * model_instance_device_id: A string containing model instance device ID
          * model_repository: Model repository path
          * model_version: Model version
          * model_name: Model name
        """
        # You must parse model_config. JSON string is not parsed here
        self.model_config = json.loads(args['model_config'])
        output_y_config = pb_utils.get_output_config_by_name(self.model_config, "y")

        # Convert Triton types to numpy types
        self.output_response_dtype = pb_utils.triton_string_to_numpy(output_y_config['data_type'])
        # TODO 读取模型
        model_path = os.path.dirname(os.path.abspath(__file__)) + "/linear/pytorch_model.bin"
        self.model = torch.load(model_path)
        self.model = self.model.eval()
        logging.info("model init success")

    def execute(self, requests):
        """`execute` MUST be implemented in every Python model. `execute`
        function receives a list of pb_utils.InferenceRequest as the only
        argument. This function is called when an inference request is made
        for this model. Depending on the batching configuration (e.g. Dynamic
        Batching) used, `requests` may contain multiple requests. Every
        Python model, must create one pb_utils.InferenceResponse for every
        pb_utils.InferenceRequest in `requests`. If there is an error, you can
        set the error argument when creating a pb_utils.InferenceResponse

        Parameters
        ----------
        requests : list
          A list of pb_utils.InferenceRequest

        Returns
        -------
        list
          A list of pb_utils.InferenceResponse. The length of this list must
          be the same as `requests`

        """
        # output_response_dtype = self.output_response_dtype
        # output_history_dtype = self.output_history_dtype

        # output_dtype = self.output_dtype
        responses = []
        # Every Python backend must iterate over everyone of the requests
        # and create a pb_utils.InferenceResponse for each of them.
        for request in requests:
            # TODO 拿到输入
            x = pb_utils.get_input_tensor_by_name(request, "x").as_numpy()

            in_log_info = {
                "x": x,
            }
            logging.info(in_log_info)
            # TODO 推理结果
            y = self.model(torch.tensor(x).float())

            out_log_info = {
                "y": y
            }
            logging.info(out_log_info)
            y = y.detach().cpu().numpy()

            y_tensor = pb_utils.Tensor("y", y.astype(self.output_response_dtype))

            final_inference_response = pb_utils.InferenceResponse(
                output_tensors=[y_tensor])
            responses.append(final_inference_response)
            # Create InferenceResponse. You can set an error here in case
            # there was a problem with handling this inference request.
            # Below is an example of how you can set errors in inference
            # response:
            #
            # pb_utils.InferenceResponse(
            #    output_tensors=..., TritonError("An error occured"))

        # You should return a list of pb_utils.InferenceResponse. Length
        # of this list must match the length of `requests` list.
        return responses

    def finalize(self):
        """`finalize` is called only once when the model is being unloaded.
        Implementing `finalize` function is OPTIONAL. This function allows
        the model to perform any necessary clean ups before exit.
        """
        print('Cleaning up...')

其中initialize方法实现了模型的初始化,execute方法实现了模型的推理逻辑,并且包转了返回。我们将该Python脚本保存命名为model.py,放置在文件1下。
服务端工作准备完成,此时linear目录结构如下

~/model_repository/linear$ tree
.
├── 1
│   ├── linear
│   │   └── pytorch_model.bin
│   └── model.py
└── config.pbtxt



(5)服务端启动

接下来通过Docker来启动Triton Inference Server镜像,将模型仓库目录model_repository整个挂载到容器内部

docker run --rm \
-p18999:8000 -p18998:8001 -p18997:8002 \
-v /home/model_repository/:/models \
triton_server:v1 \
tritonserver --model-repository=/models

服务分别占用三个端口,将宿主机的端口和其进行映射,其中8000端口用于客户端请求推理结果。tritonserver是容器中的服务启动命令,–model-repository是参数,指定了模型仓库位置。
容器启动日志如下


=============================
== Triton Inference Server ==
=============================

NVIDIA Release 21.02 (build 20174689)

Copyright (c) 2018-2021, NVIDIA CORPORATION.  All rights reserved.

...

I0322 09:41:22.286694 1 server.cc:538] 
+--------------+---------+--------+
| Model        | Version | Status |
+--------------+---------+--------+
| linear       | 1       | READY  |
+--------------+---------+--------+

I0322 09:41:22.286937 1 tritonserver.cc:1642] 
+----------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
| Option                           | Value                                                                                                                                              |
+----------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
| server_id                        | triton                                                                                                                                             |
| server_version                   | 2.7.0                                                                                                                                              |
| server_extensions                | classification sequence model_repository schedule_policy model_configuration system_shared_memory cuda_shared_memory binary_tensor_data statistics |
| model_repository_path[0]         | /models                                                                                                                                            |
| model_control_mode               | MODE_NONE                                                                                                                                          |
| strict_model_config              | 1                                                                                                                                                  |
| pinned_memory_pool_byte_size     | 268435456                                                                                                                                          |
| min_supported_compute_capability | 6.0                                                                                                                                                |
| strict_readiness                 | 1                                                                                                                                                  |
| exit_timeout                     | 30                                                                                                                                                 |
+----------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+

I0322 09:41:22.289210 1 grpc_server.cc:3979] Started GRPCInferenceService at 0.0.0.0:8001
I0322 09:41:22.289923 1 http_server.cc:2717] Started HTTPService at 0.0.0.0:8000
I0322 09:41:22.331775 1 http_server.cc:2736] Started Metrics Service at 0.0.0.0:8002

提示模型linear版本1已经READY,则启动成功。


(6)客户端服务调用

本例中客户端采用HTTP请求的方式进行调用,使用Python的requests即可进行请求,代码如下

import numpy as np
import requests
import json


if __name__ == "__main__":
    model_name = "linear"
    model_version = "1"

    raw_data = {
        "inputs": [
            {
                "name": "x",
                "datatype": "FP32",
                "shape": [3, 3],
                "data": [[2.0, 3.0, 4.0], [1.1, 2.3, 10.3], [2.0, 3.0, 4.0]]
            }
        ],
        "outputs": [
            {
                "name": "y"
            }
        ]
    }

    url = "http://0.0.0.0:18999/v2/models/linear/infer"
    import requests
    import json

    response = requests.post(url=url,
                             data=json.dumps(raw_data, ensure_ascii=True),
                             headers={"Content_Type": "application/json"},
                             timeout=2000)
    res = json.loads(response.text)
    print(res)

在客户端我们创建了三条样本,形成[3, 3]的矩阵输入给Triton服务,请求url指定了要请求的模型,url中的模型名称linear必须和配置和文件夹命名一致。请求结果打印如下

{'model_name': 'linear', 'model_version': '1', 'outputs': [{'name': 'y', 'datatype': 'FP32', 'shape': [3, 1], 'data': [-0.21258652210235596, -1.3153640031814575, -0.21258652210235596]}]}

其中data就是模型推理的输出,维度和训练过程中的nn.Linear(3, 1)一致。同步的在服务端日志会打印出请求的数据和输出的数据

I0322 09:54:17.211954 1 grpc_server.cc:3979] Started GRPCInferenceService at 0.0.0.0:8001
I0322 09:54:17.212302 1 http_server.cc:2717] Started HTTPService at 0.0.0.0:8000
I0322 09:54:17.253904 1 http_server.cc:2736] Started Metrics Service at 0.0.0.0:8002
2024-03-22 09:54:24,068 - model.py[line:98] - INFO: {'x': array([[ 2. ,  3. ,  4. ],
       [ 1.1,  2.3, 10.3],
       [ 2. ,  3. ,  4. ]], dtype=float32)}
2024-03-22 09:54:24,073 - model.py[line:105] - INFO: {'y': tensor([[-0.2126],
        [-1.3154],
        [-0.2126]], grad_fn=<AddmmBackward0>)}

至此,基于Triton Inference Server搭建的一个简单的线性模型的预测推理服务完成。

最后的最后

感谢你们的阅读和喜欢,我收藏了很多技术干货,可以共享给喜欢我文章的朋友们,如果你肯花时间沉下心去学习,它们一定能帮到你。

因为这个行业不同于其他行业,知识体系实在是过于庞大,知识更新也非常快。作为一个普通人,无法全部学完,所以我们在提升技术的时候,首先需要明确一个目标,然后制定好完整的计划,同时找到好的学习方法,这样才能更快的提升自己。

这份完整版的大模型 AI 学习资料已经上传优快云,朋友们如果需要可以微信扫描下方优快云官方认证二维码免费领取【保证100%免费

大模型知识脑图

为了成为更好的 AI大模型 开发者,这里为大家提供了总的路线图。它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
在这里插入图片描述

经典书籍阅读

阅读AI大模型经典书籍可以帮助读者提高技术水平,开拓视野,掌握核心技术,提高解决问题的能力,同时也可以借鉴他人的经验。对于想要深入学习AI大模型开发的读者来说,阅读经典书籍是非常有必要的。

在这里插入图片描述

实战案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

在这里插入图片描述

面试资料

我们学习AI大模型必然是想找到高薪的工作,下面这些面试题都是总结当前最新、最热、最高频的面试题,并且每道题都有详细的答案,面试前刷完这套面试题资料,小小offer,不在话下

在这里插入图片描述

640套AI大模型报告合集

这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。

在这里插入图片描述

这份完整版的大模型 AI 学习资料已经上传优快云,朋友们如果需要可以微信扫描下方优快云官方认证二维码免费领取【保证100%免费

<think>好的,我现在需要帮用户解析Triton Inference Server技术。首先,用户可能对Triton还不了解,所以我要先介绍它的基本概念作用。Triton是NVIDIA推出的一个推理服务器,支持多种框架硬件,这点很重要,应该放在前面。 接下来,用户可能需要了解为什么选择Triton,比如它的跨框架支持,比如TensorFlow、PyTorch这些,还有异构计算的能力,比如同时用GPUCPU。还有它的高并发动态批处理,这些对性能提升有帮助,应该详细说明。 然后,核心架构部分需要分模块讲,比如模型仓库、调度器、后端这些,用户可能关心各个组件如何协同工作。模型生命周期管理也是重点,比如加载、卸载版本控制,这些对实际部署很重要。 高级特性部分,比如并发模型、动态批处理模型集成,这些功能让Triton更强大,需要举例说明应用场景。性能优化方面,硬件加速模型分析工具是亮点,用户可能想知道如何提升效率。 应用场景部分,举一些实际例子,比如推荐系统、自动驾驶,帮助用户理解适用场景。最后,同类产品的对比,比如TensorFlow ServingTorchServe,突出Triton的优势,比如支持多框架动态批处理。 还要注意用户可能的深层需求,比如如何部署、性能调优或者成本问题,虽然用户没直接问,但可能在解析中适当提及。结构要清晰,分点讲,避免技术术语过多,确保用户容易理解。</think>以下是对NVIDIA Triton Inference Server的技术解析,分模块进行说明: 一、核心定位与核心价值 Triton Inference Server是NVIDIA推出的开源推理服务化框架,主要解决AI模型生产部署的三大痛点: 1. 框架碎片化:支持TensorFlow/PyTorch/ONNX/TensorRT等10+框架模型 2. 硬件异构化:可部署在GPU/CPU/ARM/x86等异构计算环境 3. 服务高并发:通过动态批处理等技术实现高吞吐量推理 二、系统架构解析 1. 前端接口层: - HTTP/RESTgRPC协议支持 - 提供metrics接口对接Prometheus - 支持Kafka异步消息流 2. 模型调度层: - 动态批处理引擎(最大批处理大小可配置) - 多模型并行执行(Model Pipelines) - 优先级调度队列 3. 后端运行时: - 框架后端:TF-TRT/PyTorch-TRT等加速方案 - 硬件加速:集成TensorRT/CUDA/cuDNN库 - 自定义后端:C-API支持用户扩展 三、关键技术特性 1. 并发执行模型: - 支持同一模型多个实例并行(Instance Groups) - 支持不同模型间并行推理 - GPU共享模式(CUDA MPS) 2. 模型集成: ```python # 示例模型组合配置 ensemble { step [ { model_name: "preprocessing" model_version: -1 input_map { key: "raw_data" value: "input" } output_map { key: "processed" value: "preprocessed" } }, { model_name: "inference" model_version: -1 input_map { key: "preprocessed" value: "input" } output_map { key: "prediction" value: "final_result" } } ] } ``` 3. 动态批处理: - 时间窗口控制(max_queue_delay_microseconds) - 形状自适应(允许可变尺寸输入) - 跨请求拼接(多个client请求合并batch) 四、性能优化手段 1. 硬件级加速: - GPU Direct技术减少数据拷贝 - FP16/INT8量化支持 - 使用TensorRT进行图优化 2. 模型分析工具: - 内置perf_analyzer性能剖析工具 - 生成延迟-吞吐量曲线 - 提供内存占用分析报告 五、生产实践建议 1. 部署模式选择: - Kubernetes部署:使用NVIDIA GPU Operator - 云原生方案:集成Prometheus+Grafana监控 - 边缘部署:支持Jetson系列嵌入式设备 2. 调优要点: - 根据模型特性调整instance_count - 设置合理的max_batch_size - 启用response_cache减少重复计算 同类产品对比: - 相较于TensorFlow Serving:支持更多框架类型 - 相较于TorchServe:提供更完善的动态批处理 - 相较于OpenVINO:硬件支持范围更广 典型应用场景: 1. 在线推荐系统(毫秒级响应) 2. 自动驾驶感知处理(多模型级联) 3. 工业质检(高吞吐量处理) 4. 医疗影像分析(大模型部署) 该系统的演进方向包括对新兴模型架构(如Diffusion Model)的优化支持,以及与Kubernetes生态的深度集成。最新版本已支持Multi-GPU Multi-Node分布式推理能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值