一、引言
随着项目的不断发展和迭代,单元测试(Unit Testing)在保障代码质量和稳定性方面扮演着越来越重要的角色。特别是对于PIR这样的关键任务,单测推全(即确保所有单元测试都通过)更是不可或缺的一环。为了帮助新同学更好地上手PIR单测推全的任务,了解在单测过程中可能遇到的问题以及相应的解决方案,我们特此创建一个issue来汇总这些信息,为未来的工作提供参考。
二、参与方式
具体方式是在本issue下方评论回复📝,参考格式如下。
【问题描述】:(最好给出报错堆栈截图)
【解决方案】:(介绍问题产生的原因,以及修改方法)
【示例PR】:
三、总结
通过本issue的汇总,我们希望能够为新同学提供一个关于PIR单测推全任务的全面指南和参考。在实际工作中,如果遇到类似的问题或困难,可以查阅本issue中的解决方案进行参考和借鉴。同时,我们也鼓励大家积极分享自己的经验和心得,共同完善和优化我们的工作流程和测试体系。
四、参考资料
PIR单测推全 🔗
9条答案
按热度按时间lstz6jyr1#
【问题描述】:PIR不支持.name,所以这个test_name可以跳过PIR的测试
【解决方案】:使用 with paddle.pir utils.OldlrGuard() 包裹问题代码块
【示例PR】: #66110
3npbholx2#
【问题描述】:在 @test_with_pir_api 装饰器包裹下,executor 执行 base.default_main_program() 出现报错
【解决方案】:原因:IRGuard 没有对 paddle.base.default_main_program 和 paddle.base.default_startup_program 进行替换。解决方法:在构建静态图前,实例化两个 paddle.static.Program() 分别作为 main_program 和 startup_program,并在静态图构图时使用 paddle.static.program_guard 管理上下文即可。
【示例PR】: #58259
new9mtju3#
【问题描述】:在 @test_with_pir_api 装饰器包裹下,两个不同的网络在同一个 Program 下组网,第一次执行第一个网络,第二次执行第二个网络。执行器在执行第二个网络时出现错误
【解决方案】:将两个网络分别在两个 program 下组网并执行即可
【示例PR】: #58259
yqyhoc1h4#
【问题描述】:在开启 PIR FLAGS 时,动态图代码中使用了
paddle.framework.random._manual_program_seed(self.seed)
发现原本测试精度不足【解决方案】:使用
paddle.pir_utils.OldIrGuard
包装_manual_program_seed
方法手动运行在旧静态图下。【示例PR】: PaddlePaddle/PaddleTest#2878
【问题描述】:错误中提示
TypeError: The type of '%Input' in operator conv3d should be one of [str, bytes, Variable]. but received : Valu
等关于 append op 时的报错【解决方案】:需要查找对应的 API 是否适配了 PIR 逻辑,可以添加 in_pir_mode 或者 in_dynamic_or_pir_mode 进行适配。如果当前的 API 本身是不适配 PIR 下的(比如 static.nn 下的),考虑有没有其他的 API 的可以替换(static.nn.fc可以使用 Linear),或者直接废弃。
【示例PR】: #66017
【问题描述】:代码中使用类似
feed={"data": x, "spectral_norm_0.w_0": w0, "spectral_norm_0.w_1": w1},
,feed 参数 op 时,PIR 下不支持这种写法【解决方案】:不进行 PIR 适配
【示例PR】: PaddlePaddle/PaddleTest#2885
【问题描述】:使用
paddle.static.gradients
获取反向梯度 op 的时候,不进行处理旧传入 fetch_list 中,导致传入不被允许的 None 值.【解决方案】:在之前需要判断方向梯度 op 是否为 None。fetch_list 只支持 Value 以及 str
【示例PR】: PaddlePaddle/PaddleTest#2883
camsedfj5#
【问题描述】:部分单测需要测试训练 program 以及测试 program 是否前向一致。即,使用到了
Program
的clone(for_test=True)
方法【解决方案】:该方法是因为在 PIR 下有一套新的 Program 实现,且未实现Clone接口。所以如果该接口用的比较多,可以考虑在PIR下进行实现。暂行的解决办法就是手动 Clone 一遍,但是要注意需要重设种子,以及重设startup program。
【示例PR】:https://github.com/PaddlePaddle/Paddle/pull/66114/files#diff-ba7a9b8d8540a519c64a98e7fa9edbdbcdde8f0c5bb9e026acb74cf4d8019366
cs7cruho6#
【问题描述】:部分单测需要 fetch 网络参数的 grad 。下方是一个例子:
【解决方案】:在PIR下只能 fetch Value,所以这里需要考虑得到参数 grad 对应的Value。一个方法是来自欢哥的 PR 。
paddle.base.backward.append_backward 为program 添加反向部分,并返回参数以及梯度,这时便可以利用该Value Fetch
如果是优化器单测中遇到了该问题,也可以利用优化器的 minimize(loss) 函数的返回值得到,这个可以见PR
【示例PR】: #65473#66114
btqmn9zl7#
【问题描述】:AMP使用问题,
【解决方案】:该问题是因为在 PIR 下 AMP 在
_init_amp_var()
时并未创建self._loss_scaling
,从而self._loss_scaling = None
。但是简单的将self._loss_scaling 初始化并不能解决问题,可能还会遇到网络输入不符合预期的问题。如下
实际上PIR下的AMP应该统一调用
paddle.amp.decorate
和paddle.amp.auto_cast
这两个Api。可以参考 https://github.com/PaddlePaddle/Paddle/blob/develop/test/amp/test_pir_amp.py#L67-L105 处进行修改【示例PR】:
k2fxgqgv8#
【问题描述】:错误进入老ir静态图分支,算子内部没有pir分支
【解决方案】:增加pir分支
【示例PR】: #66228
ar7v8xwq9#
如果单测中,遇到Program.create_var,Program.desc,Program.append_op等可以直接加OldGuard
类似下面的报错信息有大概率是可以直接加OldGuard解决问题的,但是有些还是需要具体查看报错栈信息
AttributeError: 'paddle.base.libpaddle.pir.Block' object has no attribute 'create_var
【示例PR】: #66226