詳解?PyTorch?Lightning模型部署到生產(chǎn)服務(wù)中
導(dǎo)讀
一篇用PyTorch Lighting提供模型服務(wù)的完全指南。
縱觀機(jī)器學(xué)習(xí)領(lǐng)域,一個(gè)主要趨勢(shì)是專(zhuān)注于將軟件工程原理應(yīng)用于機(jī)器學(xué)習(xí)的項(xiàng)目。例如,Cortex重新創(chuàng)造了部署serverless功能的體驗(yàn),但使用了推理管道。類(lèi)似地,DVC實(shí)現(xiàn)了現(xiàn)代版本控制和CI/CD管道,但是是針對(duì)ML的。\
PyTorch Lightning也有類(lèi)似的理念,只適用于訓(xùn)練。這些框架為PyTorch提供了一個(gè)Python包裝器,讓數(shù)據(jù)科學(xué)家和工程師可以編寫(xiě)干凈、易于管理和性能訓(xùn)練的代碼。
作為構(gòu)建整個(gè)部署平臺(tái)的人,部分原因是我們討厭編寫(xiě)樣板文件,我們是PyTorch Lightning的忠實(shí)粉絲。本著這種精神,我整理了這篇將PyTorch Lightning模型部署到生產(chǎn)中的指南。在此過(guò)程中,我們將了解一些用于導(dǎo)出PyTorch Lightning模型并將其包含在推理管道中的不同選項(xiàng)。
使用PyTorch Lightning模型進(jìn)行推理的各種方法
有三種方法導(dǎo)出用于PyTorch Lightning模型進(jìn)行服務(wù):
- 保存模型為PyTorch檢查點(diǎn)
- 將模型轉(zhuǎn)換為ONNX
- 導(dǎo)出模型到Torchscript
我們可以用Cortex來(lái)對(duì)這三種進(jìn)行服務(wù)。
1. 直接打包部署PyTorch Lightning模型
從最簡(jiǎn)單的方法開(kāi)始,讓我們部署一個(gè)不需要任何轉(zhuǎn)換步驟的PyTorch Lightning模型。
PyTorch Lightning訓(xùn)練器是一個(gè)抽象了樣板訓(xùn)練代碼(想想訓(xùn)練和驗(yàn)證步驟)的類(lèi),它有一個(gè)內(nèi)置的save_checkpoint()函數(shù),可以將模型保存為.ckpt文件。要將你的模型保存為一個(gè)檢查點(diǎn),只需將以下代碼添加到你的訓(xùn)練腳本中:

現(xiàn)在,在我們開(kāi)始服務(wù)這個(gè)檢查點(diǎn)之前,重要的是要注意,當(dāng)我一直說(shuō)“PyTorch Lightning模型”時(shí),PyTorch Lightning是PyTorch的一個(gè)封裝 —— 項(xiàng)目的自述文件字面上說(shuō)“PyTorch Lightning只是有組織的PyTorch”。因此,導(dǎo)出的模型是一個(gè)正常的PyTorch模型,可以相應(yīng)地提供服務(wù)。
有了保存好的檢查點(diǎn),我們就可以輕松地在Cortex中使用該模型。關(guān)于Cortex的部署過(guò)程的簡(jiǎn)單概述如下:
- 我們用Python為我們的模型編寫(xiě)了一個(gè)預(yù)測(cè)API
- 我們?cè)赮AML中定義api的基礎(chǔ)結(jié)構(gòu)和行為
- 我們通過(guò)CLI命令來(lái)部署API
我們的預(yù)測(cè)API將使用Cortex的Python Predictor類(lèi)來(lái)定義一個(gè)init()函數(shù)來(lái)初始化我們的API并加載模型,以及一個(gè)predict()函數(shù)來(lái)在查詢時(shí)提供預(yù)測(cè):
import torch
import pytorch_lightning as pl
import MyModel from training_code
from transformers import (
AutoModelForSequenceClassification,
AutoConfig,
AutoTokenizer
)
class PythonPredictor:
def __init__(self, config):
self.device = "cpu"
self.tokenizer = AutoTokenizer.from_pretrained("albert-base-v2")
self.model = MyModel.load_from_checkpoint(checkpoint_path="./model.ckpt")
def predict(self, payload):
inputs = self.tokenizer.encode_plus(payload["text"], return_tensors="pt")
predictions = self.model(**inputs)[0]
if (predictions[0] > predictions[1]):
return {"class": "unacceptable"}
else:
return {"class": "acceptable"}
很簡(jiǎn)單。我們從訓(xùn)練代碼中重新定義了一些代碼,添加了一些推理邏輯,就是這樣。需要注意的一點(diǎn)是,如果你將模型上傳到S3(推薦),你需要添加一些訪問(wèn)它的邏輯。
接下來(lái),我們?cè)赮AML中配置基礎(chǔ)的設(shè)置:
- name: acceptability-analyzer
kind: RealtimeAPI
predictor:
type: python
path: predictor.py
compute:
cpu: 1
同樣也很簡(jiǎn)單。我們給API一個(gè)名稱(chēng),告訴Cortex我們的預(yù)測(cè)API在哪里,并分配CPU。
接下來(lái),我們部署它:

