利用docker部署深度学习模型的一个最佳实践

简介:

最近团队的模型部署上线终于全面开始用上docker了,这感觉,真香!

讲道理,docker是天然的微服务,确实是能敏捷高效的解决深度学习这一块的几个痛点。

部分神经网络框架比如caffe依赖过重,安装困难。
各种网络模型未做工程化优化,部署困难。
tensorflow等框架对GPU等硬件的占用难以灵活控制。

对于做应用来说,这些问题诸如对GPU的硬件的管理,对复杂依赖的部署,而这些正好就是docker的强项。而python本身表达能力强,可以以很短的代码量达成我们的目的。

部署

具体的部署步骤涉及这几个工具链:

Dockerfile进行模型的镜像部署。
docker-py进行container的启动和关闭。
grpc和进行模型的外部通信。
python的with语句表达模型的加载和资源的释放。
gitlab进行内网的代码分发和版本控制。

整个接口的调用精简成面向对象的调用方式,with语句进入时启动模型,占用GPU,打开rpc调用端口,之后在调用结束后退出模型,释放资源,整个调用过程就简化成如下样子:


with Model_Docker() as sess:
img = cv2.imread('demo.jpg')
r = sess.run(img)
print('result:',r,'type',type(r))

其中Model_Docker是这样的:


class CTPN_Docker(object):

def __init__(self):
self.client = docker.from_env()

def get_container(self,client):
container = client.containers.run(image = DEMO_IMAGE_NAME:TAG,
command = "python server.py",
runtime='nvidia',
environment = ["CUDA_VISIBLE_DEVICES=0"],
ports = {'8888/tcp':'8888'},
detach=True,
auto_remove = True)
return container

def __enter__(self):
self.container = self.get_container(self.client)
for line in self.container.logs(stream=True):
if line.strip().find(b'grpc_server_start') >= 0:
break
return self

def __exit__(self, exc_type, exc_val, exc_tb):
self.container.stop()
print('container has stopped.')

def run(self,img):
assert isinstance(img,np.ndarray), 'img must be a numpy array.'
imgstr = img.tobytes()
shape = json.dumps(img.shape)
stub = ctpn_pb2_grpc.ModelStub(grpc.insecure_channel('localhost:50051'))
response = stub.predict(ctpn_pb2.rect_request(img=imgstr, shape=shape))
return json.loads(response.message)

整个流程是这么个步骤:

init 方法获得docker client。
get_container方法实例化一个container。
with语句进入接口的 enter 方法,负责获取container实例和实例内模型启动结束的flag。
with语句清理接口的 exit 方法,负责实例的关闭。
run方法通过grpc调用docker内模型和返回结果。

docker-py是一个docker的python接口,docker除了cmdline的操作方式,还提供了REST的调用接口,docker-py就是其中一个很人性化的封装,具体使用可见官方文档。

container的实例化中有这几个地方需要注意:

runtime需要用nvidia,与使用nvidia-docker效果一样。
detach是后台模式,与-d效果一样。
auto_remove是自动删除,与--rm效果类似。
environment 来设定CUDA_VISIBLE_DEVICES。
ports 来指定导出端口映射。

除了docker-py调用中的这些技巧,还有如下几个指令在构建过程中值得注意。

1、grpc的编译,这里没啥好说的,和grpc的官方说明文档里一样。

RUN python -m grpc_tools.protoc --python_out=. --grpc_python_out=. -I. mode.proto

2、docker image的构建,有时候构建需要添加--no-cache,避免远程资源更新了,docker构建却没重新。

docker build --no-cache -t name .

3、pip安装的时候需要添加几个参数,-r指定.txt安装,-i指定清华镜像为安装源,--no-cache-dir压缩docker镜像。

RUN pip install -r requirements_docker.txt -i https://pypi.tuna.tsinghua.edu.cn/simple --no-cache-dir

后记

这一轮AI浪潮扑腾到今天,也积累了大量可落地的框架和应用。不过在github欢快的clone代码的时候,一直注意到一些事。和web等领域不同的是,几乎所有模型几乎都是以源代码的形式分发的,很少有工程化的封装,更别说封装成库来部署了。就拿现在我在做的目标检测和文字识别的几个模型来说,yolo、fasterrcnn、ctpn和crnn等都是这样。

当然这也好理解,这些开源作品基本都是大佬在水文章之余写的,而且一个完整的模型包括训练、测试和预测,模型在公开数据集上的训练效果才是关键,工程化的问题并不是最重要的事情,不过我还是想吐槽一下。

