Skip to content

Implement continuous stream chunking for pre-tokenized C4 MLPerf dataset - #5095

Draft
snehalv2002 wants to merge 1 commit into
mainfrom
mlperf-ds-v3-stream-chunking
Draft

Implement continuous stream chunking for pre-tokenized C4 MLPerf dataset#5095
snehalv2002 wants to merge 1 commit into
mainfrom
mlperf-ds-v3-stream-chunking

Conversation

@snehalv2002

Copy link
Copy Markdown
Collaborator

Aligns the pre-tokenized C4 MLPerf input pipeline with the MLCommons DeepSeek-V3 reference specification:

  • Flatten token streams into contiguous 4096 chunks across document boundaries with 0% padding waste.
  • Set monotonic position IDs (0, 1, ..., 4095).
  • Use uniform segment IDs (1s) to allow unrestricted causal cross-document attention.
  • Ensure 100% token participation in loss calculation (eod_mask_loss=False).
  • Fix legacy format_fn issue where token 1 (quotation mark in Llama-3 vocabulary) was masked from loss.
  • Add comprehensive unit and integration tests verifying token 0 preservation, boundary handling, and end-to-end model forward/loss computation.

BUG=555814868

Description

Start with a short description of what the PR does and how this is a change from
the past.

The rest of the description includes relevant details and context, examples:

  • why is this change being made,
  • the problem being solved and any relevant context,
  • why this is a good solution,
  • some information about the specific implementation,
  • shortcomings of the solution and possible future improvements.

If the change fixes a bug or a Github issue, please include a link, e.g.,:
FIXES: b/123456
FIXES: #123456

You can also provide a comma-separated list. If you don't want to close a bug but
simply to reference it, use BUGS, e.g.:
BUGS: b/123456

Notice 1: Once all tests pass, the "pull ready" label will automatically be assigned.
This label is used for administrative purposes. Please do not add it manually.

Notice 2: For external contributions, our settings currently require an approval from a MaxText maintainer to trigger CI tests.

Tests

Please describe how you tested this change, and include any instructions and/or
commands to reproduce.

Checklist

Before submitting this PR, please make sure (put X in square brackets):

  • I have performed a self-review of my code. For an optional AI review, add the gemini-review label.
  • I have necessary comments in my code, particularly in hard-to-understand areas.
  • I have run end-to-end tests tests and provided workload links above if applicable.
  • I have made or will make corresponding changes to the doc if needed, including adding new documentation pages to the relevant Table of Contents (toctree directive) as explained in our documentation.

Aligns the pre-tokenized C4 MLPerf input pipeline with the MLCommons DeepSeek-V3 reference specification:
- Flatten token streams into contiguous 4096 chunks across document boundaries with 0% padding waste.
- Set monotonic position IDs (0, 1, ..., 4095).
- Use uniform segment IDs (1s) to allow unrestricted causal cross-document attention.
- Ensure 100% token participation in loss calculation (eod_mask_loss=False).
- Fix legacy format_fn issue where token 1 (quotation mark in Llama-3 vocabulary) was masked from loss.
- Add comprehensive unit and integration tests verifying token 0 preservation, boundary handling, and end-to-end model forward/loss computation.

BUG=555814868

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces continuous stream chunking for pre-tokenized datasets in the MLPerf input pipeline, adding functions to flatten, chunk, and format token streams with monotonic position IDs and uniform segmentations to minimize padding waste. It also includes a comprehensive set of unit tests. The feedback suggests optimizing the tensor shifting operation in format_continuous_stream_fn using tf.concat, shuffling the dataset before chunking to improve data mixing, and removing or mocking the external GCS dependency in the unit tests to prevent CI flakiness.

"""
targets_raw = tf.cast(x["targets"], tf.int32)
inputs = targets_raw
targets = _shift_left_and_pad(targets_raw, eos_id)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Using _shift_left_and_pad on a 1D tensor of fixed size is highly inefficient because it converts the tensor to a RaggedTensor and performs multiple complex operations. Since targets_raw is a 1D tensor of fixed size max_target_length, we can shift it left much more efficiently using tf.concat.

Suggested change
targets = _shift_left_and_pad(targets_raw, eos_id)
targets = tf.concat([targets_raw[1:], [eos_id]], axis=0)

Comment on lines +322 to +323
train_ds = chunk_token_stream(train_ds, feature_key="targets", sequence_length=max_target_length)
train_ds = train_ds.shuffle(shuffle_buffer_size, seed=data_shuffle_seed)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Shuffling is currently performed after chunking the token stream. Since the input stream is flattened from unshuffled documents, consecutive chunks will be highly correlated (belonging to the same or consecutive documents). Shuffling with a small buffer size of 128 after chunking does not provide sufficient global mixing. Shuffling the dataset of documents before chunking ensures that the continuous stream is constructed from randomized documents, leading to much better data mixing and model convergence.

Suggested change
train_ds = chunk_token_stream(train_ds, feature_key="targets", sequence_length=max_target_length)
train_ds = train_ds.shuffle(shuffle_buffer_size, seed=data_shuffle_seed)
train_ds = train_ds.shuffle(shuffle_buffer_size, seed=data_shuffle_seed)
train_ds = chunk_token_stream(train_ds, feature_key="targets", sequence_length=max_target_length)

Comment on lines +401 to +407
def test_real_gcs_dataset_loading(self):
"""Integration test verifying loading and stream chunking from real GCS MLPerf TFDS dataset."""
try:
builder = tfds.builder_from_directory("gs://mlperf-6-submission-us-central1/tfds-fixed-reshard/c4/en/3.0.5")
raw_ds = builder.as_dataset(split="validation[:16]")
except Exception as e:
self.skipTest(f"GCS bucket not accessible in this environment: {e}")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The unit test test_real_gcs_dataset_loading attempts to load a real dataset from a GCS bucket (gs://mlperf-6-submission-us-central1/...). Unit tests should be self-contained and not depend on external network resources or GCP credentials, as this can cause flakiness, slow execution, or failures in offline/restricted CI environments. Consider moving this integration test to a separate integration test suite, or mocking the GCS/TFDS builder calls to avoid real network requests during unit test execution.

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