TensorFlow* 是领先的深度学习和机器学习框架,这使得英特尔和谷歌确保能够从英特尔的硬件产品中获得最大性能非常重要。本文向人工智能 (AI) 社区介绍了基于英特尔® 至强® 和英特尔® 至强融核™ 处理器的平台上的 TensorFlow 优化。这些优化是英特尔的 Diane Bryant 和谷歌的 Diane Green 在首届英特尔人工智能日上宣布的英特尔和谷歌工程师之间密切合作的成果。
我们描述了我们在此优化练习中遇到的各种性能挑战以及采用的解决方案。我们还报告了常见神经网络模型样本的性能改进。这些优化可以带来数量级的更高性能。例如,我们的测量结果显示,在英特尔® 至强融核™ 处理器 7250 (KNL) 上,训练性能提高了 70 倍,推理性能提高了 85 倍。基于英特尔® 至强® 处理器 E5 v4 (BDW) 和英特尔至强融核处理器 7250 的平台,它们为英特尔的下一代产品奠定了基础。特别是,预计用户将在今年晚些时候看到英特尔至强(代号为 Skylake)和英特尔至强融核(代号为 Knights Mill)的性能提升。
在现代 CPU 上优化深度学习模型性能带来了许多挑战,与在高性能计算 (HPC) 中优化其他对性能敏感的应用程序时所见的挑战没有太大区别:
- 代码重构需要利用现代向量指令。这意味着确保将所有关键原语(例如卷积、矩阵乘法和批量标准化)矢量化为最新的 SIMD 指令(英特尔至强处理器的 AVX2 和英特尔至强融核处理器的 AVX512)。
- 最高性能需要特别注意有效地使用所有可用内核。这再次意味着查看给定层或操作内的并行化以及跨层的并行化。
- 当执行单元需要时,数据必须尽可能可用。这意味着平衡使用预取、缓存阻塞技术和促进空间和时间局部性的数据格式。
为了满足这些要求,英特尔开发了许多优化的深度学习原语,可以在不同的深度学习框架中使用,以确保我们有效地实施通用构建块。除了矩阵乘法和卷积之外,这些构建块还包括:
- 直接批量卷积
- 内积
- 池化:最大值、最小值、平均值
- 归一化:跨通道的局部响应归一化(LRN),批量归一化
- 激活:整流线性单元(ReLU)
- 数据操作:多维转置(转换)、拆分、连接、求和和缩放。
请参阅本文,了解有关这些面向深度神经网络(英特尔® MKL-DNN)优化原语的英特尔® 数学核心函数库的更多详细信息。
在 TensorFlow 中,我们实施了英特尔优化的操作版本,以确保这些操作可以尽可能利用英特尔 MKL-DNN 原语。虽然这是在英特尔® 架构上实现可扩展性能的必要步骤,但我们还必须实施许多其他优化。特别是,出于性能原因,英特尔 MKL 使用与 TensorFlow 中的默认布局不同的布局。我们需要确保将两种格式之间的转换开销保持在最低限度。我们还希望确保数据科学家和其他 TensorFlow 用户不必更改他们现有的神经网络模型来利用这些优化。
图优化
我们引入了一些图优化通道:
- 在 CPU 上运行时,将默认 TensorFlow 操作替换为 Intel 优化版本。这确保了用户可以运行他们现有的 Python 程序并实现性能提升,而无需更改他们的神经网络模型。
- 消除不必要且成本高昂的数据布局转换。
- 将多个操作融合在一起,以实现 CPU 上的高效缓存重用。
- 处理允许更快反向传播的中间状态。
这些图形优化可实现更高的性能,而不会给 TensorFlow 程序员带来任何额外的负担。数据布局优化是一个关键的性能优化。通常,对于 CPU 上的某些张量操作,原生 TensorFlow 数据格式并不是最有效的数据布局。在这种情况下,我们插入一个从 TensorFlow 原生格式到内部格式的数据布局转换操作,在 CPU 上执行该操作,并将操作输出转换回 TensorFlow 格式。但是,这些转换会带来性能开销,应尽量减少。我们的数据布局优化确定了可以使用英特尔 MKL 优化操作完全执行的子图,并消除了子图中操作内的转换。自动插入的转换节点负责子图边界处的数据布局转换。另一个关键优化是融合通道,它自动融合可以作为单个英特尔 MKL 操作高效运行的操作。
其他优化
我们还调整了一些 TensorFlow 框架组件,为各种深度学习模型提供最高的 CPU 性能。我们使用 TensorFlow 中现有的池分配器开发了一个自定义池分配器。我们的自定义池分配器确保 TensorFlow 和英特尔 MKL 共享相同的内存池(使用英特尔 MKL imalloc 功能),并且我们不会过早地将内存返回给操作系统,从而避免代价高昂的页面丢失和页面清除。此外,我们仔细调整了多个线程库(TensorFlow 使用的 pthread 和 Intel MKL 使用的 OpenMP)共存,而不是相互竞争 CPU 资源。
性能实验
我们的优化(例如上面讨论的优化)在英特尔至强和英特尔至强融核平台上带来了显着的性能提升。为了说明性能提升,我们在下面报告了我们最知名的方法(或 BKM)以及三个常见ConvNet 基准的基线和优化性能数字。
- 以下参数对于英特尔至强(代号 Broadwell)和英特尔至强融核(代号 Knights Landing)处理器的性能很重要,我们建议针对您的特定神经网络模型和平台调整它们。我们仔细调整了这些参数,以便在 Intel Xeon 和 Intel Xeon Phi 处理器上获得最大的 convnet-benchmarks 性能。
- 数据格式:我们建议用户可以为其特定的神经网络模型指定 NCHW 格式,以获得最佳性能。TensorFlow 默认的 NHWC 格式不是 CPU 最有效的数据布局,它会导致一些额外的转换开销。
- Inter-op/intra-op:我们还建议数据科学家和用户在 TensorFlow 中试验 intra-op 和 inter-op 参数,以获得每个模型和 CPU 平台的最佳设置。这些设置会影响一层内以及跨层的并行性。
- 批量大小:批量大小是另一个重要参数,它通常会影响利用所有内核的可用并行度以及工作集大小和内存性能。
- OMP_NUM_THREADS:最大性能需要有效地使用所有可用内核。此设置对于 Intel Xeon Phi 处理器的性能尤其重要,因为它控制超线程级别(1 到 4)。
- 矩阵乘法中的转置:对于某些矩阵大小,转置第二个输入矩阵 b 在 Matmul 层提供更好的性能(更好的缓存重用)。以下三个模型中使用的所有 Matmul 操作都是这种情况。用户应针对其他矩阵大小尝试此设置。
- KMP_BLOCKTIME:用户应该尝试各种设置,以了解每个线程在完成并行区域的执行后应该等待多长时间,以毫秒为单位。
英特尔® 至强® 处理器上的示例设置(代号 Broadwell - 2 Sockets - 22 Cores)
英特尔® 至强融核™ 处理器(代号 Knights Landing - 68 核)上的示例设置
- 英特尔® 至强® 处理器(代号 Broadwell – 2 Sockets – 22 Cores)的性能结果
- 英特尔® 至强融核™ 处理器(代号 Knights Landing – 68 核)上的性能结果
- 英特尔® 至强® 处理器(代号 Broadwell)和英特尔® 至强融核™ 处理器(代号 Knights Landing)上不同批次大小的性能结果 - 培训
使用 CPU 优化构建和安装 TensorFlow
- 从 TensorFlow 源目录运行“./configure”,如果您选择使用英特尔 MKL 的选项,它将自动在tensorflow/third_party/mkl/mklml中下载最新的英特尔 MKL 用于机器学习。
- 执行以下命令创建一个 pip 包,可用于安装优化的 TensorFlow 构建。
- PATH 可以更改为指向特定版本的 GCC 编译器:
export PATH=/PATH/gcc/bin:$PATH - LD_LIBRARY_PATH 也可以更改为指向新的 GLIBC:
export LD_LIBRARY_PATH=/PATH/gcc/lib64:$LD_LIBRARY_PATH。 - 在 Intel Xeon 和 Intel Xeon Phi 处理器上构建以获得最佳性能:
bazel build --config=mkl --copt="-DEIGEN_USE_VML" -c opt //tensorflow/tools/pip_package:
build_pip_package
- PATH 可以更改为指向特定版本的 GCC 编译器:
- 安装优化的 TensorFlow 轮
- bazel-bin/tensorflow/tools/pip_package/build_pip_package ~/path_to_save_wheel
pip install --upgrade --user ~/path_to_save_wheel /wheel_name.whl
- bazel-bin/tensorflow/tools/pip_package/build_pip_package ~/path_to_save_wheel
系统配置
对人工智能意味着什么
优化 TensorFlow 意味着使用这个广泛可用且应用广泛的框架构建的深度学习应用程序现在可以在英特尔处理器上运行得更快,从而提高灵活性、可访问性和可扩展性。例如,英特尔至强融核处理器旨在以近乎线性的方式跨内核和节点横向扩展,以显着减少训练机器学习模型的时间。随着我们继续增强英特尔处理器的性能以处理更大、更具挑战性的 AI 工作负载,TensorFlow 现在可以随着未来的性能提升而扩展。
英特尔与谷歌合作优化 TensorFlow 是为了让开发人员和数据科学家更容易访问人工智能,并使人工智能应用程序能够在任何类型的设备上运行——从边缘到云端——都可以在任何需要的地方运行。英特尔认为,这是创建下一代 AI 算法和模型以解决商业、科学、工程、医学和社会中最紧迫问题的关键。