当前位置:主页 > 查看内容

如何将PyTorch Lightning模型部署到生产环境?

发布时间:2021-07-18 00:00| 位朋友查看

简介:【51CTO.com快译】纵观机器学习领域,一大趋势是侧生于将软件工程原理运用于机器学习的项目数量激增。比如说,Cortex再现了部署无服务器函数的体验,不过借助推理管道。与之相仿,DVC实现了现代版本控制和CI/CD管道,但面向机器学习。 PyTorch Lightning有类……

【51CTO.com快译】纵观机器学习领域,一大趋势是侧生于将软件工程原理运用于机器学习的项目数量激增。比如说,Cortex再现了部署无服务器函数的体验,不过借助推理管道。与之相仿,DVC实现了现代版本控制和CI/CD管道,但面向机器学习。

PyTorch Lightning有类似的理念,仅运用于训练。框架提供了面向PyTorch的Python包装器,让数据科学家和工程师可以编写干净、易于管理和高性能的训练代码。

我们之所以构建整个部署平台,一方面是由于我们讨厌编写样板代码,因此我们是PyTorch Lightning的忠实拥护者。本着这种精神,我写了这篇指南,介绍将PyTorch Lightning模型部署到生产环境。在此过程中,我们将介绍导出PyTorch Lightning模型、加入到推理管道中的几种不同方法。

部署PyTorch Lightning模型用于推理的各种方法

三种方法可以导出PyTorch Lightning模型来部署:

  • 将模型另存为PyTorch检查点
  • 将模型转换成ONNX
  • 将模型导出到Torchscript

我们可以使用Cortex满足这三种方法。

1.直接包装和部署PyTorch Lightning模块

从最简单的方法开始,不妨部署一个没有任何转换步骤的PyTorch Lightning模型。

PyTorch Lightning Trainer是抽象样板训练代码(想想训练和验证步骤)的一个类,它有内置的save_checkpoint()函数,可将模型另存为.ckpt文件。要将模型另存为检查点,只需将该代码添加到训练脚本中:

图1

现在,开始部署该检查点之前,要特别注意的是,虽然我一直说“PyTorch Lightning模型”,但PyTorch Lightning是PyTorch的包装器——该项目的README实际上写着“PyTorch Lightning只是有组织的PyTorch”。因此,导出的模型是普通的PyTorch模型,可相应部署。

