【翻译】Sklearn与TensorFlow机器学习实用指南 ——第12章 设备和服务器上的分布式TensorFlow(上)

简介:

在第 11 章,我们讨论了几种可以明显加速训练的技术:更好的权重初始化,批量标准化,复杂的优化器等等。 但是,即使采用了所有这些技术,在具有单个 CPU 的单台机器上训练大型神经网络可能需要几天甚至几周的时间。

在本章中,我们将看到如何使用 TensorFlow 在多个设备(CPU 和 GPU)上分配计算并将它们并行运行(参见图 12-1)。 首先,我们会先在一台机器上的多个设备上分配计算,然后在多台机器上的多个设备上分配计算。

535370f24eef4b58e27fd985812ad302f38ee02d

与其他神经网络框架相比,TensorFlow 对分布式计算的支持是其主要亮点之一。 它使您可以完全控制如何跨设备和服务器分布(或复制)您的计算图,并且可以让您以灵活的方式并行和同步操作,以便您可以在各种并行方法之间进行选择。

我们来看一些最流行的方法来并行执行和训练一个神经网络,这让我们不再需要等待数周才能完成训练算法,而最终可能只会等待几个小时。 这不仅可以节省大量时间,还意味着您可以更轻松地尝试各种模型,并经常重新训练模型上的新数据。

还有其他很好的并行化例子,包括当我们在微调模型时可以探索更大的超参数空间,并有效地运行大规模神经网络。

但我们必须先学会走路才能跑步。 我们先从一台机器上的几个 GPU 上并行化简单图形开始。

一台机器上多设备

只需添加 GPU 卡到单个机器,您就可以获得主要的性能提升。 事实上,在很多情况下,这就足够了。 你根本不需要使用多台机器。 例如,通常在单台机器上使用 8 个 GPU,而不是在多台机器上使用 16 个 GPU(由于多机器设置中的网络通信带来的额外延迟),可以同样快地训练神经网络。

在本节中,我们将介绍如何设置您的环境,以便 TensorFlow 可以在一台机器上使用多个 GPU 卡。 然后,我们将看看如何在可用设备上进行分布操作,并且并行执行它们。

安装

为了在多个 GPU 卡上运行 TensorFlow,首先需要确保 GPU 卡具有 NVidia 计算能力(大于或等于3.0)。 这包括 Nvidia 的 Titan,Titan X,K20 和 K40(如果你拥有另一张卡,你可以在https://developer.nvidia.com/cuda-gpus 查看它的兼容性)。

如果您不拥有任何 GPU 卡,则可以使用具有 GPU 功能的主机服务器,如 Amazon AWS。 在 ŽigaAvsec 的博客文章中,提供了在 Amazon AWS GPU 实例上使用 Python 3.5 设置 TensorFlow 0.9 的详细说明。将它更新到最新版本的 TensorFlow 应该不会太难。 Google 还发布了一项名为 Cloud Machine Learning 的云服务来运行 TensorFlow 图表。 2016 年 5 月,他们宣布他们的平台现在包括配备张量处理器(TPU)的服务器,专门用于机器学习的处理器,比许多 GPU 处理 ML 任务要快得多。 当然,另一种选择只是购买你自己的 GPU 卡。 Tim Dettmers 写了一篇很棒的博客文章来帮助你选择,他会定期更新它。

您必须下载并安装相应版本的 CUDA 和 cuDNN 库(如果您使用的是 TensorFlow 1.0.0,则为 CUDA 8.0 和 cuDNN 5.1),并设置一些环境变量,以便 TensorFlow 知道在哪里可以找到 CUDA 和 cuDNN。 详细的安装说明可能会相当迅速地更改,因此最好按照 TensorFlow 网站上的说明进行操作。

Nvidia 的 CUDA 允许开发者使用支持 CUDA 的 GPU 进行各种计算(不仅仅是图形加速)。 Nvidia 的 CUDA 深度神经网络库(cuDNN)是针对 DNN 的 GPU 加速原语库。 它提供了常用 DNN 计算的优化实现,例如激活层,归一化,前向和后向卷积以及池化(参见第 13 章)。 它是 Nvidia Deep Learning SDK 的一部分(请注意,它需要创建一个 Nvidia 开发者帐户才能下载它)。 TensorFlow 使用 CUDA 和 cuDNN 来控制 GPU 卡并加速计算(见图 12-2)。

791ce85861386303ac2899b8079d52a95b3a3b37

您可以使用nvidia-smi命令来检查 CUDA 是否已正确安装。 它列出了可用的 GPU 卡以及每张卡上运行的进程:

5cfadd63eafd3066e146c8acbb5327497697b2e8

最后,您必须安装支持 GPU 的 TensorFlow。 如果你使用virtualenv创建了一个独立的环境,你首先需要激活它:


$ cd $ML_PATH
# Your ML working directory (e.g., HOME/ml)
$ source env/bin/activate

然后安装合适的支持 GPU 的 TensorFlow 版本:

$ pip3 install --upgrade tensorflow-gpu

现在您可以打开一个 Python shell 并通过导入 TensorFlow 并创建一个会话来检查 TensorFlow 是否正确检测并使用 CUDA 和 cuDNN:


>>> import tensorflow as tf
I [...]/dso_loader.cc:108] successfully opened CUDA library libcublas.so locally
I [...]/dso_loader.cc:108] successfully opened CUDA library libcudnn.so locally
I [...]/dso_loader.cc:108] successfully opened CUDA library libcuda.so.1 locally
I [...]/dso_loader.cc:108] successfully opened CUDA library libcufft.so locally
I [...]/gpu_init.cc:102] Found device 0 with properties:
I [...]/dso_loader.cc:108] successfully opened CUDA library libcurand.so locally >>> sess = tf.Session() [...] name: GRID K520
I [...]/gpu_init.cc:136] 0: Y
major: 3 minor: 0 memoryClockRate (GHz) 0.797 pciBusID 0000:00:03.0 Total memory: 4.00GiB Free memory: 3.95GiB I [...]/gpu_init.cc:126] DMA: 0
(/gpu:0) -> (device: 0, name: GRID K520, pci bus id: 0000:00:03.0)
I [...]/gpu_device.cc:839] Creating TensorFlow device

