在scf上部署pytorch的炼丹模型

2021-01-28 20:50:39 浏览数 (1)

在scf上部署pytorch的炼丹模型

在scf的使用过程中,我们收到了不少关于如何部署pytorch到scf,为啥numpy版本不对等等问题,这里让我们来一步一步训练模型并将模型部署到scf函数。我们将使用scf提供的CustomRuntime的能力自定义我们的python版本并通过cos打包上传比较大的依赖层。首先让我们来编译以来的python

编译 python

首先准备一个centos 7.2的系统或者docker镜像。然后让我们来安装编译的基础依赖

代码语言:txt复制
yum install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel libffi-devel gcc make

接下来我们在python官网下载想要部署的版本,大家可以选择3.6.8或者以上版本比如3.8系列。这里我们使用3.6.8,是比较常用且稳定的版本,下载解压缩并编译安装

代码语言:txt复制
wget https://www.python.org/ftp/python/3.6.8/Python-3.6.8.tgz
tar zxvf Python-3.6.8.tgz
cd Python-3.6.8
./configure --prefix=/opt/python --enable-shared CFLAGS=-fPIC
make 
make install

这里需要注意的是,scf的层默认会解压到opt,由于我们使用venv会建立到python执行文件的软链接,所以我们将需要部署的python直接安装到opt目录下,可以避免后续出现一些比较麻烦的情况。

创建训练的依赖环境并训练模型

首先可以clone我们写好的示例库,其中train.py是用来训练模型的代码,我们复制了来自pytorch官方的mnist示例并修改了一点保存模型的代码。

接下来让我们创建虚拟环境并安装相关的依赖

代码语言:txt复制
/opt/python/bin/python3 -m venv env
source env/bin/activate
pip install --upgrade pip
pip install torch torchvision   

环境完成安装后我们就可以直接执行训练并保存结果模型

代码语言:txt复制
python train.py --epochs 20 --lr 0.008 --save-model --no-cuda

由于我的设备是没有gpu环境的,所以需要加上--no-cuda

在20论训练后我们得到了一个mnist_cnn.pth

训练结果训练结果

在我们完成模型训练之后,按理论来说就可以直接把env一打包,加上模型直接部署到scf了。但很遗憾的是,pytorch是设计为一个方便的训练和生成模型的框架,但是可能并不适合用在服务端。我们可以看到整个env的大小有接近1.8g。如果这对于部署在scf环境上太大了。

env大小env大小

转换模型为onnx并创建服务依赖环境

正是由于pytorch本身的环境太大了,并不适合直接用做服务,所以我们可以使用onnxruntime这种优化的runtime来达成我们的要求。

首先的一步就是先执行模型转换,将pytorch模型转换为onnx模型,这里可以参考pytorch官方文章

代码语言:txt复制
pip install onnx onnxruntime
python trans.py

执行我们示例库中的trans.py代码,我们可以得到转换后的模型mnist_cnn_onnx.onnx

完成模型生成后,我们将要为后续scf环境构造一个比较简洁且小型的依赖层

代码语言:txt复制
/opt/python/bin/python3 -m venv workenv
source workenv/bin/activate
pip install --upgrade pip
pip install requests opencv-python onnxruntime

可以看见我们这个work层大小只有200m左右,只有之前1.8g的12%的大小。

workenv大小workenv大小

打包并上传层

现在我们的准备工作已经全部完成了,接下来就是把相关依赖们作为层上传

这里我们要准备三个层

1.python解释器层

代码语言:txt复制
cd /opt
zip -r python.zip python

然后我们将打包好的python.zip上传到cos

上传cos上传cos

随后新建层并选中我们之前打包好的文件创建层

上传层上传层

2.onnxruntime层

代码语言:txt复制
zip -r workenv.zip workenv

同样上传到层

  1. so文件层 由于scf默认的lib搜索路径无法搜索到python文件夹里面,所以我们需要把 libpython3.6m.so.1.0打包一份放在opt根目录下cd /opt/python/lib zip pack.zip libpython3.6m.so.1.0

创建scf函数并绑定层

让我们先打包下训练好的模型和相关server文件

代码语言:txt复制
zip code.zip bootstrap mnist_cnn_onnx.onnx server.py

创建函数,由于我们的函数文件和模型并不大,我们直接通过本地上传即可

上传scf函数上传scf函数

在函数的高级配置中将我们之前上传的多个层都绑定上。

绑定层绑定层

创建完成函数后,我们需要在函数管理里配置下

初始化超时时间 为30秒

执行超时时间 为10秒

这样可以避免由于层过大和执行太久导致失败。

执行并测试函数

我们的示例库中提供了 server.py 这个文件用于测试我们的模型。这个文件将会接受一个图片的bash64编码,然后输出识别的值。首先让我们画一张图,这里我用widnwos画图写了一个5,然后把这个5的图片转换为base64

num5.pngnum5.png

接下来让我们创建一个测试模板,在scf的cloud studio右上角点击测试模板创建一个imgtest的测试模板,将以下内容粘贴到imgtest.json文件中

代码语言:txt复制
{
  "value": "imgtest",
  "text": "Hello World事件模板",
  "context": {
    "image": "iVBORw0KGgoAAAANSUhEUgAAAIQAAAB5CAIAAAB3Kh43AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHiSURBVHhe7dXRTsJAGEThvv9L4293NWIkITHKmek5d62VMPspHDfDJAYoMUCJAUoMUGKAEgOUGKDEACUGKDFAiQFKDFBigBIDlBigxAAlBigxQIkBSgxQDRjHUfInFT jRmISA1T2kiaJSQxQwWPKJKbUPX0SU SkSolJDFB5q1olJjFAiXHXvPhn 9Y/Fobxd2e0AKZ9/YqujrEApn390pIw9rHdt3/2dPvXPtp3GcVg/Hhw60BX 9aD9kOw0/9WNsbX1lk/aj/ELuRdhpzmLxMDlBigAkZeRGKi77yOxCQGKDFAiQFKDFBigArAuI5HwE4xWF3EI2bk XFVTpI0TwxQYrDq9sjb9v7Vcbaviwqe1EeSPabMo2FJjUfLjAqPov/xfI8ejCndowpjivZow5hyPToxQj0KMSYxWCV6NGOs9nVCtRgrMVgFeYgBSgxQYoASA5QYoMQAJQYoMUCJAUoMUGKAEgNUOUaQxFSLMQxZElMnRhzDqhAjVGKqwjg/mYIXZbz1J484WmKKwXim/XRs8QOaEgOUGKDEACUGKDFAiQFKDFBigBIDlBigxAAlBigxQIkBSgxQYoASA5QYoMQAJQYoMUCJAUoMUGKAEgOUGKDEACUGKDFAiQFKDEy32xsVVPcjeMF YAAAAABJRU5ErkJggg=="
  }
}

接下里我们部署函数并点击测试,我们可以看到我们的函数正确输出了识别出来的值。

输出结果输出结果

结尾

本次文章我们从无到有的创建了经典的mnist模型,并成功在scf上部署和测试。如果大家有类似的模型需要部署在scf上也可以使用本办法。

附上我们的示例库地址 : https://github.com/TencentCloudMiddleWare/scf-customruntime-pytorch-demo

0 人点赞