有了保存的检查点,我们可以在Cortex中很轻松地部署模型。如果您不熟悉Cortex,可以在这里(https://docs.cortex.dev/)快速熟悉一下,但是Cortex部署过程的简单概述如下:

  • 我们使用Python为模型编写预测API
  • 我们使用YAML定义API基础架构和行为
  • 我们从CLI使用命令来部署API

我们的预测API将使用Cortex的Python Predictor类来定义init()函数,以初始化我们的API并加载模型,并使用predict()函数在查询时进行预测:

  1. import torch 
  2. import pytorch_lightning as pl 
  3. import MyModel from training_code 
  4. from transformers import ( 
  5.     AutoModelForSequenceClassification, 
  6.     AutoConfig, 
  7.     AutoTokenizer 
  8. class PythonPredictor: 
  9.     def __init__(self, config): 
  10.         self.device = "cpu" 
  11.         self.tokenizer = AutoTokenizer.from_pretrained("albert-base-v2"
  12.         self.model = MyModel.load_from_checkpoint(checkpoint_path="./model.ckpt"
  13.     def predict(self, payload): 
  14.         inputs = self.tokenizer.encode_plus(payload["text"], return_tensors="pt"
  15.         predictions = self.model(**inputs)[0] 
  16.         if (predictions[0] > predictions[1]): 
  17.           return {"class""unacceptable"
  18.         else
  19.           return {"class""acceptable"

很简单。我们使用训练代码改变了一些代码的用途,并增添了一点推理逻辑。要注意的一点是,如果您将模型上传到了S3(推荐),要添加访问模型的一些逻辑。

下一步,我们使用YAML配置基础架构:

  1. name: acceptability-analyzer 
  2.   kind: RealtimeAPI 
  3.   predictor: 
  4.     type: python 
  5.     path: predictor.py 
  6.   compute: 
  7.     cpu: 1 

同样很简单。我们为API取名,告诉Cortex我们的预测AI是哪个,并分配一些CPU资源。

接下来,我们部署它:

请注意:我们还可以部署到由Cortex启动并管理的集群上:

图3

针对所有部署,Cortex都会对我们的API进行容器化处理,并将其公开为Web服务。针对云部署,Cortex配置负载均衡、自动扩展、监测、更新和其他许多基础架构功能。

就是这样!现在我们有一个实际的Web API可根据要求处理模型预测。

2.通过ONNX Runtime导出到ONNX并部署

我们现已部署了一个普通的PyTorch检查点,不妨让情况复杂一些。

PyTorch Lightning最近添加了一个方便的抽象,用于将模型导出到ONNX(以前您可以使用PyTorch内置的转换函数,不过它们需要多一点的样板代码)。要将模型导出到ONNX,只需将该代码添加到训练脚本中:

图4

请注意,输入样本应模仿实际模型输入的形状。

一旦您导出了ONNX模型,可以使用Cortex的ONNX Predictor来部署。代码基本上看起来一样,过程相同。比如说,这是一个ONNX预测API:

  1. import pytorch_lightning as pl 
  2. from transformers import ( 
  3.     AutoModelForSequenceClassification, 
  4.     AutoConfig, 
  5.     AutoTokenizer 
  6. class ONNXPredictor: 
  7.     def __init__(self, onnx_client, config): 
  8.         self.device = "cpu" 
  9.         self.client = onnx_client 
  10.         self.tokenizer = AutoTokenizer.from_pretrained("albert-base-v2"
  11.          
  12.     def predict(self, payload): 
  13.         inputs = self.tokenizer.encode_plus(payload["text"], return_tensors="pt"
  14.         predictions = self.client.predict(**inputs)[0] 
  15.         if (predictions[0] > predictions[1]): 
  16.           return {"class""unacceptable"
  17.         else
  18.           return {"class""acceptable"
  19. view rawpredictor.py hosted with ❤ by GitHub 

基本上一样。唯一的区别是,不是直接初始化模型,我们通过onnx_client来访问它,这是Cortex为部署我们的模型而启动的ONNX Runtime容器。

我们的YAML看起来也很相似:

  1. name: acceptability-analyzer 
  2.   kind: RealtimeAPI 
  3.   predictor: 
  4.     type: onnx 
  5.     path: predictor.py 
  6.     model_path: s3://your-bucket/model.onnx 
  7.   monitoring: 
  8.     model_type: classification 
  9. view rawcortex.yaml hosted with ❤ by GitHub 

我在这里添加了监测标志,只为了表明配置有多容易;有一些ONNX特有的字段,不过除此之外是同样的YAML。

最后,我们使用与之前一样的$ cortex deploy命令来部署,我们的ONNX API处于活跃状态。

3. 使用Torchscript的JIT编译器来初始化

至于最后的部署,我们将把PyTorch Lightning模型导出到Torchscript,并使用PyTorch的 JIT编译器来部署。要导出模型,只需将这部分添加到训练脚本中:

图5

这方面的Python API与普通PyTorch示例一样:

  1. import torch 
  2. from torch import jit 
  3. from transformers import ( 
  4.     AutoModelForSequenceClassification, 
  5.     AutoConfig, 
  6.     AutoTokenizer 
  7. class PythonPredictor: 
  8.     def __init__(self, config): 
  9.         self.device = "cpu" 
  10.         self.tokenizer = AutoTokenizer.from_pretrained("albert-base-v2"
  11.         self.model = jit.load("model.ts"
  12.     def predict(self, payload): 
  13.         inputs = self.tokenizer.encode_plus(payload["text"], return_tensors="pt"
  14.         predictions = self.model(**inputs)[0] 
  15.         if (predictions[0] > predictions[1]): 
  16.           return {"class""unacceptable"
  17.         else
  18.           return {"class""acceptable"
  19. view rawpredictor.py hosted with ❤ by GitHub 

YAML与之前一样,当然CLI命令是一致的。如果我们想要,可以实际上更新之前的PyTorch API以使用新模型,只需把旧的predictor.py脚本换成新脚本,并再次运行$ cortex deploy:

图6

Cortex在此处自动执行滚动更新,新的API创建,然后与旧的API交换,因而防止模型更新间歇的任何停机。

就是这样。现在,您已经有了用于实时推理的完全可操作的预测API,可从Torchscript模型进行预测。

那么,您应使用哪种方法?

显而易见的问题是哪种方法效果最好。事实上,这里没有简单的答案,这取决于您的模型。

针对BERT和GPT-2之类的Transformer模型,ONNX可以提供出色的优化(我们测得CPU上的吞吐量提高了40倍)。至于其他模型,Torchscript的性能可能胜过普通PyTorch,不过也有一些地方要注意,因为并非所有模型都能干净地导出到Torchscript。

幸好,您可以并行测试所有这三种方法,看看哪种方法最适合您的特定API。

原文标题:How to deploy PyTorch Lightning models to production,作者:Caleb Kaiser

【51CTO译稿,合作站点转载请注明原文译者和出处为51CTO.com】


本文转载自网络,原文链接:http://www.51cto.com
本站部分内容转载于网络,版权归原作者所有,转载之目的在于传播更多优秀技术内容,如有侵权请联系QQ/微信:153890879删除,谢谢!

推荐图文

  • 周排行
  • 月排行
  • 总排行

随机推荐