專治“煉丹俠”各種不服:1分鐘就能搞個AI應用 | 最新開源深度學習框架工具套件TinyMS問世

賈浩楠 金磊 發自 凹非寺

量子位 報道 | 公眾號 QbitAI

“煉丹俠”們苦當前深度學習框架久矣。

本來,AI框架的初衷是簡化、加速和最佳化開發流程。但是輪子這麼多,有從學界走出的Caffe、有谷歌力推的TensorFlow、Facebook押注的Pytorch…。真正用起來省心省力的卻不多。

Caffe不支援分散式,不夠靈活,文件不夠用,安裝也比較複雜。

而TensorFlow中的迴圈和分支寫起來的複雜和痛苦,用過的人都有體會…

框架越發展,瓶頸越明顯。

這時,卻有一個“框架工具套件”站出來說:

一分鐘內上手AI應用開發、一小時掌握AI模型與資料集的自由切換。

TinyMS

,就是它,MindSpore社群新開源的深度學習框架開發工具套件,在技術文件中,官方明確地說出了前面的話。

那麼,TinyMS到底是什麼?真能在一分鐘內實現一個AI應用嗎?

TinyMS是什麼?

高階的AI開發方法,往往只需要最簡單的工具套件。

TinyMS,代表了小(Tiny)、靈(Modular)、簡(Simple),當然名字還有另外一個很好理解的角度,那就是“微型”MindSpore。

這是專門為去年同期才開源的AI計算框架MindSpore定製的高階API開發套件,目的是讓新手使用者能夠更加輕鬆地上手深度學習,有效地減少使用者在構建、訓練、驗證和推理一個模型過程中的操作次數。

TinyMS工具包主要用PyThon語言編寫,對於開發者來說,TinyMS“一站式”服務包括了AI應用開發前期必要的資料準備,中期的模型架構、訓練、編譯工具,以及後端AI模型應用服務。

當然,TinyMS仍然貼心地推出了完整線上課程教學,以AI應用中常見的深度神經網路

ResNet50

等等為例,一步步教你如何使用TinyMS實現自己的AI應用。線上課程將以網劇更新的新穎形式,在MindSpore官方B站進行不斷更新,等不及的開發者已經可以開始“追劇”了!

課程的最後還設定了一個挑戰賽,針對小白和高手分別設計了不同難度的比賽,任務是復現TinyMS的模型。每個比賽都會設一個一等獎和三個二等獎,對於參賽人員來說,只要跑通網路就有機會獲得價值三千元的獎品;如果調參的精度是Top1,即可獲得價值一萬元的獎品。感興趣的開發者可聯絡小助手微信:“mindspore0328”報名參賽。

我們接著來看看TinyMS的構成和主要功能模組。

從任務流程上看,TinyMS的基本架構分為五個部分:資料處理、模型構建、訓練、驗證、部署。

其中資料處理模組提供常用資料集下載、解壓、載入等操作,同時,為了讓模型有更好的表現,一般還針對原始資料進行資料預處理(增強)操作。

而在模型構建中,除了網路主體的構建,還包括Loss損失函式、Optimizer最佳化器等定義。

模型構建好後,就進入了訓練的流程,TinyMS在訓練中提供回撥函式的定義。即回撥操作可以在訓練的各個階段執行,可能是在epoch之間,在處理一個batch之後,甚至在滿足某個條件的情況下完全由使用者做主。

這樣一來,使用者可以利用許多創造性的方法來改進訓練和效能,節省計算資源,並獲知供有關神經網路內部發生的事情的結論。

TinyMS中的精度驗證模組,負責模型精度驗證的流程,其中評價指標metrics可由使用者自己定義。

最後,就是模型部署,serving模組可以透過搭建伺服器,來提供AI模型應用服務,為新手提供快速推理的體驗。

到底好不好用?我們一試便知。

一分鐘實現AI應用?試試看!

俗話說“光說不練假把式”,實踐才能檢驗TinyMS的真本事。

Now!上手體驗一下!

老規矩,在安裝之前,先來介紹一下環境需求:

作業系統:Ubuntu 18。04 或 Windows 10。

Python版本:3。7。5。

安裝也是非常的方便,只要

“pip一下”

就好:

pip install tinyms==

0。1

。0

此處溫馨提示:若是下載速度太慢,可以試試下面的映象哦:

mkdir -pv /root/。pip \

&& echo

“[global]”

> /root/。pip/pip。conf \

&& echo

“trusted-host=mirrors。aliyun。com”

>> /root/。pip/pip。conf \

&& echo

“index-url=http://mirrors。aliyun。com/pypi/simple/”

>> /root/。pip/pip。conf

要是想檢驗一下安裝是否成功,可以跑一下這個小demo:

import

tinyms

as

ts

from

tinyms。primitives

import

tensor_add

x = ts。ones([

2

3

])

