Skip to content

[distributed] Train a model with context parallelism in Trainer - #50521

Draft
3outeille wants to merge 2 commits into
cp-4-tester-mixinfrom
cp-11-trainer
Draft

3outeille wants to merge 2 commits into
cp-4-tester-mixinfrom
cp-11-trainer

Conversation

@3outeille

@3outeille 3outeille commented Nov 9, 2026 •

Copy link
Copy Markdown
Member

🤗 Transformers CI

What does this PR do?

Stack: #50493 → #50496 → #50511 → #50514 → #50499 → this PR → #50522

[Trainer] can now train a model loaded with DistributedConfig(cp_size=N), also combined with fsdp_size and tp_size.

  • Data: the ranks of a cp group (and of a tp group) must get the same batch. Trainer gives Accelerate's dataloader a (dp_shard, cp, tp) device mesh, so the batches are split over the data parallel ranks only. Accelerate's own context parallelism is not used: the model shards its own inputs.
  • Counting: num_items_in_batch, the loss scale, num_input_tokens_seen and the FLOPs count each batch once per data parallel group, not once per cp rank.
  • Evaluation: the loss works. predict and metrics on logits raise, because each rank only holds the logits of its own slice.
  • For a cp-sharded model, Trainer does not build the ParallelismConfig it builds for TP models, because that model's dp_size counts the cp ranks.

Tests

test_context_parallel in tests/trainer/distributed/test_trainer_distributed_transformers.py runs the same samples twice, once with CP and once in a single process. It compares the per-step loss, the grad norm, the eval loss and num_input_tokens_seen:

setup ranks
cp=2 2
cp=2, gradient accumulation 2 2
fsdp=2 × cp=2, gradient accumulation 2 4
tp=2 × cp=2 4
cp=2, average_tokens_across_devices=False 2

All cases pass on 4× H100 (NCCL) and on CPU (gloo). The existing FSDP / HSDP Trainer tests pass too.

@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.

`Trainer` trains a model loaded with `DistributedConfig(cp_size=N)` like a model on a single
device. Its dataloader mesh is `(dp_shard, cp, tp)`, so the ranks of a cp group (and of a tp group)
get the same batch and only the data parallel ranks split them. The token count that normalizes
the loss counts each sequence once, the logged loss is the loss of the full sequences, and the
per-rank token and FLOP counts gathered over every rank are divided by the batch replicas.

Evaluation supports the loss only: each rank holds the logits of its own slice of the sequences, so
`predict` refuses to gather them. The refusal added with `DistributedConfig(cp_size=N)` goes away.

The script trains a tiny model through `Trainer` with cp / tp / fsdp sizes and writes the loss, the
gradient norm, the evaluation loss and the token count, so the test compares five configurations
against a single-device run of the same samples.
…gle device

`cp_distributed_config.py` trains a tiny model through `Trainer` with cp / fsdp / tp sizes and writes the loss, the gradient norm, the evaluation loss and the token count of two steps. Five configurations (cp, cp with gradient accumulation, fsdp x cp, tp x cp, and cp with tokens not averaged across devices) are compared with a single-device run of the same samples, launched with one process so that the reference does not use `DataParallel`.

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.

2 participants