通过修改训练脚本配置调优模式(TensorFlow 1.15)
使用前须知
除了通过AOE_MODE环境变量配置调优模式之外,还可以通过修改训练脚本方式,配置调优模式。同时配置的情况下,通过修改训练脚本方式优先生效。
操作步骤
- (可选)配置相关环境变量。
1
export ASCEND_DEVICE_ID=0 # 通过该环境变量指定昇腾AI处理器的逻辑ID。取值范围[0,N-1],默认为0。其中N为当前物理机/虚拟机/容器内的设备总数。
- 修改训练脚本,通过如下参数使能AOE调优。
表1 相关参数解释 参数
说明
aoe_mode
必选参数。通过AOE工具进行调优的调优模式。
- 1:子图调优。
- 2:算子调优。
- 4:梯度切分调优。
在数据并行的场景下,使用allreduce对梯度进行聚合,梯度的切分方式与分布式训练性能强相关,切分不合理会导致反向计算结束后存在较长的通信拖尾时间,影响集群训练的性能和线性度。用户可以通过集合通信的梯度切分接口(set_split_strategy_by_idx或set_split_strategy_by_size)进行人工调优,但难度较高。因此,可以通过工具实现自动化搜索切分策略,通过在实际环境预跑采集性能数据,搜索不同的切分策略,理论评估出最优策略输出给用户,用户拿到最优策略后通过set_split_strategy_by_idx接口设置到该网络中。
说明:通过修改训练脚本和AOE_MODE环境变量都可配置调优模式,同时配置的情况下,通过修改训练脚本方式优先生效。
work_path
可选参数。AOE工具调优工作目录,存放调优配置文件和调优结果文件,默认生成在训练当前目录下。
该参数类型为字符串,指定的目录需要在启动训练的环境上(容器或Host侧)提前创建且确保安装时配置的运行用户具有读写权限,支持配置绝对路径或相对路径(相对执行命令行时的当前路径)。
- 绝对路径配置以“/”开头,例如:/home/HwHiAiUser/output。
- 相对路径配置直接以目录名开始,例如:output。
配置示例:
1
custom_op.parameter_map["work_path"].s = tf.compat.as_bytes("/home/HwHiAiUser/output")
aoe_config_file
可选参数。
通过配置文件可以实现如下功能:
- 指定算子名称或者算子类型,对指定的算子进行调优。支持指定的算子范围请参见算子列表。对于不在算子列表范围内的算子,不支持调优。该参数使用的场景举例如下:
在对网络进行Profiling性能分析后,可通过此参数指定对某个性能较低的算子进行调优。
可配置为经过GE/FE处理过的适配昇腾AI处理器的网络模型中的节点的OP Name/OP Type(此OP Name/OP Type可从Profiling调优数据中获取,详细可参见《性能分析工具使用指南》)。
- 配置不同的模式调优,包括高性能模式和正常模式。
- 指定调优功能特性开关,当前包括算子深度调优、子图非均匀切分和算子format调优。
配置示例:
1
custom_op.parameter_map["aoe_config_file"].s=tf.compat.as_bytes("/home/HwHiAiUser/cfg/tuning_config.cfg")
文件后缀不局限于.cfg格式,文件内容须为json格式的文本,文件个数只支持单个。
/home/HwHiAiUser/cfg/tuning_config.cfg中配置的是需要进行调优的算子信息、调优模式、指定的调优功能。路径和.cfg文件的名字请根据实际情况修改。tuning_config.cfg包括的内容格式如下。
1 2 3 4 5 6
{ "tune_ops_name":["bert/embeddings/addbert/embeddings/add_1","loss/MatMul"], "tune_ops_type":["Add", "Mul"] "tune_optimization_level":"O1", "feature":["deeper_opat,op_format"] }
- tune_ops_name:指定的算子名称,当前实现是支持全字匹配,可以指定一个,也可以指定多个,指定多个时需要用英文逗号分隔。
- tune_ops_type:指定的算子类型,当前实现是支持全字匹配,可以指定一个,也可以指定多个,指定多个时需要用英文逗号分隔。如果有融合算子包括了该算子类型,则该融合算子也会被调优。
- tune_optimization_level:调优模式,取值为O1表示高性能调优模式,取值为O2表示正常模式。更多介绍请参考--tune_optimization_level
- feature:调优功能特性开关,支持多个功能,用英文逗号分割。当前支持如下:
- deeper_opat:算子深度调优。可以取值为deeper_opat或者nonhomo_split,取值为deeper_opat时,表示开启算子深度调优,aoe_mode需要配置为2;取值为nonhomo_split时,表示开启子图非均匀切分,aoe_mode需要配置为1。更多介绍请参见--Fdeeper_opat和--Fnonhomo_split。
- op_format:算子format调优。aoe_mode需要配置为2,更多介绍请参见--Fop_format。
说明:- 如上配置文件的内容必须放在"{}"中,tune_ops_type、tune_ops_name和feature的配置内容必须放在"[]"中。
- tune_ops_type和tune_ops_name可以同时存在,同时存在时取并集,也可以只存在某一个。
【对于手工迁移的训练脚本】请按照如下方法修改:- 如果迁移后的训练脚本中使用了initialize_system接口,请按照如下方法使能AOE调优。
1 2 3 4 5 6 7 8 9 10 11 12
npu_init = npu_ops.initialize_system() npu_shutdown = npu_ops.shutdown_system() config = tf.ConfigProto() ... custom_op.parameter_map["aoe_mode"].s = tf.compat.as_bytes("2") ... with tf.Session(config=config) as sess: sess.run(npu_init) #调用HCCL接口... #执行训练... sess.run(npu_shutdown)
- 如果迁移后的训练脚本中没有使用initialize_system接口,请按照如下方法使能AOE调优。
对于Estimator模式的训练脚本,通过NPURunConfig中的aoe_mode和work_path参数使能AOE调优:
1 2 3 4 5
import tensorflow as tf from npu_bridge.npu_init import * session_config=tf.ConfigProto() config = NPURunConfig(session_config=session_config, aoe_mode="2")
对于sess.run模式的训练脚本,通过session配置项aoe_mode和work_path使能AOE调优:1 2 3 4 5 6 7 8
import tensorflow as tf 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["aoe_mode"].s = tf.compat.as_bytes("2") config.graph_options.rewrite_options.remapping = RewriterConfig.OFF
【对于工具迁移的训练脚本】请按照如下方法修改:- 如果迁移后的训练脚本中使用了“init_resource”,请按照如下方法使能AOE调优。
1 2 3 4 5 6 7 8 9 10 11
if __name__ == '__main__': session_config = tf.ConfigProto() custom_op = session_config.graph_options.rewrite_options.custom_optimizers.add() custom_op.name = "NpuOptimizer" custom_op.parameter_map["aoe_mode"].s = tf.compat.as_bytes("2") (npu_sess, npu_shutdown) = init_resource(config=session_config) tf.app.run() shutdown_resource(npu_sess, npu_shutdown) close_session(npu_sess)
- 如果迁移后的训练脚本没有使用“init_resource”,请按照如下方法使能AOE调优。
对于Estimator模式的训练脚本:在迁移后的脚本中找到“npu_run_config_init”,配置调优参数:
1 2 3 4 5 6 7 8 9 10 11
session_config = tf.ConfigProto(allow_soft_placement=True) custom_op = session_config.graph_options.rewrite_options.custom_optimizers.add() custom_op.name = 'NpuOptimizer' custom_op.parameter_map["aoe_mode"].s = tf.compat.as_bytes("2") run_config = tf.estimator.RunConfig( train_distribute=distribution_strategy, session_config=session_config, save_checkpoints_secs=60*60*24) classifier = tf.estimator.Estimator( model_fn=model_function, model_dir=flags_obj.model_dir, config=npu_run_config_init(run_config=run_config))
如果脚本中的运行配置函数,例如RunConfig中没有传入session_config参数,需要自行传入session_config:1 2 3 4 5 6 7 8 9 10 11
session_config = tf.ConfigProto() custom_op = session_config.graph_options.rewrite_options.custom_optimizers.add() custom_op.name = 'NpuOptimizer' custom_op.parameter_map["aoe_mode"].s = tf.compat.as_bytes("2") run_config = tf.estimator.RunConfig( train_distribute=distribution_strategy, session_config=session_config, save_checkpoints_secs=60*60*24) classifier = tf.estimator.Estimator( model_fn=model_function, model_dir=flags_obj.model_dir, config=npu_run_config_init(run_config=run_config))
对于sess.run模式的训练脚本:在脚本中找到“npu_config_proto”,并配置调优参数。
- 在脚本中找到“npu_config_proto”:
1 2 3
with tf.Session(config=npu_config_proto()) as sess: sess.run(tf.global_variables_initializer()) interaction_table.init.run()
- 配置调优参数:
1 2 3 4 5 6 7 8
config_proto = tf.ConfigProto() custom_op = config_proto.graph_options.rewrite_options.custom_optimizers.add() custom_op.name = 'NpuOptimizer' custom_op.parameter_map["aoe_mode"].s = tf.compat.as_bytes("2") config = npu_config_proto(config_proto=config_proto) with tf.Session(config=config) as sess: sess.run(tf.global_variables_initializer()) interaction_table.init.run()
- 在脚本中找到“npu_config_proto”:
- 执行训练。