-
Notifications
You must be signed in to change notification settings - Fork 989
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Integrate MS-AMP Support for FP8 as a seperate backend (#2232)
* Redo with new version * Store * Working version * Seperate for now * Min diff * check if available * Better docstring * Check for multiple models and optimizers * Check for TE and MSAMP args seperately * String clarity * Better docstring and types * Quality * Simplify a bunch for fp8 * Convert literals to type alias * Better err * Docs * toc typo * Apply suggestions from code review Co-authored-by: Marc Sun <[email protected]> * Apply suggestions from code review Co-authored-by: Maria Khalusova <[email protected]> * Address doc nits --------- Co-authored-by: Marc Sun <[email protected]> Co-authored-by: Maria Khalusova <[email protected]>
- Loading branch information
1 parent
0606784
commit b052839
Showing
10 changed files
with
337 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
<!--Copyright 2023 The HuggingFace Team. All rights reserved. | ||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with | ||
the License. You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on | ||
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the | ||
specific language governing permissions and limitations under the License. | ||
⚠️ Note that this file is in Markdown but contain specific syntax for our doc-builder (similar to MDX) that may not be | ||
rendered properly in your Markdown viewer. | ||
--> | ||
|
||
# Low Precision Training Methods | ||
|
||
The release of new kinds of hardware led to the emergence of new training paradigms that better utilize them. Currently, this is in the form of training | ||
in 8-bit precision using packages such as [TranformersEngine](https://github.com/NVIDIA/TransformerEngine) (TE) or [MS-AMP](https://github.com/Azure/MS-AMP/tree/main). | ||
|
||
For an introduction to the topics discussed today, we recommend reviewing the [low-precision usage guide](../usage_guides/low_precision_training.md) as this documentation will reference it regularly. | ||
|
||
## A Quick Chart | ||
|
||
Below is a quick chart from the MS-AMP documentation showing the different bit-precisions for each solution during training: | ||
|
||
Optimization Level | Computation(GEMM) | Comm | Weight | Master Weight | Weight Gradient | Optimizer States | ||
-- | -- | -- | -- | -- | -- | -- | ||
FP16 AMP | FP16 | FP32 | FP32 | N/A | FP32 | FP32+FP32 | ||
Nvidia TE | FP8 | FP32 | FP32 | N/A | FP32 | FP32+FP32 | ||
MS-AMP O1 | FP8 | FP8 | FP16 | N/A | FP8 | FP32+FP32 | ||
MS-AMP O2 | FP8 | FP8 | FP16 | N/A | FP8 | FP8+FP16 | ||
MS-AMP O3 | FP8 | FP8 | FP8 | FP16 | FP8 | FP8+FP16 | ||
|
||
## `TransformersEngine` | ||
|
||
`TranformersEngine` is the first solution to trying to train in 8-bit floating point. It works by using drop-in replacement layers for certain ones in a model that utilize their FP8-engine to reduce the number of bits (such as 32 to 8) without degrading the final accuracy of the model. | ||
|
||
Specifically, 🤗 Accelerate will find and replace the following layers with `TranformersEngine` versions: | ||
|
||
* `nn.LayerNorm` for `te.LayerNorm` | ||
* `nn.Linear` for `te.Linear` | ||
|
||
As a result we wind up with a model that has most of its layers in BF16, while some layers are in FP8 reducing some of the memory. | ||
|
||
Anecdotally, we have noticed that performance gains don't really start showing when using `TransformerEngine` until a large majority of the layers | ||
in the model are made up of those two layers to replace. As a result, only larger models have shown performance improvements when the number of parameters is around and upwards of a few billion. | ||
|
||
The `TransformerEngine` can receive many different arguments that customize how it performs FP8 calculations and what they do. A full list of the arguments is available below: | ||
|
||
* `margin`: The margin to use for the gradient scaling. | ||
* `interval`: The interval to use for how often the scaling factor is recomputed. | ||
* `fp8_format``: The format to use for the FP8 recipe. Must be one of `E4M3` or `HYBRID`. | ||
* `amax_history_len`: The length of the history to use for the scaling factor computation | ||
* `amax_compute_algo`: The algorithm to use for the scaling factor computation. Must be one of `max` or `most_recent`. | ||
* `override_linear_precision`: Whether or not to execute `fprop`, `dgrad`, and `wgrad` GEMMS in higher precision. | ||
|
||
You can customize each of these as part of [`utils.FP8RecipeKwargs`] to help optimize performance of your models. | ||
|
||
If we notice in the chart mentioned earlier, TE simply casts the computation layers into FP8, while everything else is in FP32. As a result this winds up utilizing the most memory but does so with the benefit of guaranteeing the least amount of loss in end accuracy during training. | ||
|
||
## `MS-AMP` | ||
|
||
MS-AMP takes a different approach to `TransformersEngine` by providing three different optimization levels to convert more operations in FP8 or FP16. | ||
|
||
* The base optimization level (`O1`), passes communications of the weights (such as in DDP) in FP8, stores the weights of the model in FP16, and leaves the optimizer states in FP32. The main benefit of this optimization level is that we can reduce the communication bandwidth by essentially half. Additionally, more GPU memory is saved due to 1/2 of everything being cast in FP8, and the weights being cast to FP16. Notably, both the optimizer states remain in FP32. | ||
|
||
* The second optimization level (`O2`) improves upon this by also reducing the precision of the optimizer states. One is in FP8 while the other is in FP16. Generally it's been shown that this will only provide a net-gain of no degredated end accuracy, increased training speed, and reduced memory as now every state is either in FP16 or FP8. | ||
|
||
* Finally, MS-AMP has a third optimization level (`O3`) which helps during DDP scenarios such as DeepSpeed. The weights of the model in memory are fully cast to FP8, and the master weights are now stored in FP16. This fully reduces memory by the highest factor as now not only is almost everything in FP8, only two states are left in FP16. Currently, only DeepSpeed versions up through 0.9.2 are supported, so this capability is not included in the 🤗 Accelerate integration | ||
|
||
## Combining the two | ||
|
||
More experiments need to be performed but it's been noted that combining both MS-AMP and TransformersEngine can lead to the highest throughput by relying on NVIDIA's optimized FP8 operators and utilizing how MS-AMP reduces the memory overhead. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
<!--Copyright 2023 The HuggingFace Team. All rights reserved. | ||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with | ||
the License. You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on | ||
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the | ||
specific language governing permissions and limitations under the License. | ||
⚠️ Note that this file is in Markdown but contain specific syntax for our doc-builder (similar to MDX) that may not be | ||
rendered properly in your Markdown viewer. | ||
--> | ||
|
||
# Low Precision Training Methods | ||
|
||
🤗 Accelerate provides integrations to train on lower precision methods using specified supported hardware through the `TransformersEngine` and `MS-AMP` packages. This documentation will help guide you through what hardware is supported, how to configure your [`Accelerator`] to leverage the low precision methods, and what you can expect when training. | ||
|
||
## What training on FP8 means | ||
|
||
To explore more of the nitty-gritty in traninig in FP8 with PyTorch and 🤗 Accelerate, check out the [concept_guide](../concept_guides/low_precision_training.md) on why this can be difficult. But essentially rather than training in BF16, some (or all) aspects of training a model can be performed using 8 bits instead of 16. The challenge is doing so without degrading final performance. | ||
|
||
This is only enabled on specific NVIDIA hardware, namely: | ||
|
||
* Anything after the 3000 series consumer graphics cards (such as the 4090) | ||
* Hopper-based GPU architectures (such as the `H100` and `H200`) | ||
|
||
What this will result in is some gain in the memory used (as we've cut the needed memory in half for some parts of training) and an increase in throughput *should* be seen as well for larger models that can replace certain layers with FP8-enabled ones. | ||
|
||
## Configuring the Accelerator | ||
|
||
Currently two different backends for FP8 are supported (`TransformersEngine` and `MS-AMP`), each with different capabilities and configurations. | ||
|
||
To use either, the same core API is used. Just pass `mixed_precision="fp8"` to either the [`Accelerator`], during `accelerate config` when prompted about mixed precision, or as part of your `config.yaml` file in the `mixed_precision` key: | ||
|
||
```{python} | ||
from accelerate import Accelerator | ||
accelerator = Accelerator(mixed_precision="fp8") | ||
``` | ||
|
||
By default, if `MS-AMP` is available in your environment, 🤗 Accelerate will automatically utilize it as a backend. To specify it yourself (and customize other parts of the FP8 mixed precision setup), you can utilize the [`utils.FP8RecipeKwargs`]: | ||
|
||
```{python} | ||
from accelerate import Accelerator | ||
from accelerate.utils import FP8RecipeKwargs | ||
kwargs = [FP8RecipeKwargs(backend="msamp")] | ||
# Or to specify the backend as `TransformersEngine` even if MS-AMP is installed | ||
# kwargs = [FP8RecipeKwargs(backend="te")] | ||
accelerator = Accelerator(mixed_precision="fp8", kwarg_handlers=kwargs) | ||
``` | ||
|
||
## Configuring MS-AMP | ||
|
||
Of the two, `MS-AMP` is traditionally the easier one to configure as there is only a single argument: the optimization level. | ||
|
||
Currently two levels of optimization are supported in the 🤗 Accelerate integration, `"O1"` and `"O2"` (using the letter 'o', not zero). | ||
|
||
* `"O1"` will cast the weight gradients and `all_reduce` communications to happen in 8-bit, while the rest are done in 16 bit. This reduces the general GPU memory usage and speeds up communication bandwidths. | ||
* `"O2"` will also cast first-order optimizer states into 8 bit, while the second order states are in FP16. (Currently just the `Adam` optimizer is supported). This tries it's best to minimize final accuracy degredation and will save the highest potential memory. | ||
|
||
To specify an optimization level, pass it to the `FP8KwargsHandler` by setting the `optimization_level` argument: | ||
|
||
```{python} | ||
from accelerate import Accelerator | ||
from accelerate.utils import FP8RecipeKwargs | ||
kwargs = [FP8RecipeKwargs(backend="msamp", optimization_level="O2")] | ||
accelerator = Accelerator(mixed_precision="fp8", kwarg_handlers=kwargs) | ||
``` | ||
|
||
## Configuring TransformersEngine | ||
|
||
TransformersEngine has much more available for customizing how and what FP8 calculations are performed. A full list of supported arguments and what they mean are available in [NVIDIA's documentation](https://docs.nvidia.com/deeplearning/transformer-engine/user-guide/api/common.html), however they are restated as part of [`FP8KwargsHandler`]'s docstring for your convience. | ||
|
||
🤗 Accelerate tries to set sensible defaults, but exploring and tweaking the various parameters yourself can lead to better performance potentially. | ||
|
||
To use it, specify `backend="te"` and modify any of the arguments you want as part of your kwarg handler: | ||
|
||
```{python} | ||
from accelerate import Accelerator | ||
from accelerate.utils import FP8RecipeKwargs | ||
kwargs = [FP8RecipeKwargs(backend="te", ...)] | ||
accelerator = Accelerator(mixed_precision="fp8", kwarg_handlers=kwargs) | ||
``` | ||
|
||
## Futher Reading | ||
|
||
To learn more about training in FP8 please check out the following resources: | ||
|
||
* [Our concept guide](../concept_guides/low_precision_training.md) detailing into more about both TransformersEngine and MS-AMP | ||
* [The `transformers-engine` documentation](https://docs.nvidia.com/deeplearning/transformer-engine/user-guide/api/common.html) | ||
* [The `MS-AMP` documentation](https://azure.github.io/MS-AMP/docs/) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.