-
Notifications
You must be signed in to change notification settings - Fork 5.6k
OP Should Not Have Unused Input
Tao Luo edited this page Dec 2, 2019
·
9 revisions
规范概要:
- 第1节,本规范说明
- 第2节,本规范的检查方法
- 第3节,未通过检查的修改建议
补充说明:
- 规范在执行过程中,可能会发现现有规范未考虑到的方面,需要在实施过程中不断补充与完善,也请大家积极反馈意见。
- 当前白名单中的OP需要进一步确认未通过的原因,对于可通过修改OP代码解决的,需要进行相应的修改。
目前,Paddle中OP的input是通过OpMaker/GradOpMaker
中注册的。然而,部分OP存在着注册了一些input,单实际kernel计算中未使用该input的问题。该问题会导致:
-
显存(内存)浪费。在显存(内存)回收(GC)/复用等策略中,需要计算引用计数,如果某个variable被设置OP的input,则引用计数会+1,如果该input实际上并未使用,则会导致该input的存活时间变长,不能及时回收或复用。
-
代码前后不一致。注册Input说明是需要使用的,但是实际上却并未使用。
因此,为了检查提高Paddle的显存(内存)性能,减少OP中未使用的input,提出了本条规范,并在CI中添加了相应的检查方法。
- 在OpKernel运行前,初始化一个
ThreadLocal set
,用于记录该使用的input。 在调用ExecutionContext
的Input / MultiInputVar / MultiInput / Inputs
等接口的时候记录使用的input的name,加入set中。 - 在OpKernel运行后,将OP的inputs与set进行比较,找出未使用的input。
- 跳过使用
mkldnn
的OP,因为mkldnn
使用特殊的内存复用方法且运行在CPU,不影响显存。 - 跳过注册过
NoNeedBufferVarsInference
的input,因为这些input不占用显存。 - 跳过未初始化tensor的input,因为这些input不占用显存。
- 跳过使用
- 设置
FLAGS_enable_unused_var_check
控制该检查的开启和关闭,目前只在PR_CI_Coverage
中开启,因为该CI运行的单测较全。 - 设置一个白名单,记录部分存量问题OP,白名单详见unused_var_check.cc。
目前已在PR_CI_Coverage
中开启本规范的检查,存量问题OP已经修复或加入白名单。
若新增OP或修改OP导致该检查不过,build_log中会出现类似如下记录:
Error Message Summary:
----------------------
PermissionDeniedError: Unused input variables check failed: Operator op_with_unused_var has input(s) not uesed: X, please make sure it(them) is(are) needed.
If not, remove it(them) from inputs; if yes, register NoNeedBufferVars or add the operator to white list in unused_var_check.h.
[Hint: Expected unsed_input_var_names.size() == 0, but received unsed_input_var_names.size():1 != 0:0.] at (/Paddle/Paddle/paddle/fluid/framework/unused_var_check.cc:82)
出现问题的原因可以分为三种情况,相应解决方法如下:
- 该input的dims和tensor在任意情况下都不需要参与计算。
- 解决方法:从OpMaker中删除该input。
- 例如PR24107中abs_grad。
- 该input的dims需要在InferShape或计算时使用,而tensor不需要参与计算。
- 解决方法:可以注册NoNeedBufferVarsInference。
- 例如PR21169中flatten_grad和squeeze_grad。
- 该input的tensor在某些条件下需要参与计算(在if语句中/或CUDA与CPU计算逻辑不同)。
- 解决方法:可以加入unused_var_check.cc文件中的白名单。
- 例如PR21169中将fake_quantize_range_abs_max加入白名单,正是因为
FakeQuantizeRangeAbsMaxKernel
中涉及if语句,不同条件使用不同input。 - 白名单的修改需要approval(CI中会提示相应审批人)。
若遇到其他问题,请联系 @zhiqiu。