Uh oh!
There was an error while loading. Please reload this page.
Update FP8 scale-inverse in kernels with FP8 output - #1083
Conversation
Signed-off-by: Tim Moon <tmoon@nvidia.com>
Signed-off-by: Tim Moon <tmoon@nvidia.com>
Signed-off-by: Tim Moon <tmoon@nvidia.com>
Signed-off-by: Tim Moon <tmoon@nvidia.com>
Signed-off-by: Tim Moon <tmoon@nvidia.com>
Signed-off-by: Tim Moon <tmoon@nvidia.com>
Signed-off-by: Tim Moon <tmoon@nvidia.com>
Signed-off-by: Tim Moon <tmoon@nvidia.com>
timmoon10
commented
Aug 7, 2024
/te-ci |
Signed-off-by: Tim Moon <tmoon@nvidia.com>
timmoon10
commented
Aug 8, 2024
/te-ci |
Use quantization scaling factor in ONNX quantize op. Signed-off-by: Tim Moon <tmoon@nvidia.com>
timmoon10
commented
Aug 9, 2024
/te-ci |
Signed-off-by: Tim Moon <tmoon@nvidia.com>
timmoon10
commented
Aug 14, 2024
/te-ci |
Uh oh!
There was an error while loading. Please reload this page.
| fp8_meta["scaling_fwd"].scale_inv, | ||
| tex.FP8FwdTensors.GEMM1_INPUT, | ||
| inputmat_scale_inv, | ||
| 0, |
There was a problem hiding this comment.
Mostly to keep the API backward-compatible. LayerNormMLP is still storing scale-invs in the fp8_meta.
There was a problem hiding this comment.
Not sure I follow - this particular call is from internal autograd function, so we should be able to change its API.
There was a problem hiding this comment.
fp8_gemm is used differently in Linear and LayerNormMLP: Linear constructs a new scale-inv tensor, LayerNormMLP still uses the fp8_meta's scale-inv and requires an offset. I avoided touching the more complicated logic in LayerNormMLP and attention to keep this PR simple.
Uh oh!
There was an error while loading. Please reload this page.
Signed-off-by: Tim Moon <4406448+timmoon10@users.noreply.github.com>
timmoon10
commented
Aug 17, 2024
/te-ci |
Signed-off-by: Tim Moon <tmoon@nvidia.com>
timmoon10
commented
Aug 19, 2024
/te-ci |
This is to accommondate the behavior change from: NVIDIA/TransformerEngine#1083
Description
We currently treat the FP8 scale-inverse (the dequantization scaling factor) as part of the FP8 recipe, along with the FP8 scale (the quantization scaling factor) and the absmax history. However, this is uncomfortable because any change to the FP8 recipe will invalidate the corresponding FP8 data. We work around this by creating copies of the scale-invs whenever there might be a recipe update, e.g. in between the forward and backward passes of the linear layer:
TransformerEngine/transformer_engine/pytorch/module/linear.py
Line 318 in 6717554
This adds non-trivial CPU overhead (I estimate ~20% for the PyTorch linear layer forward pass on an L40).
A better approach is to treat the scale-inv as part of the FP8 data, something that should be output along with the FP8 bits and should never change independently of the FP8 bits. The FP8 recipe tells us how we want to cast into FP8, while the scale-inv tells us how to convert back to higher precision. Note that this generalizes nicely to block-scaling schemes, where the scale-inv tensor may be large and must be packaged with the data during communication.
This PR makes initial work toward this scheme by including scale-inv updates in most of the kernels with FP8 output: casting, activations, LayerNorm, RMSNorm. It doesn't seem that cuBLAS supports this, so I've added a small kernel that is launched after FP8 GEMMs. I have not attempted to propagate this change into Userbuffers or attention. I've also updated the PyTorch
LinearandLayerNormLinearmodules to avoid maintaining extra copies of the scale-inv and I see a 1.12x speedup in theLinearforward pass.I'm a little apprehensive since this is technically a breaking change. Every time we generate FP8 values we will overwrite the FP8 recipe scale-inv. I have a hard time imagining why we would ever use a stale FP8 scale-inv though if the FP8 data has already been overwritten.
Type of change
Changes
LinearmoduleLayerNormLinearmoduleChecklist: