Repository navigation
fix: keep float64 weights in float64 during weight processing - #1960
Merged
jlarson4 merged 1 commit intoNov 2, 2026
Merged
Conversation
process_weights cast every floating tensor that was not float32 to float32 before folding. That was meant for bf16/fp16, but it also cast float64 down, so after enable_compatibility_mode() every processed weight of a float64 bridge was rounded to float32. The fp64 check in debugging_numerical_divergence.md then only moved the gpt2 log-prob diff against HF from 7.8e-05 (fp32) to 7.8e-06 (fp64), instead of the ~8 orders of magnitude the guide expects from noise. Record every floating tensor's dtype, cast everything except float64 to float32, and restore every key afterwards. float64 is now processed in float64 (gpt2 fp64 diff 1.8e-13), and each key, created biases included, keeps its input dtype. float32, bf16 and fp16 are processed as before.
Collaborator
|
Good catch and good fix @Sonica-B, thank you for putting this together. I am merging as is! |
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.
Description
Anyone who loads a bridge in float64 and calls
enable_compatibility_mode()gets weights rounded to float32. This hits the fp64 step of Debugging Numerical Divergence ("run fp64 ... If the diff stays the same magnitude, it's a bug. If it drops by ~8 orders of magnitude, it was noise"), the same check in the contributing guide's numerical-work section, and any analysis that uses float64 for tight tolerances. On gpt2 the documented check drops by one order instead of eight, so plain float32 noise reads as a bug.The cause is the upcast at the top of
ProcessWeights.process_weights. It is meant for reduced-precision dtypes ("bfloat16, float16"), but its guard isv.dtype != torch.float32, which also matches float64. So float64 tensors are cast down to float32, folded, and cast back, and every processed weight of a float64 model ends up exactly representable in float32. It goes back to #1176; #1912 changed the same block for created biases and kept the condition.The change records every floating tensor's dtype, casts everything except float64 to float32, and restores every key afterwards:
flowchart LR subgraph Before A1[float64 state dict] --> B1["v.dtype != float32<br/>→ v.float()"] B1 --> C1[fold_ln / center_* / fold_value_biases<br/>in float32] C1 --> D1[cast back to float64<br/>values float32-rounded] end subgraph After A2[float64 state dict] --> B2["dtype recorded<br/>float64 kept as is"] B2 --> C2[fold_ln / center_* / fold_value_biases<br/>in float64] C2 --> D2[every key restored<br/>to its input dtype] endBefore and after, gpt2 on CPU, compatibility mode against
AutoModelForCausalLMwithattn_implementation="eager", prompt"The Eiffel Tower is in the city of":On tiny
from_configmodels in float64, compat-mode log-probs against HF go from 2.3e-08 to 8.9e-16 (GPT-2), from 2.9e-08 to 8.9e-16 (GPT-J) and from 2.2e-08 to 8.9e-16 (Llama).Tests, in
tests/unit/test_weight_processing.pynext to the #1912 dtype tests:test_process_weights_keeps_float64_precision(tiny GPT-2 and GPT-J) builds the HF model in float64, enables compatibility mode, and compares log-probs atatol=1e-12. Ondevit fails at 2.6e-08 and 2.8e-08.test_process_weights_created_biases_keep_model_dtypenow also runs intorch.float64, so created biases are checked to stay float64.Run on Windows 11, Python 3.11.9, torch 2.11.0+cpu, transformers 5.13.0:
tests/unit/test_weight_processing.pyandtests/unit/test_unembed_folding_layout.py: 167 passed, 1 skipped. Ondevthe 2 new precision tests fail and the rest pass.Type of change
Checklist: