Fix ZeRO-3 checkpoint tag selection during weight reconstruction - #8501
Fix ZeRO-3 checkpoint tag selection during weight reconstruction#8501ai-yang wants to merge 1 commit into
Conversation
Signed-off-by: Rui <1685901819@qq.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1fbcf669b5
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| import pytest | ||
|
|
||
|
|
||
| class TestZeROCheckpointTag(DistributedTest): |
There was a problem hiding this comment.
Add the required Signed-off-by trailer
This non-merge commit has no Signed-off-by trailer, so it does not satisfy the repository's commit requirements. Please add the trailer using the configured Git name and email before merging.
AGENTS.md reference: AGENTS.md:L8-L8
Useful? React with 👍 / 👎.
| allowed_missing_keys = None | ||
| if self.zero_optimization_partition_weights() and not load_optimizer_states and not self.has_moe_layers: | ||
| checkpoint['module'] = get_fp32_state_dict_from_zero_checkpoint(load_dir) | ||
| checkpoint['module'] = get_fp32_state_dict_from_zero_checkpoint(load_dir, tag=tag) |
There was a problem hiding this comment.
Normalize the checkpoint tag before reconstruction
When a checkpoint was saved with a numeric tag and the caller later uses the same numeric value in load_checkpoint, this ZeRO-3 path now passes the integer directly to get_fp32_state_dict_from_zero_checkpoint, whose os.path.join(checkpoint_dir, tag) raises TypeError. This previously worked with the default save_latest=True because reconstruction re-read the stringified tag from latest, and save_checkpoint explicitly supports such values by applying str(tag); normalize the resolved load tag similarly before forwarding it.
Useful? React with 👍 / 👎.
When a non-MoE ZeRO-3 model loads an explicit checkpoint tag with
load_optimizer_states=False, FP32 reconstruction currently resolveslatestagain. As a result, a request forearliercan return its metadata while silently installinglaterweights, or fail if there is nolatestfile.Pass the already resolved
tagtoget_fp32_state_dict_from_zero_checkpoint()so the reconstructed parameters and metadata come from the same checkpoint. The production change is one call argument.Fixes #8499.
Regression coverage
TestZeROCheckpointTagtrains and saves distinct parameter snapshots, then checks restored parameters against the selected snapshot with zero tolerance. It covers explicit older tags with/withoutlatest,load_module_only=True/False, default latest selection, and full optimizer-state restoration as a control. Tests use real engine training and checkpoint files, with no loader mocks.Current-base checks on
71d316d608a56af2fcc27b84b14cf854b7052effplus this fix (2026-09-13):latest, bothload_module_onlyvalues, omitted-tag selection, and a full optimizer-state restore control.TestZeROCheckpoint::test_not_load_optimizer_state[3-False-Adam]andTestZeROCheckpoint::test_load_module_only[3]: 2 passed, each with two ranks.git diff --checkpassed.Run the new regression from the source checkout with its test dependencies installed:
The explicit version options describe the tested PyTorch installation; adjust them for another environment.
Full-model integration evidence
The same production fix was previously tested on base
29d0abbc21f11da806ca14970fa8b3ddb757a152using the complete pretrained Qwen3.5-0.8B language model, all 24 decoder layers and all 752,393,024 language-model parameters trainable. Configuration: BF16, ZeRO-3, PyTorch AdamW, sequence length 32, microbatch 1 per GPU; one and four RTX 3090 24 GiB GPUs, driver 580.173.02, PyTorch 2.12.1+cu126, Transformers 5.10.4, NCCL.Both baseline runs reproduced the wrong-tag load. With the fix, every restored model parameter matched the selected checkpoint exactly, and a subsequent training step updated parameters successfully. This was a short integration check, not a convergence or throughput benchmark; vision, multi-node training, and NVMe offload were outside its scope. Current-base regression results are listed separately above.
Related changes
#3116 and #4089 address adjacent checkpoint behavior but do not pass this engine argument. Open PR #8378 modifies the same call for frozen-parameter dtype handling; it addresses a different contract, and both arguments may need to be retained when rebasing. No public API or checkpoint format changes are introduced here.