注意,我們也可以將其部署到一個(gè)集群中,并由Cortex進(jìn)行管理:

在所有的部署中,Cortex將我們的API打包并將其作為web的服務(wù)公開(kāi)。通過(guò)云部署,Cortex可以配置負(fù)載平衡、自動(dòng)擴(kuò)展、監(jiān)控、更新和許多其他基礎(chǔ)設(shè)施功能。
現(xiàn)在,我們有了一個(gè)實(shí)時(shí)的web API,可以通過(guò)請(qǐng)求用模型進(jìn)行預(yù)測(cè)。
2. 導(dǎo)出為ONNX并通過(guò)ONNX Runtime進(jìn)行服務(wù)
現(xiàn)在我們已經(jīng)部署了一個(gè)普通的PyTorch檢查點(diǎn),讓我們把事情復(fù)雜化一點(diǎn)。
PyTorch Lightning最近添加了一個(gè)方便的抽象,用于將模型導(dǎo)出到ONNX(以前,你可以使用PyTorch的內(nèi)置轉(zhuǎn)換函數(shù),盡管它們需要更多的樣板文件)。要將模型導(dǎo)出到ONNX,只需將以下代碼添加到訓(xùn)練腳本中:

注意,輸入樣本應(yīng)該模擬實(shí)際模型輸入的形狀。
一旦你導(dǎo)出了ONNX模型,你就可以使用Cortex的ONNX Predictor來(lái)服務(wù)它。代碼基本上是一樣的,過(guò)程也是一樣的。例如,這是一個(gè)ONNX預(yù)測(cè)API:
import pytorch_lightning as pl
from transformers import (
AutoModelForSequenceClassification,
AutoConfig,
AutoTokenizer
)
class ONNXPredictor:
def __init__(self, onnx_client, config):
self.device = "cpu"
self.client = onnx_client
self.tokenizer = AutoTokenizer.from_pretrained("albert-base-v2")
def predict(self, payload):
inputs = self.tokenizer.encode_plus(payload["text"], return_tensors="pt")
predictions = self.client.predict(**inputs)[0]
if (predictions[0] > predictions[1]):
return {"class": "unacceptable"}
else:
return {"class": "acceptable"}
基本上是一樣的。唯一的區(qū)別是,我們不是直接初始化模型,而是通過(guò)onnx_client訪問(wèn)它,這是一個(gè)ONNX運(yùn)行時(shí)容器,Cortex為我們的模型提供服務(wù)。
我們的YAML看起來(lái)也很相似:
- name: acceptability-analyzer
kind: RealtimeAPI
predictor:
type: onnx
path: predictor.py
model_path: s3://your-bucket/model.onnx
monitoring:
model_type: classification
我在這里添加了一個(gè)監(jiān)視標(biāo)志,只是為了說(shuō)明配置它是多么容易,并且有一些ONNX特定的字段,但除此之外是相同的YAML。
最后,我們使用與之前相同的$ cortex deploy命令進(jìn)行部署,我們的ONNX API也是可用的。
3. 使用 Torchscript’s JIT compiler序列化
對(duì)于最后的部署,我們把PyTorch Lightning模型導(dǎo)出到Torchscript,并使用PyTorch的JIT編譯器提供服務(wù)。要導(dǎo)出模型,只需將此添加到你的訓(xùn)練腳本:

這個(gè)的Python API與普通的PyTorch示例幾乎相同:
import torch
from torch import jit
from transformers import (
AutoModelForSequenceClassification,
AutoConfig,
AutoTokenizer
)
class PythonPredictor:
def __init__(self, config):
self.device = "cpu"
self.tokenizer = AutoTokenizer.from_pretrained("albert-base-v2")
self.model = jit.load("model.ts")
def predict(self, payload):
inputs = self.tokenizer.encode_plus(payload["text"], return_tensors="pt")
predictions = self.model(**inputs)[0]
if (predictions[0] > predictions[1]):
return {"class": "unacceptable"}
else:
return {"class": "acceptable"}
YAML與以前一樣,CLI命令當(dāng)然是一致的。如果我們?cè)敢?,我們可以通過(guò)簡(jiǎn)單地用新的腳本替換舊的predictor.py腳本來(lái)更新之前的PyTorch API,并再次運(yùn)行$ cortex deploy:

在這里,Cortex會(huì)自動(dòng)執(zhí)行滾動(dòng)更新,即啟動(dòng)一個(gè)新的API,然后與舊API進(jìn)行交換,從而防止模型更新之間的停機(jī)時(shí)間。
就是這樣。現(xiàn)在,你有了一個(gè)用于實(shí)時(shí)推斷的完全可操作的預(yù)測(cè)API,從Torchscript模型提供預(yù)測(cè)。
那么,你會(huì)用哪種方法呢?
這里明顯的問(wèn)題是哪種方法性能最好。事實(shí)上,這里沒(méi)有一個(gè)簡(jiǎn)單的答案,因?yàn)樗Q于你的模型。
對(duì)于BERT和GPT-2這樣的Transformer模型,ONNX可以提供令人難以置信的優(yōu)化(我們測(cè)量了cpu吞吐量有40倍提高)。對(duì)于其他模型,Torchscript可能比vanilla PyTorch表現(xiàn)得更好 —— 盡管這也帶來(lái)了一些警告,因?yàn)椴⒉皇撬械哪P投记逦貙?dǎo)出到Torchscript。
幸運(yùn)的是,使用任何選項(xiàng)都可以很容易地進(jìn)行部署,因此可以并行測(cè)試這三種方法,看看哪種最適合你的特定API.
英文原文:towardsdatascience.com/how-to-depl…
以上就是詳解PyTorch Lightning模型部署到生產(chǎn)服務(wù)中的詳細(xì)內(nèi)容,更多關(guān)于PyTorch Lightning 模型部署的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
使用Pytorch實(shí)現(xiàn)two-head(多輸出)模型的操作
這篇文章主要介紹了使用Pytorch實(shí)現(xiàn)two-head(多輸出)模型的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-05-05
Python中pillow知識(shí)點(diǎn)學(xué)習(xí)
本文給大家通過(guò)一篇Python中pillow知識(shí)點(diǎn)學(xué)習(xí)的筆記內(nèi)容讓大家對(duì)pillow有一個(gè)學(xué)習(xí)方向的有一個(gè)認(rèn)識(shí),有興趣的朋友學(xué)習(xí)下。2018-04-04
Django中文件上傳和文件訪問(wèn)微項(xiàng)目的方法
這篇文章主要介紹了Django中文件上傳和文件訪問(wèn)微項(xiàng)目的方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04
解決Alexnet訓(xùn)練模型在每個(gè)epoch中準(zhǔn)確率和loss都會(huì)一升一降問(wèn)題
這篇文章主要介紹了解決Alexnet訓(xùn)練模型在每個(gè)epoch中準(zhǔn)確率和loss都會(huì)一升一降問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-06-06
python scrapy拆解查看Spider類(lèi)爬取優(yōu)設(shè)網(wǎng)極細(xì)講解
本篇博客為你帶來(lái) scrapy.Spider 模塊中的相關(guān)函數(shù)與類(lèi),帶你再一次認(rèn)識(shí) scrapy 的細(xì)節(jié)。本次采集的目標(biāo)站點(diǎn)為:優(yōu)設(shè)網(wǎng),有需要的朋友可以借鑒參考下2021-11-11
python中Array和DataFrame相互轉(zhuǎn)換的實(shí)例講解
在本篇文章里小編給大家整理的是一篇關(guān)于python中Array和DataFrame相互轉(zhuǎn)換的實(shí)例講解內(nèi)容,對(duì)此有需要的朋友們可以學(xué)參考下。2021-02-02