y = ts。ones([

2

3

])

print(tensor_add(x, y))

若出現如下結果,則證明安裝成功。

[[

2。

2。

2。

2。

2。

2。

]]

接下來,是時候展示TinyMS真正的實力了——

只要1分鐘

,就可以實現圖形分類應用

(LeNet5模型)

先要做工作,是匯入模組

(TinyMS中的主要功能模組)

import

json

import

tinyms。optimizers

as

opt

from

PIL

import

Image

from

tinyms

import

context

from

tinyms。data

import

MnistDataset, download_dataset

from

tinyms。vision

import

mnist_transform, ImageViewer

from

tinyms。model

import

Model, lenet5

from

tinyms。serving

import

start_server, predict, list_servables, shutdown, server_started

from

tinyms。metrics

import

Accuracy

from

tinyms。losses

import

SoftmaxCrossEntropyWithLogits

from

tinyms。callbacks

import

ModelCheckpoint, CheckpointConfig, LossMonitor

接下來是

構建模型

,但聽到這個環節不要打怵,並沒有你印象中的那麼多程式碼,現在只需要短短2行。

因為TinyMS封裝了MindSpore LeNet5模型中的init和construct函式,所以程式碼量大幅減少:

# 構建網路

net = lenet5(class_num=

10

model = Model(net)

構建完模型後,就是

下載資料集

(TinyMS自帶資料集)

# 下載資料集

mnist_path =

‘/root/mnist’

if

not

os。path。exists(mnist_path):

download_dataset(

‘mnist’

‘/root’

print(

‘************Download complete*************’

else

print(

‘************Dataset already exists。**************’

有了模型,有了資料,當然就需要開始“操練”了。

訓練模型

的過程當中,剛才下載的資料集,會被分為訓練集和驗證集。訓練完成後會進行驗證並輸出

Accuracy

指標:

# 建立mnist路徑

ckpt_folder =

‘/etc/tinyms/serving/lenet5’

ckpt_path =

‘/etc/tinyms/serving/lenet5/lenet5。ckpt’

if

not

os。path。exists(ckpt_folder):

!mkdir -p  /etc/tinyms/serving/lenet5

else

print(

‘lenet5 ckpt folder already exists’

# 設定環境引數

device_target =

“CPU”

context。set_context(mode=context。GRAPH_MODE, device_target=device_target)

dataset_sink_mode =

False

# 建立資料集

train_dataset = MnistDataset(os。path。join(mnist_path,

“train”

), shuffle=

True

train_dataset = mnist_transform。apply_ds(train_dataset)

eval_dataset = MnistDataset(os。path。join(mnist_path,

“test”

), shuffle=

True

eval_dataset = mnist_transform。apply_ds(eval_dataset)

# 設定訓練引數

lr =

0。01

momentum =

0。9

epoch_size =

1

batch_size =

32

# 定義loss函式

net_loss = SoftmaxCrossEntropyWithLogits(sparse=

True

, reduction=

‘mean’

# 定義optimizer

net_opt = opt。Momentum(net。trainable_params(), lr, momentum)

net_metrics={

“Accuracy”

: Accuracy()}

model。compile(loss_fn=net_loss, optimizer=net_opt, metrics=net_metrics)

print(

‘************************Start training*************************’

ckpoint_cb = ModelCheckpoint(prefix=

“checkpoint_lenet”

, config=CheckpointConfig(save_checkpoint_steps=

1875

, keep_checkpoint_max=

10

))

model。train(epoch_size, train_dataset, callbacks=[ckpoint_cb, LossMonitor()],dataset_sink_mode=dataset_sink_mode)

print(

‘************************Finished training*************************’

model。save_checkpoint(ckpt_path)

model。load_checkpoint(ckpt_path)

print(

‘************************Start evaluation*************************’

acc = model。eval(eval_dataset, dataset_sink_mode=dataset_sink_mode)

print(

“============== Accuracy:{} ==============”

。format(acc))

為了後續推理過程的需要,在訓練模型後,需要定義一個lenet5 servable json檔案。

該檔案定義了servable名稱,模型名稱,模型格式和分類數量:

servable_json = [{

‘name’

‘lenet5’

‘description’

‘This servable hosts a lenet5 model predicting numbers’

‘model’

: {

“name”

“lenet5”

“format”

“ckpt”

“class_num”

10

}}]

os。chdir(

“/etc/tinyms/serving”

json_data = json。dumps(servable_json, indent=

4

with

open(

‘servable。json’

‘w’

as

json_file:

json_file。write(json_data)

準備工作就緒,現在就要讓“機器”運作起來

(啟動伺服器)

start_server()

然後在命令列終端,用“scp”或者“wget”來獲取一張圖片作為輸入

(一張0~9之間的數字圖片)

使用list_servables函式檢查當前後端的serving模型:

list_servables()

如果輸出的

description

欄位顯示這是一個

lenet5

的模型,那就可以順利進入下一步——傳送推理請求。

# 設定圖片路徑和輸出策略(可以在TOP1和TOP5中選擇)

image_path =

“/root/7。png”

strategy =

“TOP1_CLASS”

# predict(image_path, servable_name, dataset=‘mnist’, strategy=‘TOP1_CLASS’)

# predict方法的四個引數分別是圖片路徑、servable名稱,資料集名稱(預設MNIST)和輸出策略(預設輸出TOP1,可以選擇TOP5)

if

server_started()

is

True

img_viewer = ImageViewer(Image。open(image_path), image_path)

img_viewer。show()

print(predict(image_path,

‘lenet5’

‘mnist’

, strategy))

else

print(

“Server not started”

如果最後你能看到這樣的輸出:

TOP1:

7

, score:

0。99934917688369750977

恭喜你,一次成功的推理,就這麼簡單、順利地完成了!

Keras、fastai還不夠用嗎?

現在有眾多為深度學習框架量身定做的API,那麼,TinyMS存在的獨特意義是什麼?

原因之一是,原生框架的API並不能滿足所有使用者/開發者的需求,所以需要框架擁有更加簡單有效的高階API、低執行開銷、模組化開發以及敏捷部署。

之前有針對TF推出的Keras,它確實好上手,但是“大而全”的Keras層層封裝,不夠靈活快速。

還有基於Pytorch的Fastai,深度學習庫專案較輕便,目錄清晰易理解,可以說是“小而美”。但在預置資料集和推理模組上存在短板。

TinyMS在高階API方面理念與Fastai相近,不同點在於TinyMS提供了常用的MindSpore預置資料集,方便開發者簡化對資料集的呼叫,而且提供了Fastai尚未提供的快速部署推理模組等。

此外,對比Keras,TinyMS在高階API方面會更為簡單抽象,較keras來說複雜度更低,比如提供了只需一行程式碼即可完成資料集的預處理,而且在設計中重點考慮到了Keras尚未提供單獨好用的工具庫,以及尚未提供的快速部署推理模組等。

其二,對於全場景AI計算框架

MindSpore

來說,高階和中階Python API已經實現了Keras的大部分功能,所以即使要做一套API,也不需要類似Keras再額外封裝一層。

因此TinyMS的重點不是基於底層框架的特點或不足進行進一步最佳化,而是著重提升開發者對MindSpore的使用體驗,尤其是面向全場景的開發和部署。

比如,TinyMS主要語言是PyThon,簡單易用,且所有功能都是易於擴充套件的模組化設計,能夠覆蓋多種業務場景。

開源深度學習開發工具包,包括了資料集處理工具、模型架構、訓練、編譯工具,以及後端AI模型應用服務,為新手提供快速推理的體驗。

由此就能看出TinyMS面向的主要使用者群體為深度學習初學者、其他研究領需要使用深度學習的科研人員、以及深度學習相關業務應用開發的企業人員。

直白的說TinyMS就是深度發揮MindSpore優勢,以實際開發需求為導向,極致簡化AI上手的複雜度。

TinyMS是一個新生的開源專案,站在Keras、fastai等巨人的肩膀上,雖然在設計理念上有所創新,但依然需要社群開發者一起持續協作,才能達到更好地服務學術界、產業界和開發者的深度和廣度。

TinyMS開源社群中除了TinyMS專案外,還有如下一些專案和活動:

Specification專案:主要用來協作制定面向模型訓練指令碼的格式規範。由於TinyMS提供了較為高階的API抽象,因此誕生了ModelZoo指令碼規範性和標準化的需求,便於高階封裝的持續迭代;

tinyms-ai。github。io:開源實現的簡單官方網站搭建,基於Github Page;

RustedAI Team:目前只有組織成員可見,RustedAI是TinyMS旨在推動利用Rust語言編寫更多的低執行時開銷的深度學習元件;

社群活動:不定期組織TinyMS模型拉力賽,以及多種多樣的Meetup活動。

開源“開源運營”

作為TinyMS的作者,MindSpore社群運營團隊除了為開發者帶來這一新的開發專案外,還與開放原子開源基金會合作,即將推出0xCommOps這一新穎的開源專案,準備將本來最沒有開放需求的開源社群運營也開源出來。分享MindSpore社群運營團隊這一年創新的全維度運營的理念,同時也號召更多的社群運營愛好者一起分享其所特有的經驗和教訓。

總之,在深度學習框架這件事上,又有一個實力玩家積極入場服務開發者。

試一試TinyMS,歡迎把體驗感想告訴我們~

TinyMS下載地址:

https://tinyms。readthedocs。io/zh_CN/latest/index。html

專治“煉丹俠”各種不服:1分鐘就能搞個AI應用 | 最新開源深度學習框架工具套件TinyMS問世