手把手教你如何部署深度学习模型

简介: 本文将讲解如何部署深度学习模型,让你不再对如何快速地将机器学习模型部署到生产中感到困扰

我刚刚训练了机器学习模型——那么现在呢

这篇文章介绍了一种快速的方法,将经过训练的机器学习模型部署到生产中。

请阅读以下内容:如果您已经成功地使用诸如Tensorflow或Caffe这样的ML框架来培训ML模型,那么您最好先做一个演示,最好早一点而不是晚一点,而且您更喜欢更便捷的解决方案,而不是将整个技术堆栈都打包。

阅读时间:10-15分钟

TL;DR:检查报告

检查您的tensorflow安装

从stdin运行在线分类

在本地主机上运行在线分类

将分类器放在硬编码代理之后

将分类器置于具有服务发现的代理之后

使用伪DNS调用分类器

ML在生产中

当我们第一次进入Hive的机器学习空间时,我们已经拥有了数百万个标记为图像的地面实况,这使得我们可以在一个星期内训练一个最先进的深度卷积图像分类模型(即随机权重),专门用于我们的用例。 然而,更典型的ML使用案例通常是数百幅图像的数量级,为此我建议微调现有的模型。例如,https://www.tensorflow.org/tutorials/image_retraining有一个很好的教程关于如何微调Imagenet模型(训练1.2图片,1000类)来对花卉样本数据(3647图片,5类)进行分类。

对于连接Tensorflow教程的快速tl;dr,在安装bazel和tensorflow之后,您需要运行以下代码,这需要大约30分钟的时间来搭建和5分钟的时间来训练:

(
cd "$HOME" && \
curl -O http://download.tensorflow.org/example_images/flower_photos.tgz && \
tar xzf flower_photos.tgz ;
) && \
bazel build tensorflow/examples/image_retraining:retrain \
          tensorflow/examples/image_retraining:label_image \
&& \
bazel-bin/tensorflow/examples/image_retraining/retrain \
  --image_dir "$HOME"/flower_photos \
  --how_many_training_steps=200
&& \
bazel-bin/tensorflow/examples/image_retraining/label_image \
  --graph=/tmp/output_graph.pb \
  --labels=/tmp/output_labels.txt \
  --output_layer=final_result:0 \
  --image=$HOME/flower_photos/daisy/21652746_cc379e0eea_m.jpg

或者,如果您安装了Docker,则可以使用以下预构建的Docker镜像

sudo docker run -it --net=host liubowei/simple-ml-serving:latest /bin/bash
 
>>> cat test.sh && bash test.sh

在容器内的交互式shell中运行上述命令;如果您愿意,您也可以跟着这个文章的其他部分在容器内操作。

现在,tensorflow已经将模型信息保存到/tmp/output_graph.pb/tmp/output_labels.txt中,这些作为命令行参数传递给label_image.py脚本。 Googleimage_recognition教程也链接到另一个推理脚本,但是现在我们将坚持使用label_image.py

将一次性推断转换为在线推断(Tensorflow)

如果我们只想接受来自标准输入的文件名,每行一个,我们就可以很容易地进行“在线”推断:

while read line ; do
bazel-bin/tensorflow/examples/image_retraining/label_image \
--graph=/tmp/output_graph.pb --labels=/tmp/output_labels.txt \
--output_layer=final_result:0 \
--image="$line" ;
done

从性能的角度来看,这很糟糕——我们正在重新加载神经网络、权重、整个Tensorflow框架和python本身,对于每个输入示例都是如此!

我们可以做得更好。 让我们开始编辑label_image.py脚本——对于我来说,它位于bazel-bin / tensorflow / examples / image_retraining / label_image.runfiles / org_tensorflow / tensorflow / examples / image_retraining / label_image.py中。

让我们改变行

141:  run_graph(image_data, labels, FLAGS.input_layer, FLAGS.output_layer,
      142:        FLAGS.num_top_predictions)

141:  for line in sys.stdin:
      142:    run_graph(load_image(line), labels, FLAGS.input_layer, FLAGS.output_layer,
      142:        FLAGS.num_top_predictions)

这确实快了很多,但是这还不是我们能做的最好的!

原因是tf.Session()在第100行上的sess构造。Tensorflow基本上每次调用run_graph时都将所有的计算加载到内存中。当您开始尝试在GPU上进行推理时,这一点就变得很明显了——您可以看到GPU内存随着Tensorflow在GPU上加载和卸载模型参数而上下移动。据我所知,这种结构并不存在于其他ML框架中,比如Caffe或Pytorch。

