我们使用SophonSDK来移植算法和模型,并在X86主机的开发环境上封装和打包算法服务。这里以LPRNet车牌识别算法服务为例进行介绍。相关文件已上传至SOPHGO的demo目录下,主要流程包括以下几步:
我们在x86文件下的main.py中封装了算法接口和HTTP服务。
车牌识别算法比较简单,我们可以把整个算法流程封装到main.py中,并提供算法调用接口。
class LPRNet(object):
...
if __name__ == "__main__":
lprnet = LPRNet()
如果算法比较复杂,涉及多个模型,我们可以把算法的相关代码放至x86文件夹下,在main.py中提供算法调用接口即可。
我们需要在SimpleHTTPRequestHandler中的do_POST函数下定义访问地址、请求方式、返回码、返回信息、调用算法接口、返回结果等。
class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
......
def do_POST(self):#ip:port/lprnet
path = str(self.path) # 获取请求的url
if path == '/lprnet':
content_length = int(self.headers['Content-Length'])
body = self.rfile.read(content_length).decode('utf-8')
print('body:',body)
jsdata = json.loads(body)
if 'image' not in jsdata:
ret_json = {"Code":1,"Msg":"请求失败,未输入图片"}
self.send_ret(ret_json)
return
image = jsdata['image']
img = base64_to_cv2(image)
if img is None:
ret_json = {"Code":1,"Msg":"请求失败,图片读取失败"}
self.send_ret(ret_json)
return
res = lprnet(img)[0]
ret_json = {"Code":0,"Msg":"请求成功","res":res}
self.send_ret(ret_json)
elif path == '/query':
content_length = int(self.headers['Content-Length'])
body = self.rfile.read(content_length).decode('utf-8')
jsdata = json.loads(body)
# if jsdata['name'] == 'font':
ret_json = {'Code':0,'Msg':'请求成功','result':[{'url':'/lprnet','status':0}]}
self.send_ret(ret_json)
else:
ret_json = {"Code":1,"Msg":"请求失败,url路径错误","res":''}
self.send_ret(ret_json)
我们还需要设置HTTPServer的访问端口。
if __name__ == "__main__":
lprnet = LPRNet()
httpd = HTTPServer(('0.0.0.0', 9093), SimpleHTTPRequestHandler)
httpd.serve_forever()
我们可以在main.sh中定义服务启动命令,并保存相关日志。
#!/bin/bash
python3 main.py >> log.txt 2>&1
算法服务封装好后,我们可以在开发环境的容器中直接运行main.sh,启动服务。
然后在宿主机或其他连通的主机上调用该服务,主要修改访问的IP、端口、地址、请求值、获取返回值等,具体可参考test.py。
python3 test.py
服务测试通过后,我们需要在开发环境的容器中,将服务所需的文件,包括环境链接库、sail包、代码、模型等,统一拷贝到指定文件夹,方便后续打包服务镜像。具体可参考assemble_x86.sh,需要视情况修改脚本中的文件路径。
./assemble_x86.sh
包括安装所需的工具和依赖库、将镜像文件夹添加到镜像中、设置启动命令等等。
FROM debian:9
# 尽量将所有的工具安装放到本层,以减少size
# 不需要的工具尽量移除,调试工具可以在docker中runtime安装,没有必要预装
RUN apt -y update \
# && add-apt-repository ppa:deadsnakes/ppa \
&& apt install -y python3 \
&& apt install -y python3-pip \
&& apt-get install ffmpeg libsm6 libxext6 -y
# Python依赖包在本层安装,并且请指明需要的版本号,以确保每次编译能编译出相同的镜像
RUN python3 -m pip install --upgrade pip \
&& pip3 install pybind11 \
&& pip3 install numpy \
&& pip3 install requests \
&& pip3 install Pillow \
&& pip3 install urllib3 \
&& pip3 install opencv-python
# 设置时区
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo 'Asia/Shanghai' >/etc/timezone
# 将镜像文件夹添加到镜像中
ADD x86 /avs_l1
# 安装sail包
RUN pip3 install /avs_l1/sophon-2.7.0-py3-none-any.whl
# 指定工作目录
WORKDIR /avs_l1
# 指定链接库路径
ENV LD_LIBRARY_PATH=.
# 设置启动命令
ENTRYPOINT ["./main.sh"]
然后,执行./build_docker_x86.sh进行服务镜像打包。需要进入到与镜像文件夹同级的目录中,主要修改dockerfile的相对路径、镜像名、镜像文件名。
# 进入到与镜像文件夹同级的目录中
cd ../../docker
# 创建docker镜像,通过-f指定dockerfile路径,-t指定镜像名
sudo docker build -f ../projects/lprnet_serve/Dockerfile_x86_sail -t avs_lprnet .
# 保存docker镜像,通过-o指定保存的文件名称
sudo docker save avs_lprnet -o avs_lprnet_x86.docker
# 修改镜像文件权限
sudo chmod 666 avs_lprnet_x86.docker
# 删除镜像
sudo docker rmi avs_lprnet
第一步:加载服务镜像
docker load -i avs_lprnet_x86.docker
注意修改服务镜像路径。
第二步:创建镜像容器,启动服务
./run_docker.sh avs_lprnet:latest lprnet
注意修改镜像名(第1个参数)和容器名(第2个参数),可在脚本中自行更改容器端口映射。
第三步:服务调用与测试示例
sudo python3 test.py
注意修改测试脚本里面的测试图片路径、访问IP、端口、地址、请求值、获取返回值等。
————————————————
版权声明:本文为CSDN博主「weixin_44087610」的原创文章,遵循CC 4.0 BY-SA版权协议