機器之心發布
機器之心編輯部
本文詳細介紹了如何使用百度 Paddle Serving 來實現高效的服務化部署。
常見的深度學習模型開發流程需要經過問題定義、數據準備、特徵提取、建模、訓練幾個過程,以及最後一個環節——將訓練出來的模型部署應用到實際業務中。如下圖所示,當前用戶在訓練出一個可用的模型後,可以選擇如下四種部署方式:
伺服器端高性能部署:將模型部署在伺服器上,利用伺服器的高性能幫助用戶處理推理業務;
服務化部署:將模型以線上服務的形式部署在伺服器或者雲端,用戶通過客戶端或瀏覽器發送需要推理的輸入內容,伺服器或者雲通過響應報文將推理結果返回給用戶;
移動端部署:將模型部署在移動端上,例如手機或者物聯網的嵌入式端;
Web 端部署:將模型部署在網頁上,用戶通過網頁完成推理業務。
今天我們就來講講如何使用飛槳的服務化部署框架 Paddle Serving 來實現第二種部署方式。
這時可能會有讀者說了:部署?算了吧,我直接用 python 也能做推理,而且部署太複雜了,都是企業才能幹的事情,與我無關。
這位客官慢走!今天咱們說的 Paddle Serving 用起來可是非常簡單,而且部署成功後,那可是在線服務,可謂「獨樂樂不如眾樂樂!」,不僅自己可以使用它做推理,而且還可以讓其他人使用手機、電腦等設備通過客戶端或瀏覽器一起使用推理服務,瞬間讓你人氣值爆棚!下面我們就先介紹一種最基礎的用法,0 代碼完成在線服務部署!
0 代碼完成在線服務部署
使用 Paddle Serving 部署在線推理服務的過程非常簡單,主要分為 3 個步驟,獲取可用於部署在線服務的模型、啟動服務端和使用客戶端訪問服務端進行推理,也就是說最多 3 步就可以完成部署,是不是和把大象關到冰箱裡一樣簡單?
具體怎麼操作,咱們以常用的波士頓房價預測模型為例來快速體驗一下如何將這個模型部署到伺服器上。為了方便用戶使用,飛槳已經把波士頓房價預測等比較常用的模型文件保存在 GitHub 或 Gitee 上,歡迎大家下載體驗。
Paddle Serving 部署用例的下載地址:
https://github.com/PaddlePaddle/Serving/tree/develop/python/examples
如果用戶想了解如何訓練或保存用於部署的模型,可以參考如下地址:
https://github.com/PaddlePaddle/Serving/blob/develop/doc/SAVE_CN.md
在獲取模型後,用戶僅需要在伺服器上執行如下命令即可部署推理在線服務。
python -m paddle_serving_server_gpu.serve --model fit_a_line/uci_housing_model --thread 10 --port 9393 --name uci
其中 paddle_serving_server_gpu.serve 是使用 GPU 部署在線服務的模塊,如果使用 CPU 則是 paddle_serving_server.serve。其它參數則分別是模型所在位置、當前服務的並發數量、服務埠和 HTTP 服務的名稱。
在部署成功後,用戶就可以在自己的設備上使用如下 cURL 命令向伺服器請求推理服務。
curl -H "Content-Type:application/json" -X POST -d '{"feed":[{"x": [0.0137, -0.1136, 0.2553, -0.0692, 0.0582, -0.0727, -0.1583, -0.0584, 0.6283, 0.4919, 0.1856, 0.0795, -0.0332]}], "fetch":["price"]}' http://X.X.X.X:9393/uci/prediction
其中 「X」 和其後的一串數字是波士頓房價預測這個模型用於推理的 13 個特徵值,而 「price」 是咱們希望獲取的推理結果。「X.X.X.X」是伺服器的地址,而 「9393」 和「uci」分別和前面部署命令中 port 和 name 參數指定的值相對應。
以上過程可以說是完全 0 代碼部署在線推理服務,當然這只是最簡單的 Paddle Serving 的使用方式,其中服務端和客戶端之間是使用的 HTTP 協議通信,我們可以把這種在線服務稱之為 Web 服務。
如果用戶希望使用性能更好的 RPC 通信協議,即部署 RPC 在線服務,或者需要部署的模型稍微複雜一些,需要數據預處理或後處理,那麼就需要使用下面的進階部署方案了。
說到這裡,有的用戶可能就會頭疼了,不是為別的,就是因為剛剛提到的數據處理。要知道無論是圖像還是自然語言的文本,這些數據的處理都需要一定的領域知識,可是咱們大部分的用戶朋友們可不是圖像學或語言學專業畢業的,做個數據處理不僅需要學習相關的基礎知識,還要編寫不少代碼。這樣的情況下,使用 Paddle Serving 還會很簡單完成部署嗎?答案是當然可以!不過咱們也實事求是,0 代碼是不太可能的,不過低代碼還是沒問題的,請往下看!
進階流程—低代碼完成帶數據處理的在線服務部署
在 CV 和 NLP 領域,原始的數據通常要經過複雜的預處理才能轉換為模型的直接輸入,預測結果也需要經過後處理變成更直觀的圖像或者文字,這就咱們常說的數據預處理和後處理。這些本不是深度學習開發的核心環節,卻經常成為開發者們最頭疼的步驟。
為了方便用戶使用 Paddle Serving,飛槳的工程師們開發了內置預處理模塊 paddle-serving-app。paddle-serving-app 模塊集成了許多輔助功能,可以幫助用戶更快地體驗示例推理服務、編寫和部署自己的推理服務、分析推理服務中的各階段耗時、對服務進行調試等。paddle-serving-app 的安裝方法也很簡單僅需要一條命令即可。
pip install paddle_serving_app
paddle-serving-app 最主要的作用之一就是其內部添加了許多圖像(CV)和文本(NLP)的預處理方法。
對於 CV 任務,大部分預處理方法的操作都很相似。因此在 paddle-serving-app 中,這些預處理操作都被封裝成了獨立的類,然後 paddle-serving-app 提供了 Sequential 類,Sequential 類可以將各個預處理操作的類串聯起來,形成不同任務所需要的預處理方法。目前提供的預處理步驟包括:File2Image(從文件讀取圖像)、URL2Image(從連結中讀取圖像)、Normalize(歸一化)、CenterCrop(裁剪)、Resize(尺寸變換)、RGB2BGR(格式轉換)、Transpose(通道轉換)等方法。此外對於圖像檢測、圖像分割等任務,paddle-serving-app 還提供了 RCNNPostProcess、SegPostProcess 等後處理方法,可以將推理結果可視化。
對於 NLP 任務,不同類型的任務所對應的預處理方法會差異很大,定製化程度較深。因此對於不同的 NLP 任務分別實現了不同數據處理方法,分別是中文分詞模型預處理 LACReader、中文語義模型預處理 ChineseBertReader 和中文情感分析模型預處理 SentaReader。
此外,paddle-serving-app 中內置了多種 NLP 和 CV 領域的示例模型的獲取方法,用戶可以通過執行如下命令即可下載模型文件壓縮包,其中 model_name 為模型名稱。
python -m paddle_serving_app.package --get_model ${model_name}
因此 Paddle Serving 配合 paddle-serving-app 有如猛虎添翼,可以幫助用戶輕鬆完成更加複雜的在線服務部署場景。
下面我們將通過部署圖像分割服務和中文情感分析服務兩個示例,來為大家講解如何使用 Paddle Serving 和 paddle-serving-app 模塊實現低代碼部署 RPC 服務和 Web 服務。
部署圖像分割服務
圖像分割通過給出圖像中每個像素點的標籤,將圖像劃分成若干帶類別標籤的區塊的視覺任務,可以看作對每個像素進行分類。圖像分割是圖像處理的重要組成部分,也是難點之一。隨著人工智慧的發展,圖像分割技術已經在交通控制、醫療影像和人臉識別等多個領域得到了廣泛的應用。
本例將部署圖像分割的 RPC 服務,RPC 服務與前面的 Web 服務相比,對於用戶來說最大的差異是要編寫客戶端腳本,通過客戶端腳本來使用推理服務。而對於服務端來說,同樣只需要一條命令就可以啟動服務。下面我們來介紹具體的實現過程。
1. 獲取示例模型文件
使用 paddle-serving-app 下載圖像分割模型示例文件。
python -m paddle_serving_app.package --get deeplabv3+cityscapestar xf deeplabv3+cityscapes.tar.gz
解壓後將會生成服務端和客戶端的部署文件 seg_server_conf 和 seg_client_conf。其中 seg_server_conf 是在服務端使用,而 seg_client_conf 需要轉存到客戶端使用。
2. 啟動推理服務
使用如下命令啟動圖像分割在線服務,服務埠號為 9393。
python -m paddle_serving_server_gpu.serve --model seg_server_conf --port 9393 --gpu_ids 0
3. 啟動客戶端
本示例中,需要對圖像做預處理和後處理,這是因為圖像在輸入到模型網絡之前需要經過預處理將原始圖像進行尺寸的轉換,變成 numpy.array 格式的像素值矩陣。而模型的輸出是一個矩陣,矩陣值可以標記不同的區域,但是並不直觀。需要經過後處理來將推理結果可視化,即將矩陣轉化為圖片。
上述預處理和後處理操作,將會通過少量代碼在客戶端調用 paddle-serving-app 來實現。圖像分割服務客戶端代碼(Seg_Client.py)如下:
from paddle_serving_client import Client# 從app模塊中獲取圖像預處理方法from paddle_serving_app.reader import Sequential, File2Image, Resize, SegPostprocessimport sysimport cv2# 創建客戶端client = Client()# 加載客戶端的配置文件client.load_client_config("seg_client_conf/serving_client_conf.prototxt")# 連接服務,X.X.X.X為服務端的地址client.connect(["X.X.X.X:9393"])# 圖像預處理,從文件中讀取圖像,統一圖像尺寸為512*512並做像素插值preprocess = Sequential( [File2Image(), Resize( (512, 512), interpolation=cv2.INTER_LINEAR)])# 分割任務的後處理算子,參數為訓練時的分割類別數,本例為19類分割postprocess = SegPostprocess(19) # 在線預估filename = "munster.png"im = preprocess(filename)fetch_map = client.predict(feed={"image": im}, fetch=["arg_max_0.tmp_0"])fetch_map["filename"] = filename# 圖像後處理postprocess(fetch_map)
用戶可以在自己的電腦上執行下面的命令來調用 Seg_Client.py 腳本使用推理服務。
python Seg_Client.py
推理成功後會在當前目錄生成一張圖像分割結果圖片。
原始圖像:
後處理後的推理結果圖像:
部署中文情感分析服務
情感分析任務是對於一條中文語句,來判斷這條語句的情感屬於積極還是消極,如下圖所示。
本示例任務的整體流程如下圖所示,原始的語句會進行多次預處理,並且待分析句子將會通過 LAC 模型進行切詞處理,然後將切詞的結果交給 Senta 模型做情感分析推理,總之,我們可以把使用 Senta 模型推理之前的部分都看做 Senta 模型輸入數據的預處理。
本例將使用 Web 服務的形式進行部署。在部署 Web 服務的場景中,上述數據預處理操作都會在服務端通過編寫腳本實現。具體操作步驟如下所示:
1. 獲取示例模型文件
使用 paddle-serving-app 下載圖像分割模型示例文件。
python -m paddle_serving_app.package --get_model senta_bilstmpython -m paddle_serving_app.package --get_model lactar -xzf senta_bilstm.tar.gztar -xzf lac.tar.gz
解壓後將會生成 LAC 模型和 Senta 模型的服務端和客戶端的部署文件 lac_model、lac_client、senta_bilstm_model 和 senta_bilstm_client。
2. 啟動推理服務
先在 9300 埠上啟動預處理使用的 LAC 模型的推理服務。
python -m paddle_serving_server.serve --model lac_model --port 9300
在 Senta 模型的推理服務中,會在預處理部分去訪問本地的 9300 埠,獲取 LAC 模型的推理結果再進一步處理成為 Senta 模型的輸入數據。啟動 Senta 服務的腳本(senta_web_service.py)如下所示:
from paddle_serving_server.web_service import WebServicefrom paddle_serving_client import Clientfrom paddle_serving_app.reader import LACReader, SentaReader
class SentaService(WebService): #初始化LAC模型預測服務 def init_lac_client(self, lac_port, lac_client_config): self.lac_reader = LACReader() self.senta_reader = SentaReader() # 創建LAC模型推理的客戶端 self.lac_client = Client() # 加載LAC模型的配置文件 self.lac_client.load_client_config(lac_client_config) # 連接LAC服務 self.lac_client.connect(["X.X.X.X:{}".format(lac_port)])
#定義Senta模型推理服務的預處理,調用順序:lac reader->LAC模型推理->推理結果後處理->senta reader def preprocess(self, feed=[], fetch=[]): feed_data = [{ "words": self.lac_reader.process(x["words"]) } for x in feed] lac_result = self.lac_client.predict( feed=feed_data, fetch=["crf_decode"]) feed_batch = [] result_lod = lac_result["crf_decode.lod"] for i in range(len(feed)): segs = self.lac_reader.parse_result( feed[i]["words"], lac_result["crf_decode"][result_lod[i]:result_lod[i + 1]]) feed_data = self.senta_reader.process(segs) feed_batch.append({"words": feed_data}) return feed_batch, fetch# Senta Service封裝了啟動Senta模型和對接Senta預處理的流程#聲明推理服務 senta_service = SentaService(name="senta") #加載Senta模型的配置文件 senta_service.load_model_config("senta_bilstm_model") #配置推理服務的工作目錄和埠 senta_service.prepare_server(workdir="workdir", port=9393) #初始化LAC分詞推理服務的客戶端 senta_service.init_lac_client( lac_port=9300, lac_client_config="lac_model/serving_server_conf.prototxt") #啟動Senta模型推理服務的RPC服務部分,Senta模型使用RPC協議和LAC模型通信senta_service.run_rpc_service() #啟動Senta模型推理服務的http服務部分 senta_service.run_web_service()
用戶可以在服務端上執行下面的命令來調用 senta_web_service.py 腳本來啟動 Senta 推理服務,推理服務的埠為 9393。
3. 通過客戶端訪問推理服務
通過 HTTP 請求來訪問服務,其中 X.X.X.X 為服務端的地址。
curl -H "Content-Type:application/json" -X POST -d '{"feed":[{"words": "天氣不錯"}], "fetch":["class_probs"]}' http://X.X.X.X:9393/senta/prediction
獲取到的返回結果如下所示,class_probs 中為樣本的推理概率,分別為消極情緒的概率和積極情緒的概率。
{"result":{"class_probs":[[0.0690595954656601,0.9309403896331787]]}}
除了以上內容,Paddle Serving 還內置了更多類型、更多方向的推理服務示例等您來嘗試。並且作為工業級的在線服務框架,Paddle Serving 還擁有 ABTest、模型熱加載等實際業務場景中常用的功能,點擊下面的連結可以了解更多框架相關的信息和用法。
https://github.com/PaddlePaddle/Serving
寫在最後
綜上所述,飛槳的服務化部署框架 Paddle Serving 可以為人工智慧落地的最後一公裡提供越來越專業、可靠、易用的服務。當前 Paddle Serving 支持部署 RPC 服務和 Web 服務兩種類型且都支持通過一行命令啟動服務的功能。如果推理服務中涉及數據處理,則用戶可以通過 paddle-serving-app 模塊編寫少量代碼,即可輕鬆搞定數據處理工作。
Paddle Serving 接下來會在後續的版本中繼續降低用戶的使用門檻,提高用戶部署在線服務的效率,開放更多開箱即用的模型,敬請關注!
如果您加入官方 QQ 群,您將遇上大批志同道合的深度學習同學。官方 QQ 群:703252161。
如果您想詳細了解更多飛槳的相關內容,請參閱以下文檔。
官網地址:https://www.paddlepaddle.org.cn
飛槳 Paddle Serving 項目地址:
GitHub:https://github.com/PaddlePaddle/Serving
Gitee: https://gitee.com/paddlepaddle/Serving
飛槳開源框架項目地址:
GitHub: https://github.com/PaddlePaddle/Paddle
Gitee: https://gitee.com/paddlepaddle/Paddle