使用Blade EAS Plugin优化并部署模型

EAS PluginEAS在模型部署前进行统一的前处理机制。基于该机制,Blade推出了Blade EAS Plugin,用于部署前的模型优化。相比直接使用Blade Python Wheel包进行模型优化,Blade EAS Plugin能够自动嵌入到模型的发布流程中,极大简化了集成Blade的工程开销。本文介绍如何通过EAS服务配置文件使用Blade EAS Plugin进行模型优化及部署。

背景信息

目前EASTensorFlowPyTorch Processor已经集成了Blade运行时SDK,因此如果您使用这两种Processor进行模型部署,则可以通过配置EAS服务配置文件的方式进行模型优化。

说明

启用Blade EAS Plugin将在EAS服务之前对您提供的模型提前优化,优化过程根据模型复杂程度可能持续3~10分钟左右,Blade EAS Plugin只在部署EAS服务时执行一次,服务后续缩扩容都直接使用优化后的模型。

目前,Blade EAS Plugin功能只能在通过eascmd客户端创建服务时启用。关于如何配置和使用eascmd客户端,请参见下载并认证客户端命令使用说明

启动Blade EAS PluginEAS服务配置文件中增加plugins字段。关于该字段详情请参见下文的plugins字段。本文也提供了如下示例,以演示如何在PAI-EAS的服务配置文件中启动Blade EAS Plugin:

plugins字段

启动Blade EAS Plugin,您只需要在EAS服务配置文件中增加plugins字段。该字段是一个列表,列表包含一个或多个字典元素。关于EAS服务配置文件的字段详情,请参见创建服务

每个字典元素包含的key如下表所示。

表 1. plugins包含的字段

key

是否必选

描述

command

运行的优化命令,取值请参见下文的ProcessorPlugin镜像的对应表

image

Blade EAS Plugin的镜像地址。Blade EAS Plugin目前支持TensorFlowPyTorch框架,支持CPUGPU(CUDA 10.0)两种设备,对应的Processor名称与Plugin镜像地址如下文的ProcessorPlugin镜像的对应表所示。

resource

执行优化的资源组。您需要将该参数与服务描述文件最外层表示EAS服务运行资源组的resource字段区分开。

如果进行GPU优化,则必须配置该参数。在华东1(杭州)和华东2(上海)两个地域可以使用T4_8CORE资源组执行Blade EAS Plugin。此外,在华东2(上海)还可以使用V100_8COREP4_8CORE资源组。

说明

对于GPU而言,执行Blade EAS Plugin的资源组卡型需要与最终创建EAS服务的资源组的卡型一致。

gpu

优化时使用的GPU数量,通常取值为1。

config

高级优化配置项。目前只有model_info一个子项。

model_info中可以配置多个模型的优化项,目前只支持配置一个模型的优化项。

模型的key为模型的文件名,value支持多个优化项,这些优化项与PAI-Blade Wheel包中的blade.optimize接口参数对齐。支持的优化项如下文的优化项列表所示。

表 2. ProcessorPlugin镜像的对应表

设备类型

key

value

CPU

image(Blade EAS Plugin镜像地址)

registry.cn-shanghai.aliyuncs.com/eas/pai-blade-deploy:cpu_latest

command(插件运行的优化命令)

blade --mode eas_plugin --optimize_for cpu

processor

  • TensorFlow Processor对应的valuetensorflow_cpu_1.15

  • PyTorch Processor对应的valuepytorch_cpu_1.6

GPU

image(Blade EAS Plugin镜像地址)

  • CUDA 10.0:registry.cn-shanghai.aliyuncs.com/eas/pai-blade-deploy:gpu_latest

  • CUDA 11.0:registry.cn-shanghai.aliyuncs.com/eas/pai-blade-deploy:cu110_latest

command(插件运行的优化命令)

blade --mode eas_plugin --optimize_for gpu

processor

  • TensorFlow 1.15(CUDA 10.0)对应的valuetensorflow_gpu_1.15

  • Tensorflow 2.4(CUDA 11.0)对应的valuetensorflow_gpu_2.4

  • PyTorch 1.6(CUDA 10.0)对应的valuepytorch_gpu_1.6

  • PyTorch 1.7(CUDA 11.0)对应的valuepytorch_gpu_1.7

表 3. 优化项列表

优化项

描述

optimization_level

optimization_level分为以下两个等级:

  • o1:默认值,表示无损精度优化,根据实际使用硬件尝试FP32FP16优化,以保证精度损失在一个极小的阈值范围内。

  • o2:表示开启INT8量化。对于支持INT8的硬件可以开启该优化级别。

test_data

