Skip to content

Fix flaky Lion optimizer test on HIP/AMD GPUs - #95

Open
kudomcho wants to merge 1 commit into
ROCm:rocm_enabled_multi_backendfrom
kudomcho:fix/lion-optimizer-tolerance-hip
Open

Fix flaky Lion optimizer test on HIP/AMD GPUs#95
kudomcho wants to merge 1 commit into
ROCm:rocm_enabled_multi_backendfrom
kudomcho:fix/lion-optimizer-tolerance-hip

Conversation

@kudomcho

@kudomcho kudomcho commented Aug 6, 2026

Copy link
Copy Markdown

Summary

  • Scale max_error_count in test_optimizer32bit with tensor size instead of hardcoding 10
  • Fixes flaky test_optimizer32bit[dim2=4097-dim1=1024-fp32-opt=lion] on MI300X (~30% failure rate)

Root Cause

Lion uses sgn() on a lerp of momentum and gradient. When the lerp value is near zero, the fused bnb kernel and the separate-op PyTorch reference can disagree on the sign due to different FMA contraction by HIP's clang vs nvcc. Each sign flip causes exactly 2 * lr = 0.0002 error. Larger tensors have more boundary cases — the 4.19M element case was hitting ~12 errors against a limit of 10.

New formula: max(10, p1.numel() // 200000) — keeps the floor at 10 for small tensors, scales up for larger ones.

Test plan

  • Flaky test dim2=4097-dim1=1024-fp32-opt=lion: 10/10 passes (was 7/10 before)
  • Full test_optim.py: 151 passed, 26 skipped, 0 failed
  • Full test_functional.py: 411 passed, 339 skipped, 0 failures related to this change

🤖 Generated with Claude Code

Scale max_error_count with tensor size instead of hardcoding 10.
Lion uses sgn() on a lerp value, and when it's near zero the fused
bnb kernel and separate-op PyTorch reference disagree on the sign
due to different FMA contraction by HIP clang vs nvcc. Each flip
causes exactly 2*lr error. Larger tensors have more boundary cases,
so the tolerance should scale accordingly.

For dim2=4097 x dim1=1024 (4.19M elements), the new limit is 20
instead of 10. The test was failing ~30% of runs on MI300X with
12 errors — just 2 over the old limit.

Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
Comment thread tests/test_optim.py
# Lion uses sgn() which amplifies FMA rounding differences at the
# sign boundary; HIP/clang contracts FMA differently from nvcc,
# producing more boundary flips on AMD GPUs.
lion_max_err = max(10, p1.numel() // 200000)

@liligwu liligwu Aug 11, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @kudomcho , shall we discuss with bitsandbytes about the relax of this boundary?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @liligwu I checked upstream (bitsandbytes-foundation/bitsandbytes main) and they've already bumped max_error_count from 10 to 15 on the main assertion (line 210), though the state-reload checks are still at 10. So they've hit the same boundary issue.

This approach (max(10, p1.numel() // 200000)) is more robust since it scales with tensor size, a fixed 15 could still flake on larger dims.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants