r"""Checkpoint a model or part of the model Checkpointing works by trading compute for memory. Rather than storing all intermediate activations of the entire computation graph for computing backward, the checkpointed part does **not** save intermediate activations, and instead recom
(function, *args, **kwargs)
| 104 | |
| 105 | |
| 106 | def checkpoint(function, *args, **kwargs): |
| 107 | r"""Checkpoint a model or part of the model |
| 108 | |
| 109 | Checkpointing works by trading compute for memory. Rather than storing all |
| 110 | intermediate activations of the entire computation graph for computing |
| 111 | backward, the checkpointed part does **not** save intermediate activations, |
| 112 | and instead recomputes them in backward pass. It can be applied on any part |
| 113 | of a model. |
| 114 | |
| 115 | Specifically, in the forward pass, :attr:`function` will run in |
| 116 | :func:`torch.no_grad` manner, i.e., not storing the intermediate |
| 117 | activations. Instead, the forward pass saves the inputs tuple and the |
| 118 | :attr:`function` parameter. In the backwards pass, the saved inputs and |
| 119 | :attr:`function` is retrieved, and the forward pass is computed on |
| 120 | :attr:`function` again, now tracking the intermediate activations, and then |
| 121 | the gradients are calculated using these activation values. |
| 122 | |
| 123 | .. warning:: |
| 124 | Checkpointing doesn't work with :func:`torch.autograd.grad`, but only |
| 125 | with :func:`torch.autograd.backward`. |
| 126 | |
| 127 | .. warning:: |
| 128 | If :attr:`function` invocation during backward does anything different |
| 129 | than the one during forward, e.g., due to some global variable, the |
| 130 | checkpointed version won't be equivalent, and unfortunately it can't be |
| 131 | detected. |
| 132 | |
| 133 | .. warning:: |
| 134 | If checkpointed segment contains tensors detached from the computational |
| 135 | graph by `detach()` or `torch.no_grad()`, the backward pass will raise an |
| 136 | error. This is because `checkpoint` makes all the outputs require |
| 137 | gradients which causes issues when a tensor is defined to have no |
| 138 | gradient in the model. To circumvent this, detach the tensors outside of |
| 139 | the `checkpoint` function. |
| 140 | |
| 141 | .. warning: |
| 142 | At least one of the inputs needs to have :code:`requires_grad=True` if |
| 143 | grads are needed for model inputs, otherwise the checkpointed part of the |
| 144 | model won't have gradients. |
| 145 | |
| 146 | Args: |
| 147 | function: describes what to run in the forward pass of the model or |
| 148 | part of the model. It should also know how to handle the inputs |
| 149 | passed as the tuple. For example, in LSTM, if user passes |
| 150 | ``(activation, hidden)``, :attr:`function` should correctly use the |
| 151 | first input as ``activation`` and the second input as ``hidden`` |
| 152 | preserve_rng_state(bool, optional, default=True): Omit stashing and restoring |
| 153 | the RNG state during each checkpoint. |
| 154 | args: tuple containing inputs to the :attr:`function` |
| 155 | |
| 156 | Returns: |
| 157 | Output of running :attr:`function` on :attr:`*args` |
| 158 | """ |
| 159 | # Hack to mix *args with **kwargs in a python 2.7-compliant way |
| 160 | preserve = kwargs.pop('preserve_rng_state', True) |
| 161 | if kwargs: |
| 162 | raise ValueError("Unexpected keyword arguments: " + ",".join(arg for arg in kwargs)) |
| 163 |
no outgoing calls
no test coverage detected