Files
FastDeploy/serving/docs/zh_CN/demo.md
charl-u 02eab973ce [Doc]Add English version of documents in docs/cn and api/vision_results (#931)
* 第一次提交

* 补充一处漏翻译

* deleted:    docs/en/quantize.md

* Update one translation

* Update en version

* Update one translation in code

* Standardize one writing

* Standardize one writing

* Update some en version

* Fix a grammer problem

* Update en version for api/vision result

* Merge branch 'develop' of https://github.com/charl-u/FastDeploy into develop

* Checkout the link in README in vision_results/ to the en documents

* Modify a title

* Add link to serving/docs/

* Finish translation of demo.md
2022-12-22 18:15:01 +08:00

8.4 KiB
Raw Blame History

中文 English

服务化部署示例

我们以最简单的yolov5模型为例讲述如何进行服务化部署详细的代码和操作步骤见yolov5服务化部署,阅读本文之前建议您先阅读以下文档:

基本原理介绍

像常见的深度学习模型一样yolov5完整的运行过程包含前处理+模型预测+后处理三个阶段。

在FastDeployServer中将前处理、模型预测、后处理均视为1个模型服务,每个模型服务的config.pbtxt配置文件中均描述了其输入数据格式、输出数据格式、模型服务的类型即config.pbtxt中的backendplatform字段)、以及其他的一些配置选项。

前处理和后处理一般是运行一段Python代码为了方便后续描述我们称之为Python模型服务其config.pbtxt配置文件中的backend: "python"

模型预测阶段是深度学习模型预测引擎加载用户提供的深度学习模型文件来运行模型预测,我们称之为Runtime模型服务其config.pbtxt配置文件中的backend: "fastdeploy"

根据用户提供的模型类型的不同,可以在optimization字段中设置使用CPU、GPU、TRT、ONNX等配置配置方法参考服务化部署配置说明

除此之外,还需要一个Ensemble模型服务来将前处理、模型预测、后处理3个模型服务组合为1个整体并描述3个模型服务之间的关联关系。例如前处理的输出与模型预测的输入之间的对应关系多个模型服务的调用顺序、串并联关系等Ensemble模型服务的config.pbtxt配置文件中的platform: "ensemble"

在本文的yolov5服务化示例中Ensemble模型服务将前处理、模型预测、后处理3个模型服务串联组合为1个整体整体的结构如下图所示。



对于像OCR这样多个深度学习模型的组合模型,或者流式输入输出的深度学习模型,其Ensemble模型服务的配置会更加复杂。

Python模型服务简介

我们以yolov5前处理为例简单介绍一下编写Python模型服务中的注意事项。

Python模型服务的代码model.py的整体结构框架如下所示。Python代码的核心是1个class TritonPythonModel类中包含3个成员函数initializeexecutefinalize,类名、成员函数名、函数输入变量都不允许更改。在此基础上,用户可以自行编写代码。

import json
import numpy as np
import time
import fastdeploy as fd

# 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

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
        """
        #你的初始化操作代码initialize函数只在模型加载的时候调用1次
        
    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 is requested
        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`
        """
        #你的前处理代码每次预测调用均会调用execute函数
        #FastDeploy提供了部分模型的python前后处理函数无须用户编写
        #调用方式为fd.vision.detection.YOLOv5.preprocess(data)
        #用户也可以自行编写需要的处理逻辑
        
    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.
        """
        #你的析构代码finalize只在模型卸载的时候被调用1次

initialize中一般放置初始化的一些操作该函数只在Python模型服务被加载的时候执行1次。

finalize中一般放置一些析构释放的操作该函数只在Python模型服务被卸载的时候执行1次。

execute中放置用户需要的前后处理的逻辑该函数在每次服务端收到客户端请求的时候被执行1次。

execute函数的输入参数requests为InferenceRequest的集合在没有开启动态合并Batch功能时候requests的长度是1即只有1个InferenceRequest。

execute函数的返回参数responses必须是InferenceResponse的集合通常情况下长度与requests的长度一致即有N个InferenceRequest就必须返回N个InferenceResponse。

用户可以在execute函数中自行编写Python代码进行数据前处理或后处理为了方便用户FastDeploy提供了部分模型的python前后处理函数使用方式如下

import fastdeploy as fd
fd.vision.detection.YOLOv5.preprocess(data)

动态合并Batch功能

动态合并Batch的原理如下图所示。当用户请求request并发量较大但GPU利用率较小时可以通过将不同用户的request组合为1个大的Batch进行模型预测从而提高服务的吞吐性能。



开启动态合并Batch功能非常简单仅需在config.pbtxt结尾处增加dynamic_batching{}字段即可但最大的合并Batch不会超过max_batch_size

注意ensemble_scheduling字段与dynamic_batching字段不可共存,即对于Ensemble模型服务不存在动态合并Batch功能这也可以理解因为Ensemble模型服务本身仅仅是多个模型服务的组合。

多模型实例

多模型实例的原理如下图所示。当前后处理通常不支持Batch成为整个服务的性能瓶颈时能通过增加多个前后处理的Python模型服务实例,来提高整个服务的时延性能。

当然也可以开启多个Runtime模型服务实例来提升GPU利用率。



设置多模式实例的方法很简单,如下所示。

instance_group [
  {
      count: 3
      kind: KIND_CPU
  }
]