-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Upgrade OP Precision to Float64
Upgrade the precision of op test from float32 to float64 (English Version)
规范概要:
- 第1节,本规范的说明
- 第2节,本规范的检查方法
- 第3节,未满足本规范的修改建议
- 第4节,验证是否满足本规范
补充:
此规范在执行过程中,可能存在未考虑周全的地方。请大家积极反馈意见,在实施过程中不断补充与完善。
目前,大部分OP单测的精度是float32,而且误差阈值没有完全统一。为了进一步保证OP的正确性,提出OP单测精度升级到float64的规范。
所有继承OpTest的OP单测,会根据inputs的类型推断单测精度。如果OP单测的精度是float32,应该将精度升级到float64,同时通过统一误差阈值的前向和反向检查。
具体来说,OP单测的inputs会包含多个输入,将所有输入最高精度推断为该单测的精度,即float64>float32>float16>int64>int32>int16>int8>bool
。
当OP单测的精度升级为float64
后,前向检查的绝对误差阈值统一为atol=0
,反向检查的相对误差阈值统一为max_relative_error=1e-7
。注意,虽然统一 max_relative_error=1e-7
,但是在单测反向检查中,实质是根据需要检查的数值大小使用分段的阈值,具体为:如果数值小于1e-10,要求绝对误差小于1e-10;如果数值在1e-10到1e-8之间,要求相对误差小于1e-3;如果数值在1e-8到1e-6之间,要求相对误差小于1e-5;如果数值大于1e-6,要求相对误差小于1e-7。
所有继承OpTest的OP单测,会根据inputs的类型推断单测精度。
- 如果单测精度是float32,在单测结束后会发现没有执行float64精度的check_grad,进行报错提醒。报错信息如
AssertionError: This test of ** op needs check_grad with fp64 precision.
。 - 如果单测精度是float64,前向检查的绝对误差阈值统一为
atol=0
,反向检查的相对误差阈值统一为max_relative_error=1e-7
,然后执行单测前向和反向检查。当无法通过标准误差阈值的检查,进行报错提醒,报错信息如AssertionError: ** Variable ** max gradient diff ** over limit 1e-7
。
特殊情况:
- 保存在EMPTY_GRAD_OP_LIST中OP没有反向计算,则会通过该白名单跳过必须执行float64精度check_grad的检查。
- 当单测被skip_check_grad_ci装饰,会为单测增加no_need_check_grad成员变量,跳过必须执行float64精度check_grad的检查。
当OP单测没有满足精度升级到float64的规范,可以参考以下建议进行修改:
- 如果该OP单测不需要调用OpTest基类的函数,继承的父类可以修改为unittest.TestCase。请参考示例。
- 如果该OP未实现反向计算,则不需要进行反向检查,可以保存到白名单EMPTY_GRAD_OP_LIST将其豁免。使用白名单需要特定人员审核。请参考示例。
- 如果该OP单测inputs类型是float32,将inputs中的输入类型改为float64,则该单测精度升级为float64,然后执行该单测查看是否满足规范。请参考示例。
- 如果该OP单测精度升级为float64后,不能满足规范,需要检查并修改OP内核计算的错误
- 如果该OP因为特殊原因无法进行梯度检查或者无法达到标准误差阈值的要求,使用skip_check_grad_ci装饰器,并描述原因。使用该装饰器需要特定人员审核。请参考示例。
按照上述方法修改OP的所有单测后,将该OP从白名单(python/paddle/fluid/tests/unittests/white_list/op_accuracy_white_list.py中的NO_FP64_CHECK_GRAD_OP_LIST)删除,如果CI可以跑通,则验证该OP满足本规范。
若遇到其他问题,请联系 @juncaipeng