
# 使用Msprobe工具分析偏差
观察[上一章](https://support.huaweicloud.com/bestpractice-modelarts/modelarts_09_2010.html)Loss趋势，在首个Step有较小偏差，所以对第一个Step进行比对分析。此处使用Msprobe的整网Dump和比对分析功能。
1. 执行以下命令，安装社区Msprobe工具。
   ```
   pip install mindstudio-probe
   ```
   
2. 使能工具进行数据Dump分析。本实验可在train.py中如下两处添加使能代码： ![](https://support.huaweicloud.com/bestpractice-modelarts/figure/zh-cn_image_0000002126110065.png "点击放大")
   ![](https://support.huaweicloud.com/bestpractice-modelarts/figure/zh-cn_image_0000002090630392.png "点击放大")
   其中config.json的内容如下：
   ```
   {
   "task": "statistics",
   "dump_path": "/home/data_dump",
   "rank": [],
   "step": [0],
   "level": "L1",
   "seed": 1234,
   "is_deterministic": false,
   "enable_dataloader": false,
   "statistics": {
   "scope": [],
   "list": [],
   "data_mode": ["all"],
   "summary_mode": "statistics"
   }
   }
   ```
   这里Step指定为0表示只对首个Step进行数据Dump。task指定为statistics表示使用统计量模式，该模式下针对整网训练API输入输出保存最大值、最小值、均值等统计量信息比对，落盘数据量较小。GPU和NPU环境依次进行数据Dump，正常执行结束标识如下图回显Exception: msprobe: exit after iteration 0。
   ![](https://support.huaweicloud.com/bestpractice-modelarts/figure/zh-cn_image_0000002090470556.png "点击放大")
   
3. 创建如下compare.json文件。
   ```
   {
   "npu_path": "./npu_dump/dump.json",
   "bench_path": "./bench_dump/dump.json",
   "stack_path": "./npu_dump/stack.json",
   "is_print_compare_log": true
   }
   ```
   
4. 指定对应Dump数据目录后进行比对分析。
   ```
   msprobe -f pytorch compare -i ./compare.json -o ./output -s
   ```
   生成CSV分析表格之后进行分析，该问题第一个偏差来源如下：
   ![](https://support.huaweicloud.com/bestpractice-modelarts/figure/zh-cn_image_0000002126229781.png "点击放大")
   Tensor.__getitem__.0 在forward阶段的第一个输入存在偏差，追溯输入来源发现是torch.randint()函数在device侧随机初始化（下图第214行），由于device侧随机性无法通过seed等自动化方式固定，先通过切换CPU侧计算初始化之后再切回device侧。在train.py中做如下图第215行代码修改。
   ![](https://support.huaweicloud.com/bestpractice-modelarts/figure/zh-cn_image_0000002126110069.png "点击放大")
   
5. 重新训练Dump比对分析后续计算是否存在偏差。比对之后发现：Tensor.__mul__.2在forward计算阶段的第一个input存在偏差。 ![](https://support.huaweicloud.com/bestpractice-modelarts/figure/zh-cn_image_0000002090630396.png "点击放大")
   追溯代码实现是下图中noise变量使用torch.rand_like ()作noise变量的初始化 (下图第730行)。由于torch.rand_like()该函数会根据输入的input构造同样size、dtype、device、layout信息的数据，详情请参见[PyTorch docs介绍](https://pytorch.org/docs/stable/generated/torch.randn_like.html)。所以同样是在device侧做变量初始化引入精度偏差，在diffusion/gaussian_diffusion.py中用等CPU侧初始化实现替换完成计算之后再切回device进行计算(下图第731行)。
   ![](https://support.huaweicloud.com/bestpractice-modelarts/figure/zh-cn_image_0000002090470560.png "点击放大")
   然后再比对分析发现所有API计算都已对齐结果，转而查看Loss对齐情况。
   
 
