:class:`FP16_Optimizer` is designed to wrap an existing PyTorch optimizer, and manage static or dynamic loss scaling and master weights in a manner transparent to the user. For standard use, only two lines must be changed: creating the :class:`FP16_Optimizer` instance, and changin
| 84 | |
| 85 | # TODO: Update overflow check + downscale to use Carl's fused kernel. |
| 86 | class FP16_Optimizer(object): |
| 87 | """ |
| 88 | :class:`FP16_Optimizer` is designed to wrap an existing PyTorch optimizer, |
| 89 | and manage static or dynamic loss scaling and master weights in a manner transparent to the user. |
| 90 | For standard use, only two lines must be changed: creating the :class:`FP16_Optimizer` instance, |
| 91 | and changing the call to ``backward``. |
| 92 | |
| 93 | Example:: |
| 94 | |
| 95 | model = torch.nn.Linear(D_in, D_out).cuda().half() |
| 96 | optimizer = torch.optim.SGD(model.parameters(), lr=1e-3) |
| 97 | # Name the FP16_Optimizer instance to replace the existing optimizer |
| 98 | # (recommended but not required): |
| 99 | optimizer = FP16_Optimizer(optimizer, static_loss_scale = 128.0) |
| 100 | ... |
| 101 | # loss.backward() becomes: |
| 102 | optimizer.backward(loss) |
| 103 | ... |
| 104 | |
| 105 | Example with dynamic loss scaling:: |
| 106 | |
| 107 | ... |
| 108 | optimizer = FP16_Optimizer(optimizer, dynamic_loss_scale=True) |
| 109 | # optional arg to control dynamic loss scaling behavior |
| 110 | # dynamic_loss_args={'scale_window' : 500}) |
| 111 | # Usually, dynamic_loss_args is not necessary. |
| 112 | |
| 113 | Args: |
| 114 | init_optimizer (torch.optim.optimizer): Existing optimizer created with the parameters to optimize. Internally, :class:`FP16_Optimizer` replaces the passed optimizer's fp16 parameters, if any, with fp32 master parameters copied from the original ones. :class:`FP16_Optimizer` also stores references to the original fp16 parameters, and updates these fp16 parameters from the master fp32 copy at the end of each :attr:`step`. |
| 115 | static_loss_scale (float, optional, default=1.0): Loss scale used internally to scale gradients computed by the model. Any fp16 gradients will be copied to fp32, then downscaled before being applied to the fp32 master params, so ``static_loss_scale`` should not affect learning rate. |
| 116 | dynamic_loss_scale (bool, optional, default=False): Use dynamic loss scaling. If True, this will override any ``static_loss_scale`` option. |
| 117 | dynamic_loss_args (dict, optional, default=None): Dict of kwargs that will be forwarded to the internal :class:`DynamicLossScaler` instance's constructor. Keys of this dict must match kwargs accepted by :class:`DynamicLossScaler`'s constructor. If ``dynamic_loss_args`` is unspecified, :class:`DynamicLossScaler`'s defaults will be used. |
| 118 | verbose (bool, optional, default=True): By default, FP16_Optimizer's constructor prints out the parameters and parameter groups it is ingesting, as a sanity check. If this becomes annoying (e.g. for large models), it can be disabled by passing ``verbose=False``. ``verbose=False`` will not disable printing when the loss scale is readjusted during dynamic loss scaling. |
| 119 | |
| 120 | ``init_optimizer`` is expected to have been constructed in the ordinary way. |
| 121 | It is recommended (although not required) that the newly constructed :class:`FP16_Optimizer` instance be |
| 122 | named to replace ``init_optimizer``, for two reasons: |
| 123 | First, it means that references to the same name |
| 124 | later in the file will not have to change. |
| 125 | Second, :class:`FP16_Optimizer` reserves the right (as an implementation detail) to |
| 126 | modify ``init_optimizer``. If you do choose a unique name for the new |
| 127 | :class:`FP16_Optimizer` instance, you should only work with this new instance, |
| 128 | because the preexisting optimizer might no longer behave as expected. |
| 129 | |
| 130 | ``init_optimizer`` may be any Pytorch optimizer. |
| 131 | It may contain a mixture of fp16 and fp32 parameters organized into any number of |
| 132 | ``param_groups`` with different hyperparameters. The :class:`FP16_Optimizer` constructor will |
| 133 | ingest these ``param_groups`` and remember them. |
| 134 | |
| 135 | Calls to :: |
| 136 | |
| 137 | loss.backward() |
| 138 | |
| 139 | must be replaced with :: |
| 140 | |
| 141 | optimizer.backward(loss) |
| 142 | |
| 143 | because :class:`FP16_Optimizer` requires ownership of the backward pass to implement |