feat(input): Megatron MMap Data Formats for MaxText Grain - #4625
Open
Yitrus wants to merge 1 commit into
Open
Conversation
Add a Megatron mmap-backed Grain input pipeline with index parsing, dataset blending, split handling, and configurable file type support. Document the new data path and add unit coverage for mmap loading, packing, blending, and alignment with Megatron.
Yitrus
requested review from
A9isha,
NuojCheng,
RissyRan,
SurbhiJainUSC,
abhinavclemson,
aireenmei,
bvandermoon,
darisoy,
dipannita08,
gagika,
gobbleturk,
hengtaoguo,
huytransformer,
igorts-git,
jacoguzo,
jiangjy1982,
khatwanimohit,
richjames0,
shralex,
suexu1025,
vipannalla and
xibinliu
as code owners
July 27, 2026 10:31
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
1. Summary
This proposal adds
mmapandmmap_npydata formats to MaxText's Grain input pipeline so training can consume Megatron-LM text-preprocessing.bin/.idxdatasets directly.mmapis a simpler Grain-native reader;mmap_npyuses Megatron-style indices to reproduce document shuffle, fixed-length sample construction, sample shuffle, and multi-dataset blending order.The goal of
mmap_npyis element-by-element equivalence to MegatronGPTDatasetfor rawL + 1token samples. It does not introduce a separate training runtime: data still reaches the JAX model through Grain transforms, batching, andMultiHostDataLoadIterator.Indices can be built offline with a CLI or automatically on the first training run. The runtime cache is keyed by an epoch bucket; on a cache miss every host deterministically computes indices in memory while only host 0 atomically persists the shared cache, so no barrier is required.
2. Motivation and scope
Megatron-LM is widely used for large-scale pretraining, and users often already own
.bin/.idxdata assets. Without a direct reader, moving to MaxText requires data conversion or accepting a different sample order, which confounds convergence, throughput, and numerical comparisons.This design covers Megatron text indexed datasets only. Input data must contain EOD tokens written during preprocessing with
--append-eod; runtime code does not insert EOD again. ArrayRecord, TFRecord, Parquet, HF, TFDS, and other existing training paths remain unchanged.3. User-facing formats and configuration
3.1 Select a format
The implementation continues to use
dataset_type=grainand addsgrain_file_type=mmapandgrain_file_type=mmap_npy.mmapreads.bin/.idxand uses EOD-aware Grain transforms; it is suitable for simple training or exploration but does not promise complete MegatronGPTDatasetsample-order parity.mmap_npyreads the same data format and loads or builds three.npyindices to provide Megatron sample-order compatibility.3.2 Configure mmap/mmap_npy
The table below lists the configuration needed to use mmap/mmap_npy.
grain_file_typesrc/maxtext/configs/base.ymlsrc/maxtext/configs/types.py::GrainDatasetmmap: direct.bin/.idxreader.mmap_npy: Megatron-style indexed reader.mmap_npyis the compatibility path for Megatron GPT sample order;mmapis the simpler path.grain_train_filesgrain_eval_filessrc/maxtext/configs/base.ymlsrc/maxtext/configs/types.py::GrainDatasetmmap: a prefix/directory, or weighted entries separated by;.mmap_npy:npy_dir|bin_prefix_or_directory; weighted entries use,weightand;.Path strings and dimensionless weights.
npy_dircontains only index files; the.bin/.idxprefix or directory contains tokens. Mixture weights must be non-negative and have a positive total.max_target_lengthsrc/maxtext/configs/base.ymlsrc/maxtext/configs/types.py::MaxTextConfigL, in tokens.mmap_npyreadsL+1raw tokens and emits length-Lmodel fields. It must match the intended Megatron sequence length.mmap_eod_idsrc/maxtext/configs/base.ymlsrc/maxtext/configs/types.py::MMapDataset0.--append-eod. It replaced the earlierpad_idname because EOD and padding differ semantically;bos_idis not used by this path.mmap_split_sentencessrc/maxtext/configs/base.ymlsrc/maxtext/configs/types.py::MMapDatasetfalse.trueonly when the indexed dataset was produced with Megatron--split-sentences; otherwise the reader reports a layout mismatch.mmap_npy_splitsrc/maxtext/configs/base.ymlsrc/maxtext/configs/types.py::MMapDatasetComma-separated ratios such as
99,1or98,1,1enable splitting.mmap_npy. Training uses split 0; evaluation uses split 1 when a split is configured. Boundaries use Megatron-compatible rounding and document indices retain global document IDs.blend_cache_dirsrc/maxtext/configs/base.ymlsrc/maxtext/configs/types.py::MMapDatasetOtherwise a writable directory path.
mmap_npyblending. It stores runtime-generated global blend dispatch indices; cache-write failure falls back to in-memory indices.blend_index_dirsrc/maxtext/configs/base.ymlsrc/maxtext/configs/types.py::MMapDatasetOtherwise a directory containing
dataset_index.npyanddataset_sample_index.npy, or one uniquely identifiable equivalent pair.mmap_npyblending and takes precedence overblend_cache_dir. The pair must match dataset order and requested size; invalid files fall back to a rebuilt dispatch.reset_attention_masksrc/maxtext/configs/base.ymlsrc/maxtext/configs/types.py::MMapDatasettrue.truestarts a new attention segment after EOD and restarts the next position at 0;falsekeeps one continuous segment and positions. The standard Grain pretraining path does not read this field.eod_mask_losssrc/maxtext/configs/base.ymlsrc/maxtext/configs/types.py::MMapDatasetfalse.truemasks positions whose input token is EOD;falsekeeps them in loss. It is independent of attention reset. The simplemmappath has a ShiftData limitation that still masks EOD-related loss when this field isfalse; usemmap_npyfor strict Megatron loss semantics.packing_max_segments_per_samplesrc/maxtext/configs/base.ymlsrc/maxtext/configs/types.py::MMapDataset25.<=0disables short-segment merging.max_target_length // packing_max_segments_per_sampletokens. EOD-derived boundaries at or below the threshold are merged; this is independent of Grain packing itself. Set<=0to retain every EOD boundary.3.3 Prepare and run a dataset
The following is a single-dataset example that strictly preserves Megatron GPT next-token, EOD, and index-order semantics.
The offline tool
tools/data_processing/mmap_index_builder.pyis a CLI wrapper around the core library. It is not a required training prerequisite: a runtime cache miss builds the same indices automatically. Offline construction is useful when users want to inspect artifacts before training, publish indices to a read-only directory, or avoid index computation during first-job startup.The following single-dataset command corresponds to the YAML above.
Multi-dataset offline construction uses the
blendsubcommand.python3 tools/data_processing/mmap_index_builder.py blend \ --datasets '/data/wiki_text_document,0.7;/data/code_text_document,0.3' \ --output-dir /cache/wiki_code_blend \ --seq-length 2048 \ --total-samples 1024000 \ --seed 1234 \ --margin 0.5 \ --add-extra-token 1Offline blend artifacts require both child-index directories and the root dispatch directory; add the following snippet to the same experiment YAML.
4. Compatibility contract
4.1 model batches
For ordinary pretraining, optional features can add
dataset_id, image, or SFT/DPO fields, but both standard Grain andmmap_npydeliver the following six core fields to the model.The following example uses
L=4,PAD=0,EOD=99,reset_attention_mask=True, andeod_mask_loss=False. The rawL+1tokens are[10, 11, 99, 20, 21], where99is the EOD boundary between two documents.Standard Grain without packing does not treat EOD as a document boundary: valid tokens are in segment 1, padding is in segment 0, and positions increase continuously.
ShiftDataleft-shifts targets and pads the tail and a zero loss mask at the last position.Packing is a separate feature: it places multiple short, independent samples into one fixed-length sequence to reduce padding. Each original sample restarts positions at 0, and segment boundaries are defined by the Grain packer's sample-concatenation points rather than automatically by EOD.
mmap_npyforms next-token pairs directly from realL+1tokens:inputs=tokens[:-1]andtargets=tokens[1:],whereasmmap_npyretains a real final target and computes its loss. With reset enabled, EOD still belongs to the preceding document; the following20starts a new attention segment and position resets to 0. Witheod_mask_loss=False, every target contributes to supervision.Consequently, standard Grain has a padded final target, The ordinary standard-Grain pretraining path does not read
reset_attention_maskoreod_mask_loss, and it neither resets positions nor increments input segments at EOD.Both simple
mmapandmmap_npyuse EOD-aware attention/position transforms; their main difference is next-token sample construction.mmapstill usesShiftDataafterwards, so witheod_mask_loss=Falseit masks EOD-related loss becausemmap_eod_idalso acts as an ignored ID; usemmap_npywhen strict Megatron loss semantics are required.4.2 Megatron parity boundary
mmap_npypromises MegatronGPTDatasetdata-consumption semantics: with the same data, configuration, and random seed, each position in the global sample stream reads the same raw tokens and constructs semantically corresponding model fields.This promise requires
grain_file_type=mmap_npyand matching.bin/.idx, EOD ID, sequence length, shuffle seed, split/blend configuration, and requested sample count. Conventional Megatron GPT EOD semantics additionally requirereset_attention_mask=true,eod_mask_loss=false, andpacking_max_segments_per_sample=0.5. Architecture and runtime behavior
5.1 Dataloader placement
The diagram shows where the new logic belongs: offline preprocessing ends at
.bin/.idx;mmap_npygenerates or loads Megatron indices before the Grain runtime, then joins the existing Grain transforms, batching, and multi-host loader. The optional offline CLI only produces indices; training can still rebuild them when the cache is absent.5.2 Megatron-parity implementation map
.bin/.idxformat and relies on the EOD token written during preprocessing.MMapIndexedDatasetin_mmap_datasource.pyparses the index and performs token reads. Runtime does not insert EOD.L+1sample construction, and sample shuffle.build_indices()in_mmap_index_utils.pyimplements these three steps and produces the document, sample, and shuffle indices.MegatronNpyDataSourceconsumes the resulting arrays for random access.mmap_npy_splitto select the documents for a split and writes their global IDs intodocument_index.npy.MegatronNpyDataSourceuses those IDs to read the corresponding documents from the original.bin/.idxdataset.build_blending_indices()andMegatronBlendedDataSourcein_megatron_blending.py; offline/cache dispatch files are an optional MaxText delivery mechanism.GenerateDocSegmentIdsandMegatronSplitInputsTargetsininput_pipeline_utils.pyconstruct the six model fields._mmap_pretrain_pipeline()andmake_grain_train_iterator()attach the source to Grain;MultiHostDataLoadIteratortransfers local batches to the JAX global mesh. This runtime is MaxText-specific rather than a Megatron dataloader replica.6. Validation, robustness, and tests
6.1 Unit tests
Unit tests cover reader format and corrupted-input checks, offline and runtime indices, data sources, EOD transforms, and alignment with real Megatron helpers/GPTDataset. The table below describes the primary purpose of each test file.
tests/unit/mmap_index_builder_test.pyconvertCLI, and offline blend-index output.tests/unit/mmap_data_processing_test.py.idx/.binparsing, reader/source boundaries and failures, sentence-split layout, simplemmapGrain pipeline integration, EOD semantics, and the no-runtime-EOD-insertion rule.tests/unit/megatron_npy_datasource_test.pymmap_npypath resolution, index discovery, random access and fixed-length output, pickle safety, runtime index-cache lifecycle, and pipeline integration.tests/unit/megatron_split_dataset_id_test.pytests/unit/packing_max_segments_test.pypacking_max_segments_per_sample, including disabled and invalid settings.tests/unit/megatron_dataloader_alignment_test.pyGPTDataset.6.2 End-to-end checkpoint-resume smoke test
resume_file_type_test.shis a single-process TPU-VMmmap_npycheckpoint-resume smoke test. It validates the smaller but critical end-to-end path that a saved Grain iterator state can be restored by a subsequent MaxText run in the same training directory.The script requires a TPU-VM checkout on the target branch and caller-provided
GRAIN_TRAIN_FILES,MMAP_EOD_ID,TOKENIZER_PATH, andVOCAB_SIZE. It fixesgrain_file_type=mmap_npy, disables the elastic iterator, and runs two trainings with the samerun_nameand output directory: Run A trains forSTEPS_Aand saves a final checkpoint, after which the script confirms that a single-process Grain iterator state exists. Run B raises the total step count toSTEPS_B, checks the log for restoration from that run directory, and continues training. The script rejects a pre-existing checkpoint directory so that it cannot accidentally consume stale state.Checklist