Skip to content

feat(model): balance DP workloads inside TransformersModel by default - #367

Open
lincq2000 wants to merge 3 commits into
modelscope:dev-swift-v5from
lincq2000:feat/dp-balance-default
Open

lincq2000 wants to merge 3 commits into
modelscope:dev-swift-v5from
lincq2000:feat/dp-balance-default

Conversation

@lincq2000

@lincq2000 lincq2000 commented Nov 3, 2026 •

Copy link
Copy Markdown
Collaborator

PR type

  • Bug Fix
  • New Feature
  • Document Updates
  • More Models or Datasets Support

PR information

Follow-up to #355. #355 added plan_dp_balance, but the training loop had to call it and reorder every per-sample field itself. This PR builds it into TransformersModel and turns it on by default.

  • New option TransformersModel(dp_balance=True). In Ray mode, before forward_backward / forward_only split a batch across DP ranks, the driver reorders the batch, and every per-sample argument with it (old_logps, advantages, ...), to even out the per-rank workload. It then returns the outputs in the caller's order. Pass dp_balance=False to keep the original split.
  • Local (torchrun) mode is supported too. Each rank holds only its own slice, so the ranks all-gather their sequence lengths and plan the joined batch the same way. When the plan reorders, they swap samples and send every per-sample output back to the rank that holds its input. Steps that need no reordering only exchange the lengths.
  • Losses declare which samples must stay together (Loss.dp_balance_group_size):
    • DPO-style and reward losses keep each pair together (2);
    • REALLoss keeps each group of num_generations together;
    • embedding and listwise reranker losses are never reordered.
  • A call is dispatched unchanged when it cannot be reordered safely, for example:
    • DP = 1;
    • return_logits=True;
    • unencoded inputs;
    • a list argument whose length differs from the batch size;
    • a batch that does not split evenly across ranks.
  • calculate_loss raises an error if it gets per-sample lists after a reordered forward_only.
  • dp_balance/* metrics are reported by model.calculate_metric.
  • The GRPO cookbook no longer calls plan_dp_balance. Docs are updated (en/zh).

Scope: TransformersModel, Ray and local mode.

Experiment results

The planner is the same as in #355.

Tests

tests/model/test_dp_balance.py (reordering, restoring outputs, keeping pairs together, skip cases, a two-process local-mode run on gloo), tests/model/test_micro_batch.py, tests/infra: 114 passed.

lincq2000 and others added 3 commits November 3, 2026 16:08
forward_backward and forward_only now reorder each slice_dp batch on the
driver (Ray mode) so every DP rank gets a similar workload, reorder every
batch-aligned argument with it, and return the outputs in the caller's
order. TransformersModel(dp_balance=False) turns it off.

- remote_function(dp_balance=True) asks the model's _dp_balance_call for
  a plan; calls with object refs, raw logits, unencoded inputs or lists of
  another length are dispatched unchanged.
- Loss.dp_balance_group_size keeps paired samples together (preference
  and reward losses: 2, REAL: num_generations); embedding and listwise
  reranker losses, and plain callables, opt out.
- calculate_loss rejects per-sample lists after a reordered forward_only.
- dp_balance/* metrics are reported by calculate_metric.
- The GRPO cookbook no longer calls plan_dp_balance itself.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
- Skip the blocking _dp_balance_spec round trip once a model reports
  dp_balance off; the flag is fixed at construction.
- Do not reorder when the loss for the call cannot be resolved.
- Leave the hidden-size default to estimate_workload.
- Drop the unread wrapper._dp_balance and the one-line micro-batch
  config helper.
- Document dp_balance in the TransformersModel docs (en/zh).

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Each rank holds only its own slice, so the ranks all-gather their sequence
lengths, plan the joined batch as the Ray driver would, swap samples when
the plan reorders, and send per-sample outputs back to their rank.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
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.

1 participant