写点什么

昇腾迁移丨 4 个 TensorFlow 模型训练案例解读

  • 2023-11-06
    广东
  • 本文字数:2899 字

    阅读完需:约 10 分钟

昇腾迁移丨4个TensorFlow模型训练案例解读

本文分享自华为云社区《TensorFlow模型训练常见案例》,作者: 昇腾 CANN。


基于 TensorFlow 的 Python API 开发的训练脚本默认运行在 CPU/GPU/TPU 上,为了使这些脚本能够利用昇腾 AI 处理器的强大算力,需要将其迁移到昇腾平台。


本期分享几个 TensorFlow 网络迁移到昇腾平台后执行失败或者执行性能差的典型案例,并给出原因分析及解决方法。

01 数据预处理中存在资源类算子,导致训练异常

问题现象


TensorFlow 网络执行时,报如下错误:


[2021-03-19 13:50:24.895266: W tensorflow/core/framework/op_kernel.cc:1651] OP_REQUIRES failed at lookup_table_op.cc:809 : Failed precondition: Table not initialized.
[2021-03-19 13:50:24.895283: W tensorflow/core/framework/op_kernel.cc:1651] OP_REQUIRES failed at lookup_table_op.cc:809 : Failed precondition: Table not initialized.
复制代码

原因分析


初始化图中存在资源类算子 HaskTableV2 ,数据预处理中存在资源类算子 LookupTableFindV2,两个算子需要配对使用。


昇腾 AI 处理器默认采用计算全下沉模式,即所有的计算类算子(包括初始化图中的资源类算子)全部在 Device 侧执行,数据预处理仍在 Host 执行。这样数据预处理中的 LookupTableFindV2 算子与初始化图中的 HaskTableV2 算子未在同一设备执行,导致网络运行出错。

解决方案


需要修改训练脚本,使能混合计算能力,将资源类算子的初始化图也留在 Host 侧执行,训练脚本修改方法如下:


from npu_bridge.npu_init import *
config = tf.ConfigProto()
custom_op = config.graph_options.rewrite_options.custom_optimizers.add()
custom_op.name = "NpuOptimizer"
custom_op.parameter_map["mix_compile_mode"].b = True
config.graph_options.rewrite_options.remapping = RewriterConfig.OFF
config.graph_options.rewrite_options.memory_optimization = RewriterConfig.OFF
with tf.Session(config=config) as sess:
sess.run(...)
复制代码


其中配置参数“mix_compile_mode”是混合计算开启开关,当此开关配置为“True”后,会将需要成对使用的资源类算子留在前端框架在线执行。


补充说明:当用户的预处理脚本中存在需要成对使用的 tf.contrib.lookup 下 Table 类的 API 时,需要参考此方法使能混合计算功能,将初始化图中的对应算子留在 Host 侧执行。

02 数据预处理中存在 tf.Variable,导致训练异常

问题现象


TensorFlow 网络执行时,报如下错误:


tensorflow.python.framework.errors_impl.FailedPreconditionError: Error while reading resource variable inference/embed_continuous from Container: localhost. This could mean that the variable was uninitialized. Not found: Resource localhost/inference/embed_continuous/N10tensorflow3VarE does not exist.
复制代码

原因分析


此问题是由于数据预处理脚本中存在 tf.Variable 变量。训练脚本在昇腾平台运行时,tf.Variable 变量在 Host 侧执行,而 tf.Variable 变量的初始化在 Device 侧执行,变量执行和变量初始化不在同一设备执行,导致训练异常。


使用了 tf.Variable 的训练脚本代码示例如下:


batch_size = tf.Variable(
tf.placeholder(tf.int64, [], 'batch_size'),
trainable= False, collections=[]
)
train_dataset = train_dataset.batch(batch_size, drop_remainder=True)
复制代码

解决方案


需要修改训练脚本,将 tf.Variable 修改成常量,修改示例如下:


batch_size = 64 train_dataset = train_dataset.batch(batch_size, drop_remainder=True)
batch_size = 64
train_dataset = train_dataset.batch(batch_size, drop_remainder=True)
复制代码

03 动态 shape 网络执行时报 v1 控制流算子不支持的错误

问题现象


TensorFlow 1.15 版本的动态 shape 网络执行时,报如下错误:


