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