看起来不错!TensorFlow 检测到 CUDA 和 cuDNN 库,并使用 CUDA 库来检测 GPU 卡(在这种情况下是 Nvidia Grid K520 卡)。

管理 GPU 内存

默认情况下,TensorFlow 会在您第一次运行图形时自动获取所有可用 GPU 中的所有 RAM,因此当第一个程序仍在运行时,您将无法启动第二个 TensorFlow 程序。 如果你尝试,你会得到以下错误:

E [...]/cuda_driver.cc:965] failed to allocate 3.66G (3928915968 bytes) from device: CUDA_ERROR_OUT_OF_MEMORY

一种解决方案是在不同的 GPU 卡上运行每个进程。 为此,最简单的选择是设置CUDA_VISIBLE_DEVICES环境变量,以便每个进程只能看到对应的 GPU 卡。 例如,你可以像这样启动两个程序:


$ CUDA_VISIBLE_DEVICES=0,1 python3 program_1.py
# and in another terminal:
$ CUDA_VISIBLE_DEVICES=3,2 python3 program_2.py

程序 #1 只会看到 GPU 卡 0 和 1(分别编号为 0 和 1),程序 #2 只会看到 GPU 卡 2 和 3(分别编号为 1 和 0)。 一切都会正常工作(见图 12-3)。

ee33778ec7e1b6d792deb9b056a2c80b6923a5ec

另一种选择是告诉 TensorFlow 只抓取一小部分内存。 例如,要使 TensorFlow 只占用每个 GPU 内存的 40%,您必须创建一个ConfigProto对象,将其gpu_options.per_process_gpu_memory_fraction选项设置为 0.4,并使用以下配置创建session


config = tf.ConfigProto()
config.gpu_options.per_process_gpu_memory_fraction = 0.4
session = tf.Session(config=config)

现在像这样的两个程序可以使用相同的 GPU 卡并行运行(但不是三个,因为3×0.4> 1)。 见图 12-4。

e943df87ba140eb10e6a9f7538fe043aeb7708ce

如果在两个程序都运行时运行nvidia-smi命令,则应该看到每个进程占用每个卡的总 RAM 大约 40%:

7814284c6a09b087c5606fdca8e9c09e470e2717

