PyTorch实战(29)------使用TorchServe部署PyTorch模型
0. 前言
在PyTorch 深度学习模型部署一节,我们学习了如何使用 Flask 库创建可远程部署、通过网络提供预测服务的模型服务器。在本节中,我们将继续讨论使用 TorchServe 将一个已经训练并测试过的 PyTorch 深度学习模型对象部署到一个独立的环境中,使其能够对新输入数据进行预测或推理。这也称为模型的生产化,即将模型部署到生产系统中。
1. TorchServe 简介
TorchServe 是一个专为 PyTorch 模型提供服务的框架。借助 TorchServe 提供的功能,我们可以同时部署多个模型,保持低预测延迟,而无需编写大量自定义代码。此外,TorchServe 还提供了模型版本控制、性能监控、数据预处理和后处理等功能。这显然使得 TorchServe 成为比 使用 Flask 部署 PyTorch 深度学习模型部署更先进的模型部署替代方案。
本节将继续以手写数字分类模型为例,演示使用 TorchServe 部署 PyTorch 模型的完整流程。通过本节学习,将掌握 TorchServe 的核心使用方法,并能进一步探索其高级功能。
2. 安装 TorchServe
需先安装 Java SDK 作为运行依赖,对于 Linux 操作系统,运行以下命令:
shell
$ sudo apt-get install openjdk-11-jdk
对于 macOS,需要在命令行中运行以下命令:
shell
$ brew tap AdoptOpenJDK/openjdk
$ brew install --cask adoptopenjdk11
接下来,通过运行以下命令来安装 TorchServe:
shell
$ pip install torchserve torch-model-archiver
需要注意的是,我们还需要安装 torch-model-archiver 库,这个归档工具的目的是创建一个包含模型参数和模型架构定义的单一模型文件,并以独立的序列化格式保存为 .mar 文件。
3. 启动和使用 TorchServe 服务器
完成所有必要组件的安装后,我们可以整合现有代码,通过 TorchServe 部署模型。
(1) 首先,将现有的模型架构代码保存为 convnet.py 模型文件:
python
import torch
import torch.nn as nn
import torch.nn.functional as F
class ConvNet(nn.Module):
def __init__(self):
super(ConvNet, self).__init__()
self.cn1 = nn.Conv2d(1, 16, 3, 1)
self.cn2 = nn.Conv2d(16, 32, 3, 1)
self.dp1 = nn.Dropout2d(0.10)
self.dp2 = nn.Dropout2d(0.25)
self.fc1 = nn.Linear(4608, 64) # 4608 is basically 12 X 12 X 32
self.fc2 = nn.Linear(64, 10)
def forward(self, x):
x = self.cn1(x)
x = F.relu(x)
x = self.cn2(x)
x = F.relu(x)
x = F.max_pool2d(x, 2)
x = self.dp1(x)
x = torch.flatten(x, 1)
x = self.fc1(x)
x = F.relu(x)
x = self.dp2(x)
x = self.fc2(x)
op = F.log_softmax(x, dim=1)
return op
该模型文件是 torch-model-archiver 工具生成统一 .mar 格式文件的必要输入之一。
任何模型推理流程都包含三个环节:数据预处理、模型预测和后处理。TorchServe 提供了针对常见机器学习任务的处理器 (handler),可处理以下任务的预处理与后处理环节:图像分类 (image_classifier)、图像分割 (image_segmenter)、目标检测 (object_detector) 和 文本分类 (text_classifier)等。
(2) 针对本节任务,我们将创建一个自定义图像处理器 (convnet_handler.py),继承自默认的 Image_classifier 处理器:
python
from torchvision import transforms
from ts.torch_handler.image_classifier import ImageClassifier
class ConvNetClassifier(ImageClassifier):
image_processing = transforms.Compose([
transforms.Grayscale(),
transforms.Resize((28, 28)),
transforms.ToTensor(),
transforms.Normalize((0.1302,), (0.3069,))
])
def postprocess(self, output):
return output.argmax(1).tolist()
我们选择创建一个自定义处理器,因为与通常处理彩色 (RGB) 图像的图像分类模型不同,我们的模型处理的是特定尺寸 (28x28 像素)的灰度图像。
首先,我们导入默认的 image_classifier 处理器,该处理器已具备图像分类推理流程的基础处理能力。接着通过继承 ImageClassifier 处理器类,我们定义了自定义的 ConvNetClassifier 处理器类。其中包含两个自定义代码块:
- 数据预处理步骤,对数据应用了一系列转换
- 后处理步骤,定义在
postprocess方法中,从所有类别的预测概率列表中提取预测的类别标签
(3) 在创建模型推理流程时,我们已生成 convnet.pth 文件。现在结合 convnet.py 模型文件、convnet_handler.py 处理器文件以及 convnet.pth 模型参数文件,可通过以下命令使用 torch-model-archiver 工具生成 .mar 格式的模型归档文件:
shell
$ torch-model-archiver --model-name convnet --version 1 --model-file convnet.py --serialized-file convnet.pth --handler convnet_handler.py
执行该命令后,当前工作目录将生成名为 convnet.mar 的模型归档文件。我们指定了 model_name 参数用于命名 .mar 文件; version 参数用于模型版本控制(便于同时管理同一模型的多个变体版本)。通过 model-file、serialized-file 和 handler 参数,分别指定了 convnet.py (用于模型架构)、convnet.pth (用于模型权重)和 convnet_handler.py (用于预处理和后处理)文件的位置。
(4) 接下来需在当前工作目录创建新文件夹,并将生成的 convnet.mar 文件移至该目录:
shell
$ mkdir model_store
$ mv convnet.mar model_store/
此操作是为了满足 TorchServe 框架的目录结构要求。
(5) 最后通过以下命令启动 TorchServe 模型服务器:
shell
$ torchserve --start --ncs --model-store model_store --disable-token-auth --models convnet=convnet.mar
服务器启动,终端会显示包含如下信息的日志内容:

可以看到,TorchServe 会自动检测当前设备的硬件资源,并为推理、管理和监控指标分配了三个独立的 URL。要验证模型是否正常服务,可通过以下命令查询管理接口:
shell
$ curl http://localhost:8081/models
输出结果如下所示:

验证了 TorchServe 服务器已成功托管模型。
(6) 接下来通过发起推理请求测试模型服务。由于处理器 (handler) 已内置输入图像处理功能,因此无需编写Python脚本。直接使用示例文件 digit_image.jpg 发起请求:
shell
$ curl -X POST http://127.0.0.1:8080/predictions/convnet -T digit_image.jpg
输出预测结果为 2,得到了正确的预测结果。
(7) 最后,使用完毕后,可通过以下命令停止模型服务器:
shell
$ torchserve --stop
小结
在本节中,我们探讨了 PyTorch 官方推出的专用部署工具------TorchServe,介绍了使用 TorchServe 部署 PyTorch 模型服务并进行预测的全流程,通过本节的学习,能够使用 TorchServe 部署模型服务。
系列链接
PyTorch实战(1)------深度学习(Deep Learning)
PyTorch实战(2)------使用PyTorch构建神经网络
PyTorch实战(3)------PyTorch vs. TensorFlow详解
PyTorch实战(4)------卷积神经网络(Convolutional Neural Network,CNN)
PyTorch实战(5)------深度卷积神经网络
PyTorch实战(6)------模型微调详解
PyTorch实战(7)------循环神经网络
PyTorch实战(8)------图像描述生成
PyTorch实战(9)------从零开始实现Transformer
PyTorch实战(10)------从零开始实现GPT模型
PyTorch实战(11)------随机连接神经网络(RandWireNN)
PyTorch实战(12)------图神经网络(Graph Neural Network,GNN)
PyTorch实战(13)------图卷积网络(Graph Convolutional Network,GCN)
PyTorch实战(14)------图注意力网络(Graph Attention Network,GAT)
PyTorch实战(15)------基于Transformer的文本生成技术
PyTorch实战(16)------基于LSTM实现音乐生成
PyTorch实战(17)------神经风格迁移
PyTorch实战(18)------自编码器(Autoencoder,AE)
PyTorch实战(19)------变分自编码器(Variational Autoencoder,VAE)
PyTorch实战(20)------生成对抗网络(Generative Adversarial Network,GAN)
PyTorch实战(21)------扩散模型(Diffusion Model)
PyTorch实战(22)------MuseGAN详解与实现
PyTorch实战(23)------基于Transformer生成音乐
PyTorch实战(24)------深度强化学习
PyTorch实战(25)------使用PyTorch构建DQN模型
PyTorch实战(26)------PyTorch分布式训练
PyTorch实战(27)------自动混合精度训练
PyTorch实战(28)------PyTorch深度学习模型部署