亚马逊AWS官方博客

SageMaker 运行自定义环境——以 PaddlePaddle 为例

随着机器学习的场景越来越多样,我们遇到了更多迁自定义运行环境的 SageMaker 场景需求,SageMaker 提供 bring your own container(https://docs.aws.amazon.com/zh_cn/sagemaker/latest/dg/your-algorithms-inference-code.html)的方式提供自定义运行环境,但是对于新手来说,如何构建容器镜像并进行运行测试,最终部署上线都是挑战。本篇以广泛使用的 paddlepaddle 为例探讨如何将自定义容器镜像部署在 SageMaker 上。

本次自定义镜像的用户端调用顺序如下:

本次 blog 代码位于https://github.com/zhaoanbei/sagemaker_paddle_nlp_classification_byoc.git 不包括模型文件。

首先,我们开启一个 g4dn.xlarge 的 SageMaker jupyter instance 模拟本地开发环境。https://docs.aws.amazon.com/zh_cn/sagemaker/latest/dg/gs-setup-working-env.html

在 jupyter instance status 变为 InService 之后,点击左上角 “+”, 选择最下边 Others—Terminal

cd SageMaker

git clone https://github.com/zhaoanbei/sagemaker_paddle_nlp_classification_byoc.git

打开 byoc.ipynb

运行 byoc.ipynb 中第一行:

sudo chmod +777 utils/setup.sh
./utils/setup.sh

确认 instance 有根用户权限以及 nvidia-docker2 可用。

之后在 terminal 中输入:

sudo vim /etc/sysconfig/docker

在配置文件中增加:

OPTIONS="--selinux-enabled -g /home/ec2-user/SageMaker/docker"

更改 docker image 存放路径。这一步是可选项,避免镜像占用根卷。之后运行:

sudo service docker restart

运行 nvidia-smi 检查 cuda driver 版本,根据https://www.paddlepaddle.org.cn/install/quick?docurl=/documentation/docs/zh/install/docker/linux-docker.html确认registry路径。

这里我们的 cuda 版本是11.0,可以使用 registry.baidubce.com/paddlepaddle/paddle:2.4.1-gpu-cuda11.2-cudnn8.2-trt8.0

之后 Terminal 中运行镜像并建立端口映射:nvidia-docker run --name paddle -p 8080:8080 -it -v $PWD:/paddle registry.baidubce.com/paddlepaddle/paddle:2.4.1-gpu-cuda11.2-cudnn8.2-trt8.0 /bin/bash

进入容器交互模式,

mkdir /opt/program/

新开一个 terminal, 将脚本和模型复制到/opt/program/下。

docker cp ./model /opt/program/

返回容器交互模式,运行:

cd /opt/program/
pip3 install -i https://mirror.baidu.com/pypi/simple --upgrade pip
pip3 install -i https://mirror.baidu.com/pypi/simple networkx==2.3 flask gevent gunicorn boto3
pip3 install -i https://mirror.baidu.com/pypi/simple paddlenlp onnx onnxconverter_common onnxruntime-gpu nvgpu
apt-get -y update && apt-get install -y --no-install-recommends wget nginx ca-certificates && rm -rf /var/lib/apt/lists/*
./serve

这时可以看到服务开始运行。回到 byoc.ipynb, 运行:

#locally
url='http://localhost:8080/invocations'
texts = ['sagemaker-kwm-new','债务人: cksdafgsfgsjhkvgdkjsV 破产管理人:kjLFHk;fhs;dhsd;f']
payload = json.dumps(texts)
headers = {'Content-Type': 'application/json'}
r = requests.post(url,data=payload,headers=headers)
r.json()

看到结果输出后,我们回想一下环境部署过程写 Dockerfile:

FROM registry.baidubce.com/paddlepaddle/paddle:2.4.1-gpu-cuda10.2-cudnn7.6-trt7.0 
ENV LANG=en_US.utf8
ENV LANG=C.UTF-8

ENV PYTHONUNBUFFERED=TRUE
ENV PYTHONDONTWRITEBYTECODE=TRUE
ENV PATH="/opt/program:${PATH}"

RUN mkdir /opt/program/
RUN pip3 install -i https://mirror.baidu.com/pypi/simple networkx==2.3 flask gevent gunicorn boto3
RUN pip3 install -i https://mirror.baidu.com/pypi/simple paddlenlp onnx onnxconverter_common onnxruntime-gpu nvgpu

RUN apt-get -y update && apt-get install -y --no-install-recommends \
         wget \
         nginx \
         ca-certificates \
    && rm -rf /var/lib/apt/lists/*

RUN ln -sf /dev/stdout /var/log/nginx/access.log
RUN ln -sf /dev/stderr /var/log/nginx/error.log

COPY model /opt/program
RUN ls /opt/program

WORKDIR /opt/program

为了快速在托管镜像仓库服务 push 镜像,我们提供了build_and_push.sh。只需sh build_and_push.sh <仓库名>,即可一键 build 并 push。之后通过 SageMaker SDK 定义 model 进行 deploy。为了测试,可以定义instance_type='local_gpu'来加速测试流程。在运行model.deploy之后,在 terminal 中输入docker ps, 可以看到有一个 container 在运行中。

再次运行:

#locally
url='http://localhost:8080/invocations'
texts = ['sagemaker-kwm-new','债务人: cksdafgsfgsjhkvgdkjsV 破产管理人:kjLFHk;fhs;dhsd;f']
payload = json.dumps(texts)
headers = {'Content-Type': 'application/json'}
r = requests.post(url,data=payload,headers=headers)
r.json()

确认结果返回正确后,我们把 instance_type 改为 ‘ml.g4dn.xlarge’ 再次运行。返回 SageMaker 控制台,在推理—终端节点下可以看到在部署到终端节点。

在状态成为 InService 之后,运行:

除了 paddlepaddle 外,其他自定义环境也可以通过同样的流程进行整理,测试与部署。

本篇作者

王吴越

就职于金杜律师事务所信息系统管理部,美国圣母大学法学博士、数据科学硕士,主要研究领域为人工智能在法律领域的应用(AI for Law)。

赵安蓓

AWS 解决方案架构师,负责基于 AWS 云平台的解决方案咨询和设计,尤其在大数据分析与建模领域有着丰富的实践经验。

Kelvin Guo

亚马逊云科技资深解决方案架构师。主要技术方向为 MLOps,DevOps,容器。20 年+软件开发,项目管理,敏捷思想落地,工程效能咨询经验。