(Alibaba) Junjie Cai; King Sheng; (Intel) Jason Dai; Ban Hsu; Wesley Du; Yang Wang; Yina Chen等作者

在阿里云ECS上使用Analytics Zoo对人工智能应用进行bfloat16加速

本文将介绍在阿里云第七代高主频 ECS 实例上,利用 Analytics Zoo 和第三代智能英特尔® 至强® 可扩展处理器提供的 bfloat16 特性提高人工智能应用的性能。作者:(Alibaba) Junjie Cai; King Sheng; (Intel) Jason Dai; Ban Hsu; Wesley Du; Yang Wang; Yina Chen; Jack Chen; Ning Wang。

背景信息

阿里云第七代高主频 ECS 实例构建于第三代神龙平台之上,基于第三代智能英特尔® 至强® 可扩展处理器创建。相对于上一代,阿里云 ECS 云服务器第七代高主频实例计算性能最大可以提升 260%。在 ECS 上使用 Analytics Zoo,可以利用 Analytics Zoo 的高级流水线特性,比如使用英特尔优化的深度学习框架(例如 TensorFlow、PyTorch 等)开发深度学习应用。

·第三代智能英特尔® 至强® 可扩展处理器提供了业界领先、经工作负载优化的平台,并内置了 AI 加速功能--增强型英特尔® Deep Learning Boost(英特尔® DL Boost)。增强型英特尔® DL Boost 通过业界首次对 bfloat16 的 x86 支持,增强了人工智能推理和训练性能。

·第三代智能英特尔® 至强® 可扩展处理器可运行复杂的人工智能工作负载。增强型英特尔® DL Boost 将人工智能训练最高提升 1.93 倍,图像分类性能最高提升 1.87 倍,自然语言处理的训练性能提升 1.7 倍,推理提升 1.9 倍。新的 bfloat16 处理支持使医疗保健、金融服务和零售业的人工智能训练工作负载受益匪浅。

·Analytics Zoo 是英特尔开源的统一的大数据和 AI 平台,它可以无缝的将 TensorFlow、Keras、PyTorch 等 AI 程序扩展到分布式 Spark、Flink、Ray 等大数据平台上运行。Analytics Zoo 提供了以下特性:

o为基于 TensorFlow、PyTorch、OpenVINO 等的 AI 模型提供运行在大数据平台之上的端到端的流水线。例如开发者可以在 Spark 代码中嵌入 TensorFlow 或者 PyTorch 代码,进行分布式的训练和推理。开发者可以在 Spark ML 流水线中使用原生的深度学习支持如 TensorFlow、Keras、PyTorch、BigDL 等。

o为自动化的机器学习任务提供了高级 ML 工作流支持,例如自动的 TensorFlow、PyTorch、OpenVINO 等模型的分布式推理 Cluster Serving 以及可扩展的时序数据预测的 AutoML 功能。

o内置提供了 Recommendation、Time Series、CV、NLP 等应用常用的模型。

·bfloat16 是一种业界广泛用于神经网络的数字格式。

·Resnet50 是一个 50 层的残差网络 (Residual Network),该神经网络广泛用于目标分类等领域。

操作步骤

如果您想在 ECS 上使用 Analytics Zoo 对人工智能应用进行 bfloat16 加速,按照以下步骤在 ECS 上加速人工智能应用。下面步骤以训练 Resnet50 模型的工作负载为例进行说明。

1.步骤一:创建高主频 ECS 实例

2.步骤二:在 ECS 上准备带有 bfloat16 优化支持的 Analytics Zoo 环境

3.步骤三:在 ECS 实例上训练 Resnet50 模型和 bfloat16 的性能提升

步骤一:创建高主频 ECS 实例

完成以下操作,创建一台 ECS 实例。

1.前往实例创建页

2.创建一台 hfc7 实例。具体操作,请参见使用向导创建实例

3.在配置参数时,您需要注意当前场景支持的实例规格族包括 hfc7 和 hfg7。具体规格,请参见高主频型

4.在实例列表中,找到创建的实例,单击实例 ID。查看并确认实例规格。

步骤二:在 ECS 上准备带有 bfloat16 优化支持的 Analytics Zoo 环境

Analytics Zoo 提供了预先创建的支持 bfloat16 的 docker image,按照方法一可以轻松在阿里云 ECS 上获取 Analytics Zoo 的 docker image。您也可以按照方法二使用 Analytics Zoo nightly build 来支持 bfloat16。

·方法一:在 ECS 上获取 Analytics Zoo 预先创建的 docker image 创建。

1)连接 ECS 实例。具体步骤,请参见连接 ECS 实例

2)运行以下命令安装并运行 Docker。

1.yum install docker-io -y  
2.systemctl start docker  

3)运行以下命令获取支持 bfloat16 的 Analytics Zoo docker image。

1.docker pull intelanalytics/analytics-zoo:0.8.1-bigdl_0.10.0-spark_2.4.3-bf16  

4)运行以下命令运行 docker container。

1.docker run -itd --name az1 --net=host  --privileged intelanalytics/analytics-zoo:0.8.1-bigdl_0.10.0-spark_2.4.3-bf16  

5)运行以下命令进入 container。

1.docker exec -it az1 bash  

·方法二:用户使用 Analytics Zoo nightly build 来支持 bfloat16 手动创建。

1)连接 ECS 实例。具体步骤,请参见连接 ECS 实例

2)运行以下命令下载并解压最新的 Analytics Zoo nightly build pre-build package。

1.Wget https://oss.sonatype.org/content/repositories/snapshots/com/intel/analytics/zoo/analytics-zoo-bigdl_0.11.1-spark_2.4.3/0.9.0-SNAPSHOT/analytics-zoo-bigdl_0.11.1-spark_2.4.3-0.9.0-20201026.210040-51-dist-all.zip  
2.unzip analytics-zoo-bigdl_0.11.1-spark_2.4.3-0.9.0-{datetime}-dist-all.zip -d analytics-zoo  

3)运行以下命令安装 git。

1.yum -y install git 

4)运行以下命令下载 TensorFlow 源代码。

1.git clone https://github.com/Intel-tensorflow/tensorflow.git  
2.git checkout v1.15.0up1  

5)运行以下命令编译 TensorFlow。

1.bazel build --cxxopt=-D_GLIBCXX_USE_CXX11_ABI=0 --copt=-O3 --copt=-Wformat  
2.--copt=-Wformat-security --copt=-fstack-protector --copt=-fPIC  
3.--copt=-fpic --linkopt=-znoexecstack --linkopt=-zrelro  
4.--linkopt=-znow --linkopt=-fstack-protector --config=mkl –define  
5.build_with_mkl_dnn_v1_only=true --copt=-DENABLE_INTEL_MKL_BFLOAT16  
6.--copt=-march=native  
7.//tensorflow/tools/lib_package:libtensorflow_jni.tar.gz  
8.//tensorflow/java:libtensorflow.jar  
9.//tensorflow/java:libtensorflow-src.jar  
10.//tensorflow/tools/lib_package:libtensorflow_proto.zip  

6)运行以下命令整理 Analytics Zoo 需要的库文件。

1.cd bazel-bin/tensorflow/tools/lib_package  
2.mkdir linux-x86_64  
3.tar -xzvf libtensorflow_jni.tar.gz -C linux_x86-64  
4.rm libtensorflow_framework.so  
5.rm libtensorflow_framework.so.1  
6.mv libtensorflow_framework.so.1.15.0 libtensorflow_framework-zoo.so  
7.cp ../../../../_solib_k8/_U@mkl_Ulinux_S_S_Cmkl_Ulibs_Ulinux___Uexternal_Smkl_Ulinux_Slib/* ./  

7)运行以下命令更新 Analytics Zoo Jar。

1.cd ~/analytics-zoo/lib/  
2.cp ~/tensorflow/bazel-bin/tensorflow/tools/lib_package/linux-x86_64 ./  
3.jar -ufanalytics-zoo-bigdl_0.11.1-spark_2.4.3-0.9.0-SNAPSHOT-jar-with-dependencies.jar linux-x86_64/*  

步骤三:在 ECS 实例上训练 Resnet50 模型和 bfloat16 的性能提升

1.运行以下命令进入 Analytic Zoo docker 容器。

1.docker exec -it az1 bash  

2.运行以下命令配置 spark,对 /opt/work/spark-2.4.3/conf/spark-defaults.conf 进行修改。

1.spark.authenticate=false  
2.spark.ui.killEnabled=true  
3.spark.eventLog.enabled=true  
4.spark.history.ui.port=18080  
5.spark.eventLog.dir=file:///var/log/spark/spark-events  
6.spark.history.fs.logDirectory=file:///var/log/spark/spark-events  
7.spark.shuffle.service.port=7337  
8.spark.master=spark://$(hostname):7077  

3.运行以下命令启动 spark master。

1.cd /opt/work/spark-2.4.3  
2../sbin/start-master.sh  

4.用 numactl 命令启动 8 个 spark workers,每个 worker 绑定到 12 个 vcpu。在 /opt/work/spark-2.4.3/bin 目录下创建如下脚本。

1.numactl -C 0-11 ./spark-class org.apache.spark.deploy.worker.Worker spark://$(hostname):7077 &  
2.numactl -C 12-23 ./spark-class org.apache.spark.deploy.worker.Worker spark://$(hostname):7077 &  
3.numactl -C 24-35 ./spark-class org.apache.spark.deploy.worker.Worker spark://$(hostname):7077 &  
4.numactl -C 36-47 ./spark-class org.apache.spark.deploy.worker.Worker spark://$(hostname):7077 &  
5.numactl -C 48-59 ./spark-class org.apache.spark.deploy.worker.Worker spark://$(hostname):7077 &  
6.numactl -C 60-71 ./spark-class org.apache.spark.deploy.worker.Worker spark://$(hostname):7077 &  
7.numactl -C 72-83 ./spark-class org.apache.spark.deploy.worker.Worker spark://$(hostname):7077 &  
8.numactl -C 84-95 ./spark-class org.apache.spark.deploy.worker.Worker spark://$(hostname):7077 &  

5.运行以下命令检查,返回 8 表示已启动了 8 个 Worker。

1.jps | grep Worker | wc -l  

6.运行以下命令从 github 上下载 resnet50 示例代码。

1.git clone https://github.com/yangw1234/models-1.git  
2.git checkout branch-1.6.1-zoo  

7.在 models-1/models/image_recognition/tensorflow/resnet50v1_5/training/mlperf_resnet 目录下运行 run.sh 脚本,用--use_bfloat16 选项来开启 bfloat16 训练,不加此选项则默认为 FP32 训练。

1.# Register the model as a source root
2.export PYTHONPATH="$(pwd):${PYTHONPATH}"
3.export KMP_BLOCKTIME=0  
4.# 8 instances
5.export OMP_NUM_THREADS=6  
6.export KMP_AFFINITY=granularity=fine,compact,1,0  
7.export KMP_SETTINGS=1  
8.export ANALYTICS_ZOO_HOME=/opt/work/analytics-zoo/dist  
9.export SPARK_HOME=/opt/work/spark-2.4.3  
10.bash $ANALYTICS_ZOO_HOME/bin/spark-submit-python-with-zoo.sh –master  
11.spark://$(hostname):7077 \  
12.--executor-cores 1 --total-executor-cores 8 --driver-memory 20g --executor-memory 18g \  
13.--conf spark.network.timeout=10000000 --conf spark.executor.heartbeatInterval=100000 \  
14.imagenet_main.py 1 --model_dir ./logs --batch_size 128 --version 1 \  
15.--resnet_size 50 --train_epochs 90 --data_dir /opt/ILSVRC2012/ --use_bfloat16  

本次训练测试结果如下所示。

模型训练

FP32

BF16

BF16 相对 FP32 的性能提升

Throughput (images/sec)

119.636

212.315

1.775


代码示例:Analytics Zoo 如何利用 bfloat16 加速深度模型训练

下面的代码用于说明 Analytics Zoo 如何利用 bfloat16 来加速深度学习模型的训练(例如 Resnet50 等)。在 Analytics Zoo 的 docker image 中已经包含,您不需要任何操作,仅作示例参考。

1.通过以下代码将输入图片转换成 bfloat16 格式。

1.if use_bfloat16 == True:  
2.dtype = tf.bfloat16  
3.features = tf.cast(features, dtype)  

2.通过以下代码编写 custom_dtype_getter。

1.DEFAULT_DTYPE = tf.float32  
2.CASTABLE_TYPES = (tf.float16,tf.bfloat16)  
3.def _custom_dtype_getter(getter, name, shape=None, dtype=DEFAULT_DTYPE,      
4.      *args, **kwargs):  
5.if dtype in CASTABLE_TYPES:  
6.      var = getter(name, shape, tf.float32, *args, **kwargs)  
7.return tf.cast(var, dtype=dtype, name=name + '_cast')  
8.else:  
9.return getter(name, shape, dtype, *args, **kwargs)  

3.通过以下代码创建 variable_scope,并在该 scope 下构建模型。

1.def _model_variable_scope():|  
2.return tf.compat.v1.variable_scope('resnet_model',  
3.                    custom_getter=_custom_dtype_getter)  
4.with _model_variable_scope():  
5.    logits = _resnet_50_model(features)  

4.通过以下代码将 logits 装换成 float32 计算 loss 以保证数值稳定性(numerical stability)。

1.logits = tf.cast(logits, tf.float32)  

5.使用 Analytics TFPark 进行分布式训练。具体操作,请参见 Analytics Zoo 分布式 TensorFlow

工程阿里云Analytics Zoo
1
暂无评论
暂无评论~