Skip to content

Reshard FSDP2 modules before creating the optimizer - #50535

Open
qgallouedec wants to merge 3 commits into
mainfrom
fsdp2-reshard-before-optimizer
Open

qgallouedec wants to merge 3 commits into
mainfrom
fsdp2-reshard-before-optimizer

Conversation

@qgallouedec

@qgallouedec qgallouedec commented Nov 9, 2026 •

Copy link
Copy Markdown
Member

🤗 Transformers CI

Found while fixing #48841.

After evaluate(), the FSDP2 modules sharded with reshard_after_forward=False (the final norm and LM head under DistributedConfig, the root under Accelerate) keep their unsharded parameters registered. train() then builds the optimizer from those, the next forward registers the sharded ones again, and these weights never train. This reshards every FSDP2 module before creating the optimizer.

@qgallouedec
qgallouedec requested a review from SunMarc November 9, 2026 20:44
@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.

@SunMarc SunMarc left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks ! just a couple of nits

Comment on lines 35 to +37
PEFT_SAVE_SCRIPT = os.path.join(SCRIPTS_DIR, "peft_save_distributed_config.py")
GRAD_ACCUM_SCRIPT = os.path.join(SCRIPTS_DIR, "grad_accum_distributed_config.py")
EVAL_BEFORE_TRAIN_SCRIPT = os.path.join(SCRIPTS_DIR, "eval_before_train_distributed_config.py")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for all these, maybe just move them in the test directly, i prefer not having global var + we will probably have much more test file in the future

parser.add_argument("--output_dir", required=True)
script_args = parser.parse_args()

dist.init_process_group(backend=get_distributed_backend(torch_device), timeout=timedelta(seconds=60))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we shouldn't need this no ?

Suggested change
dist.init_process_group(backend=get_distributed_backend(torch_device), timeout=timedelta(seconds=60))

@SunMarc
SunMarc requested a review from 3outeille November 12, 2026 15:45

This branch has not been deployed

No deployments
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.

3 participants