Skip to content

Compile spectral descent Newton-Schulz with foreach_map - #274

Draft
mlazos wants to merge 1 commit into
facebookresearch:mainfrom
mlazos:muon-symmetric-gemm
Draft

Compile spectral descent Newton-Schulz with foreach_map#274
mlazos wants to merge 1 commit into
facebookresearch:mainfrom
mlazos:muon-symmetric-gemm

Conversation

@mlazos

@mlazos mlazos commented Aug 6, 2026

Copy link
Copy Markdown

Summary

  • express the BF16 Newton-Schulz spectral descent update with foreach_map
  • compile the foreach preconditioner separately when Shampoo PT2 compilation is enabled
  • retain the existing implementation for other dtypes and SVD orthogonalization

The separate compiled callable is needed because the surrounding optimizer preconditioning path intentionally disables compilation. It lets compatible matrix updates reach PT2 as one operation and enables grouped symmetric GEMM lowering when used with the corresponding PyTorch Inductor changes.

This draft currently depends on PyTorch Inductor symmetric/grouped GEMM changes that are not yet upstream.

Test plan

ruff check distributed_shampoo/distributed_shampoo.py distributed_shampoo/preconditioner/spectral_descent_preconditioner_list.py distributed_shampoo/preconditioner/tests/spectral_descent_preconditioner_list_test.py
ruff format --check distributed_shampoo/distributed_shampoo.py distributed_shampoo/preconditioner/spectral_descent_preconditioner_list.py distributed_shampoo/preconditioner/tests/spectral_descent_preconditioner_list_test.py
python -m pytest distributed_shampoo/preconditioner/tests/spectral_descent_preconditioner_list_test.py -q -k 'bfloat16_uses_foreach_map or empty_list'

The two focused tests pass. Running the entire test file gives 11 passes and two unrelated SVD failures because the locally built PyTorch does not include LAPACK.

Local performance measurements with the dependent PyTorch changes:

  • four 1536 x 5120 BF16 matrices: 2.043 ms to 1.396 ms for the isolated preconditioner (1.46x)
  • two-rank Gloo full optimizer step on two GB200 GPUs: 31.386 ms baseline and 31.992 ms compiled (0.981x)

The distributed result is included to avoid implying an end-to-end speedup; communication dominates this configuration. An NCCL-enabled measurement is still needed.

Express the BF16 Newton-Schulz spectral descent update as a foreach_map so
PT2 can compile compatible matrices together. Compile the preconditioner
callable independently because the surrounding optimizer preconditioning
path intentionally disables compilation.

Other dtypes and SVD orthogonalization continue to use the existing scalar
implementation.

Test Plan:

```
ruff check distributed_shampoo/distributed_shampoo.py distributed_shampoo/preconditioner/spectral_descent_preconditioner_list.py distributed_shampoo/preconditioner/tests/spectral_descent_preconditioner_list_test.py
ruff format --check distributed_shampoo/distributed_shampoo.py distributed_shampoo/preconditioner/spectral_descent_preconditioner_list.py distributed_shampoo/preconditioner/tests/spectral_descent_preconditioner_list_test.py
python -m pytest distributed_shampoo/preconditioner/tests/spectral_descent_preconditioner_list_test.py -q -k 'bfloat16_uses_foreach_map or empty_list'
```

Authored with an AI assistant.
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Aug 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant