用Docker容器自带的tensorflow serving部署模型对外服务
相信很多人和我一樣,在試圖安裝tensorflow serving的時(shí)候,翻遍了網(wǎng)上的博客和官網(wǎng)文檔,安裝都是以失敗而告終,我也是一樣,這個(gè)問題折磨了我兩個(gè)星期之久,都快放棄了。幸運(yùn)的是在同事的建議下,我采用了一種迂回的策略安裝成功了。
?
我們采用的策略是:
? ? ? ? pull一個(gè)已經(jīng)安裝好了tensorflow serving的docker鏡像,替換它自帶的一些模型為我們自己的模型。
?
步驟:
1、拉取帶tensorflow serving的docker鏡像,這樣我們服務(wù)器上就有了一個(gè)安裝了ModelServer的docker容器, 這個(gè)容器就可以看做一臺(tái)虛擬機(jī),這個(gè)虛擬機(jī)上已經(jīng)安裝好了tensorflow serving,環(huán)境有了,就可以用它來部署我們的模型了。注意這個(gè)拉取下來后不是直接放在當(dāng)前目錄的,而是docker默認(rèn)存儲(chǔ)的路徑,這個(gè)是個(gè)docker容器,和第2步clone下來的不是同一個(gè)東西
$docker pull tensorflow/serving2、獲取例子模型:(當(dāng)然,也可以直接用上面容器中自帶的例子),當(dāng)然這里是直接拉取了tensorflow serving的源碼,源碼中有一些訓(xùn)練好的例子模型
3、用第一步拉取的docker容器運(yùn)行例子模型
第2步中clone下來的serving源碼中有這樣一個(gè)訓(xùn)練好的例子模型,路徑為:
/root/software/serving/tensorflow_serving/servables/tensorflow/testdata/saved_model_half_plus_two_cpu現(xiàn)在我們就要用第1步拉下來的docker容器來運(yùn)行部署這個(gè)例子模型
參數(shù)說明:
這步注意,如果執(zhí)行報(bào)錯(cuò)無法識(shí)別type=bind, 那應(yīng)該是source的路徑有問題
4、調(diào)用這個(gè)服務(wù),這里用的http接口
得到的結(jié)果如下:
{ "predictions": [2.5, 3.0, 4.5] }這就表明服務(wù)已經(jīng)部署成功了,當(dāng)然你也可以用requests來模型上述http請(qǐng)求
5、查看啟動(dòng)的這個(gè)模型的目錄的結(jié)構(gòu)
我們可以看到啟動(dòng)服務(wù)的命令有一個(gè)參數(shù):
source=/root/software/serving/tensorflow_serving/servables/tensorflow/testdata/saved_model_half_plus_two_cpu這實(shí)際就是模型的位置, 我們進(jìn)入到這個(gè)目錄下(這個(gè)目錄基于自己pull時(shí)所在的目錄),可以看到里面是一個(gè)名為00000123的目錄,這實(shí)際是模型的版本,再進(jìn)入到這個(gè)目錄下可以看到一個(gè)如下兩個(gè)文件:
saved_model.pb, variablesvariable目錄下有如下兩個(gè)文件:
variables.data-00000-of-00001, variables.index6、用自己的模型替換上述half_plus_two模型
我在和saved_model_half_plus_two_cpu模型同級(jí)的目錄下創(chuàng)建了一個(gè)文件夾,名為textcnnrnn, 這是我模型的名稱,然后
我一開始是直接用的我之前訓(xùn)練好的模型放到了variables目錄下,我訓(xùn)練好的模型包含如下幾個(gè)文件:
best_validation.data-00000-of-00001 best_validation.index best_validation.meta checkpoint相信大家都看出來了,這個(gè)是用這種方式保存的:
于是我激動(dòng)的去重新啟動(dòng)我的模型,當(dāng)然這里要修改模型的地址,我也把我的模型的名字改了下:
docker run -p 8501:8501 --mount source=/root/software/serving/tensorflow_serving/servables/tensorflow/testdata/textcnnrnn,type=bind,target=/models/find_lemma_category -e MODEL_NAME=find_lemma_category -t tensorflow/serving &可是這個(gè)時(shí)候報(bào)錯(cuò)了,做法不對(duì)。下面是正確的做法。
其實(shí)仔細(xì)比較我的模型的幾個(gè)文件和half_plus_two模型的下的文件的結(jié)構(gòu)根本不一樣,怎么辦呢? 其實(shí)應(yīng)該對(duì)模型的格式進(jìn)行轉(zhuǎn)換。 代碼如下:
執(zhí)行后,會(huì)在當(dāng)前目錄下生成一個(gè)名稱為./model_name/2的文件夾, 這個(gè)文件夾下的文件格式和halt_plus_two中的文件格式是一致的了,這下肯定沒錯(cuò)了。
將./model_name/2文件夾下的內(nèi)容拷貝到textcnnrnn/00000123目錄下即可。
重新啟動(dòng)模型,這次啟動(dòng)成功了,沒有報(bào)錯(cuò),說明我們的模型已經(jīng)被識(shí)別成功。
7、調(diào)用模型
咋調(diào)啊?咋傳參數(shù)啊?懵逼,先看看調(diào)用自帶的模型怎么傳參數(shù)的吧:
看樣子instances應(yīng)該是參數(shù)的名字,于是我想看看tensorflow serving源碼里面是怎么解析這個(gè)參數(shù)的,所以我在源碼根目錄下全局搜索了這個(gè)關(guān)鍵字,在根目錄下搜索關(guān)鍵詞instances:
$find . -name '*.*' | xargs grep -l instances可以找到一個(gè)名為json_tensor.h的文件,這個(gè)文件詳細(xì)介紹了不同的傳參的方式:
instances是一個(gè)list,list中每個(gè)元素是一個(gè)待預(yù)測(cè)實(shí)例,每個(gè)實(shí)例里面是所有參數(shù)的值, 所以參數(shù)按照這種方式構(gòu)造就可以了。
這里json.dumps的時(shí)候可能會(huì)遇到一個(gè)序列化的錯(cuò)誤,原因是json.dumps對(duì)于含numpy.array類型的數(shù)據(jù)無法序列化, 可以構(gòu)造一個(gè)編碼器, 然后作為json.dumps參數(shù):
這樣就大功告成了!
這里還有一個(gè)地方需要注意:其實(shí)我的模型Input_x本身是直接可以接收多個(gè)實(shí)例的,也就是上面我的參數(shù)x_test是多個(gè)實(shí)例構(gòu)造的參數(shù),但是直接傳入會(huì)出錯(cuò),所以我只能傳入一個(gè)實(shí)例x_test[0]。 如果想同時(shí)預(yù)測(cè)多個(gè)的話只能這樣構(gòu)造參數(shù):
8、參數(shù)要預(yù)處理怎么辦?
假如我們需要在將參數(shù)輸入模型之前做一些預(yù)處理怎么辦?比如要對(duì)大段文本進(jìn)行分詞等等。
解決辦法: 部署一個(gè)中轉(zhuǎn)服務(wù),我采用的策略是用tornado再部署一個(gè)服務(wù),這個(gè)服務(wù)負(fù)責(zé)對(duì)業(yè)務(wù)方傳輸過來的參數(shù)進(jìn)行預(yù)處理,處理成模型需要的格式后,再傳輸給模型, 所以我的結(jié)構(gòu)是這樣的:
業(yè)務(wù)方 ==> ?tornado服務(wù)(參數(shù)預(yù)處理) ==> 模型(tensorflow serving服務(wù))
這里面的兩次遠(yuǎn)程調(diào)用都是http協(xié)議。
?
參考地址:
? ??https://www.tensorflow.org/serving/docker
? ??https://www.jianshu.com/p/2fffd0e332bc
?
?
?
?
?
總結(jié)
以上是生活随笔為你收集整理的用Docker容器自带的tensorflow serving部署模型对外服务的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java中<? super T>和Lis
- 下一篇: GAN-代码实现资料整合(1)