由于近期比赛的要求,需要将训练好的深度学习模型利用Docker进行部署,因此记录一下学习过程。利用Docker,可以快捷方便地构建一个包含已训练的深度学习模型的镜像,该镜像部署到其他机器上可获得可复现一致的结果。
具体地,我们在开发机器上需要将深度学习模型训练好,并写好模型inference的过程,然后利用docker技术制作好镜像,这样对于非开发机器,直接执行docker镜像即可完成模型inference,而无需安装复杂的依赖库。
安装Docker Engine
在开发机器上安装官网提示直接安装,在完成安装后,执行下面命令,以确保安装成功:
sudo docker run hello-world
执行后看到打印出来正常的提示信息则表示安装成功。
编写Dockerfile
Docker镜像的制作由Dockerfile文件来指定具体操作。
在编写Dockerfile文件之前,需要完成深度学习模型的inference过程,这里以这个项目为例子,这个项目利用PyTorch在ImageNet-1K数据集上预训练的ResNet-18进行图片分类。具体地,执行deploy_models.py会读取data/images文件夹下所有的图片,逐张通过训练好的ResNet-18网络进行预测,预测结果保存在/data/results下的一个文本文件中。
确定好了模型inference过程后,Dockerfile可以写成:
FROM pytorch/pytorch
WORKDIR /docker_sample
COPY . /docker_sample
RUN pip install -r requirements.txt
CMD [“python”, “deploy_models.py”]
这个Dockerfile的第2行表明是基于pytorch/pytorch的docker镜像来制作,相当在这个镜像的基础上做了扩展来形成我们自己的镜像,其中pytorch/pytorch表示docker镜像名,默认docker镜像的tag为latest,类比于版本,pytorch/pytorch:latest的docker镜像可以在Docker Hub中找到;第5行表示该镜像的工作目录;第8行表示将当前文件夹下的所有文件copy到docker镜像中的目录/docker_sample目录下;第11行表示在docker镜像中使用pip安装所有依赖库;第14行表示当容器(container)运行时默认执行的命令。
镜像(image)和容器(container):容器表示富贵论坛运行起来的镜像,相当于镜像的一个实例。
制作Docker镜像
运行下面命令
sudo docker build -t docker_sample:latest .
其中-t参数指定镜像的名称为docker_sample和tag标签为latest,其中tag标签相当于版本号,最后的小点"."表示当前目录,因为当前目录下有Dockerfile文件。
导出Docker镜像
sudo docker save -o docker_image.tar docker_sample:latest
发布Docker镜像
sudo docker login
sudo docker tag docker_sample YOUR_DOCKER_ID/docker_sample
sudo docker push YOUR_DOCKER_ID/docker_sample
这里首先登陆自己的Docker账号,然后将本地Docker镜像的tag更改为正确tag格式,然后上传至Docker Hub中。
上面已经可以在开发机器上制作Docker镜像,并将它们导出或者发布了,因此在非开发机器上获取镜像文件就可执行。
导入Docker镜像
sudo docker load -i docker_image.tar
运行Docker镜像
sudo docker run -it --rm docker_sample
由于Docker镜像执行后只会预测在文件夹/dockersample/data/images下的图像,为了能让该Docker镜像预测自己的图像,可以先把需要预测的图像保存在PATH_TO_IMAGES文件夹中,然后运行:
sudo docker run -v PATH_TO_IMAGES:/dockersample/data -it --rm docker_sample
为了让Docker镜像使用NVIDIA GPU,可以运行:
sudo docker run --gpus all -v PATH_TO_IMAGES:/dockersample/data -it --rm docker_sample
Docker其他常用命令
删除容器
docker rm CONTAINER_ID
列出所有容器(包括正在运行的和已经退出的容器)
docker ps -a
停止正在运行的容器
docker stop CONTAINER_ID
删除镜像(删除镜像之前需要删除所有该镜像下的容器)
docker rmi IMAGE_ID