测试数据文件,可选。测试数据文件需要包含在model_path指定的路径或压缩包中。建议您提供一组可以正常进行模型推理的真实测试数据(尤其是PyTorch模型优化)。关于测试数据文件的生成方式请参见下文的用于优化的辅助数据

calibration_dataset

量化校准数据文件,可选。量化校准数据文件需要包含在model_path指定的路径或压缩包中。

如果没有指定该字段,则进行Online INT8量化。如果指定了该字段,则进行Offline INT8量化。

通常建议您提供100条以上的校正数据。量化校准数据文件的生成方式请参见下文的用于优化的辅助数据

inputs

字符串列表,可选。该参数表示模型输入节点的名称。如果没有指定该参数,Blade会将没有上游的节点作为输入节点。

PyTorch模型无需指定该参数。

outputs

字符串列表,可选。该参数表示模型输出节点的名称。如果没有指定该参数,Blade会将没有下游的节点作为输出节点。

PyTorch模型无需指定该参数。

input_shapes

输入Tensor可能的形状,用于提升特定场景的优化效果。内层列表元素个数必须等于模型输入Tensor的数量,每个元素是一个字符串,表示某种输入的形状,例如'1*512'

如果有多组可能的形状,则在外层列表中增加元素即可。例如,有两个输入的模型可能有如下形状或若干组可能的形状,取值示例如下:

  • [['1*512', '3*256']]

  • [              
        ['1*512', '3*256'],
        ['5*512', '9*256'],     
        ['10*512', '27*256']      
    ]

input_ranges

每个输入Tensor的元素取值范围。内层列表元素数量必须等于模型输入Tensor的数量,每个元素是一个字符串,表示某种取值范围。

取值范围可以使用方括号加实数或字符表示,例如'[1,2]''[0.3,0.9]''[a,f]'

如果有多组可能的取值范围,则在外层列表中增加元素即可。例如,有两个输入的模型可能有如下取值范围或若干组可能的取值范围,取值示例分别如下:

  • [['[0.1,0.4]', '[a,f]']]

  • [           
        ['[0.1,0.4]', '[a,f]'],
        ['[1.1,1.4]', '[h,l]'],     
        ['[2.1,2.4]', '[n,z]']      
    ]

quantization

该参数是一个JSON字典,目前仅支持唯一的keyweight_adjustment,表示是否尝试调整模型参数以减小量化精度损失。该key值对应的value支持如下取值:

  • "true":开启该选项。

  • "false":关闭该选项。

用于优化的辅助数据

O1优化级别中,提供test_data可以使优化更具指向性。在O2优化级别中,提供calibration_dataset可以指导Blade进行离线INT8优化。这两个参数均需符合Blade的优化辅助数据格式。TensorFlowPyTorch的优化辅助数据格式如下所示:

  • TensorFlow的辅助数据是List of Feed Dict格式。Feed Dictkey是字符串,valuenumpyndarray。辅助数据文件保存为 .npy文件。

  • PyTorch的辅助数据是List of Tensor Tuple格式,保存为.pth文件。

您可以参考如下示例代码生成TensorFlow的辅助数据文件。

import numpy as np

calib_data = list()
for i in range(10):
    feed_dict = {
        'image_placeholder:0': np.ones((8, 3, 224, 224), dtype=np.float32),
        'threshold_placeholder:0': np.float32(0.5),
    }
    calib_data.append(feed_dict)
np.save("calib_data.npy", calib_data)

您可以参考如下示例代码生成PyTorch的辅助数据文件。

import numpy as np
import torch

calib_data = list()
for i in range(10):
    image = torch.ones(8, 3, 224, 224)
    threshold = torch.tensor(0.5)
    feed_tuple = (image, threshold)
    calib_data.append(feed_tuple)
torch.save(calib_data, 'calib_data.pth')

示例1:不使用Blade EAS Plugin

如下是一个简单的、不使用Blade EAS PluginEAS服务配置文件。

{
  "name": "blade_eas_plugin_test",
  "model_path": "oss://<yourBucket>/<pathToYourModel>/",
  "processor": "tensorflow_cpu_1.15",
  "metadata": {
    "instance": 1,
    "memory": 4000
  },
  "resource": "<yourEASResource>"
}

关于EAS服务配置文件的字段详情,请参见创建服务

将以上服务配置文件保存为service.json,使用如下命令即可创建一个部署在CPU上的TensorFlow 1.15服务。

eascmd create service.json

系统输出类似如下结果。

