Skip to content

Commit 4e9878b

Browse files
committed
fix(data): scope batch-sampler shuffling to training
Signed-off-by: Hristo Filaretov <hfilaretov@nvidia.com>
1 parent 14a4fe2 commit 4e9878b

4 files changed

Lines changed: 19 additions & 15 deletions

File tree

‎src/megatron/bridge/data/base.py‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,12 @@ class DataloaderConfig:
4343
drop_last: bool = True
4444
"""Whether dataloaders drop the last incomplete batch."""
4545

46-
shuffle: bool = True
47-
"""Whether the global-batch sampler used by ``dataloader_type="batch"`` reshuffles samples each epoch."""
46+
train_shuffle: bool = True
47+
"""Whether the training global-batch sampler reshuffles samples each epoch.
48+
49+
Only used when ``dataloader_type="batch"``. Validation and test samples are
50+
never shuffled.
51+
"""
4852

4953
persistent_workers: bool = True
5054
"""Whether dataloader workers persist between iterations."""

‎src/megatron/bridge/data/loaders.py‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ def worker_init_fn(_):
334334
global_batch_size=cfg.train.global_batch_size,
335335
drop_last=drop_last,
336336
seed=sampler_seed,
337-
shuffle=cfg.dataset.shuffle,
337+
shuffle=cfg.dataset.train_shuffle,
338338
)
339339
eval_gbs = (
340340
cfg.validation.eval_global_batch_size
@@ -363,7 +363,7 @@ def worker_init_fn(_):
363363
global_batch_size=eval_gbs,
364364
drop_last=not (isinstance(cfg.dataset, GPTSFTDatasetConfig) and cfg.dataset.dataloader_type == "batch"),
365365
seed=sampler_seed,
366-
shuffle=cfg.dataset.shuffle,
366+
shuffle=False,
367367
)
368368
elif cfg.validation.eval_iters > 0:
369369
val_dataloader_type = "cyclic" if isinstance(cfg.dataset, GPTDatasetConfig) else cfg.dataset.dataloader_type
@@ -383,7 +383,7 @@ def worker_init_fn(_):
383383
global_batch_size=eval_gbs,
384384
drop_last=not (isinstance(cfg.dataset, GPTSFTDatasetConfig) and val_dataloader_type == "batch"),
385385
seed=sampler_seed,
386-
shuffle=cfg.dataset.shuffle,
386+
shuffle=False,
387387
)
388388

389389
if cfg.validation.eval_iters > 0:
@@ -403,7 +403,7 @@ def worker_init_fn(_):
403403
global_batch_size=eval_gbs,
404404
drop_last=not (isinstance(cfg.dataset, GPTSFTDatasetConfig) and cfg.dataset.dataloader_type == "batch"),
405405
seed=sampler_seed,
406-
shuffle=cfg.dataset.shuffle,
406+
shuffle=False,
407407
)
408408

409409
# Flags to know if we need to do training/validation/testing.

‎tests/functional_tests/test_groups/data/test_loaders.py‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ def test_build_train_valid_test_data_loaders_uses_eval_dp_group(
320320
dataset_root="/tmp/dataset",
321321
seq_length=512,
322322
seed=4321,
323-
shuffle=False,
323+
train_shuffle=False,
324324
num_workers=0,
325325
persistent_workers=False,
326326
)
@@ -356,14 +356,14 @@ def test_build_train_valid_test_data_loaders_uses_eval_dp_group(
356356
assert train_call.kwargs["seed"] == expected_seed
357357
assert valid_call.kwargs["seed"] == expected_seed
358358
assert test_call.kwargs["seed"] == expected_seed
359-
assert train_call.kwargs["shuffle"] is cfg.dataset.shuffle
360-
assert valid_call.kwargs["shuffle"] is cfg.dataset.shuffle
361-
assert test_call.kwargs["shuffle"] is cfg.dataset.shuffle
359+
assert train_call.kwargs["shuffle"] is cfg.dataset.train_shuffle
360+
assert valid_call.kwargs["shuffle"] is False
361+
assert test_call.kwargs["shuffle"] is False
362362

363363
@mock.patch("torch.distributed.broadcast")
364364
@mock.patch("torch.distributed.get_world_size", return_value=1)
365365
@mock.patch("torch.distributed.get_rank", return_value=0)
366-
def test_gpt_sft_batch_eval_preserves_split_smaller_than_global_batch(
366+
def test_gpt_sft_batch_eval_is_unshuffled_and_preserves_split_smaller_than_global_batch(
367367
self, _mock_rank, _mock_world_size, _mock_broadcast
368368
):
369369
class PaddingAwareDataset:
@@ -404,8 +404,8 @@ def __getitem__(self, index):
404404
test_batch = next(iter(test_dataloader))
405405
assert valid_batch.shape == (cfg.validation.eval_global_batch_size,)
406406
assert test_batch.shape == (cfg.validation.eval_global_batch_size,)
407-
assert -1 in valid_batch
408-
assert -1 in test_batch
407+
assert valid_batch.tolist() == [0, 1, 2, -1]
408+
assert test_batch.tolist() == [0, 1, 2, -1]
409409

410410
@mock.patch("torch.distributed.broadcast")
411411
@mock.patch("torch.distributed.get_world_size", return_value=1)

‎tests/unit_tests/data/builders/test_gpt_sft_config.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ def test_config_round_trip_is_declarative_and_serializable(tmp_path):
5959
hf_output_root=str(tmp_path),
6060
hf_validation_proportion=0.1,
6161
seed=5678,
62-
shuffle=False,
62+
train_shuffle=False,
6363
enable_offline_packing=True,
6464
offline_packing_specs=specs,
6565
do_test=False,
@@ -74,7 +74,7 @@ def test_config_round_trip_is_declarative_and_serializable(tmp_path):
7474
assert restored.offline_packing_specs.packed_sequence_size == 128
7575
assert restored.offline_packing_specs.max_single_sequence_length == 120
7676
assert isinstance(restored.preprocessing, PromptCompletionSFTPreprocessingConfig)
77-
assert restored.shuffle is False
77+
assert restored.train_shuffle is False
7878
assert "tokenizer" not in serialized
7979

8080

0 commit comments

Comments
 (0)