背景信息
● 阿里云第七代高主频 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 模型的工作负载为例进行说明。
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。
相关代码说明请参见代码示例:Analytics Zoo 如何利用 bfloat16 加速深度模型训练。
• 方法一:在 ECS 上获取 Analytics Zoo 预先创建的 docker image 创建。
i. 连接 ECS 实例。具体步骤,请参见连接 ECS 实例。
ii. 运行以下命令安装并运行 Docker。
yum install docker-io -y
systemctl start docker
iii. 运行以下命令获取支持 bfloat16 的 Analytics Zoo docker image。
docker pull intelanalytics/analytics-zoo:0.8.1-bigdl_0.10.0-spark_2.4.3-bf16
iv. 运行以下命令运行 docker container。
docker run -itd --name az1 --net=host --privileged intelanalytics/analytics-zoo:0.8.1-bigdl_0.10.0-spark_2.4.3-bf16
v. 运行以下命令进入 container。
docker exec -it az1 bash
• 方法二:用户使用 Analytics Zoo nightly build 来支持 bfloat16 手动创建。
i. 连接 ECS 实例。具体步骤,请参见连接 ECS 实例。
ii. 运行以下命令下载并解压最新的 Analytics Zoo nightly build pre-build package。
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
unzip analytics-zoo-bigdl_0.11.1-spark_2.4.3-0.9.0-{datetime}-dist-all.zip -d analytics-zoo
iii. 运行以下命令安装 git。
yum -y install git
iv. 运行以下命令下载 TensorFlow 源代码。
git clone https://github.com/Intel-tensorflow/tensorflow.git
git checkout v1.15.0up1
v. 运行以下命令编译 TensorFlow。
bazel build --cxxopt=-D_GLIBCXX_USE_CXX11_ABI=0 --copt=-O3 --copt=-Wformat
--copt=-Wformat-security --copt=-fstack-protector --copt=-fPIC
--copt=-fpic --linkopt=-znoexecstack --linkopt=-zrelro
--linkopt=-znow --linkopt=-fstack-protector --config=mkl --define
build_with_mkl_dnn_v1_only=true --copt=-DENABLE_INTEL_MKL_BFLOAT16
--copt=-march=native
//tensorflow/tools/lib_package:libtensorflow_jni.tar.gz
//tensorflow/java:libtensorflow.jar
//tensorflow/java:libtensorflow-src.jar
//tensorflow/tools/lib_package:libtensorflow_proto.zip
vi. 运行以下命令整理 Analytics Zoo 需要的库文件。
cd bazel-bin/tensorflow/tools/lib_package
mkdir linux-x86_64
tar -xzvf libtensorflow_jni.tar.gz -C linux_x86-64
rm libtensorflow_framework.so
rm libtensorflow_framework.so.1
mv libtensorflow_framework.so.1.15.0 libtensorflow_framework-zoo.so
cp ../../../../_solib_k8/_U@mkl_Ulinux_S_S_Cmkl_Ulibs_Ulinux___Uexternal_Smkl_Ulinux_Slib/* ./
vii. 运行以下命令更新 Analytics Zoo Jar。
cd ~/analytics-zoo/lib/
cp ~/tensorflow/bazel-bin/tensorflow/tools/lib_package/linux-x86_64 ./
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 容器。
docker exec -it az1 bash
2. 运行以下命令配置 spark,对 /opt/work/spark-2.4.3/conf/spark-defaults.conf 进行修改。
spark.authenticate=false
spark.ui.killEnabled=true
spark.eventLog.enabled=true
spark.history.ui.port=18080
spark.eventLog.dir=file:///var/log/spark/spark-events
spark.history.fs.logDirectory=file:///var/log/spark/spark-events
spark.shuffle.service.port=7337
spark.master=spark://$(hostname):7077
3. 运行以下命令启动 spark master。
cd /opt/work/spark-2.4.3
./sbin/start-master.sh
4. 用 numactl 命令启动 8 个 spark workers,每个 worker 绑定到 12 个 vcpu。在 /opt/work/spark-2.4.3/bin 目录下创建如下脚本。
numactl -C 0-11 ./spark-class org.apache.spark.deploy.worker.Worker spark://$(hostname):7077 &
numactl -C 12-23 ./spark-class org.apache.spark.deploy.worker.Worker spark://$(hostname):7077 &
numactl -C 24-35 ./spark-class org.apache.spark.deploy.worker.Worker spark://$(hostname):7077 &
numactl -C 36-47 ./spark-class org.apache.spark.deploy.worker.Worker spark://$(hostname):7077 &
numactl -C 48-59 ./spark-class org.apache.spark.deploy.worker.Worker spark://$(hostname):7077 &
numactl -C 60-71 ./spark-class org.apache.spark.deploy.worker.Worker spark://$(hostname):7077 &
numactl -C 72-83 ./spark-class org.apache.spark.deploy.worker.Worker spark://$(hostname):7077 &
numactl -C 84-95 ./spark-class org.apache.spark.deploy.worker.Worker spark://$(hostname):7077 &
5. 运行以下命令检查,返回 8 表示已启动了 8 个 Worker。
jps | grep Worker | wc -l
6. 运行以下命令从 github 上下载 resnet50 示例代码。
git clone https://github.com/yangw1234/models-1.git
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 训练。
# Register the model as a source root
export PYTHONPATH="$(pwd):${PYTHONPATH}"
export KMP_BLOCKTIME=0
# 8 instances
export OMP_NUM_THREADS=6
export KMP_AFFINITY=granularity=fine,compact,1,0
export KMP_SETTINGS=1
export ANALYTICS_ZOO_HOME=/opt/work/analytics-zoo/dist
export SPARK_HOME=/opt/work/spark-2.4.3
bash $ANALYTICS_ZOO_HOME/bin/spark-submit-python-with-zoo.sh --master
spark://$(hostname):7077 \
--executor-cores 1 --total-executor-cores 8 --driver-memory 20g --executor-memory 18g \
--conf spark.network.timeout=10000000 --conf spark.executor.heartbeatInterval=100000 \
imagenet_main.py 1 --model_dir ./logs --batch_size 128 --version 1 \
--resnet_size 50 --train_epochs 90 --data_dir /opt/ILSVRC2012/ --use_bfloat16
本次训练测试结果如下所示。
Resnet50 模型训练 |
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 格式。
if use_bfloat16 == True:
dtype = tf.bfloat16
features = tf.cast(features, dtype)
2. 通过以下代码编写 custom_dtype_getter。
DEFAULT_DTYPE = tf.float32
CASTABLE_TYPES = (tf.float16,tf.bfloat16)
def _custom_dtype_getter(getter, name, shape=None, dtype=DEFAULT_DTYPE,
*args, **kwargs):
if dtype in CASTABLE_TYPES:
var = getter(name, shape, tf.float32, *args, **kwargs)
return tf.cast(var, dtype=dtype, name=name + '_cast')
else:
return getter(name, shape, dtype, *args, **kwargs)
3. 通过以下代码创建 variable_scope,并在该 scope 下构建模型。
def _model_variable_scope():
return tf.compat.v1.variable_scope('resnet_model',
custom_getter=_custom_dtype_getter)
with _model_variable_scope():
logits = _resnet_50_model(features)
4. 通过以下代码将 logits 装换成 float32 计算 loss 以保证数值稳定性(numerical stability)。
logits = tf.cast(logits, tf.float32)
5. 使用 Analytics TFPark 进行分布式训练。具体操作,请参见 Analytics Zoo 分布式 TensorFlow。