diff --git a/debug/accuracy_tools/msprobe/docs/05.data_dump_PyTorch.md b/debug/accuracy_tools/msprobe/docs/05.data_dump_PyTorch.md index b78f532615e0c11229f5feaec1776ddb590eedb8..83dec6a403ee15719105bd5320370c8f76bd8cb7 100644 --- a/debug/accuracy_tools/msprobe/docs/05.data_dump_PyTorch.md +++ b/debug/accuracy_tools/msprobe/docs/05.data_dump_PyTorch.md @@ -15,6 +15,8 @@ functional: # functional为算子类别,找到对应的类别,在该类别 删除API的场景:部分模型代码逻辑会存在API原生类型校验,工具执行dump操作时,对模型的API封装可能与模型的原生API类型不一致,此时可能引发校验失败,详见《[FAQ](FAQ.md)》中“异常情况”的第10和11条。 +加工具后loss/gnorm发生变化:可能是工具中的item操作引入同步,pt/ms框架的hook机制等原因导致的,详见《[工具导致计算结果变化](36.calculation_result_change.md)》。 + ## 快速上手 这个示例定义了一个 nn.Module 类型的简单网络,使用原型函数 PrecisionDebugger 进行数据采集。 diff --git a/debug/accuracy_tools/msprobe/docs/06.data_dump_MindSpore.md b/debug/accuracy_tools/msprobe/docs/06.data_dump_MindSpore.md index 76a57429dfbc98f2dc588aaba7933edf1367bd9c..32272668e8a700d2e4b873f63453dcf32f6b4716 100644 --- a/debug/accuracy_tools/msprobe/docs/06.data_dump_MindSpore.md +++ b/debug/accuracy_tools/msprobe/docs/06.data_dump_MindSpore.md @@ -28,7 +28,11 @@ msprobe 工具通过在训练脚本中添加 `PrecisionDebugger` 接口并启动 dump "statistics"模式的性能膨胀大小"与"tensor"模式采集的数据量大小,可以参考[dump基线](data_dump_MindSpore/data_dump_MindSpore_baseline.md)。 -**注意**:因 MindSpore 框架自动微分机制的限制,dump 数据中可能会缺少原地操作模块/API 及其上一个模块/API 的反向数据。 +**注意**: + +* 因 MindSpore 框架自动微分机制的限制,dump 数据中可能会缺少原地操作模块/API 及其上一个模块/API 的反向数据。 + +* 使用msprobe工具后loss/gnorm发生变化:可能是工具中的item操作引入同步,pt/ms框架的hook机制等原因导致的,详见《工具导致计算结果变化》。 ## 5. 场景介绍 diff --git a/debug/accuracy_tools/msprobe/docs/36.calculation_result_change.md b/debug/accuracy_tools/msprobe/docs/36.calculation_result_change.md new file mode 100644 index 0000000000000000000000000000000000000000..8fa97d8e433725f20ed595fb5161dc2885b0f132 --- /dev/null +++ b/debug/accuracy_tools/msprobe/docs/36.calculation_result_change.md @@ -0,0 +1,75 @@ +# 模型计算结果改变原因分析 + +## 介绍 +在模型训练场景下,使用seed_all接口同时固定随机性和打开计算,通信确定性计算,是能够保证模型跑两次得到的loss和gnorm结果完全一样。如果出现使能工具后loss或者gnorm出现偏差,可能是以下原因导致。 + +## 工具引入同步导致计算结果变化 +工具采集统计量数据时,会涉及到将device上的tensor计算后的统计量信息通过item的时候传到cpu侧,再落盘到json文件中,item操作是一个同步的操作,可能会导致模型的计算结果出现变化。**一般的现象就是模型计算出现了NaN,但加了工具后问题不复现了。** + +ASCEND_LAUNCH_BLOCKING 是一个环境变量,用于控制在 PyTorch 训练或在线推理场景中算子的执行模式。当设置为“1”时,算子将采用同步模式运行。因此如果出现加工具计算结果变化,可以设置ASCEND_LAUNCH_BLOCKING 为1,如果结果一样发生了变化,则说明是由于同步引起的结果改变。这个时候需要复现问题现象完成问题定位,推荐使用msprobe工具的异步dump功能,具体使用方式可查看[config配置](02.config_introduction.md)中的async_dump字段。 + +## Hook机制导致计算结果变化 + +pytorch/mindspore的hook机制会导致某些特殊场景下梯度计算的累加序产生变化,从而影响模型反向计算的gnorm结果。具体代码示例如下: +```python +import random, os +import numpy as np +import torch +from torch import nn + + +class Net(nn.Module): + def __init__(self) -> None: + super().__init__() + self.ln1 = nn.Linear(32, 32) + self.bn1 = nn.BatchNorm1d(32) + self.ln2 = nn.Linear(32, 32) + + def forward(self, x): + x1 = self.ln1(x) + + x2 = self.bn1(x) + x2 = self.ln2(x2) + return x1 + x2 + + +class BigNet(nn.Module): + def __init__(self) -> None: + super().__init__() + self.net1 = Net() + self.net2 = Net() + + def forward(self, x): + out1 = self.net1(x) + out2 = self.net2(out1) + return out1, out2 + + +def my_backward_hook(module, grad_input, grad_output): + pass + + +if __name__ == "__main__": + os.environ["HCCL_DETERMINISTIC"] = 'true' + + seed = 1234 + os.environ["PYTHONHASHSEED"] = str(seed) + torch.manual_seed(seed) + random.seed(seed) + np.random.seed(seed) + + model = BigNet() + model.net2.register_full_backward_hook(my_backward_hook) + inputs = torch.randn(3, 32) + + out1, out2 = model(inputs) + loss = out1.sum() + out2.sum() + loss.backward() + + for name, param in model.named_parameters(): + print(f"{name}: {param.grad.mean()}") + +``` +执行一遍以上脚本,可以打印得到模型中各层的权重梯度,注释model.net2.register_full_backward_hook(my_backward_hook)后再执行一篇,可以看出bn层的权重梯度已经发生了变化。 + +**如果在msprobe L0,mix级别采集出现gnorm发生变化,可以尝试将采集级别改为L1,若L1级别gnorm不发生变化,则大概率是hook机制导致的梯度计算结果变化。**