NLP第18課:模型部署上線的幾種服務(wù)發(fā)布方式

在前面所有的模型訓練和預(yù)測中肛跌,我們訓練好的模型都是直接通過控制臺或者 Jupyter Notebook 來進行預(yù)測和交互的,在一個系統(tǒng)或者項目中使用這種方式顯然不可能箩溃,那在 Web 應(yīng)用中如何使用我們訓練好的模型呢抒抬?本文將通過以下四個方面對該問題進行講解:

  1. 微服務(wù)架構(gòu)簡介马篮;
  2. 模型的持久化與加載方式;
  3. Flask 和 Bottle 微服務(wù)框架拦焚;
  4. 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)在以下幾個方面:

  1. 一組小的服務(wù):服務(wù)粒度要小悟民,而每個服務(wù)是針對一個單一職責的業(yè)務(wù)能力的封裝,專注做好一件事情篷就;

  2. 獨立部署運行和擴展:每個服務(wù)能夠獨立被部署并運行在一個進程內(nèi)射亏。這種運行和部署方式能夠賦予系統(tǒng)靈活的代碼組織方式和發(fā)布節(jié)奏近忙,使得快速交付和應(yīng)對變化成為可能。

  3. 獨立開發(fā)和演化:技術(shù)選型靈活智润,不受遺留系統(tǒng)技術(shù)約束及舍。合適的業(yè)務(wù)問題選擇合適的技術(shù)可以獨立演化。服務(wù)與服務(wù)之間采取與語言無關(guān)的 API 進行集成窟绷。相對單體架構(gòu)锯玛,微服務(wù)架構(gòu)是更面向業(yè)務(wù)創(chuàng)新的一種架構(gòu)模式。

  4. 獨立團隊和自治:團隊對服務(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è)計:

enter image description here

模型的持久化與加載方式

開發(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 對象青扔,代碼如下:

enter image description here

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渣聚,代碼如下。

enter image description here

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ù)框架 BottleFlask壹置。

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 來舉例堰乔。

  1. 第一個最小的 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 端口苟翻,在瀏覽器訪問:

enter image description here

這時我們就得到了服務(wù)在瀏覽器上的返回結(jié)果,于是也成功構(gòu)建了與瀏覽器交互的服務(wù)只怎。

如果要修改服務(wù)對應(yīng)的 IP 地址和端口怎么辦袜瞬?只需要修改這行代碼,即可修改 IP 地址和端口:

app.run(host='192.168.31.19',port=8088)
  1. 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)了模型和前端瀏覽器的交互包晰。

enter image description here

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)用溺欧。

參考文獻以及推薦閱讀

  1. Bottle 文檔
  2. Flask 文檔
  3. 面向機器智能的 TensorFlow 實踐:產(chǎn)品環(huán)境中模型的部署
  4. Tensorflow Serving 服務(wù)部署與訪問(Python + Java)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末喊熟,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子姐刁,更是在濱河造成了極大的恐慌芥牌,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,029評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件聂使,死亡現(xiàn)場離奇詭異壁拉,居然都是意外死亡,警方通過查閱死者的電腦和手機柏靶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,395評論 3 385
  • 文/潘曉璐 我一進店門弃理,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人宿礁,你說我怎么就攤上這事案铺。” “怎么了?”我有些...
    開封第一講書人閱讀 157,570評論 0 348
  • 文/不壞的土叔 我叫張陵控汉,是天一觀的道長笔诵。 經(jīng)常有香客問我,道長姑子,這世上最難降的妖魔是什么乎婿? 我笑而不...
    開封第一講書人閱讀 56,535評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮街佑,結(jié)果婚禮上谢翎,老公的妹妹穿的比我還像新娘。我一直安慰自己沐旨,他們只是感情好森逮,可當我...
    茶點故事閱讀 65,650評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著磁携,像睡著了一般褒侧。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上谊迄,一...
    開封第一講書人閱讀 49,850評論 1 290
  • 那天闷供,我揣著相機與錄音,去河邊找鬼统诺。 笑死歪脏,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的粮呢。 我是一名探鬼主播婿失,決...
    沈念sama閱讀 39,006評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼鬼贱!你這毒婦竟也來了移怯?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,747評論 0 268
  • 序言:老撾萬榮一對情侶失蹤这难,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后葡秒,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體姻乓,經(jīng)...
    沈念sama閱讀 44,207評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,536評論 2 327
  • 正文 我和宋清朗相戀三年眯牧,在試婚紗的時候發(fā)現(xiàn)自己被綠了蹋岩。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,683評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡学少,死狀恐怖剪个,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情版确,我是刑警寧澤扣囊,帶...
    沈念sama閱讀 34,342評論 4 330
  • 正文 年R本政府宣布乎折,位于F島的核電站,受9級特大地震影響侵歇,放射性物質(zhì)發(fā)生泄漏骂澄。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,964評論 3 315
  • 文/蒙蒙 一惕虑、第九天 我趴在偏房一處隱蔽的房頂上張望坟冲。 院中可真熱鬧,春花似錦溃蔫、人聲如沸健提。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,772評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽私痹。三九已至,卻和暖如春痪伦,著一層夾襖步出監(jiān)牢的瞬間侄榴,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,004評論 1 266
  • 我被黑心中介騙來泰國打工网沾, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留癞蚕,地道東北人。 一個月前我還...
    沈念sama閱讀 46,401評論 2 360
  • 正文 我出身青樓辉哥,卻偏偏與公主長得像桦山,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子醋旦,可洞房花燭夜當晚...
    茶點故事閱讀 43,566評論 2 349

推薦閱讀更多精彩內(nèi)容