Docker部署深度学习模型及微服务化
环境:
- CentOS 7
- Pytorch
- Flask
- Nvidia显卡
以人脸检测、人脸识别任务为例,使用Pytorch框架构建MTCNN人脸检测和FaceNet人脸识别网络,检测数据集使用wider face,识别数据集使用casia-maxpy-clean。
使用Flask进行算法接口封装,并使用docker打包成镜像进行快捷部署、容器化
一、宿主机
需安装GPU相关包和驱动,例如Nvidia GPU驱动、CUDA和cudnn;需安装Docker环境(一般使用社区版Docker-CE);
安装nvidia-container-toolkit,容器才能使用宿主机GPU
安装nvidia-container-toolkit,相应指令如下:
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.repo | sudo tee /etc/yum.repos.d/nvidia-docker.repo
sudo yum install -y nvidia-container-toolkit
然后,对宿主机docker服务进行重启
systemctl restart docker
二、Flask接口
封装算法模型的推理为一个接口,使用轻量级的Flask框架
app.py
import cv2
import json
import numpy as np
import time
from Facenet.facenet import Facenet
from MTCNN.core.detect import MtcnnDetector, create_mtcnn_net
from MTCNN.core.video_vision import plot_face
from flask import Flask, request, redirect
from PIL import Image
# 模型初始化
model = Facenet()
pnet, rnet, onet = create_mtcnn_net(p_model_path=r'./MTCNN/model/pnet_epoch.pt', r_model_path=r'./MTCNN/model/rnet_epoch.pt', o_model_path=r'./MTCNN/model/onet_epoch.pt', use_cuda=True)
mtcnn_detector = MtcnnDetector(pnet=pnet, rnet=rnet, onet=onet, min_face_size=24)
# 测试图
test_img = r"./012.jpg"
val_img = cv2.imread(test_img)
val_bbox, val_landmark = mtcnn_detector.detect_face(val_img)
val_img, val_crop = plot_face(val_bbox, val_landmark, val_img, color=(0, 0, 255))
val_crop = Image.fromarray(val_crop)
# numpy 序列化
class NumpyEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, np.ndarray):
return obj.tolist()
return json.JSONEncoder.default(self, obj)
@app.route('/')
def index():
return "test"
@app.route('/detect', methods=['GET', 'POST'])
def detect():
start_time = time.time()
if request.method == 'POST':
if 'file' not in request.files:
return redirect(request.url)
file = request.files.get('file')
if not file:
return
img_bytes = file.read()
image = cv2.imdecode(np.frombuffer(img_bytes, np.uint8), cv2.IMREAD_COLOR)
bboxs, landmarks = mtcnn_detector.detect_face(image)
img, crop = plot_face(bboxs, landmarks, image, color=(0, 0, 255))
crop = Image.fromarray(crop)
distance = model.detect_image(val_crop, crop)
end_time = time.time()
result = {}
result['time'] = f'{end_time - start_time}s'
result['distance'] = distance
return json.dumps(result, cls=NumpyEncoder)
if __name__ == '__main__':
app.run(host="0.0.0.0", debug=True, port=5000)
三、深度学习Docker环境构建
1.基础镜像
使用Pytorch官方提供的镜像,进入
https://hub.docker.com/r/pytorch/pytorch/tags?page=1&ordering=last_updated
选择符合宿主机版本的镜像
注意:pytorch镜像内环境是ubuntu内核
例:
docker pull pytorch/pytorch:1.9.0-cuda10.2-cudnn7-runtime
此时,可以看到镜像仓库内拉下来了基础深度学习镜像,我们还需要使用Dockerfile来对我们的Flask及OpenCV环境封装一个更为完整的镜像。
2.Flask+Pytorch+OpenCV
将本地的Flask+算法模型相关代码放在宿主机某目录下,在该目录下编写Dockerfile
# 拉取Pytorch基础镜像
FROM pytorch/pytorch:1.9.0-cuda10.2-cudnn7-runtime
MAINTAINER luorunshu lrs0730@163.com
# 将算法模型代码加入容器的目录
ADD ./flask_face_detect /code
# 设置工作路径
WORKDIR /code
RUN apt-get update
# 安装OpenCV依赖
RUN apt-get install -y libsm6 libxext6 libgl1-mesa-glx libglib2.0-0
# 安装相应的代码所需包,使用豆瓣源
RUN pip install -r requirements.txt -i https://pypi.douban.com/simple
# 容器暴露端口5000
EXPOSE 5000
CMD ["python", "/code/app.py"]
编写好Dockerfile即可以开始构建新的算法镜像
sudo docker built -t luorunshu/flask-pytorch1.9-cuda10.2-cudnn7-runtime:latest .
等待构建完毕,使用相应的gpu指令运行docker
docker run --gpus=all -p 5000:5000 -itd luorunshu/flask-pytorch1.9-cuda10.2-cudnn7-runtime:latest
四、性能测试
使用POSTMAN进行测试,请求方式POST:
宿主机的ip地址:5000/detect
使用gpu加速推理使算法速度加快了5倍(200+ms --> 48ms)
人脸图片输入:
测试图片:
返回值说明:
time算法推理时间
probability两张人脸之间的距离,越小代表两张人脸越相似