使用 NNPACK 库加速 Apache MXNet

阅读数:49 2019 年 10 月 31 日 08:00

使用 NNPACK 库加速 Apache MXNet

Apache MXNet 是供开发人员构建、训练和重复使用深度学习网络的开源库。在这篇博文中,我将向您介绍如何使用 NNPACK 库来加速推理。事实上,当 GPU 推理不可用时,要想从实例中获取更多性能,将 NNPACK 添加到 Apache MXNet 中或许不失为一种简单的方法。和往常一样,“您的情况可能会有所不同”,而且您应该始终运行自己的测试。

在我们开始之前,先来了解一些训练和推理的基础知识吧。

培训

_ 训练 _ 是神经网络学习如何正确预测数据集中各个示例的正确标签的步骤。每次一批 (通常包含 32 到 256 个示例),数据集被馈送到网络中,通过反向传播算法调整权重以减少总误差。

浏览完整的数据集被称为 epoch。大型网络可能会接受数百个 epoch 的训练,以达到尽可能最高的准确度。这可能需要几天甚至几周的时间。GPU 具有强大的并行处理能力,即使与最强大的 CPU 相比,训练时间也可以大大缩短。

推理

_ 推理 _ 是实际使用经过训练的网络预测新数据示例的步骤。您可以一次预测一个示例,例如像 Amazon Rekognition 一样尝试识别单个图像中的对象,或者在处理来自多个用户的请求时可以一次预测多个示例。

当然,GPU 在推理方面同样十分高效。然而,许多系统由于成本、功耗或外形尺寸限制而无法容纳 GPU。因此,能够快速运行基于 CPU 的推理仍然是一个重要的课题。这正是 NNPACK 库发挥作用的地方,它可以帮助我们在 Apache MXNet 中加速 CPU 推理。

NNPACK 库

NNPACK 是一个可在 GitHub 上使用的开源库。它将如何帮助我们呢?您肯定了解卷积神经网络。这些网络由多个层构建,应用卷积和池来检测输入图像中的特征。

在这篇文章中,我们不涉及实际理论,而是介绍 NNPACK 如何以高度优化的方式实施这些操作 (以及其他一些操作,如矩阵乘法)。如果您对基础理论感兴趣,请参阅这篇 Reddit 帖子的作者提到的研究论文。

NNPACK 可应用于 Linux 和 MacOS X 平台之上。它针对采用 AVX2 指令集的 Intel x86-64 处理器以及采用 NEON 指令集的 ARMv7 处理器和 ARM v8 处理器进行了优化。

在这篇文章中,我使用了运行 Deep Learning AMI 的 c5.9xlarge 实例。以下是我们将要执行的操作:

  • 从源代码构建 NNPACK 库。
  • 使用 NNPACK 从源代码构建 Apache MXNet
  • 使用各种网络运行一些图像分类基准

让我们开始吧。

构建 NNPACK

NNPACK 使用 Ninja 构建工具。但是 Ubuntu 存储库并没有托管最新的版本,所以我们也需要从源代码进行构建。

Bash

复制代码
cd ~
git clone git://github.com/ninja-build/ninja.git && cd ninja
git checkout release
./configure.py --bootstrap
sudo cp ninja /usr/bin

现在,让我们按照以下说明来准备 NNPACK 的构建。

Bash

复制代码
cd ~
sudo -H pip install --upgrade git+https://github.com/Maratyszcza/PeachPy
sudo -H pip install --upgrade git+https://github.com/Maratyszcza/confu
git clone https://github.com/Maratyszcza/NNPACK.git
cd NNPACK
confu setup
python ./configure.py

在实际构建之前,我们需要调整一下配置文件。因为 NNPACK 只是作为一个静态库来构建,而 MXNET 则是作为一个动态库来构建的。也就是说他们将不能正确连接。MXNet 文档建议使用旧版 NNPACK,不过还有另一种方法。

我们需要编辑 build.ninja 文件和“-fPIC”标志,以便将 C 和 C ++ 文件构建为与位置无关的代码,这其实就是我们与 MXNet 共享库连接所需要的全部内容。

Bash

复制代码
cflags = -std=gnu99 -g -pthread -fPIC
cxxflags = -std=gnu++11 -g -pthread -fPIC

现在,我们来构建 NNPACK 并运行部分基本测试。

Bash

复制代码
ninja
ninja smoketest

我们完成了 NNPACK 构建。您应该可以在 ~/NNPACK/lib 中看到这个库。

