天天看點

在ModelArts上部署項目

預設已完成modelarts的注冊登入以及秘鑰設定。以圖像分類項目為例(我用的是pytorch,就拿pytorch來說明)

一、編寫訓練代碼(如果有訓練好的模型就可以跳過這一步)

1、使用modelarts提供的notebook開發環境進行訓練

  • 把訓練所需要的資料傳到桶中,如果數量較多建議先壓縮,往桶中傳壓縮包。可以使用OBS Browser+進行批量上傳。
    在ModelArts上部署項目
  • 在開發環境中建立并運作一個notebook環境,存儲配置選擇OBS中資料所在的位置。
  • 建立一個ipynb檔案,選擇适合的引擎。
  • 把訓練需要的資料進行同步。
    在ModelArts上部署項目
  • 在notebook中可以檢視目前的工作路徑以及剛剛同步好的資料壓縮包
    在ModelArts上部署項目
  • 解壓(按照自己的需求進行修改)
    import zipfile
    def unzip_file(zip_src,dst_dir):
        r=zipfile.is_zipfile(zip_src)
        if r:
            fz=zipfile.ZipFile(zip_src,'r')
            for file in fz .namelist():
                fz.extract(file,dst_dir)
            else:
                print('This is not zip')
    current_path = os.getcwd()
    unzip_file(os.path.join(current_path+'/1-11.zip'),os.path.join(current_path+'/train'))
    unzip_file(os.path.join(current_path+'/12-25.zip'),os.path.join(current_path+'/train'))
    unzip_file(os.path.join(current_path+'/26-41.zip'),os.path.join(current_path+'/train'))
               
    用其他的方法也能達到同步資料的效果,可在modelarts的官方文檔中檢視
  • 編寫訓練代碼(Github上找找)
  • 儲存訓練模型到obs
    torch.save(model.state_dict(), 'model.pt')
    
    from modelarts.session import Session
    session=Session()
    session.upload_data(bucket_path="/桶名稱/具體路徑",path="/home/ma-user/work/model.pt")
               

2、使用PyCharm ToolKit插件利用pycharm進行訓練

這部分我翻車了,諸君加油~,我擇日再踩坑。

二、編寫推理代碼和配置檔案

在modelarts上部署上線,需要按照要求把模型、推理代碼、配置檔案放在一起,詳細要求以官方文檔為準。仍舊以pytorch為例,将需要的檔案放在model檔案夾下,如下圖所示:

在ModelArts上部署項目

1、推理代碼(我還是以pytorch說明的,其他情況看官方文檔)

官方給出了使用MNIST資料集的一個推理代碼,我們在它的基礎上進行修改,主要是對輸入的資料進行處理,使他适合模型的輸入,:

from PIL import Image
import log
from model_service.pytorch_model_service import PTServingBaseService
import torch.nn.functional as F

import torch.nn as nn
import torch
import json

import numpy as np

logger = log.getLogger(__name__)

import torchvision.transforms as transforms

# 這一部分也還是根據個人需求進行修改的,直接删了也不影響,你也不一定會用到這個處理方式,看個人。

# 定義模型預處理
infer_transformation = transforms.Compose([
    transforms.Resize((28,28)),
    # 需要處理成pytorch tensor
    transforms.ToTensor()
])


import os


class PTVisionService(PTServingBaseService):

    def __init__(self, model_name, model_path):
        # 調用父類構造方法
        super(PTVisionService, self).__init__(model_name, model_path)

        # 調用自定義函數加載模型
        # 要是把最後面的函數名改了,這裡也要改的。
        self.model = Mnist(model_path)

        # 加載标簽 根據自己的模型進行修改
        self.label = [0,1,2,3,4,5,6,7,8,9]
        
        #我是初學者,不會整什麼幺蛾子,沒用下面的這個,直接給删了。
        # 亦可通過檔案标簽檔案加載
        # model目錄下放置label.json檔案,此處讀取
        dir_path = os.path.dirname(os.path.realpath(self.model_path))
        with open(os.path.join(dir_path, 'label.json')) as f:
            self.label = json.load(f)

    #按照自己訓練模型中的資料處理方式去處理資料
    #我沒啥好辦法,隻能寫一次,拿上去嘗試部署上線一次,然後看日志報錯接着改。
    def _preprocess(self, data):

        preprocessed_data = {}
        for k, v in data.items():
            input_batch = []
            for file_name, file_content in v.items():
                with Image.open(file_content) as image1:
                    # 灰階處理
                    # 很明顯image1就是圖檔,按照訓練代碼中的要求轉換為tensor
                    image1 = image1.convert("L")
                    if torch.cuda.is_available():
                        input_batch.append(infer_transformation(image1).cuda())
                    else:
                        input_batch.append(infer_transformation(image1))
            input_batch_var = torch.autograd.Variable(torch.stack(input_batch, dim=0), volatile=True)
            print(input_batch_var.shape)
            preprocessed_data[k] = input_batch_var

        return preprocessed_data
    #根據模型傳回的資料判斷類别(參照訓練時計算acc和loss的那一部分代碼),把要輸出的結果append到results中
    def _postprocess(self, data):
        results = []
        for k, v in data.items():
            result = torch.argmax(v[0])
            result = {k: self.label[result]}
            results.append(result)
        return results

#參考自己的神經網絡結構,直接從訓練代碼中複制過來替換這一部分,調用的時候注意一下就行
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.hidden1 = nn.Linear(784, 5120, bias=False)
        self.output = nn.Linear(5120, 10, bias=False)

    def forward(self, x):
        x = x.view(x.size()[0], -1)
        x = F.relu((self.hidden1(x)))
        x = F.dropout(x, 0.2)
        x = self.output(x)
        return F.log_softmax(x)


#這部分基本不用改,要是看着函數名字難受可以給改了
def Mnist(model_path, **kwargs):
    # 生成網絡
    model = Net()
    # 加載模型
    if torch.cuda.is_available():
        device = torch.device('cuda')
        model.load_state_dict(torch.load(model_path, map_location="cuda:0"))
    else:
        device = torch.device('cpu')
        model.load_state_dict(torch.load(model_path, map_location=device))
    # CPU或者GPU映射
    model.to(device)
    # 聲明為推理模式
    model.eval()

    return model

           

需要改的地方:

  • def init(self, model_name, model_path)裡标簽和加載模型的函數
  • class Net(nn.Module)直接換成自己的網絡代碼。
  • def _preprocess(self, data):
  • def _postprocess(self, data):

其它不用管

2、配置檔案

遇事不決,複制粘貼。網址在此:https://support.huaweicloud.com/engineers-modelarts/modelarts_23_0092.html#modelarts_23_0092__table7143191919436

根據需求把model_algorithm,dependencies,metrics改改

推理代碼的坑慢慢踩吧,每個人的都不一樣 :)

三、導入模型、部署上線

在ModelArts中找到模型管理選擇導入,元模型來源選擇OBS,選中model的"上一級檔案夾"就行。選擇建立,等它完成之後部署上線。

在ModelArts上部署項目

(其實這一部分在編寫推理代碼的時候會頻繁用到,因為modelarts暫時不支援推理代碼的運作調試,隻有部署上去運作才能發現錯誤)

ps:導入資料、導入模型等各個步驟都不唯一,選擇自己需要的方式

pps:官方文檔寫的很全,多看看,很多問題都能找到答案