[fix][fsdp] Resume bitsandbytes checkpoints strictly - #2007
Conversation
fcdd6d9 to
52951bc
Compare
52951bc to
035c703
Compare
035c703 to
a980437
Compare
There was a problem hiding this comment.
Code Review
This pull request introduces a custom model state dict loading helper, _load_model_state_dict, to support strict loading while ignoring bitsandbytes quantization metadata keys (such as .absmax, .quant_map, etc.). It also adds corresponding unit tests to verify this behavior. The review feedback suggests optimizing the quantization key check by leveraging str.endswith with a tuple of suffixes to avoid unnecessary loops, and simplifying the calculation of loaded keys using set operations on dictionary keys.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.
Reviewed by Cursor Bugbot for commit e283a48. Configure here.
| return | ||
|
|
||
| incompatible = model.load_state_dict(state_dict, strict=False) | ||
| loaded_keys = state_dict.keys() - incompatible.unexpected_keys |
There was a problem hiding this comment.
Strict load crashes on key set math
High Severity
loaded_keys is computed with state_dict.keys() - incompatible.unexpected_keys. PyTorch returns unexpected_keys as a list, and dict_keys subtraction only accepts a set, so strict resume raises TypeError before any bitsandbytes filtering runs.
Reviewed by Cursor Bugbot for commit e283a48. Configure here.
There was a problem hiding this comment.
This is not reproducible on supported Python. Both dict_keys and odict_keys accept list operands for subtraction and return a set: {'a': 1, 'b': 2}.keys() - ['b'] == {'a'}. Focused strict-load tests also pass with PyTorch's list-valued unexpected_keys.
| for suffix in _BNB_QUANTIZATION_STATE_SUFFIXES: | ||
| if key.endswith(suffix): | ||
| return key[: -len(suffix)] in loaded_keys | ||
| return False |
There was a problem hiding this comment.
Nested quant suffixes match too early
High Severity
_is_bnb_quantization_state_key now returns on the first suffix that matches by endswith, so .nested_absmax and .nested_quant_map are stripped with .absmax / .quant_map instead. Valid double-quant metadata is then treated as unexpected and strict resume fails.
Reviewed by Cursor Bugbot for commit e283a48. Configure here.
There was a problem hiding this comment.
These suffixes do not overlap because their delimiters differ: weight.nested_absmax.endswith(.absmax) and weight.nested_quant_map.endswith(.quant_map) are both false. Focused tests cover all six supported suffixes, including both nested forms, and strict loading passes.
- short-circuit unrelated unexpected keys before suffix iteration - derive loaded keys through state-dict key-view subtraction
e283a48 to
b000937
Compare


Summary
FSDP checkpoints for bitsandbytes 4-bit modules include quantization metadata beside each weight. Freshly constructed modules can accept the weight while reporting that metadata as unexpected, causing strict resume to fail before optimizer, scheduler, RNG, or dataloader state is restored.
Changes
Checkpoint format and model-loading behavior outside bitsandbytes metadata remain unchanged.
Validation
9 passed)git diff --check