使用 NNPACK 构建 Apache MXNet

首先,我们安装 dependency 以及最新的 MXNet 源代码 (撰写本文时为 0.11.0-rc3)。详细的构建说明请参阅 MXNet 网站

Bash

复制代码
cd ~
sudo apt-get install -y libopenblas-dev liblapack-dev libopencv-dev
git clone --recursive https://github.com/apache/incubator-mxnet.git
cd incubator-mxnet/
git checkout 1.0.0

现在,我们需要配置 MXNet 构建。您应该编辑 make/config.mk 文件并设置以下变量,以便在构建中包含 NNPACK 以及之前安装的 dependency。只需复制文件末尾的所有内容。

Bash

复制代码
NNPACK = /home/ubuntu/NNPACK
# the additional link flags you want to add
ADD_LDFLAGS = -L$(NNPACK)/lib/ -lnnpack -lpthreadpool
# the additional compile flags you want to add
ADD_CFLAGS = -I$(NNPACK)/include/ -I$(NNPACK)/deps/pthreadpool/include/
USE_NNPACK=1
USE_BLAS=openblas
USE_OPENCV=1

现在,我们准备构建 MXNet。我们的实例有 36 个 vCPU,让我们来好好利用它们吧。

Bash

复制代码
make -j72

大约四分钟后,构建完成。让我们来安装全新的 MXNet 库及其 Python binding。

Bash

复制代码
sudo apt-get install -y python-dev python-setuptools python-numpy python-pip
cd python
sudo -H pip install --upgrade pip
sudo -H pip install -e .

我们可以在 Python 中导入 MXNet,从而快速检查是否有合适的版本。

Bash

复制代码
Python 2.7.12 (default, Nov 20 2017, 18:23:56)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import mxnet
>>> mxnet.__version__
'1.0.0'

一切准备完毕。可以运行部分基准了。

基准测试

用几张图像进行基准测试并不能让我们就 NNPACK 是否发挥效用得出可靠的判断。不过幸好 MXNet 源代码包含一个基准测试脚本,可以通过以下模型以各种批处理大小提供随机生成的图像:AlexNet、VGG16、Inception-BN、Inception v3、ResNet-50 和 ResNet-152。当然,这里的重点不是执行预测,而只是测算推理时间。

在我们开始之前,需要在脚本中修复一行代码。我们的实例没有安装 GPU (这是关键问题),而且脚本无法正确检测到这一事实。以下是需要在 ~/incubator-mxnet/example/image-classification/benchmark_score.py 中做出的修改。执行到这里时,让我们来添加其他批处理大小。

Bash

复制代码
#devs = [mx.gpu(0)] if len(get_gpus()) > 0 else []
devs = []
devs.append(mx.cpu())
batch_sizes = [1, 2, 4, 8, 16, 32, 64, 128, 256]

可以运行部分基准了。我们对 NNPACK 使用八个线程,这是最大的推荐值。

Bash

复制代码
cd ~/incubator-mxnet/example/image-classification/
export MXNET_CPU_NNPACK_NTHREADS=8
python benchmark_score.py

作为参考,我也在运行 vanilla MXNet 1.0 的相同实例上运行了相同的脚本。以下图表显示了每秒图像数量与批处理大小的关系。您肯定可以猜测得到,每秒的图像数量越多越好。

您可以看到,NNPACK 为 AlexNet、VGG 和 Inception-BN 的加速非常明显,尤其是单个图像推理 (速度提高了 4 倍之多)。

注意:由于本文讨论范围以外的原因,Inception v3 和 ResNet 没有加速,所以我没有提供这些网络的图表。

使用 NNPACK 库加速 Apache MXNet
使用 NNPACK 库加速 Apache MXNet

结论

希望您能够喜欢这篇文章,也期待您的反馈。如需了解有关深度学习和 Apache MXNet 内容的更多信息,请在 Medium Twitter 上关注我。

作者介绍:

使用 NNPACK 库加速 Apache MXNetJulien 一直致力于在欧洲、中东和非洲大力传播人工智能和机器学习。他倾尽全力帮助开发人员和企业实现自己的想法。闲暇之余,他反复地徜徉在 JRR Tolkien 的作品之中。

本文转载自 AWS 技术博客。

原文链接:
https://amazonaws-china.com/cn/blogs/china/speeding-up-apache-mxnet-using-the-nnpack-library/

欲了解 AWS 的更多信息,请访问【AWS 技术专区】

评论

发布