+-------------------+-------------------------------------------------------------------------------------------------+
| Internet Endpoint | http://123456789012****.cn-shanghai.pai-eas.aliyuncs.com/api/predict/blade_eas_plugin_test       |
| Intranet Endpoint | http://123456789012****.vpc.cn-shanghai.pai-eas.aliyuncs.com/api/predict/blade_eas_plugin_test   |
|             Token | owic823JI3kRmMDZlOTQzMTA3ODhmOWIzMmVkZmZmZGQyNmQ1N2M5****                                        |
+-------------------+-------------------------------------------------------------------------------------------------+
[OK] Service is now creating
[OK] Schedule process to node cn-shanghai.i-uf6hv6kfua25q1k8****
[OK] Fetching processor from [http://pai-blade.oss-cn-zhangjiakou.aliyuncs.com/release/3.18.0/py3.6.8_cpu_tf1.15.0_torch1.6.0_abiprecxx11/TENSORFLOW_SDK_CPU.d12d3dc-91024d0-1.15.0-Linux.tar.gz]
[OK] Successfully downloaded all artifacts
[OK] Building image registry-vpc.cn-shanghai.aliyuncs.com/eas/blade_eas_plugin_test_cn-shanghai:v0.0.1-20211117170541
[OK] Pushing image registry-vpc.cn-shanghai.aliyuncs.com/eas/blade_eas_plugin_test_cn-shanghai:v0.0.1-20211117170541
[OK] Successfully pushed image registry-vpc.cn-shanghai.aliyuncs.com/eas/blade_eas_plugin_test_cn-shanghai:v0.0.1-20211117170541
[OK] Successfully created ingress
[OK] Successfully synchronized resources
[OK] Waiting [Total: 1, Pending: 1, Running: 0]
[OK] Running [Total: 1, Pending: 0, Running: 1]
[OK] Service is running

示例2:使用Blade EAS Plugin的简单示例

启动Blade EAS Plugin,您只需要在EAS服务配置文件中增加plugins字段。该字段是一个列表,在如下示例中只有一个Blade的优化插件,所以列表中只有一个字典元素。

{
  "name": "blade_eas_plugin_test",
  "model_path": "oss://<yourBucket>/<pathToYourModel>/",
  "processor": "tensorflow_cpu_1.15",
  "metadata": {
    "instance": 1,
    "memory": 4000
  },
  "plugins": [
      {
          "command": "blade --mode eas_plugin --optimize_for cpu",
          "image": "registry.cn-shanghai.aliyuncs.com/eas/pai-blade-deploy:cpu_latest"
      }
  ],
  "resource": "<yourEASResource>"
}

上述示例中的除 plugins外,其他字段仍然遵循PAI-EAS服务配置文件的格式,详情请参见创建服务plugins列表下的字典元素包含如下两个key:

  • command字段:表示运行的优化命令。其中--mode eas_plugin表示执行EAS Plugin优化模式,--optimize_for cpu表示为CPU推理进行优化。

  • image字段:表示Blade EAS Plugin的镜像地址,所有CPU优化都使用镜像registry.cn-shanghai.aliyuncs.com/eas/pai-blade-deploy:cpu_latest

上述示例即完成了CPU设备上不带测试数据的优化配置。将以上服务配置文件保存为service1.json,通过eascmd客户端工具的create命令即可创建服务,如下所示。

eascmd create service1.json

系统输出类似如下结果。

+-------------------+-------------------------------------------------------------------------------------------------+
| Internet Endpoint | http://123456789012****.cn-shanghai.pai-eas.aliyuncs.com/api/predict/blade_eas_plugin_test       |
| Intranet Endpoint | http://123456789012****.vpc.cn-shanghai.pai-eas.aliyuncs.com/api/predict/blade_eas_plugin_test   |
|             Token | owic823JI3kRmMDZlOTQzMTA3ODhmOWIzMmVkZmZmZGQyNmQ1N2M5****                                       |
+-------------------+-------------------------------------------------------------------------------------------------+
[OK] Service is now creating
[OK] Fetching processor from [http://pai-blade.oss-cn-zhangjiakou.aliyuncs.com/release/3.18.0/py3.6.8_cpu_tf1.15.0_torch1.6.0_abiprecxx11/TENSORFLOW_SDK_CPU.d12d3dc-91024d0-1.15.0-Linux.tar.gz]
[OK] Successfully downloaded all artifacts
[OK] Executing plugin eas-plugin-73d70d54: registry.cn-shanghai.aliyuncs.com/eas/pai-blade-deploy:cpu_latest
[OK] Building image registry-vpc.cn-shanghai.aliyuncs.com/eas/blade_eas_plugin_test_cn-shanghai:v0.0.1-20211117172259
[OK] Pushing image registry-vpc.cn-shanghai.aliyuncs.com/eas/blade_eas_plugin_test_cn-shanghai:v0.0.1-20211117172259
[OK] Successfully pushed image registry-vpc.cn-shanghai.aliyuncs.com/eas/blade_eas_plugin_test_cn-shanghai:v0.0.1-20211117172259
[OK] Successfully created ingress
[OK] Successfully patch resources
[OK] Waiting [Total: 1, Pending: 1, Running: 0]
[OK] Running [Total: 1, Pending: 0, Running: 1]
[OK] Service is running

观察上述日志,您可以发现对比不启动Blade EAS Plugin的配置,多了如下一行日志,表示成功执行了Blade优化。

[OK] Executing plugin eas-plugin-73d70d54: registry.cn-shanghai.aliyuncs.com/eas/pai-blade-deploy:cpu_latest

示例3:使用Blade EAS Plugin的复杂示例

通常情况下,提供更多有关模型的信息有助于提升优化的准确性和加速比。以下示例带有更多优化参数,且以GPU为例,服务描述文件如下所示。

{
    "name": "blade_eas_plugin_test",
    "metadata": {
        "cpu": 4,
        "gpu": 1,
        "instance": 1,
        "memory": 4096,
        "cuda": "10.0"
    },
    "model_path": "oss://<yourBucket>/<pathToYourModel>/",
    "plugins": [
        {
            "command": "blade --mode eas_plugin --optimize_for gpu",
            "image": "registry.cn-shanghai.aliyuncs.com/eas/pai-blade-deploy:gpu_latest",
            "resource": "T4_8CORE",
            "gpu": 1,
            "config": {
                "model_info": {
                    "frozen.pb": {
                        "optimization_level": "o1",
                        "inputs": [
                            "input_ids_a_1"
                        ],
                        "outputs": [
                            "l2_normalize"
                        ],
                        "test_data": "test_len9240_bc1.npy"
                    }
                }
            }
        }
    ],
    "processor": "tensorflow_gpu_1.15",
    "resource": "<yourEASResource>"
}

上述示例中除 plugins外,其他字段仍然遵循EAS服务配置文件的格式,详情请参见创建服务plugins包含的字段详情请参见上文的plugins包含的字段。此外,上述服务配置文件中的frozen.pb是模型的文件名,表示优化fronzon.pb文件中的TensorFlow模型。

将以上服务配置文件保存为service2.json,通过eascmd客户端工具的create命令即可创建服务,如下所示。

eascmd create service2.json

系统输出类似如下结果。

+-------------------+-------------------------------------------------------------------------------------------------+
| Internet Endpoint | http://123456789012****cn-shanghai.pai-eas.aliyuncs.com/api/predict/blade_eas_plugin_test      |
| Intranet Endpoint | http://123456789012****.vpc.cn-shanghai.pai-eas.aliyuncs.com/api/predict/blade_eas_plugin_test  |
|             Token | owic823JI3kRmMDZlOTQzMTA3ODhmOWIzMmVkZmZmZGQyNmQ1N2M5****                                        |
+-------------------+-------------------------------------------------------------------------------------------------+
[OK] Service is now creating
[OK] Schedule process to node cn-shanghai.i-uf642ocg20xinsme****
[OK] Downloading oss file: oss://blade-qa/test_assets/tf_security_textcnn/
[OK] Fetching processor from [http://pai-blade.oss-cn-zhangjiakou.aliyuncs.com/release/3.18.0/py3.6.8_cu100_tf1.15.0_torch1.6.0_abiprecxx11/TENSORFLOW_SDK_GPU.d12d3dc-91024d0-1.15.0-Linux.tar.gz]
[OK] Successfully downloaded all artifacts
[OK] Executing plugin eas-plugin-7126ee68: registry.cn-shanghai.aliyuncs.com/eas/pai-blade-deploy:gpu_latest
[OK] Building image registry-vpc.cn-shanghai.aliyuncs.com/eas/blade_eas_plugin_test_cn-shanghai:v0.0.1-20211117191732
[OK] Pushing image registry-vpc.cn-shanghai.aliyuncs.com/eas/blade_eas_plugin_test_cn-shanghai:v0.0.1-20211117191732
[OK] Successfully pushed image registry-vpc.cn-shanghai.aliyuncs.com/eas/blade_eas_plugin_test_cn-shanghai:v0.0.1-20211117191732
[OK] Successfully created ingress
[OK] Successfully synchronized resources
[OK] Waiting [Total: 1, Pending: 1, Running: 0]
[OK] Running [Total: 1, Pending: 0, Running: 1]
[OK] Service is running

观察上述日志,您可以发现对比不启动Blade EAS Plugin的配置,多了如下一行日志,表示成功执行了Blade优化。

[OK] Executing plugin eas-plugin-7126ee68: registry.cn-shanghai.aliyuncs.com/eas/pai-blade-deploy:gpu_latest