基于Serverless Devs的深度學習模型部署
配置
函數計算的基本配置
- 下載下傳 Serverless Devs開發者工具 , 并完成 阿裡雲密鑰配置 之後。
- 使用指令
完成項目的基本配置,以阿裡雲為例,選擇帶http觸發器的python3的環境,并輸入第一步獲得的密鑰。s init
- 修改項目的配置檔案
,完成項目名稱以及描述的配置s.yaml
配置NAS和VPC
在深度學習模型的部署中,最難處理的是大體積的機器學習依賴安裝以及深度學習模型參數的儲存問題。通常而言,機器學習的庫大小能接近1G,而深度模型一般也有100M起步。對于函數計算來說,為了減少平台的冷啟動,都會設定代碼包大小限制,阿裡雲的函數計算代碼包必須在100MB以内。是以,我們需要一個雲存儲來解決依賴調用與模型參數加載的問題。在本示例中,我們使用NAS(Network Attached Storage)來存放我們的依賴與模型。NAS,簡單來說說就是連接配接在網絡上,具備資料存儲功能的儲存系統,我們可以通過挂載的方式對NAS進行通路。
- 開通 阿裡雲NAS服務 ,并建立一個檔案系統,根據業務需求我們可以選擇不同的配置。
- 将獲得的NAS位址寫入配置,并将VPC設定為自動。
配置注意事項
- 由于深度學習模型初始化時間較長,建議将初始化時間
調至120s以上initializationTimeout
- 由于深度學習模型記憶體占用較大,建議将最大記憶體
調至521MB以上memorySize
- 更多配置可參考 s工具配置文檔 。
代碼架構
簡單來說,我們可以将基于serverless devs的工程分成三個部分。
.s
檔案夾中存放部配置設定置檔案,以及我們build出來的依賴和代碼;
src
檔案夾存放我們的源代碼和深度學習模型參數;
s.yaml
檔案存放我們對函數計算的配置。
其中,
src
檔案夾的
index.py
檔案一般存放我們的函數入口,這裡給出部分示例代碼。在本項目中,我們需要對使用者上傳的圖檔進行處理。為了友善擷取圖檔,這裡我們使用flask架構。需要注意的是,對于每次執行都會進行的操作如加載模型參數,為了減少模型推理時間,我們将其放置在initialize函數中,這樣這段代碼隻會被執行一次。
# -*- coding: utf-8 -*-
import logging
import numpy as np
from PIL import Image
import io
from skimage.transform import resize
import torch as torch
import torch.nn.functional as F
from flask import Flask, request
from models import VGG
import transforms as transforms
net = VGG('VGG19')
class_names = ['Angry', 'Disgust', 'Fear',
'Happy', 'Sad', 'Surprise', 'Neutral']
logger = logging.getLogger()
app = Flask(__name__)
def initialize(context):
# Get parameters from NAS
ROOT_DIR = r'/mnt/auto/'
# ROOT_DIR = r''
MODEL_PATH = ROOT_DIR + 'vgg_emo_dect.t7'
# Load the VGG network
logger.info('load the model ...')
checkpoint = torch.load(
MODEL_PATH, map_location=torch.device('cpu'))
net.load_state_dict(checkpoint['net'])
net.eval()
@app.route("/", methods=["POST", "GET"])
def predict():
logger.info('processing ...')
# get the image buffer
image = request.files.get('file').read()
# transform it to the np array
image_data = np.array(Image.open(io.BytesIO(image)))
# return the final result
inputs = preprocess(image_data)
score, predict = infer(inputs)
res = dict(zip(class_names, score.tolist()))
logger.info(class_names[int(predict)])
res['pred'] = class_names[int(predict)]
return res
本地調試
由于本地的調試環境與遠端的函數計算環境往往不同,為了相容性,我們最好使用
Docker拉取函數計算遠端鏡像進行調試。
- 下載下傳docker(如果本機沒有docker的話)
-
進行依賴安裝s build --use-docker
-
進行本地調試。s local invoke/start
- 建構簡單測試,對本地接口進行調用,示例測試代碼:
import requests files = {'file':('1.jpg',open('1.jpg','rb'),'image/jpg')} url = 'http://localhost:7218/2016-08-15/proxy/emo-dectioon/get-emotion/' res = requests.post(url=url, files=files) print(res.text)
上傳依賴與模型參數
上傳依賴與模型參數到NAS
- 上傳依賴:
s nas upload -r .s/build/artifacts/emo-dectioon/get-emotion/.s/python nas:///mnt/auto/python
- 上傳模型:
s nas upload src/vgg_emo_dect.t7 nas:///mnt/auto
- 檢視是否上傳成功:
s nas command ls nas://mnt/auto
- 檢視安裝的依賴:
s nas command ls nas:///mnt/auto/python/lib/python3.6/site-packages
上傳成功後,我們可以在代碼中簡單使用路徑擷取對應檔案:)
模型部署
在本地調試時,我們模型參數和依賴的路徑都是本地路徑。現在,我們要将這些路徑轉化為NAS的路徑,并删去本地模型參數和調試生成的依賴(不然因代碼包過大而無法進行部署)。需要注意的是,對于依賴,我們需要修改python的引用路徑,這展現在我們的配置檔案中:
接着,運作指令
s depoly
即可将代碼部署到遠端:
用上述測試代碼調用遠端接口進行測試:
完整代碼連結:
Emotion Dection: The AI model deployment based on Serverless Devs