然后解决方案是拉出with语句,并传递一个sess变量到run_graph:

 

(在https://github.com/hiveml/simple-ml-serving/blob/master/label_image.py上看代码)

如果你运行这个程序,你会发现每张图片加载大约需要0.1秒,对于在线使用来说足够快。

将一次性推断转换为在线推理(其他ML框架)

Caffe使用它的net.forward代码,这个代码很容易放入可调用的框架中:请参阅http://nbviewer.jupyter.org/github/BVLC/caffe/blob/master/examples/00-classification.ipynb

Mxnet也是非常独特的:它实际上具有开源的随时可用的推理服务器代码:https://github.com/awslabs/mxnet-model-server

部署

计划是将这些代码包装在Flask应用程序中。 如果您还没有听说过它,Flask是一个非常轻量级的Python Web框架,它允许您用最少的工作来创建一个http api服务器。

作为一个快速的参考,这是一个flask应用程序,它接收来自多个表单数据的POST请求:

 

这是对应的flask应用程序连接到run_graph上面:

 

这看起来很好,除了flask和tensorflow都是完全同步的——按照接收到的顺序一次处理一个请求,而Tensorflow在进行图像分类时完全占用线程。

正如它所写的那样,速度瓶颈可能还在实际的计算工作中,所以升级Flask包装代码没有太多的意义。现在,也许这段代码足够处理您的负载了。

有两种很明显的方法可以提高请求的通用性:通过增加worker的数量来横向放大,这在下一节将会介绍,或者通过使用GPU和批处理逻辑来纵向扩展。实现后者需要一个能够同时处理多个挂起请求的web服务器,并决定是否继续等待更大的批处理,或者将其发送到Tensorflow图形线程,以便进行分类,而这对于Flask应用程序是非常不适合。有两种可能性,使用Twisted + Klein来保存Python代码,或者如果您更喜欢第一个类的事件循环支持,并且能够连接到非Python ML框架(如Torch),则可以使用Node.js + ZeroMQ。

扩展:负载平衡和服务发现

好的,现在我们有一台服务器来服务我们的模型,但也许它太慢了,或者我们的负载变得太高了。我们想要启动更多的这些服务器——我们如何在每个服务器上分配请求?

普通的方法是添加一个代理层,可能是haproxy或nginx,它平衡后端服务器之间的负载,同时向客户机提供一个统一的接口。为了在本节稍后使用,以下是运行基本Node.js负载均衡器http代理的一些示例代码:

 

为了自动检测后端服务器的数量和位置,人们通常会使用“服务发现”工具,该工具可能与负载平衡器捆绑在一起或者是单独的。一些知名的是Consul和Zookeeper。设置和学习如何使用它不在本文的讨论范围之内,所以我使用了node.js服务发现包seaport来包含一个非常基本的代理。

代理代码:

 

Worker 代码:

 

但是,对于ML,这个设置会遇到带宽问题。

在任何地方,每秒几十到几百张图像,系统就会被网络带宽阻塞。在目前的设置中,所有的数据都必须通过我们的单个seaport 主站,这是呈现给客户端的单个端点。

为了解决这个问题,我们要求我们的客户端不在http://127.0.0.1:12480点击单个端点,而是在后端服务器之间自动轮换点击。如果你知道一些网络,这听起来就像DNS的工作!

但是,设置自定义的DNS服务器已经超出了本文的范围。 相反,通过更改客户端来遵循两步“手动DNS”协议,我们可以重新使用我们的基本seaport代理来实现客户端直接连接到其服务器的“点对点”协议:

代理代码:

 

(worker代码与上述相同)

客户端代码:

 

RPC部署

即将到来!上面的Flask版本被ZeroMQ替换。

结论和进一步阅读

在这一点上,你应该有一些在生产中工作的东西,但它肯定不是未来的保障。本指南中没有涉及到的几个重要的主题:

  • 自动部署和设置新的硬件。
    • 如果你在自己的硬件上,值得注意的工具包括Openstack/VMwareChef / Puppet用于安装Docker和处理网络路由,以及Docker用于安装TensorflowPython和其他任何东西。
    • 如果你在云端,KubernetesMarathon/Mesos也很棒。
  • 模型版本管理
    • 在开始的时候手动处理并不太难。
    • Tensorflow Serving是一个很好的工具,它可以非常彻底地处理这个问题,以及批处理和整体部署。缺点是设置和编写客户端代码有点困难,而且不支持Caffe/PyTorch
  • 如何从Matlab移植你的ML代码
    • 不要在生产中使用matlab
  • GPU驱动程序,CudaCUDNN
    • 使用nvidia-docker并尝试在线查找一些Docker文件。
  • 后处理图层。一旦您在生产中获得了一些不同的ML模型,您可能会开始想要混合并匹配不同的用例——只有在模型B不确定的情况下运行模型A,在Caffe中运行模型C,并将结果传递给Tensorflow中的模型D等等。


作者信息

Bowei,Hive机器学习工程师

本文由北邮@爱可-爱生老师推荐,阿里云云栖组织翻译。

文章原标题《Step-by-step Guide to Deploying Deep Learning Models

作者:Bowei 译者:董昭男 审核:袁虎

文章为简译,更为详细内容,请查看原文

相关实践学习
基于阿里云DeepGPU实例,用AI画唯美国风少女
本实验基于阿里云DeepGPU实例,使用aiacctorch加速stable-diffusion-webui,用AI画唯美国风少女,可提升性能至高至原性能的2.6倍。
相关文章
|
1月前
|
机器学习/深度学习 数据采集 算法
构建高效图像分类模型:深度学习在处理大规模视觉数据中的应用
随着数字化时代的到来,海量的图像数据被不断产生。深度学习技术因其在处理高维度、非线性和大规模数据集上的卓越性能,已成为图像分类任务的核心方法。本文将详细探讨如何构建一个高效的深度学习模型用于图像分类,包括数据预处理、选择合适的网络架构、训练技巧以及模型优化策略。我们将重点分析卷积神经网络(CNN)在图像识别中的运用,并提出一种改进的训练流程,旨在提升模型的泛化能力和计算效率。通过实验验证,我们的模型能够在保持较低计算成本的同时,达到较高的准确率,为大规模图像数据的自动分类和识别提供了一种有效的解决方案。
|
2月前
|
机器学习/深度学习 编解码 API
深度学习+不良身体姿势检测+警报系统+代码+部署(姿态识别矫正系统)
深度学习+不良身体姿势检测+警报系统+代码+部署(姿态识别矫正系统)
54 0
|
1月前
|
机器学习/深度学习 数据采集 PyTorch
使用PyTorch解决多分类问题:构建、训练和评估深度学习模型
使用PyTorch解决多分类问题:构建、训练和评估深度学习模型
使用PyTorch解决多分类问题:构建、训练和评估深度学习模型
|
6天前
|
机器学习/深度学习 API 算法框架/工具
R语言深度学习:用keras神经网络回归模型预测时间序列数据
R语言深度学习:用keras神经网络回归模型预测时间序列数据
16 0
|
6天前
|
机器学习/深度学习 并行计算 算法
R语言深度学习不同模型对比分析案例
R语言深度学习不同模型对比分析案例
21 0
|
7天前
|
机器学习/深度学习 人工智能 分布式计算
R和Python机器学习:广义线性回归glm,样条glm,梯度增强,随机森林和深度学习模型分析
R和Python机器学习:广义线性回归glm,样条glm,梯度增强,随机森林和深度学习模型分析
13 0
|
10天前
|
机器学习/深度学习 自然语言处理 算法
探索深度学习中的序列建模新范式:Mamba模型的突破与挑战
【4月更文挑战第13天】Mamba模型,一种新型序列建模架构,通过选择性状态空间提高处理长序列数据的效率,实现线性时间复杂度。在语言、音频和DNA序列建模中展现优秀性能,尤其在大规模预训练中超越Transformer。然而,面对连续信号数据时可能不及LTI模型,且模型参数优化及硬件实现具有挑战性。
32 5
探索深度学习中的序列建模新范式:Mamba模型的突破与挑战
|
29天前
|
机器学习/深度学习 数据可视化 Linux
深度学习模型可视化工具——Netron使用介绍
深度学习模型可视化工具——Netron使用介绍
41 2
|
29天前
|
机器学习/深度学习 资源调度 算法
深度学习模型数值稳定性——梯度衰减和梯度爆炸的说明
深度学习模型数值稳定性——梯度衰减和梯度爆炸的说明
18 0
|
1月前
|
机器学习/深度学习 PyTorch TensorFlow
python实现深度学习模型(如:卷积神经网络)。
【2月更文挑战第14天】【2月更文挑战第38篇】实现深度学习模型(如:卷积神经网络)。