1 torch serve介绍

在生产中部署和管理模型通常是机器学习过程中最困难的部分,这项工作包括构建定制的预测 API,对其进行扩展,并加以保护等等。

简化模型部署过程的一种方法是使用模型服务器,即专门设计用于在生产中提供机器学习预测的现成的 Web 应用程序。

模型服务器可轻松加载一个或多个模型,并自动创建由可扩展 Web 服务器提供支持的预测 API。

模型服务器还可以根据预测请求运行代码预处理和后处理。

最后同样重要的一点是,模型服务器还提供对生产至关重要的功能,例如日志记录、监控和安全性等。

广为使用的模型服务器有 TensorFlow Serving 和 Multi Model Server。

torchserve是Pytorch(Facebook)和Amazon于2020年联合推出的PYtorch模型服务库,可使大规模部署经过训练的 PyTorch 更加轻松,不需要编写自定义代码。

Github地址:https://github.com/pytorch/serve

2 使用教程

2.1 安装

TorchServe 由 Java 实现,因此需要最新版本的 OpenJDK 来运行。

apt install openjdk-11-jdk

如果是win环境,需要手动安装,参考这里:

接下来,为 TorchServe 创建一个新 Conda 环境并激活。这样做可使我的 Python 软件包保持整洁。

conda create -n torchserve
source activate torchserve

接下来安装 TorchServe 的依赖项。

pip install sentencepiece
pip install torch-model-archiver
conda install psutil pytorch torchserve torchvision torchtext

如果要使用 GPU 实例,则需要额外的软件包。

conda install cudatoolkit=10.1

现在依赖项已安装完毕,可以克隆 TorchServe 存储库,然后安装 TorchServe。

git clone https://github.com/pytorch/serve.git

cd serve

pip install .

cd model-archiver

pip install .

设置完成,下面开始部署模型!

2.2 封装模型

为了演示方便,我将从 PyTorch 模型园随意下载一个预训练过的模型。在实际应用中,您可以使用自己的模型,文件保存格式为pth后缀。

wget https://download.pytorch.org/models/densenet161-8d451a50.pth

下面,我需要将该模型封装到一个模型存档中。

模型存档包括

  • 存储模型本身的 ZIP 文件 (densenet161-8d451a50.pth)
  • 用于加载状态字典的 Python 脚本(将张量与层匹配)
  • 可能需要的任何附加文件。这里,我添加了一个名为 index_to_name.json 的文件,它将类标识符映射到类名称。

内置的 image_classifier 处理程序将使用该文件,该处理程序负责预测逻辑。

TorchServe 中还有其他内置处理程序(object_detector、text_classifier、image_segmenter),您也可以使用自己的处理程序。

torch-model-archiver --model-name densenet161 --version 1.0 --model-file examples/image_classifier/densenet_161/model.py --serialized-file densenet161-8d451a50.pth --handler image_classifier --extra-files examples/image_classifier/index_to_name.json
torch-model-archiver --model-name densenet161 \  # 封装的模型名称
					 --version 1.0 \  # 定义版本号
					 --model-file examples/image_classifier/densenet_161/model.py \  # 加载状态字典的 Python 脚本(将张量与层匹配)
					 --serialized-file densenet161-8d451a50.pth \   # 模型文件的地址
					 --extra-files examples/image_classifier/index_to_name.json \ # 其他文件
					 --handler image_classifier   # 调用借口

接下来,创建一个目录来存储模型存档,并将刚刚创建的模型存档移动到该目录。

mkdir model_store

mv densenet161.mar model_store/

现在,可以启动 TorchServe,并将其指向模型存储和想要加载的模型。当然,如果有需要,可以加载几个模型。

2.3 部署模型

启动torchserve 如下格式,会出现一个连续的日志打印,不会主动结束,包括一些模型参数和接口

torchserve --start --ncs --model-store model_store --models densenet161=densenet161.mar

复制或者新建一个会话,进一步可以查看部署好的模型