另一种选择是告诉 TensorFlow 只在需要时才抓取内存。 为此,您必须将config.gpu_options.allow_growth设置为True。但是,TensorFlow 一旦抓取内存就不会释放内存(以避免内存碎片),因此您可能会在一段时间后内存不足。 是否使用此选项可能难以确定,因此一般而言,您可能想要坚持之前的某个选项。

好的,现在你已经有了一个支持 GPU 的 TensorFlow 安装。 让我们看看如何使用它!

设备布置操作

TensorFlow 白皮书介绍了一种友好的动态布置器算法,该算法能够自动将操作分布到所有可用设备上,并考虑到以前运行图中所测量的计算时间,估算每次操作的输入和输出张量的大小, 每个设备可用的 RAM,传输数据进出设备时的通信延迟,来自用户的提示和约束等等。 不幸的是,这种复杂的算法是谷歌内部的,它并没有在 TensorFlow 的开源版本中发布。它被排除在外的原因似乎是,由用户指定的一小部分放置规则实际上比动态放置器放置的更有效。 然而,TensorFlow 团队正在努力改进它,并且最终可能会被开放。

在此之前,TensorFlow都是简单的放置,它(如其名称所示)非常基本。

简单放置

无论何时运行图形,如果 TensorFlow 需要求值尚未放置在设备上的节点,则它会使用简单放置器将其放置在未放置的所有其他节点上。 简单放置尊重以下规则:

d47e62d2b349aca45e42305ed6714efbe5ed61d9 如果某个节点已经放置在图形的上一次运行中的某个设备上,则该节点将保留在该设备上。
d47e62d2b349aca45e42305ed6714efbe5ed61d9 否则,如果用户将一个节点固定到设备上(下面介绍),则放置器将其放置在该设备上。
d47e62d2b349aca45e42305ed6714efbe5ed61d9 否则,它默认为 GPU#0,如果没有 GPU,则默认为 CPU。

正如您所看到的,将操作放在适当的设备上主要取决于您。 如果您不做任何事情,整个图表将被放置在默认设备上。 要将节点固定到设备上,您必须使用device()函数创建一个设备块。 例如,以下代码将变量a和常量b固定在 CPU 上,但乘法节点c不固定在任何设备上,因此将放置在默认设备上:


with tf.device("/cpu:0"):
a = tf.Variable(3.0)
c = a * b
b = tf.constant(4.0)

其中,"/cpu:0"设备合计多 CPU 系统上的所有 CPU。 目前没有办法在特定 CPU 上固定节点或仅使用所有 CPU 的子集。

记录放置位置

让我们检查一下简单的放置器是否遵守我们刚刚定义的布局约束条件。 为此,您可以将log_device_placement选项设置为True;这告诉放置器在放置节点时记录消息。例如:


>>> config = tf.ConfigProto()
>>> config.log_device_placement = True
>>> sess = tf.Session(config=config)
I [...] Creating TensorFlow device (/gpu:0) -> (device: 0, name: GRID K520, pci bus id: 0000:00:03.0)
[...] >>> x.initializer.run(session=sess) I [...] a: /job:localhost/replica:0/task:0/cpu:0
I [...] a/Assign: /job:localhost/replica:0/task:0/cpu:0
I [...] a/read: /job:localhost/replica:0/task:0/cpu:0 I [...] mul: /job:localhost/replica:0/task:0/gpu:0
12
I [...] b: /job:localhost/replica:0/task:0/cpu:0 I [...] a/initial_value: /job:localhost/replica:0/task:0/cpu:0
>>> sess.run(c)

Info中以大写字母I开头的行是日志消息。 当我们创建一个会话时,TensorFlow 会记录一条消息,告诉我们它已经找到了一个 GPU 卡(在这个例子中是 Grid K520 卡)。 然后,我们第一次运行图形(在这种情况下,当初始化变量a时),简单布局器运行,并将每个节点放置在分配给它的设备上。正如预期的那样,日志消息显示所有节点都放在"/cpu:0"上,除了乘法节点,它以默认设备"/gpu:0"结束(您可以先忽略前缀:/job:localhost/replica:0/task:0;我们将在一会儿讨论它)。 注意,我们第二次运行图(计算c)时,由于 TensorFlow 需要计算的所有节点c都已经放置,所以不使用布局器。

动态放置功能

创建设备块时,可以指定一个函数,而不是设备名称。TensorFlow 会调用这个函数来进行每个需要放置在设备块中的操作,并且该函数必须返回设备的名称来固定操作。 例如,以下代码将固定所有变量节点到"/cpu:0"(在本例中只是变量a)和所有其他节点到"/gpu:0"


