Skip to main content

Package for gradient accumulation in TensorFlow

Project description

GradientAccumulator

Seemless gradient accumulation for TensorFlow 2

Pip Downloads PyPI version License DOI CI

GradientAccumulator was developed by SINTEF Health due to the lack of an easy-to-use method for gradient accumulation in TensorFlow 2.

The package is available on PyPI and is compatible with and have been tested against TF >= 2.2 and Python >= 3.6 (tested with 3.6-3.10), and works cross-platform (Ubuntu, Windows, macOS).

What?

Gradient accumulation (GA) enables reduced GPU memory consumption through dividing a batch into smaller reduced batches, and performing gradient computation either in a distributing setting across multiple GPUs or sequentially on the same GPU. When the full batch is processed, the gradients are the accumulated to produce the full batch gradient.

Why?

In TensorFlow 2, there did not exist a plug-and-play method to use gradient accumulation with any custom pipeline. Hence, we have implemented two generic TF2-compatible approaches:

Method Usage
GAModelWrapper model = GAModelWrapper(accum_steps=4, inputs=model.input, outputs=model.output)
GAOptimizerWrapper opt = GAOptimizerWrapper(accum_steps=4, optimizer=tf.keras.optimizers.Adam(1e-3))

a generic TF2-compatible approach wich overloads the train_step of any given tf.keras.Model. To update correctly according to te user-specified number of accumulation steps.

For our single-GPU approach, our implementation enables theoretically infinitely large batch size, with identical memory consumption as for a regular mini batch. This comes at the cost of increased training runtime. Multiple GPUs could be used to increase runtime performance. However, our train_step approach is not currently compatible with TensorFlow's tf.distribute (thoroughly discussed here).

As batch normalization is not natively compatible with GA, support for adaptive gradient clipping has been added as an alternative. We have also added support for mixed precision and both GPU and TPU support.

Install

Stable release from PyPI:

pip install gradient-accumulator

Or from source:

pip install git+https://github.com/andreped/GradientAccumulator

Usage

from gradient_accumulator.GAModelWrapper import GAModelWrapper
from tensorflow.keras.models import Model

model = Model(...)
model = GAModelWrapper(accum_steps=4, inputs=model.input, outputs=model.output)

Then simply use the model as you normally would!

Mixed precision

There has also been added experimental support for mixed precision:

from tensorflow.keras import mixed_precision
from tensorflow.keras.optimizers import Adam

mixed_precision.set_global_policy('mixed_float16')
model = GAModelWrapper(accum_steps=4, mixed_precision=True, inputs=model.input, outputs=model.output)

opt = Adam(1e-3, epsilon=1e-4)
opt = mixed_precision.LossScaleOptimizer(opt)

If using TPUs, use bfloat16 instead of float16, like so:

mixed_precision.set_global_policy('mixed_bfloat16')

There is also an example of how to use gradient accumulation with mixed precision here.

Adaptive gradient clipping

There has also been added support for adaptive gradient clipping, based on this implementation:

model = GAModelWrapper(accum_steps=4, use_agc=True, clip_factor=0.01, eps=1e-3, inputs=model.input, outputs=model.output)

The hyperparameters values for clip_factor and eps presented here are the default values.

Model format

It is recommended to use the SavedModel format when using this implementation. That is because the HDF5 format is only compatible with TF <= 2.6 when using the model wrapper. However, if you are using older TF versions, both formats work out-of-the-box. The SavedModel format works fine for all versions of TF 2.x

macOS compatibility

Note that GradientAccumulator is perfectly compatible with macOS, both with and without GPUs. In order to have GPU support on macOS, you will need to install the tensorflow-compiled version that is compatible with metal:

pip install tensorflow-metal

GradientAccumulator can be used as usually. However, note that there only exists one tf-metal version, which should be equivalent to TF==2.5.

TF 1.x

For TF 1, I suggest using the AccumOptimizer implementation in the H2G-Net repository instead, which wraps the optimizer instead of overloading the train_step of the Model itself (new feature in TF2).

PyTorch

For PyTorch, I would recommend using accelerate. HuggingFace :hugs: has a great tutorial on how to use it here.

Troubleshooting

Overloading of train_step method of tf.keras.Model was introduced in TF 2.2, hence, this code is compatible with TF >= 2.2.

Also, note that TF depends on different python versions. If you are having problems getting TF working, try a different TF version or python version.

Disclaimer

In theory, one should be able to get identical results for batch training and using gradient accumulation. However, in practice, one may observe a slight difference. One of the cause may be when operations are used (or layers/optimizer/etc) that update for each step, such as Batch Normalization. It is not recommended to use BN with GA, as BN would update too frequently. However, you could try to adjust the momentum of BN (see here).

It was also observed a small difference when using adaptive optimizers, which I believe might be due to how frequently they are updated. Nonetheless, for the optimizers, the difference was quite small, and one may approximate batch training quite well using our GA implementation, as rigorously tested here).

Acknowledgements

The gradient accumulator model wrapper is based on the implementation presented in this thread on stack overflow. The adaptive gradient clipping method is based on the implementation by @sayakpaul. The optimizer wrapper is derived from the implementation by @fsx950223 and @stefan-falk.

How to cite?

If you used this package or found the project relevant in your research, please, considering including the following citation:

@software{andre_pedersen_2022_7306095,
  author       = {André Pedersen and David Bouget},
  title        = {andreped/GradientAccumulator: v0.2.2},
  month        = nov,
  year         = 2022,
  publisher    = {Zenodo},
  version      = {v0.2.2},
  doi          = {10.5281/zenodo.7306095},
  url          = {https://doi.org/10.5281/zenodo.7306095}
}

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gradient-accumulator-0.3.0.tar.gz (13.1 kB view details)

Uploaded Source

Built Distribution

gradient_accumulator-0.3.0-py3-none-any.whl (13.9 kB view details)

Uploaded Python 3

File details

Details for the file gradient-accumulator-0.3.0.tar.gz.

File metadata

  • Download URL: gradient-accumulator-0.3.0.tar.gz
  • Upload date:
  • Size: 13.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.16

File hashes

Hashes for gradient-accumulator-0.3.0.tar.gz
Algorithm Hash digest
SHA256 1be029eb9038888eabfde621cf6b6ec1602eab55cb349e707318a335b4b9e75e
MD5 9244f4146703dc670be08a71eef6a419
BLAKE2b-256 d967c4a05bb9770f2f45e5040210cf6c9cefa504bc71b18f7624d4074ec4b252

See more details on using hashes here.

File details

Details for the file gradient_accumulator-0.3.0-py3-none-any.whl.

File metadata

File hashes

Hashes for gradient_accumulator-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e58170e8ed858633510545ff4f31df54f9a4ed9f5285dd3a670dc0a78a002512
MD5 f32e24c2c3e2de4b640f15cc28de59ba
BLAKE2b-256 db6d3a05785162f6aca32a07bda952162ffccd069b724fa583737745d1cde6bd

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page