比如fasterrcnn中训练数据是写死的,准备好训练集后得通过一个软连接将训练集和训练数据替换掉。这还不是最毒瘤的,较新的ctpn是继承自fasterrcnn,也是采用这种方法.

又比如在导入数据阶段也是各用各的法子,这些做法有往往采用多线程和多进程,结果管理不好,一大堆死线程不说,还经常把cpu跑满,用过的模型中darkflow和east都有这样的问题。

还有在写inference是,还常常遇到需要修改输入输出tensor的情况,在输入端加placeholder,稍微对tensorflow不熟,同时还需要修改一些在预测阶段有所改变的tensor。确实是很不人道。

最后想提一点,这种部署方式除了部署时灵活方便,另外一个额外的好处就是使用jupyter时也方便,在jupyter使用时最常见的问题有两个,一个是需要经常使用set_env去设置CUDA_VISIBLE_DEVICES,另一个是用完了得把notebook关掉,不然jupyter进程会一直占用GPU。


原文发布时间为:2018-09-5

本文作者:丁果

本文来自云栖社区合作伙伴“Python中文社区”,了解相关信息可以关注“Python中文社区”。

相关实践学习
基于阿里云DeepGPU实例,用AI画唯美国风少女
本实验基于阿里云DeepGPU实例,使用aiacctorch加速stable-diffusion-webui,用AI画唯美国风少女,可提升性能至高至原性能的2.6倍。
相关文章
|
2天前
|
机器学习/深度学习 API 算法框架/工具
R语言深度学习:用keras神经网络回归模型预测时间序列数据
R语言深度学习:用keras神经网络回归模型预测时间序列数据
13 0
|
2天前
|
测试技术 Linux 网络安全
【好玩的开源项目】使用Docker部署SyncTV视频同步和共享平台
【4月更文挑战第16天】使用Docker部署SyncTV视频同步和共享平台
37 1
|
2天前
|
机器学习/深度学习 并行计算 算法
R语言深度学习不同模型对比分析案例
R语言深度学习不同模型对比分析案例
21 0
|
3天前
|
机器学习/深度学习 人工智能 分布式计算
R和Python机器学习:广义线性回归glm,样条glm,梯度增强,随机森林和深度学习模型分析
R和Python机器学习:广义线性回归glm,样条glm,梯度增强,随机森林和深度学习模型分析
|
6天前
|
机器学习/深度学习 自然语言处理 算法
探索深度学习中的序列建模新范式:Mamba模型的突破与挑战
【4月更文挑战第13天】Mamba模型,一种新型序列建模架构,通过选择性状态空间提高处理长序列数据的效率,实现线性时间复杂度。在语言、音频和DNA序列建模中展现优秀性能,尤其在大规模预训练中超越Transformer。然而,面对连续信号数据时可能不及LTI模型,且模型参数优化及硬件实现具有挑战性。
23 5
探索深度学习中的序列建模新范式:Mamba模型的突破与挑战
|
6天前
|
测试技术 Linux 数据安全/隐私保护
【Docker项目实战】使用Docker部署Seatsurfing预订座位系统
【4月更文挑战第12天】使用Docker部署Seatsurfing预订座位系统
32 3
|
9天前
|
JavaScript 前端开发 Docker
全栈开发实战:结合Python、Vue和Docker进行部署
【4月更文挑战第10天】本文介绍了如何使用Python、Vue.js和Docker进行全栈开发和部署。Python搭配Flask创建后端API,Vue.js构建前端界面,Docker负责应用的容器化部署。通过编写Dockerfile,将Python应用构建成Docker镜像并运行,前端部分使用Vue CLI创建项目并与后端交互。最后,通过Nginx和另一个Dockerfile部署前端应用。这种组合提升了开发效率,保证了应用的可维护性和扩展性,适合不同规模的企业使用。
|
10天前
|
Linux Shell 虚拟化
linux 部署docker容器虚拟化平台(二)--------docker 镜像制作方法
linux 部署docker容器虚拟化平台(二)--------docker 镜像制作方法
15 0
|
10天前
|
存储 Linux Shell
centos 部署docker容器 安装 、基本使用方法(一)
centos 部署docker容器 安装 、基本使用方法(一)
19 0
|
13天前
|
测试技术 Linux 数据安全/隐私保护
【Docker项目实战】使用Docker部署PicoShare共享文件平台
【4月更文挑战第5天】使用Docker部署PicoShare共享文件平台
46 4