Enable dynamic batching - #52
Conversation
7af3ba4 to
5b8e1ab
Compare
Signed-off-by: Joseph Lee <jiosephlee@gmail.com>
5b8e1ab to
1882f79
Compare
|
/claude review |
|
LGTM Reviewed the padded dynamic-batch feature end to end (CLI validation → replay-buffer partitioning → rollout forward-batch scheduling → worker |
|
Automodel team will implement this via VLM seq packing~ |
|
@hijkzzz sounds good! I'll leave the PR open for now in case the team faces blockers; I would like to see this feature sooner than later as it's a rather large speed-up for non-FA users (was a big fan of your previous repo OpenRLHF; happy to see this project get started) |
What does this PR do?
Padding-free packing with FA2 already solves the issue of padding + packing, but not all models support FA2 (e.g. GPT-OSS uses FlexAttention).
With sample-based batching, the token footprint of each microbatch varies with sequence length. Thus, users often have to choose a conservatively small microbatch size so an unlucky group of long sequences doesn't OOM. This is inefficient and unreliable.
This PR enables dynamic batching. It balances sequences across data-parallel ranks, groups similar-length sequences, and constructs rank-local microbatches under
--train.max_tokens_per_gpu. Each GPU can therefore use its available memory according to a token-level budget instead of a fixed number of samples.Length-aware grouping spends a controlled amount of padding to replace several small forwards with fewer, larger, more GPU-efficient forwards. Each rank may use a different local padded length while executing the same number of microbatches, keeping FSDP collectives aligned.
The scheduler preserves optimizer windows, sample coverage, and global-token loss normalization. Non-singleton batches remain within the configured padded-footprint budget. A sequence that individually exceeds the budget remains a warned singleton rather than being dropped, so the configured budget must still account for the longest supported sequence and other model memory.
--train.dynamic_batch_pad_to_multiplecontrols optional shape bucketing and defaults to1, meaning exact padded lengths. This is dynamic microbatch sizing, not sequence packing or padding-free training.Existing fixed microbatching and packed dynamic batching remain unchanged, and dynamic batching stays opt-in.
GPU validation
The fixed and dynamic paths were compared on two NVIDIA B200 GPUs using frozen replay. Each arm ran in three fresh processes for 23 optimizer steps; the first three steps were excluded as warm-up.
Both arms used padded training with
--train.micro_batch_size 1. The dynamic arm additionally used:All 12 runs consumed 184/184 samples and completed 23/23 optimizer steps without OOMs, hangs, missing samples, or collective failures.
The correctness comparisons used the same checkpoints, samples, rewards, and optimizer windows:
0.998696, final-weight cosine0.999999999999, and maximum parameter difference3.815e-6.0.972842and relative update difference23.305%.0.999956, relative update difference0.942%, and maximum parameter difference3.815e-6.These results establish numerical training equivalence within expected BF16 reduction differences, not bitwise-identical gradients or updates.
Validation
python -m compileall -q molt examples/python testspython -m pytest -q tests/unit/test_dynamic_batch.py: 11 passed, 1 skippedpython -m pytest -q: 202 passed, 3 skippedCaveats
pad_to_multiple=1) is the recommended configuration.+0.059 GiB) because the new shape triggered a FlexAttention compile (issues with FlexAttention should be investigated deeper and addressed by a different PR)