配置运行信息
概述
初始化网络之前要配置context参数,用于控制程序执行的策略。比如选择执行模式、选择执行后端、配置分布式相关参数等。按照context参数设置实现的不同功能,可以将其分为执行模式管理、硬件管理、分布式管理和维测管理等。
context接口详细介绍可以查看mindspore.context。
执行模式管理
MindSpore支持Graph和PyNative两种运行模式。默认情况下,MindSpore处于Graph模式。Graph模式是MindSpore的主模式,而PyNative模式用于调试等用途。
GRAPH_MODE
:静态图模式或者图模式,将神经网络模型编译成一整张图,然后下发执行。该模式利用图优化等技术提高运行性能,同时有助于规模部署和跨平台运行。PYNATIVE_MODE
:动态图模式,将神经网络中的各个算子逐一下发执行,方便用户编写和调试神经网络模型。
模式选择
通过配置context参数可以控制程序运行的模式。Graph和PyNative两种模式的区别主要有:
使用场景:Graph模式需要一开始就构建好网络结构,然后框架做整图优化和执行,比较适合网络固定没有变化,且需要高性能的场景。而PyNative模式逐行执行算子,支持执行单算子、普通函数和网络,以及单独求梯度的操作。
网络执行:Graph模式和PyNative模式在执行相同的网络和算子时,精度效果是一致的。由于Graph模式运用了图优化、计算图整图下沉等技术,Graph模式执行网络的性能和效率更高。
代码调试:在脚本开发和网络流程调试中,推荐使用PyNative模式进行调试。在PyNative模式下,可以方便地设置断点,获取网络执行的中间结果,也可以通过pdb的方式对网络进行调试。而Graph模式无法设置断点,只能先指定算子进行打印,然后在网络执行完成后查看输出结果。
Graph模式和PyNative模式使用的是一种基于图表示的函数式IR,即MindIR,采用了接近于ANF函数式的语义。使用Graph模式时,将context中的运行模式设置为GRAPH_MODE
,需要使用nn.Cell
类,并且在construct
函数中编写执行代码, 或者调用@ms_function
装饰器。
代码样例如下:
[1]:
import numpy as np
import mindspore.nn as nn
import mindspore.ops as ops
from mindspore import context, Tensor
context.set_context(mode=context.GRAPH_MODE, device_target="Ascend")
class Net(nn.Cell):
def __init__(self):
super(Net, self).__init__()
self.mul = ops.Mul()
def construct(self, x, y):
return self.mul(x, y)
x = Tensor(np.array([1.0, 2.0, 3.0]).astype(np.float32))
y = Tensor(np.array([4.0, 5.0, 6.0]).astype(np.float32))
net = Net()
print(net(x, y))
[1]:
[ 4. 10. 18.]
模式切换
MindSpore提供了静态图和动态图统一的编码方式,大大增加了静态图和动态图的可兼容性,用户无需开发多套代码,仅变更一行代码便可切换静态图/动态图模式。模式切换时,请留意目标模式的约束。例如,PyNative模式不支持数据下沉等。
MindSpore处于Graph模式时,可以通过 context.set_context(mode=context.PYNATIVE_MODE)
切换为PyNative模式;同样地,MindSpore处于PyNative模式时,可以通过context.set_context(mode=context.GRAPH_MODE)
切换为Graph模式。
硬件管理
硬件管理部分主要包括device_target
和device_id
两个参数。
device_target
: 用于设置目标设备,支持Ascend、GPU和CPU,可以根据实际环境情况设置。device_id
: 表示卡物理序号,即卡所在机器中的实际序号。如果目标设备为Ascend,且规格为NAscend(其中N>1,如8Ascend),在非分布式模式执行的情况下,为了避免设备的使用冲突,可以通过设置device_id
决定程序执行的device编号,该编号范围为:0 ~ 服务器总设备数量-1,服务器总设备数量不能超过4096,默认为设备0。
在GPU和CPU上,设置
device_id
参数无效。
代码样例如下:
from mindspore import context
context.set_context(device_target="Ascend", device_id=6)
分布式管理
context中有专门用于配置并行训练参数的接口:context.set_auto_parallel_context
,该接口必须在初始化网络之前调用。
分布式并行训练详细介绍可以查看分布式并行训练。
维测管理
为了方便维护和定位问题,context提供了大量维测相关的参数配置,如采集profiling数据、异步数据dump功能和print算子落盘等。
采集profiling数据
系统支持在训练过程中采集profiling数据,然后通过profiling工具进行性能分析。当前支持采集的profiling数据包括:
enable_profiling
:是否开启profiling功能。设置为True,表示开启profiling功能,从enable_options
读取profiling的采集选项;设置为False,表示关闭profiling功能,仅采集training_trace
。profiling_options
:profiling采集选项,取值如下,支持采集多项数据。result_path
:Profiling采集结果文件保存路径。该参数指定的目录需要在启动训练的环境上(容器或Host侧)提前创建且确保安装时配置的运行用户具有读写权限,支持配置绝对路径或相对路径(相对执行命令时的当前路径)。training_trace
:采集迭代轨迹数据,即训练任务及AI软件栈的软件信息,实现对训练任务的性能分析,重点关注数据增强、前后向计算、梯度聚合更新等相关数据,取值on/off。task_trace
:采集任务轨迹数据,即昇腾910处理器HWTS/AICore的硬件信息,分析任务开始、结束等信息,取值on/off。aicpu_trace
:采集aicpu数据增强的profiling数据。取值on/off。fp_point
:training_trace
为on时需要配置。指定训练网络迭代轨迹正向算子的开始位置,用于记录前向算子开始时间戳。配置值为指定的正向第一个算子名字。当该值为空时,系统自动获取正向第一个算子名字。bp_point
:training_trace
为on时需要配置。指定训练网络迭代轨迹反向算子的结束位置,用于记录反向算子结束时间戳。配置值为指定的反向最后一个算子名字。当该值为空时,系统自动获取反向最后一个算子名字。ai_core_metrics
取值如下:ArithmeticUtilization:各种计算类指标占比统计。
PipeUtilization:计算单元和搬运单元耗时占比,该项为默认值。
Memory:外部内存读写类指令占比。
MemoryL0:内部内存读写类指令占比。
ResourceConflictRatio:流水线队列类指令占比。
代码样例如下:
from mindspore import context
context.set_context(enable_profiling=True, profiling_options= '{"result_path":"/home/data/output","training_trace":"on"}')
保存MindIR
通过context.set_context(save_graphs=True)
来保存各个编译阶段的中间代码。
被保存的中间代码有两种格式:一个是后缀名为.ir
的文本格式,一个是后缀名为.dot
的图形化格式。
当网络规模较大时建议使用更高效的文本格式来查看,当网络规模不大时,建议使用更直观的图形化格式来查看。
代码样例如下:
from mindspore import context
context.set_context(save_graphs=True)
本篇采集profiling数据的方法,更适合高阶开发者进行复杂问题分析。若需采集profiling数据,进行性能分析,可以参考性能调优。
MindIR详细介绍可以查看MindSpore IR(MindIR)。
print算子落盘
默认情况下,MindSpore的自研print算子可以将用户输入的Tensor或字符串信息打印出来,支持多字符串输入,多Tensor输入和字符串与Tensor的混合输入,输入参数以逗号隔开。
Print打印功能可以查看Print算子功能介绍。
print_file_path
:可以将print算子数据保存到文件,同时关闭屏幕打印功能。如果保存的文件已经存在,则会给文件添加时间戳后缀。数据保存到文件可以解决数据量较大时屏幕打印数据丢失的问题。
代码样例如下:
from mindspore import context
context.set_context(print_file_path="print.pb")