在前面所有的模型訓練和預(yù)測中肛跌,我們訓練好的模型都是直接通過控制臺或者 Jupyter Notebook 來進行預(yù)測和交互的,在一個系統(tǒng)或者項目中使用這種方式顯然不可能箩溃,那在 Web 應(yīng)用中如何使用我們訓練好的模型呢抒抬?本文將通過以下四個方面對該問題進行講解:
- 微服務(wù)架構(gòu)簡介马篮;
- 模型的持久化與加載方式;
- Flask 和 Bottle 微服務(wù)框架拦焚;
- Tensorflow Serving 模型部署和服務(wù)蜡坊。
微服務(wù)架構(gòu)簡介
微服務(wù)是指開發(fā)一個單個小型的但有業(yè)務(wù)功能的服務(wù),每個服務(wù)都有自己的處理和輕量通訊機制赎败,可以部署在單個或多個服務(wù)器上秕衙。微服務(wù)也指一種松耦合的、有一定的有界上下文的面向服務(wù)架構(gòu)僵刮。也就是說据忘,如果每個服務(wù)都要同時修改,那么它們就不是微服務(wù)搞糕,因為它們緊耦合在一起勇吊;如果你需要掌握一個服務(wù)太多的上下文場景使用條件,那么它就是一個有上下文邊界的服務(wù)窍仰,這個定義來自 DDD 領(lǐng)域驅(qū)動設(shè)計汉规。
相對于單體架構(gòu)和 SOA,它的主要特點是組件化驹吮、松耦合针史、自治、去中心化钥屈,體現(xiàn)在以下幾個方面:
一組小的服務(wù):服務(wù)粒度要小悟民,而每個服務(wù)是針對一個單一職責的業(yè)務(wù)能力的封裝,專注做好一件事情篷就;
獨立部署運行和擴展:每個服務(wù)能夠獨立被部署并運行在一個進程內(nèi)射亏。這種運行和部署方式能夠賦予系統(tǒng)靈活的代碼組織方式和發(fā)布節(jié)奏近忙,使得快速交付和應(yīng)對變化成為可能。
獨立開發(fā)和演化:技術(shù)選型靈活智润,不受遺留系統(tǒng)技術(shù)約束及舍。合適的業(yè)務(wù)問題選擇合適的技術(shù)可以獨立演化。服務(wù)與服務(wù)之間采取與語言無關(guān)的 API 進行集成窟绷。相對單體架構(gòu)锯玛,微服務(wù)架構(gòu)是更面向業(yè)務(wù)創(chuàng)新的一種架構(gòu)模式。
獨立團隊和自治:團隊對服務(wù)的整個生命周期負責兼蜈,工作在獨立的上下文中攘残,自己決策自己治理,而不需要統(tǒng)一的指揮中心为狸。團隊和團隊之間通過松散的社區(qū)部落進行銜接歼郭。
由此,我們可以看到整個微服務(wù)的思想辐棒,與我們現(xiàn)在面對信息爆炸病曾、知識爆炸做事情的思路是相通的:通過解耦我們所做的事情,分而治之以減少不必要的損耗漾根,使得整個復(fù)雜的系統(tǒng)和組織能夠快速地應(yīng)對變化泰涂。
我們?yōu)槭裁床捎梦⒎?wù)呢?
“讓我們的系統(tǒng)盡可能快地響應(yīng)變化”
——Rebecca Parson
下面是一個簡單的微服務(wù)模型架構(gòu)設(shè)計:
模型的持久化與加載方式
開發(fā)過 J2EE 應(yīng)用的人應(yīng)該對持久化的概念很清楚辐怕。通俗得講逼蒙,就是臨時數(shù)據(jù)(比如內(nèi)存中的數(shù)據(jù),是不能永久保存的)持久化為持久數(shù)據(jù)(比如持久化至數(shù)據(jù)庫中秘蛇,能夠長久保存)其做。
那我們訓練好的模型一般都是存儲在內(nèi)存中,這個時候就需要用到持久化方式赁还,在 Python 中妖泄,常用的模型持久化方式有三種,并且都是以文件的方式持久化艘策。
1.JSON(JavaScript Object Notation)格式蹈胡。
JSON 是一種輕量級的數(shù)據(jù)交換格式,易于人們閱讀和編寫朋蔫。使用 JSON 函數(shù)需要導(dǎo)入 JSON 庫:
import json
它擁有兩個格式處理函數(shù):
- json.dumps:將 Python 對象編碼成 JSON 字符串罚渐;
- json.loads:將已編碼的 JSON 字符串解碼為 Python 對象。
下面看一個例子驯妄。
首先我們創(chuàng)建一個 List 對象 data荷并,然后把 data 編碼成 JSON 字符串保存在 data.json 文件中,之后再讀取 data.json 文件中的字符串解碼成 Python 對象青扔,代碼如下:
2. pickle 模塊
pickle 提供了一個簡單的持久化功能源织◆嫖保可以將對象以文件的形式存放在磁盤上。pickle 模塊只能在 Python 中使用谈息,Python 中幾乎所有的數(shù)據(jù)類型(列表缘屹、字典、集合侠仇、類等)都可以用 pickle 來序列化轻姿。pickle 序列化后的數(shù)據(jù),可讀性差逻炊,人一般無法識別互亮。
使用的時候需要引入庫:
import pickle
它有以下兩個方法:
pickle.dump(obj, file[, protocol]):序列化對象,并將結(jié)果數(shù)據(jù)流寫入到文件對象中嗅骄。參數(shù) protocol 是序列化模式胳挎,默認值為0饼疙,表示以文本的形式序列化溺森。protocol 的值還可以是1或2,表示以二進制的形式序列化窑眯。
pickle.load(file):反序列化對象屏积。將文件中的數(shù)據(jù)解析為一個 Python 對象。
我們繼續(xù)延用上面的例子磅甩。實現(xiàn)的不同點在于炊林,這次文件打開時用了 with...as...
語法,使用 pickle 保存結(jié)果卷要,文件保存為 data.pkl渣聚,代碼如下。
3. sklearn 中的 joblib 模塊僧叉。
使用 joblib奕枝,首先需要引入包:
from sklearn.externals import joblib
使用方法如下,基本和 JSON瓶堕、pickle一樣隘道,這里不再詳細講解。第17課中郎笆,進行模型保存時使用的就是這種方式谭梗,可以看代碼,回顧一下宛蚓。
joblib.dump(model, model_path) #模型保存
joblib.load(model_path) #模型加載
Flask 和 Bottle 微服務(wù)框架
通過上面激捏,我們對微服務(wù)和 Python 中三種模型持久化和加載方式有了基本了解。下面我們看看凄吏,Python 中如何把模型發(fā)布成一個微服務(wù)的远舅。
這里給出兩個微服務(wù)框架 Bottle 和 Flask壹置。
Bottle 是一個非常小巧但高效的微型 Python Web 框架,它被設(shè)計為僅僅只有一個文件的 Python 模塊表谊,并且除 Python 標準庫外钞护,它不依賴于任何第三方模塊。
Bottle 本身主要包含以下四個模塊爆办,依靠它們便可快速開發(fā)微 Web 服務(wù):
- 路由(Routing):將請求映射到函數(shù)难咕,可以創(chuàng)建十分優(yōu)雅的 URL;
- 模板(Templates):可以快速構(gòu)建 Python 內(nèi)置模板引擎距辆,同時還支持 Mako余佃、Jinja2、Cheetah 等第三方模板引擎跨算;
- 工具集(Utilites):用于快速讀取 form 數(shù)據(jù)爆土,上傳文件,訪問 Cookies,Headers 或者其它 HTTP 相關(guān)的 metadata;
- 服務(wù)器(Server):內(nèi)置 HTTP 開發(fā)服務(wù)器甜刻,并且支持 paste翁垂、fapws3、 bjoern、Google App Engine、Cherrypy 或者其它任何 WSGI HTTP 服務(wù)器。
Flask 也是一個 Python 編寫的 Web 微框架倔矾,可以讓我們使用 Python 語言快速實現(xiàn)一個網(wǎng)站或 Web 服務(wù)。并使用方式和 Bottle 相似柱锹,F(xiàn)lask 依賴 Jinja2 模板和 Werkzeug WSGI 服務(wù)哪自。Werkzeug 本質(zhì)是 Socket 服務(wù)端,其用于接收 HTTP 請求并對請求進行預(yù)處理禁熏,然后觸發(fā) Flask 框架壤巷,開發(fā)人員基于 Flask 框架提供的功能對請求進行相應(yīng)的處理,并返回給用戶匹层,如果返回給用戶的內(nèi)容比較復(fù)雜時隙笆,需要借助 Jinja2 模板來實現(xiàn)對模板的處理,即將模板和數(shù)據(jù)進行渲染升筏,將渲染后的字符串返回給用戶瀏覽器撑柔。
Bottle 和 Flask 在使用上相似,而且 Flask 的文檔資料更全您访,發(fā)布的服務(wù)更穩(wěn)定铅忿,因此下面重點以 Flask 為例,來說明模型的微服務(wù)發(fā)布過程灵汪。
如果大家想進一步了解這兩個框架檀训,可以參考說明文檔柑潦。
1.安裝。
對 Bottle 和 Flask 進行安裝峻凫,分別執(zhí)行如下命令即可安裝成功:
pip install bottle
pip install Flask
安裝好之后渗鬼,分別進入需要的包就可以寫微服務(wù)程序了。這兩個框架在使用時荧琼,用法譬胎、語法結(jié)構(gòu)都差不多,網(wǎng)上 Flask 的中文資料相對多一些命锄,所以這里用 Flask 來舉例堰乔。
- 第一個最小的 Flask 應(yīng)用。
第一個最小的 Flask 應(yīng)用看起來會是這樣:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run()
把它保存為 hello.py(或是類似的)脐恩,然后用 Python 解釋器來運行:
python hello.py
或者直接在 Jupyter Notebook 里面執(zhí)行镐侯,都沒有問題。服務(wù)啟動將在控制臺打印如下消息:
Running on http://127.0.0.1:5000/
意思就是驶冒,可以通過 localhost 和 5000 端口苟翻,在瀏覽器訪問:
這時我們就得到了服務(wù)在瀏覽器上的返回結(jié)果,于是也成功構(gòu)建了與瀏覽器交互的服務(wù)只怎。
如果要修改服務(wù)對應(yīng)的 IP 地址和端口怎么辦袜瞬?只需要修改這行代碼,即可修改 IP 地址和端口:
app.run(host='192.168.31.19',port=8088)
- Flask 發(fā)布一個預(yù)測模型身堡。
首先,我們這里使用第17課保存的模型“model.pkl”拍鲤。如果不使用瀏覽器贴谎,常規(guī)的控制臺交互,我們這樣就可以實現(xiàn):
from sklearn.externals import joblib
model_path = "D://達人課//中文自然語言處理入門實戰(zhàn)課程//ch18//model.pkl"
model = joblib.load(model_path)
sen =[[['堅決', 'a', 'ad', '1_v'],
['懲治', 'v', 'v', '0_Root'],
['貪污', 'v', 'v', '1_v'],
['賄賂', 'n', 'n', '-1_v'],
['等', 'u', 'udeng', '-1_v'],
['經(jīng)濟', 'n', 'n', '1_v'],
['犯罪', 'v', 'vn', '-2_v']]]
print(model.predict(sen))
如果你現(xiàn)在有個需求季稳,要求你的模型和瀏覽器進行交互擅这,那 Flask 就可以實現(xiàn)。
在第一個最小的 Flask 應(yīng)用基礎(chǔ)上景鼠,我們增加模型預(yù)測接口仲翎,這里注意:啟動之前把 IP 地址修改為自己本機的地址或者服務(wù)器工作站所在的 IP 地址。
完整的代碼如下铛漓,首先在啟動之前先把模型預(yù)加載到內(nèi)存中溯香,然后重新定義 predict 函數(shù),接受一個參數(shù) sen:
from sklearn.externals import joblib
from flask import Flask,request
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World!'
@app.route('/predict/<sen>')
def predict(sen):
result = model.predict(sen)
return str(result)
if __name__ == '__main__':
model_path = "D://ch18//model.pkl"
model = joblib.load(model_path)
app.run(host='192.168.31.19')
啟動 Flask 服務(wù)之后浓恶,在瀏覽器地址中輸入:
http://192.168.31.19:5000/predict/[[['堅決', 'a', 'ad', '1v'], ['懲治', 'v', 'v', '0Root'], ['貪污', 'v', 'v', '1v'], ['賄賂', 'n', 'n', '-1v'], ['等', 'u', 'udeng', '-1v'], ['經(jīng)濟', 'n', 'n', '1v'], ['犯罪', 'v', 'vn', '-2_v']]]
得到預(yù)測結(jié)果玫坛,這樣就完成了微服務(wù)的發(fā)布,并實現(xiàn)了模型和前端瀏覽器的交互包晰。
Tensorflow Serving 模型部署和服務(wù)
TensorFlow Serving 是一個用于機器學習模型 Serving 的高性能開源庫湿镀。它可以將訓練好的機器學習模型部署到線上炕吸,使用 gRPC 作為接口接受外部調(diào)用。更加讓人眼前一亮的是勉痴,它支持模型熱更新與自動模型版本管理赫模。這意味著一旦部署 TensorFlow Serving 后,你再也不需要為線上服務(wù)操心蒸矛,只需要關(guān)心你的線下模型訓練嘴瓤。
同樣,TensorFlow Serving 可以將模型部署在移動端莉钙,如安卓或者 iOS 系統(tǒng)的 App 應(yīng)用上廓脆。關(guān)于 Tensorflow Serving 模型部署和服務(wù),這里不在列舉示例磁玉,直接參考文末的推薦閱讀停忿。
總結(jié)
本節(jié)對微服務(wù)架構(gòu)做了簡單介紹,并介紹了三種機器學習模型持久化和加載的方式蚊伞,接著介紹了 Python 的兩個輕量級微服務(wù)框架 Bottle 和 Flask席赂。隨后,我們通過 Flask 制作了一個簡單的微服務(wù)預(yù)測接口时迫,實現(xiàn)模型的預(yù)測和瀏覽器交互功能颅停,最后簡單介紹了 TensorFlow Servin 模型的部署和服務(wù)功能。
學完上述內(nèi)容掠拳,讀者可輕易實現(xiàn)自己訓練的模型和 Web 應(yīng)用的結(jié)合癞揉,提供微服務(wù)接口,實現(xiàn)模型上線應(yīng)用溺欧。
參考文獻以及推薦閱讀