def variables_on_cpu(op):
if op.type == "Variable":
return "/cpu:0" else:
with tf.device(variables_on_cpu):
return "/gpu:0" a = tf.Variable(3.0)
c = a * b
b = tf.constant(4.0)

您可以轻松实现更复杂的算法,例如以循环方式用GPU锁定变量。

操作和内核

对于在设备上运行的 TensorFlow 操作,它需要具有该设备的实现;这被称为内核。 许多操作对于 CPU 和 GPU 都有内核,但并非全部都是。 例如,TensorFlow 没有用于整数变量的 GPU 内核,因此当 TensorFlow 尝试将变量i放置到 GPU#0 时,以下代码将失败:


>>> with tf.device("/gpu:0"):
... i = tf.Variable(3)
>>> sess.run(i.initializer)
[...]
Traceback (most recent call last):
[...]
tensorflow.python.framework.errors.InvalidArgumentError: Cannot assign a device to node 'Variable': Could not satisfy explicit device specification

请注意,TensorFlow 推断变量必须是int32类型,因为初始化值是一个整数。 如果将初始化值更改为 3.0 而不是 3,或者如果在创建变量时显式设置dtype = tf.float32,则一切正常。

软放置

默认情况下,如果您尝试在操作没有内核的设备上固定操作,则当 TensorFlow 尝试将操作放置在设备上时,您会看到前面显示的异常。 如果您更喜欢 TensorFlow 回退到 CPU,则可以将allow_soft_placement配置选项设置为True


with tf.device("/gpu:0"):
i = tf.Variable(3)
config.allow_soft_placement = True
config = tf.ConfigProto()
sess.run(i.initializer) # the placer runs and falls back to /cpu:0
sess = tf.Session(config=config)

到目前为止,我们已经讨论了如何在不同设备上放置节点。 现在让我们看看 TensorFlow 如何并行运行这些节点。


原文发布时间为:2018-06-26

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