(base) root@hcvmwy:~# curl http://127.0.0.1:8081/models

{ “models”: [
{
“modelName”: “densenet161”,
“modelUrl”: “densenet161.mar”
} ] }

2.4 预测

下载一张图片到本机,也可以是用本地数据

curl -O https://s3.amazonaws.com/model-server/inputs/kitten.jpg

加载模型并进行预测,注意:这里的接口就根据上面日志打印的接口

2022-04-18T12:08:07,184 [INFO ] main org.pytorch.serve.ModelServer - Inference API bind to: http://127.0.0.1:8080
2022-04-18T12:08:07,184 [INFO ] main org.pytorch.serve.ModelServer - Initialize Management server with: EpollServerSocketChannel.
2022-04-18T12:08:07,188 [INFO ] main org.pytorch.serve.ModelServer - Management API bind to: http://127.0.0.1:8081
2022-04-18T12:08:07,188 [INFO ] main org.pytorch.serve.ModelServer - Initialize Metrics server with: EpollServerSocketChannel.
2022-04-18T12:08:07,189 [INFO ] main org.pytorch.serve.ModelServer - Metrics API bind to: http://127.0.0.1:8082

curl -X POST http://127.0.0.1:8081/predictions/densenet161 -T kitten.jpg

得到预测结果:分类的预测概率

{ “tiger_cat”: 0.46933597326278687,
“tabby”: 0.4633874297142029,
“Egyptian_cat”: 0.06456142663955688,
“lynx”: 0.0012828202452510595,
“plastic_bag”: 0.00023323069035541266 }

然后,使用“stop”命令停止 TorchServe 运行。

torchserve --stop

如果使用huggingface transformers模型进行文本方面的计算可以采用:
值得注意的是,-T后面的数据路径一定要正确,不然会出现can’t load local data/file 的错误。

curl -X host  http://localhost:8080/predictions/sentence_Transformer_BERT -T /root/weiyan/serve/examples/Huggingface_Transformers/Seq_classification_artifacts/sample_text.txt

3 配置 TorchServe 提供远程服务

我们为 TorchServe 创建一个配置文件,取名为 config.properties(默认名称)。
此文件定义要加载的模型,并设置远程服务。这里,我将该服务器与所有公有 IP 地址绑定,但如有需要,您可以将其限制为特定地址。我需要确保在安全组中打开端口 8080 和 8081。

model_store=model_store
load_models=densenet161.mar
inference_address=http://0.0.0.0:8080
management_address=http://0.0.0.0:8081

现在可以在相同的目录中启动 TorchServe 了,不再需要传递任何命令行参数。

torchserve  --start --ts-config  config.properties

返回本地机器,现在可以远程调用 TorchServe 并获得相同的结果了。

curl -X POST http://ec2-54-85-61-250.compute-1.amazonaws.com:8080/predictions/densenet161 -T kitten.jpg

大家可能注意到了,我使用的是 HTTP。我猜许多人在生产环境中需要使用 HTTPS,下面我将演示如何进行设置。

配置 TorchServe 使用 HTTPS

TorchServe 可视使用 Java 密钥库或证书。这里我选择后者。

首先,使用 openssl 创建一个证书和一个私有密钥。

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout mykey.key -out mycert.pem

然后,更新配置文件来定义证书和密钥的位置,将 TorchServe 与其默认的安全端口绑定(不要忘记更新安全组)。

model_store=model_store
load_models=densenet161.mar
inference_address=https://0.0.0.0:8443
management_address=https://0.0.0.0:8444
private_key_file=mykey.key
certificate_file=mycert.pem

重新启动 TorchServe,然后就可以使用 HTTPS 调用它了。由于使用了自签名证书,需要将“–insecure”标志传递给 curl。

curl --insecure -X POST https://ec2-54-85-61-250.compute-1.amazonaws.com:8443/predictions/densenet161 -T kitten.jpg

Docker

docker build -t ptserve-sbert:v1 -f dockerfile .