Skip to content

Commit 55c19b4

Browse files
committed
fix(data): share DirectHF batch packing path
Signed-off-by: yaoyu-33 <yaoyu.094@gmail.com>
1 parent 7c65d60 commit 55c19b4

2 files changed

Lines changed: 84 additions & 1 deletion

File tree

‎src/megatron/bridge/data/datasets/direct_sft.py‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ def __init__(
7373
self._base_examples = base_examples
7474
self._length = int(max(0, target_length))
7575
self._processor = processor
76+
# The global-batch sampler uses this runtime capability to collate each
77+
# logical microbatch independently before THD packing. Step-owned packing
78+
# must continue through the ordinary dense global-batch path.
79+
self.enable_in_batch_packing = enable_in_batch_packing and not defer_in_batch_packing_to_step
7680
# Choose collate implementation by processor type name when not provided
7781
collate_key = type(processor).__name__ if processor is not None else "default"
7882
explicit_collate_impl = collate_impl is not None
@@ -88,7 +92,7 @@ def __init__(
8892
"pad_to_multiple_of": pad_to_multiple_of,
8993
# Active deferral user: Qwen3-VL. Other VLM/HF collates should pack
9094
# here when enable_in_batch_packing is set.
91-
"enable_in_batch_packing": enable_in_batch_packing and not defer_in_batch_packing_to_step,
95+
"enable_in_batch_packing": self.enable_in_batch_packing,
9296
"in_batch_packing_pad_to_multiple_of": in_batch_packing_pad_to_multiple_of,
9397
}
9498
if explicit_collate_impl:

‎tests/unit_tests/data/datasets/test_direct_sft.py‎

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
import pytest
44
import torch
55

6+
from megatron.bridge.data.batch_utils import prepare_finetuning_batch
67
from megatron.bridge.data.collators.sft import text_chat_collate_fn
78
from megatron.bridge.data.datasets.direct_sft import DirectSFTDataset
9+
from megatron.bridge.data.samplers import build_pretraining_data_loader
810

911

1012
pytestmark = pytest.mark.unit
@@ -95,6 +97,83 @@ def test_direct_sft_dataset_forwards_supported_packing_options():
9597
"enable_in_batch_packing": True,
9698
"in_batch_packing_pad_to_multiple_of": 8,
9799
}
100+
assert dataset.enable_in_batch_packing is True
101+
102+
103+
def test_direct_sft_batch_dataloader_packs_each_logical_microbatch():
104+
collate_sizes = []
105+
106+
def _packed_collate(examples, processor, *, enable_in_batch_packing=False, **kwargs):
107+
del processor, kwargs
108+
collate_sizes.append(len(examples))
109+
assert enable_in_batch_packing is True
110+
return {"tokens": torch.arange(len(examples)).unsqueeze(0)}
111+
112+
dataset = DirectSFTDataset(
113+
base_examples=[_example()],
114+
target_length=4,
115+
processor=_Processor(),
116+
collate_impl=_packed_collate,
117+
enable_in_batch_packing=True,
118+
)
119+
dataloader = build_pretraining_data_loader(
120+
dataset,
121+
consumed_samples=0,
122+
dataloader_type="batch",
123+
micro_batch_size=2,
124+
global_batch_size=4,
125+
num_workers=0,
126+
data_sharding=False,
127+
collate_fn=dataset.collate_fn,
128+
pin_memory=False,
129+
data_parallel_rank=0,
130+
data_parallel_size=1,
131+
)
132+
133+
microbatch_iter, _ = prepare_finetuning_batch(iter(dataloader), 2, 16)
134+
microbatches = list(microbatch_iter)
135+
136+
assert collate_sizes == [2, 2]
137+
assert [microbatch["tokens"].shape for microbatch in microbatches] == [(1, 2), (1, 2)]
138+
139+
140+
def test_direct_sft_batch_dataloader_does_not_precollate_step_owned_packing():
141+
collate_sizes = []
142+
143+
def _deferred_collate(examples, processor, *, enable_in_batch_packing=False, **kwargs):
144+
del processor, kwargs
145+
collate_sizes.append(len(examples))
146+
assert enable_in_batch_packing is False
147+
return {"tokens": torch.arange(len(examples) * 2).reshape(len(examples), 2)}
148+
149+
dataset = DirectSFTDataset(
150+
base_examples=[_example()],
151+
target_length=4,
152+
processor=_Processor(),
153+
collate_impl=_deferred_collate,
154+
enable_in_batch_packing=True,
155+
defer_in_batch_packing_to_step=True,
156+
)
157+
assert dataset.enable_in_batch_packing is False
158+
dataloader = build_pretraining_data_loader(
159+
dataset,
160+
consumed_samples=0,
161+
dataloader_type="batch",
162+
micro_batch_size=2,
163+
global_batch_size=4,
164+
num_workers=0,
165+
data_sharding=False,
166+
collate_fn=dataset.collate_fn,
167+
pin_memory=False,
168+
data_parallel_rank=0,
169+
data_parallel_size=1,
170+
)
171+
172+
microbatch_iter, _ = prepare_finetuning_batch(iter(dataloader), 2, 16)
173+
microbatches = list(microbatch_iter)
174+
175+
assert collate_sizes == [4]
176+
assert [microbatch["tokens"].shape for microbatch in microbatches] == [(2, 2), (2, 2)]
98177

99178

100179
def test_direct_sft_dataset_rejects_collate_without_packing_support():

0 commit comments

Comments
 (0)