相关实践学习
部署Stable Diffusion玩转AI绘画(GPU云服务器)
本实验通过在ECS上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。
相关文章
|
7天前
|
机器学习/深度学习 人工智能 算法
【手写数字识别】Python+深度学习+机器学习+人工智能+TensorFlow+算法模型
手写数字识别系统,使用Python作为主要开发语言,基于深度学习TensorFlow框架,搭建卷积神经网络算法。并通过对数据集进行训练,最后得到一个识别精度较高的模型。并基于Flask框架,开发网页端操作平台,实现用户上传一张图片识别其名称。
24 0
【手写数字识别】Python+深度学习+机器学习+人工智能+TensorFlow+算法模型
|
18天前
|
机器学习/深度学习 TensorFlow API
机器学习实战:TensorFlow在图像识别中的应用探索
【10月更文挑战第28天】随着深度学习技术的发展,图像识别取得了显著进步。TensorFlow作为Google开源的机器学习框架,凭借其强大的功能和灵活的API,在图像识别任务中广泛应用。本文通过实战案例,探讨TensorFlow在图像识别中的优势与挑战,展示如何使用TensorFlow构建和训练卷积神经网络(CNN),并评估模型的性能。尽管面临学习曲线和资源消耗等挑战,TensorFlow仍展现出广阔的应用前景。
46 5
|
1月前
|
机器学习/深度学习 人工智能 算法
【玉米病害识别】Python+卷积神经网络算法+人工智能+深度学习+计算机课设项目+TensorFlow+模型训练
玉米病害识别系统,本系统使用Python作为主要开发语言,通过收集了8种常见的玉米叶部病害图片数据集('矮花叶病', '健康', '灰斑病一般', '灰斑病严重', '锈病一般', '锈病严重', '叶斑病一般', '叶斑病严重'),然后基于TensorFlow搭建卷积神经网络算法模型,通过对数据集进行多轮迭代训练,最后得到一个识别精度较高的模型文件。再使用Django搭建Web网页操作平台,实现用户上传一张玉米病害图片识别其名称。
56 0
【玉米病害识别】Python+卷积神经网络算法+人工智能+深度学习+计算机课设项目+TensorFlow+模型训练
|
2月前
|
机器学习/深度学习 算法 TensorFlow
交通标志识别系统Python+卷积神经网络算法+深度学习人工智能+TensorFlow模型训练+计算机课设项目+Django网页界面
交通标志识别系统。本系统使用Python作为主要编程语言,在交通标志图像识别功能实现中,基于TensorFlow搭建卷积神经网络算法模型,通过对收集到的58种常见的交通标志图像作为数据集,进行迭代训练最后得到一个识别精度较高的模型文件,然后保存为本地的h5格式文件。再使用Django开发Web网页端操作界面,实现用户上传一张交通标志图片,识别其名称。
103 6
交通标志识别系统Python+卷积神经网络算法+深度学习人工智能+TensorFlow模型训练+计算机课设项目+Django网页界面
|
1月前
|
机器学习/深度学习 算法 数据可视化
【机器学习】决策树------迅速了解其基本思想,Sklearn的决策树API及构建决策树的步骤!!!
【机器学习】决策树------迅速了解其基本思想,Sklearn的决策树API及构建决策树的步骤!!!
|
3月前
|
持续交付 测试技术 jenkins
JSF 邂逅持续集成,紧跟技术热点潮流,开启高效开发之旅,引发开发者强烈情感共鸣
【8月更文挑战第31天】在快速发展的软件开发领域,JavaServer Faces(JSF)这一强大的Java Web应用框架与持续集成(CI)结合,可显著提升开发效率及软件质量。持续集成通过频繁的代码集成及自动化构建测试,实现快速反馈、高质量代码、加强团队协作及简化部署流程。以Jenkins为例,配合Maven或Gradle,可轻松搭建JSF项目的CI环境,通过JUnit和Selenium编写自动化测试,确保每次构建的稳定性和正确性。
62 0
|
3月前
|
缓存 开发者 测试技术
跨平台应用开发必备秘籍:运用 Uno Platform 打造高性能与优雅设计兼备的多平台应用,全面解析从代码共享到最佳实践的每一个细节
【8月更文挑战第31天】Uno Platform 是一种强大的工具,允许开发者使用 C# 和 XAML 构建跨平台应用。本文探讨了 Uno Platform 中实现跨平台应用的最佳实践,包括代码共享、平台特定功能、性能优化及测试等方面。通过共享代码、采用 MVVM 模式、使用条件编译指令以及优化性能,开发者可以高效构建高质量应用。Uno Platform 支持多种测试方法,确保应用在各平台上的稳定性和可靠性。这使得 Uno Platform 成为个人项目和企业应用的理想选择。
64 0
|
3月前
|
API UED 开发者
如何在Uno Platform中轻松实现流畅动画效果——从基础到优化,全方位打造用户友好的动态交互体验!
【8月更文挑战第31天】在开发跨平台应用时,确保用户界面流畅且具吸引力至关重要。Uno Platform 作为多端统一的开发框架,不仅支持跨系统应用开发,还能通过优化实现流畅动画,增强用户体验。本文探讨了Uno Platform中实现流畅动画的多个方面,包括动画基础、性能优化、实践技巧及问题排查,帮助开发者掌握具体优化策略,提升应用质量与用户满意度。通过合理利用故事板、减少布局复杂性、使用硬件加速等技术,结合异步方法与预设缓存技巧,开发者能够创建美观且流畅的动画效果。
80 0
|
1月前
|
机器学习/深度学习 人工智能 自然语言处理
【MM2024】阿里云 PAI 团队图像编辑算法论文入选 MM2024
阿里云人工智能平台 PAI 团队发表的图像编辑算法论文在 MM2024 上正式亮相发表。ACM MM(ACM国际多媒体会议)是国际多媒体领域的顶级会议,旨在为研究人员、工程师和行业专家提供一个交流平台,以展示在多媒体领域的最新研究成果、技术进展和应用案例。其主题涵盖了图像处理、视频分析、音频处理、社交媒体和多媒体系统等广泛领域。此次入选标志着阿里云人工智能平台 PAI 在图像编辑算法方面的研究获得了学术界的充分认可。
【MM2024】阿里云 PAI 团队图像编辑算法论文入选 MM2024
|
28天前
|
机器学习/深度学习 算法 Java
机器学习、基础算法、python常见面试题必知必答系列大全:(面试问题持续更新)
机器学习、基础算法、python常见面试题必知必答系列大全:(面试问题持续更新)