模型部署 — PaddleNLP 基於 Paddle Serving 快速使用(服務化部署

2023-07-25 15:02:26


影象識別 + 資訊抽取(UIE-X),部署介面供別的應用呼叫
最終在自己部署的環境中識別時報錯,不知道是不是和GPU有關,還在嘗試中

流程

  • 在百度 BML CodeLab 中跑好模型(免費算力,玩玩夠了)
  • 下載模型 (比較大,我這個有10G了,可以適當做裁剪)
  • Linux 上安裝 Docker ,所以的事項在 Docker 中執行

版本

虛機設定:CentOS 7 、 記憶體:12G、CPU:4核
本文版本號:
Python 3.7.13 Docker 映象已經整合
PaddlePaddle 2.4.0 Docker 映象已經整合
PaddleNLP 2.5.2
PaddleOcr 2.6.1.3

注意: Python 版本 (Docker 映象中的 Python 已經整合好)
PaddlePaddle 2.4.0 - => Python 3.7.4
PaddlePaddle 2.4.1 + => Python 3.9.0

檢視版本 注意各個應用的版本關係
https://hub.docker.com/r/paddlepaddle/paddle/tags/?page=1&name=cpu

安裝

虛機設定:CentOS 7 、 記憶體:12G、CPU:4核
映象中整合好了 Python 3.7.12 比較方便

Docker 安裝

# 切換進 opt/ppnlp 目錄,後面 $PWD 掛載時會用到當前的路徑
[root@localhost ~]# cd /opt/ppnlp/
[root@localhost ppnlp]# pwd
/opt/ppocr
[root@localhost ppnlp]# 

# 獲取映象 -- 沒有GPU環境,使用CPU跑了玩玩
[root@localhost ppnlp]# docker pull registry.baidubce.com/paddlepaddle/paddle:2.4.0-cpu
# 建立一個名字為 ppnlp 的docker容器,並將當前目錄對映到容器的/paddle目錄下
[root@localhost ppnlp]# docker run --name ppnlp -v $PWD:/paddle --network=host -it registry.baidubce.com/paddlepaddle/paddle:2.4.0-cpu /bin/bash
# --name ppnlp:設定 Docker 的名稱,ppnlp 是自己設定的名稱;
# -it:引數說明容器已和本機互動式執行;
# -v $PWD:/paddle:指定將當前路徑(PWD 變數會展開為當前路徑的絕對路徑--Linux宿主機的路徑,所以執行命令的路徑要選好)掛載到容器內部的 /paddle 目錄;(相當於 /opt/ppnlp 掛載到容器內)
# registry.baidubce.com/paddlepaddle/paddle:2.4.0-cpu:指定需要使用的 image 名稱,您可以通過docker images命令檢視;/bin/bash 是在 Docker 中要執行的命令

# ctrl+P+Q可退出docker 容器,重新進入docker 容器使用如下命令
[root@localhost ppocr]# docker exec -it ppnlp /bin/bash
λ localhost /home

[root@localhost 開頭的都是在Linux 伺服器上執行
以下命令都是在容器中執行,防止混淆,下面命令省掉了 λ localhost /home

PaddleNLP 安裝

# 升級 pip 
pip install -U pip -i https://mirror.baidu.com/pypi/simple
# 容器中已經包含了 paddlepaddle 2.4.0
pip list
# 安裝 PaddleNLP
pip install paddlenlp -i https://mirror.baidu.com/pypi/simple
# 安裝 PaddleOCR
pip install paddleocr -i https://mirror.baidu.com/pypi/simple

環境準備

模型準備

前面已經訓練好了:https://aistudio.baidu.com/aistudio/projectdetail/6518069?sUid=2631487&shared=1&ts=1689903307978

壓縮模型

# 先重新命名 mv checkpoint checkpoint2 # 建立目錄 mkdir -p checkpoint/model_best # 複製需要的檔案 cp checkpoint2/model_best/model.pdiparams model.pdiparams cp checkpoint2/model_best/model.pdiparams.info model.pdiparams cp checkpoint2/model_best/model.pdmodel model.pdiparams cp checkpoint2/model_best/model_state.pdparams model.pdiparams cp checkpoint2/model_best/sentencepiece.bpe.model model.pdiparams
# 壓縮檔案 --大概要10G左右
tar cf checkpoint.tar checkpoint

下載模型

檔案有點大,10G左右

模型部署

[root@localhost ~]# cd /opt/ppnlp
# 將模型,複製到容器中
[root@localhost ppnlp]# docker cp checkpoint.tar ppnlp:/home
# 進入容器
[root@localhost ppnlp]# docker exec -it ppnlp /bin/bash
λ localhost /home ll
total 9.5G
drwxr-xr-x. 1 root root   55 Jul 21 02:58  ./
drwxr-xr-x. 1 root root   66 Jul 21 02:58  ../
-rw-r--r--. 1 root root 9.5G Jul 21 02:24  checkpoint.tar
drwxr-xr-x. 6 root root   52 Aug 17  2022  cmake-3.16.0-Linux-x86_64/
λ localhost /home
λ localhost /home tar -xvf checkpoint.tar
# 容器中安裝 tree
λ localhost /home apt-get install tree 

環境設定

https://gitee.com/paddlepaddle/PaddleNLP/tree/v2.5.2/applications/information_extraction/document/deploy/simple_serving
將 server.py、client.py、test.jpg 根據環境修改設定後,上傳至容器中
test.jpg

server.py

from paddlenlp import SimpleServer, Taskflow

# The schema changed to your defined schema
schema = ["開票日期", "名稱", "納稅人識別號", "開戶行及賬號", "金額", "價稅合計", "No", "稅率", "地址、電話", "稅額"]
# The task path changed to your best model path
uie = Taskflow(
    "information_extraction",
    schema=schema,
    task_path="/home/checkpoint/model_best", # 注意路徑
)
# If you want to define the finetuned uie service
app = SimpleServer()
app.register_taskflow("taskflow/uie", uie)

client.py


import json

import requests

from paddlenlp.utils.doc_parser import DocParser

# Define the docuemnt parser
doc_parser = DocParser()

image_paths = ["/home/test.jpg"] # 注意路徑
image_base64_docs = []

# Get the image base64 to post
for image_path in image_paths:
    req_dict = {}
    doc = doc_parser.parse({"doc": image_path}, do_ocr=False)
    base64 = doc["image"]
    req_dict["doc"] = base64
    image_base64_docs.append(req_dict)

url = "http://0.0.0.0:8189/taskflow/uie"
headers = {"Content-Type": "application/json"}
data = {"data": {"text": image_base64_docs}}

# Post the requests
r = requests.post(url=url, headers=headers, data=json.dumps(data))
datas = json.loads(r.text)
print(datas)

將檔案傳到容器內

# 將檔案傳至容器
[root@localhost ppnlp]# docker cp client.py ppnlp:/home
[root@localhost ppnlp]# docker cp server.py ppnlp:/home
[root@localhost ppnlp]# docker cp test.jpg ppnlp:/home
# 進入容器
[root@localhost ppnlp]# docker exec -it ppnlp /bin/bash
λ localhost /home ll
total 9.5G
-rw-r--r--. 1 root root   77 Jul 20 09:27 '='
drwxr-xr-x. 1 root root  105 Jul 21 05:24  ./
drwxr-xr-x. 1 root root   66 Jul 21 05:24  ../
drwxr-xr-x. 3 1000 1000   24 Jul 18 09:36  checkpoint/
-rw-r--r--. 1 root root 9.5G Jul 21 02:24  checkpoint.tar
-rw-r--r--. 1 root root 1.3K Jul 21 04:02  client.py
drwxr-xr-x. 6 root root   52 Aug 17  2022  cmake-3.16.0-Linux-x86_64/
-rw-r--r--. 1 root root 1.2K Jul 21 03:57  server.py
-rw-r--r--. 1 root root 1.4M Jul 21 03:55  test.jpg
λ localhost /home

啟動服務

# 進入容器
[root@localhost ppnlp]# docker exec -it ppnlp /bin/bash
# 啟動服務
λ localhost /home paddlenlp server server:app --workers 1 --host 0.0.0.0 --port 8189
# 後臺執行 -- 測試時不要用後臺執行,中間會報很多錯誤,開兩個視窗,偵錯時方便
# λ localhost /home nohup paddlenlp server server:app --workers 1 --host 0.0.0.0 --port 8189 &>log.txt &

測試 -- 暫時還沒通過

# 再開一個視窗執行
# 進入容器
[root@localhost ppnlp]# docker exec -it ppnlp /bin/bash
λ localhost /home python client.py

百度的環境重現了,問題就是我的伺服器沒有GPU

from pprint import pprint
from paddlenlp import Taskflow
schema = {
    '專案名稱': [
        '結果',
        '單位',
        '參考範圍'
    ]
}
my_ie = Taskflow("information_extraction", model="uie-x-base", schema=schema, task_path='./checkpoint/model_best')

# 加上device_id=0,使用CPU,會就報
my_ie = Taskflow("information_extraction", model="uie-x-base", schema=schema, device_id=0, task_path='./checkpoint/model_best')

百度 BML CodeLab 環境中,加上device_id=0, 使用CPU,會就報下面錯誤 推測我的虛機裡面錯誤,應該是沒有GPU環境有關

重啟

# 如果容器停止,重啟容器
[root@localhost ppocr]# docker restart ppnlp
# 進入容器
[root@localhost ppocr]# docker exec -it ppnlp /bin/bash

# 啟動服務
λ localhost /home paddlenlp server server:app --workers 1 --host 0.0.0.0 --port 8189
# 後臺執行 -- 測試時不要用後臺執行,中間會報很多錯誤,開兩個視窗,偵錯時方便
# λ localhost /home nohup paddlenlp server server:app --workers 1 --host 0.0.0.0 --port 8189 &>log.txt &