提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
本文章主要讲述Windows系统下的paddle模型服务化部署,目前Win系统只支持用web service的方式搭建local predictor预测服务,linux系统的RPC服务部署请参考https://aistudio.baidu.com/aistudio/projectdetail/545527
一、可部署模型准备
安装百度飞桨框架:
python -m pip install paddlepaddle==2.3.0 -i https://mirror.baidu.com/pypi/simple
安装服务端与客户端:
pip install paddle-serving-client -i https://mirror.baidu.com/pypi/simple
pip install paddle-serving-server -i https://mirror.baidu.com/pypi/simple
pip install paddle-serving-app -i https://mirror.baidu.com/pypi/simple
请参考上述连接文章训练好模型并将模型文件转化为可部署的server端与client端文件:
注意其中的conf.prototxt文件中feed与fetch分别为模型的输入与输出,需要打开查看,与下文服务端代码中的feed与fetch对应填上:
二、服务端框架
服务端基于paddle serving的web框架,具体设计原理可查阅官方文档:
https://github.com/PaddlePaddle/Serving/blob/develop/doc/Windows_Tutorial_CN.md
服务端代码如下(示例):
from PIL import Image
from paddle_serving_client import Client
from paddle_serving_app.reader import OCRReader
import cv2
import sys
import numpy as np
# import os
# from paddle_serving_client import Client
# from paddle_serving_app.reader import Sequential, URL2Image, ResizeByFactor
# from paddle_serving_app.reader import Div, Normalize, Transpose
# from paddle_serving_app.reader import DBPostProcess, FilterBoxes, GetRotateCropImage, SortedBoxes
# from paddle_serving_client.pipeline.channel import ChannelData
if sys.argv[1] == 'gpu':
from paddle_serving_server.web_service import WebService
elif sys.argv[1] == 'cpu':
print(3)
from paddle_serving_server.web_service import WebService
print(1)
from paddle_serving_app.local_predict import LocalPredictor
import time
import re
import base64
class NUMPICweb(WebService):
def init_det_debugger(self, det_model_config):
self.det_client = LocalPredictor()
if sys.argv[1] == 'gpu':
self.det_client.load_model_config(
det_model_config, use_gpu=True, gpu_id=1)
elif sys.argv[1] == 'cpu':
self.det_client.load_model_config(det_model_config)
def preprocess(self, feed=[],fetch=[]):
data = base64.b64decode(feed[0]['image'].encode('utf8'))
data = np.fromstring(data, np.uint8)
im = cv2.imdecode(data, cv2.IMREAD_COLOR)
cv2.imwrite('test.png',im)
file = r"test.png"
im = cv2.imread(file)
im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)#转为灰度图
im = 255-im#对图片反色处理
im = im / 255.0 * 2.0 - 1.0#(255-im)/255.0
#im = Image.open(file).convert('L')
cv2.imshow('a',im)
cv2.waitKey()
im = cv2.resize(im,(28,28)) # resize image with high-quality 图像大小为28*28
im = np.array(im).reshape(1, 1, 28, 28).astype(np.float32) # 返回新形状的数组,把它变成一个 numpy 数组以匹配数据馈送格式。
print(im)
#im = (255-im)/255.0#im / 255.0 * 2.0 - 1.0
feed = {"image":im}
fetch = ['fc_2.tmp_2']
#print(feed)
fetch_map = self.det_client.predict(feed={"image":im}, fetch=['fc_2.tmp_2'])
lab = fetch_map['fc_2.tmp_2']
print(lab)
print(np.argmax(lab[0]))
return feed,fetch,False
def postprocess(self, feed={}, fetch=[],fetch_map=None):
res = {"res": [f"{np.argmax(fetch_map['fc_2.tmp_2'])}"]}
return res
# class PICService(WebService):
# def get_pipeline_response(self, read_op):
# image_op = NUMPICOp(name="pic", input_ops=[read_op])
# return image_op
pic_service = NUMPICweb(name="pic")
pic_service.load_model_config("serving_server_dir")#你模型的服务端路径
pic_service.prepare_server(workdir="workdir", port=9292)
pic_service.init_det_debugger(det_model_config="serving_server_dir")
if sys.argv[1] == 'gpu':
pic_service.set_gpus("0")
pic_service.run_debugger_service(gpu=True)
elif sys.argv[1] == 'cpu':
pic_service.run_debugger_service()
pic_service.run_web_service()
其中preprocess为图片预处理,即对传入的base64数据进行解码,保存图片,转灰度以及反色等,因为这里的测试集图像是我自己画的白底黑字数字,训练用的图像都是黑底白字所以要保证预测的输入一致。postprocess为返回客户端的json数据,类似于python的字典格式,这俩个核心函数具体原理请参考上述Web Service设计官方文档。
三、客户端实现
代码如下(示例):
import requests
import json
import cv2
import base64
import os, sys
import time
def cv2_to_base64(image):
#data = cv2.imencode('.jpg', image)[1]
return base64.b64encode(image).decode(
'utf8') #data.tostring()).decode('utf8')
headers = {"Content-type": "application/json"}
url = "http://127.0.0.1:9292/pic/prediction"
test_img_dir = "D:/Mypy_pro/1/deep_learning/num_pic"#你的测试集数字图像路径
for img_file in os.listdir(test_img_dir):
with open(os.path.join(test_img_dir, img_file), 'rb') as file:
image_data1 = file.read()
image = cv2_to_base64(image_data1)
data = {"feed": [{"image":image}], "fetch": ['fc_2.tmp_2']}
r = requests.post(url=url, headers=headers, data=json.dumps(data))
print(r)
实验示例
手画的数字图片:
建议使用原始MNIST数据集的数字图片预测,自己手写的数字后面789基本识别不出来!
在工程目录下开启服务命令:python pic_web_server.py cpu
打开一个新的终端作为客户端:python pic-pipeline_http_client.py
博主也是新手小白,刚入手才不到俩三个星期,后续会持续更新并尝试pipeline serving服务部署,各位可参考大佬的文章https://blog.csdn.net/qianbin3200896/article/details/124330556,22年4月底写的,非常适合新手学习,有问题欢迎随时在评论区交流一起学习!