fix(transform): prevent NaN in Adam-family optimizers on float16 zero-gradient steps - #1769
Open
somuai wants to merge 7 commits into
Open
fix(transform): prevent NaN in Adam-family optimizers on float16 zero-gradient steps#1769somuai wants to merge 7 commits into
somuai wants to merge 7 commits into
Conversation
…-gradient steps - Evaluate denominator in float32 promoted precision before division in scale_by_adam, scale_by_amsgrad, scale_by_belief, scale_by_yogi, and scale_by_radam - Prevents float16 eps underflow to 0.0 on zero-gradient steps from causing 0/0 NaN - Preserves complex parameter imaginary components during update - Add regression tests for zero-grad float16 stability and complex parameter preservation - Fixes google-deepmind#1754
sylvesterkaczmarek
left a comment
There was a problem hiding this comment.
The ArrayLike epsilon path can still reproduce this: eps=jnp.asarray(1e-8, dtype=jnp.float16) is already zero before it is added to the promoted denominator, so zero gradients can still produce 0/0. Promote/cast eps and eps_root to the safe denominator dtype (or reject non-representable epsilons) and add an array-epsilon regression test.
…denominator dtype - Cast eps and eps_root to safe_dtype in _update across Adam family - Reject non-representable or non-positive eps in constructors - Add test_adam_family_array_epsilon regression test for ArrayLike and underflowed eps
Author
|
Great catch @sylvesterkaczmarek! Addressed in commit
Ready for another look! |
… to tiny - Guard eps validation with not isinstance(eps, jax.core.Tracer) to prevent TracerBoolConversionError during JIT / inject_hyperparams - Clamp denominator to finfo(safe_dtype).tiny to prevent 0/0 division on any underflowed eps - Ensure all line lengths strictly conform to PEP8 / ruff limit
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resolves #1754.
Problem
scale_by_adam,scale_by_amsgrad,scale_by_belief,scale_by_yogi, andscale_by_radaminoptax/_src/transform.pycompute parameter updates asm / (sqrt(v + eps_root) + eps). When parameters and gradients are infloat16, Python floateps(default1e-8, or1e-16for AdaBelief) underflows below the IEEE 754 float16 subnormal threshold (~5.96e-8) to0.0.On any step with an exact zero gradient (e.g. masked tokens, frozen layers, unused embedding rows), both moment estimates are
0.0, resulting insqrt(0.0) + 0.0 == 0.0in the denominator and producing0.0 / 0.0 = NaN. Once generated,NaNvalues propagate through all subsequent training steps.Solution
scale_by_adam,scale_by_amsgrad,scale_by_belief,scale_by_yogi, and_radam_updateto evaluate the denominator in at leastfloat32precision usingjnp.promote_types(v.dtype, jnp.float32).(m / denom).astype(m.dtype), avoiding denominator underflow while cleanly preserving imaginary components for complex parameters (complex64).optax/_src/transform_test.py:test_adam_family_no_nan_on_float16_zero_grad: verifies all 5 optimizers produce exact0.0updates without NaNs on zero-gradientfloat16inputs.test_adam_family_complex_parameters: verifies complex parameter updates retain imaginary components.