ModuleValidator¶
- class opacus.validators.module_validator.ModuleValidator[source]¶
Encapsulates all the validation logic required by Opacus. Also works as a namespace to hold registered validators and fixers.
- classmethod fix(module, *, remove_inplace_ops=False, **kwargs)[source]¶
Make the module and sub_modules DP compatible by running registered custom fixers.
In addition to the per-module-type fixers, this always disables in-place activation flags (e.g.
nn.ReLU(inplace=True)) since in-place writes are incompatible with Opacus’ backward hooks. This is a cheap, type-preserving fix that requires no tracing.Functional/tensor in-place ops baked into
forward(e.g. a ResNet’sout += identity) are only rewritten whenremove_inplace_ops=True, because doing so requires symbolic tracing and changes the returned type. It is opt-in: models without such ops (or whose only in-place ops are the activation flags handled above) do not need it. If your model crashes undergrad_sample_mode="hooks"withRuntimeError: Output 0 of BackwardHookFunction is a view and is being modified inplace, re-run withremove_inplace_ops=True.When
remove_inplace_ops=Trueand tracing succeeds, the returned object is atorch.fx.GraphModule, not the originalnn.Modulesubclass.GraphModuleis a subclass ofnn.Moduleand preserves forward outputs for typical models, butisinstancechecks against the original class, custom methods defined on the original class, pickling by class name, and similar type-dependent code will observe the GraphModule type instead. A warning is emitted in this case.FX tracing also records a single execution path: data-independent control flow in the root
forward(e.g.if self.training) is frozen to the branch taken during tracing, so a later.train()/.eval()toggle may have no effect. Standardnn.Dropout/nn.BatchNormsubmodules keep their own flags and are unaffected.Rewriting replaces in-place writes with out-of-place equivalents. Forward outputs are preserved, but aliasing semantics change: a tensor mutated in place is instead replaced by a new tensor, so other aliases to the original storage will not see the update. Code relying on in-place side effects via aliasing may diverge in behavior.
Models that cannot be symbolically traced (e.g. data-dependent control flow) are returned unchanged and the fallback is logged at INFO level.
- Parameters:
- Return type:
- Returns:
Fixed module. Type is
torch.fx.GraphModulewhen tracing succeeds withremove_inplace_ops=True, otherwise the original (cloned)nn.Moduletype.
- classmethod fix_and_validate(module, **kwargs)[source]¶
Fix the module and sub_modules first, and then run validation.
- classmethod is_valid(module)[source]¶
Check if module and sub_modules are valid by running registered custom validators.
- opacus.validators.utils.register_module_fixer(target_class_or_classes, validator_class=<class 'opacus.validators.module_validator.ModuleValidator'>)[source]¶
Registers the decorated function as the
fixeroftarget_class_or_classes, which is the function that will be invoked every time you want to fix an incompatoble module to make it work for training with Opacus. You may supply your own validator_class that holds the registry of FIXERS. The signature of every fixer is always the same:>>> @register_module_fixer(MyCustomModel) ... def fix(module: nn.Module, **kwargs) -> nn.Module: ... pass
It may help you to take a look at the existing fixers inside Opacus, under
opacus.validators.
- opacus.validators.utils.register_module_validator(target_class_or_classes, validator_class=<class 'opacus.validators.module_validator.ModuleValidator'>)[source]¶
Registers the decorated function as the
validatoroftarget_class_or_classes, which is the function that will be invoked every time you want to validate that a module is compatible for training with Opacus. You may supply your own validator_class that holds the registry of VALIDATORS. The signature of every validator is always the same:>>> @register_module_validator(MyCustomModel) ... def validate(module: nn.Module, **kwargs) -> List[opacus.validators.errors.UnsupportedError]: ... pass
It may help you to take a look at the existing validator inside Opacus, under
opacus.validators.