Skip to content

FSDP orchestration: apply + loading/saving#46990

Open
3outeille wants to merge 33 commits into
split/a-pr-3-dual-path-loadingfrom
split/a-pr-4-fsdp-orchestration
Open

FSDP orchestration: apply + loading/saving#46990
3outeille wants to merge 33 commits into
split/a-pr-3-dual-path-loadingfrom
split/a-pr-4-fsdp-orchestration

Conversation

@3outeille

@3outeille 3outeille commented Jul 1, 2026

Copy link
Copy Markdown
Member

CI

Summary

  • FSDP:
    • Only 1 model for now has base_fsdp_plan. Will do another PR to edit every other models later
    • now wired through from_pretrained
    • For FSDP: loading through shard-on-Read + saving like TP (DCP optional)
    • Add FSDP Ci
    • DistributedMixin
  • TP:
    • Wired DistributedConfig everywhere (no more tp_plan=auto)
    • TP left untouched (no Dtensor yet)

Stack

3outeille and others added 4 commits July 1, 2026 05:08
Wire distributed_config from_pretrained/save_pretrained alongside the legacy tp_plan path, add distributed/utils.py for mesh orchestration and checkpoint I/O, and extend sharding_utils with DTensor gather/optimizer fusion helpers needed by save/load.
@HuggingFaceDocBuilderDev

Copy link
Copy Markdown

The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update.

@3outeille 3outeille marked this pull request as draft July 1, 2026 08:49
3outeille added a commit to 3outeille/transformers-test-ci that referenced this pull request Jul 3, 2026
Wire FSDP tests into the dynamic PR CI caller, mirroring tests_tensor_parallel_ci:
detect tests_fsdp_ci_test_list.txt, run with is_fsdp_test marker and RUN_FSDP_TESTS,
and exclude FSDP tests from the tests_torch job.

Companion to huggingface/transformers#46990 (tests_fetcher changes stay in transformers).

Co-authored-by: Cursor <cursoragent@cursor.com>
@3outeille 3outeille changed the title FSDP orchestration: mesh init, distribute-before-load, DCP save FSDP orchestration: apply + loading/saving Jul 3, 2026
@3outeille 3outeille marked this pull request as ready for review July 3, 2026 03:49
@3outeille

Copy link
Copy Markdown
Member Author

run-slow: cohere2_moe, deepseek_v4, glm_moe_dsa, gpt_oss

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Workflow Run ⚙️

This comment contains run-slow, running the specified jobs:

models: ["models/cohere2_moe", "models/deepseek_v4", "models/glm_moe_dsa", "models/gpt_oss"]
quantizations: []

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

CI Results

Workflow Run ⚙️

Commit Info

Context Commit Description
RUN 1bcc0fb0 workflow commit (merge commit)
PR 37df13ee branch commit (from PR)
main 70544cd9 base commit (on main)

⚠️ Model CI failed to report results

The test failure analysis could not be completed. Please check the workflow run for details.

@3outeille 3outeille requested a review from ArthurZucker July 3, 2026 05:10
tarekziade pushed a commit to huggingface/transformers-test-ci that referenced this pull request Jul 3, 2026
Wire FSDP tests into the dynamic PR CI caller, mirroring tests_tensor_parallel_ci:
detect tests_fsdp_ci_test_list.txt, run with is_fsdp_test marker and RUN_FSDP_TESTS,
and exclude FSDP tests from the tests_torch job.

Companion to huggingface/transformers#46990 (tests_fetcher changes stay in transformers).

Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

[For maintainers] Suggested jobs to run (before merge)

run-slow: cohere2_moe, deepseek_v4, glm_moe_dsa, gpt_oss

Comment thread src/transformers/modeling_utils.py
@3outeille 3outeille force-pushed the split/a-pr-4-fsdp-orchestration branch from d70939a to 84dd107 Compare July 6, 2026 06:58
@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

CI recap

Dashboard: View test results in Grafana
Latest run: 28772915580:1
Result: failure | Jobs: 2 | Tests: 21 | Failures: 1 | Duration: 2m 16s

Code quality check failed: test jobs were skipped. Fix the code quality issues and push again to run tests.

@ArthurZucker ArthurZucker left a comment

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.

ty, isolate changes as much as possible

# Get the model state_dict
# --- FSDP path: DCP save (large models, torch >= 2.7) ---
if distributed_checkpoint:
self.save_distributed_checkpoint(model_to_save, save_directory)

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.

Suggested change
self.save_distributed_checkpoint(model_to_save, save_directory)
self.save_distributed_checkpoint(model_to_save, save_directory, push_to_hub, save_on_this_rank)

Comment on lines +3423 to +3434
if push_to_hub and save_on_this_rank:
model_card = create_and_tag_model_card(repo_id, self.model_tags, token=token)
model_card.save(os.path.join(save_directory, "README.md"))
self._upload_modified_files(
save_directory,
repo_id,
files_timestamps,
commit_message=commit_message,
token=token,
create_pr=create_pr,
)
return

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.

Suggested change
if push_to_hub and save_on_this_rank:
model_card = create_and_tag_model_card(repo_id, self.model_tags, token=token)
model_card.save(os.path.join(save_directory, "README.md"))
self._upload_modified_files(
save_directory,
repo_id,
files_timestamps,
commit_message=commit_message,
token=token,
create_pr=create_pr,
)
return


# Get the model state_dict
# --- FSDP path: DCP save (large models, torch >= 2.7) ---
if distributed_checkpoint:

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.

anything happening in this if -> in a separated function

Comment on lines +3529 to +3564
filename = os.path.join(save_directory, shard_file)
shard_state_dict = {}
for tensor_name in tensor_names:
# Get the tensor, and remove it from state_dict to avoid keeping the ref
tensor = state_dict.pop(tensor_name)

# If the param was offloaded, we need to load it back from disk to resave it. It's a strange pattern,
# but it would otherwise not be contained in the saved shard if we were to simply move the file
# or something
if is_offloaded and tensor.device.type == "meta":
tensor = load_offloaded_parameter(model_to_save, tensor_name)

# only do contiguous after it's permuted correctly in case of TP
shard_state_dict[tensor_name] = tensor.contiguous()

# TODO: it would be very nice to do the writing concurrently, but safetensors never releases the GIL,
# so it's not possible for now....
# Write the shard to disk
safe_save_file(shard_state_dict, filename, metadata=metadata)
# Cleanup the data before next loop (important with offloading, so we don't blowup cpu RAM)
del shard_state_dict

if index is None:
path_to_weights = os.path.join(save_directory, weights_name)
logger.info(f"Model weights saved in {path_to_weights}")
else:
save_index_file = SAFE_WEIGHTS_INDEX_NAME
save_index_file = os.path.join(save_directory, _add_variant(save_index_file, variant))
# Save the index as well
with open(save_index_file, "w", encoding="utf-8") as f:
content = json.dumps(index, indent=2, sort_keys=True) + "\n"
f.write(content)
logger.info(
f"The model is bigger than the maximum size per checkpoint ({max_shard_size}) and is going to be "
f"split in {len(state_dict_split.filename_to_tensors)} checkpoint shards. You can find where each parameters has been saved in the "
f"index located at {save_index_file}."

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.

should be in distributed

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.

4 participants