node node_name(node_type) is v1 control operator, which is not supported, please convert to v2 control operator
复制代码

原因分析


由于当前 TensorFlow 网络为动态 shape 网络,且存在 V1 版本的控制流算子。在昇腾 AI 处理器执行 TensorFlow 动态 shape 网络当前不支持 V1 版本的控制流算子,所以会造成网络运行失败。

解决方案


将网络中的 TensorFlow V1 版本的控制流算子转换为 V2 版本,即可解决此问题。


方法一:通过设置如下环境变量将 TensorFlow V1 版本的控制流算子转换为 V2 版本。


export ENABLE_FORCE_V2_CONTROL=1
复制代码


方法二:修改网络脚本,在 import tensorflow as tf 后增加如下两条指令,将 TensorFlow V1 版本的控制流算子转换为 V2 版本。


tf.enable_control_flow_v2()
tf.enable_resource_variables()
复制代码

04 网络调测时 ReduceSum 算子执行性能差

问题现象


网络调测时,网络整体性能较慢。通过 Profiling 工具获取网络的 Profiling 数据,并进行算子的性能数据分析,发现 ReduceSum 算子的性能很差。


查看 Profiling 性能数据中 ReduceSum 算子的详细信息,关键字段如下表蓝色字体所示:



ReduceSum 算子的输入数据类型(input_data_type)为“DT_FLOAT16”,block_dim 字段的值为“1”,说明该算子未开启多核并行计算。

原因分析


针对昇腾 AI 处理器的 ReduceSum 算子,若输入数据类型为 float16,由于硬件限制,某些场景下会无法开启多核计算。

解决方案


ReduceSum 算子输入数据是 float16 的情况可能有如下两种场景:


场景一


网络调测时未开启混合精度,ReduceSum 算子的输入数据本身就是 float16 类型,此种情况下,若 ReduceSum 算子的性能较差,可尝试在 ReduceSum 算子前插入一个 Cast 算子,将算子的输入数据类型从 float16 转换为 float32。


ReduceSum 算子在输入类型为 float32 的场景下,会使能多核并发计算,从而达到提升该算子性能的效果。


场景二


网络调测时开启了混合精度,将 ReduceSum 算子的输入数据类型从 float32 转换成了 float16,此种情况下,可将 ReduceSum 算子加入混合精度黑名单,这样网络调测时 ReduceSum 算子就不会被转换成 float16 类型,从而避免该算子性能的劣化。


将 ReduceSum 算子加入混合精度黑名单的方法如下:


1) 修改网络脚本,通过 modify_mixlist 参数指定需要修改的混合精度算子黑名单,修改示例如下:


# Estimator模式修改方法
npu_config=NPURunConfig(
...
precision_mode="allow_mix_precision",
modify_mixlist="/home/test/ops_info.json"
)
# sess.run模式修改方法
config = tf.ConfigProto()
custom_op = config.graph_options.rewrite_options.custom_optimizers.add()
custom_op.name = "NpuOptimizer"
custom_op.parameter_map["use_off_line"].b = True
custom_op.parameter_map["precision_mode"].s = tf.compat.as_bytes("allow_mix_precision")
custom_op.parameter_map["modify_mixlist"].s = tf.compat.as_bytes("/home/test/ops_info.json")
复制代码


2) 在 ops_info.json 文件中进行算子黑名单的配置,配置示例如下:


{
"black-list": {
"to-add": ["ReduceSumD"]
}
}
复制代码


补充说明:仅在 ReduceSum 算子性能较差时,且符合本案例中的问题现象时,可尝试使用此方法进行性能提升。

05 更多介绍


[1]昇腾文档中心:https://www.hiascend.com/zh/document

[2]昇腾社区在线课程:https://www.hiascend.com/zh/edu/courses

[3]昇腾论坛:https://www.hiascend.com/forum


点击关注,第一时间了解华为云新鲜技术~

发布于: 刚刚阅读数: 6
用户头像

提供全面深入的云计算技术干货 2020-07-14 加入

生于云,长于云,让开发者成为决定性力量

评论

发布
暂无评论
昇腾迁移丨4个TensorFlow模型训练案例解读_人工智能_华为云开发者联盟_InfoQ写作社区