nemo_automodel.components.datasets.llm.packed_sequence
nemo_automodel.components.datasets.llm.packed_sequence
Module Contents
Functions
Data
API
Converts a pack into tensors. Pack comes in as a dict of lists and is converted to tensors.
Return dataset[i] for the row’s __index__ (a datasets.Dataset.map worker).
The row is produced by the dataset’s own __getitem__, so any per-index
behavior (e.g. a sample-skipping fallback) is preserved exactly rather than
re-implemented.
Parameters:
A single mapped row holding the integer "__index__".
The map-style dataset to index.
Returns: dict
The tokenized sample dict dataset[index_row["__index__"]].
Pads a pack to packed_sequence_size.
seq_lens contains original lengths. seq_lens_padded applies CP padding (if cp_size > 1) and pack-level padding.
If max packs is set, stop packing when we reach that number.
Splits the current pack at the boundary, processes it, adds it to packs.
…and returns the start of the next pack.
TODO(@akoumparouli): refactor.
converts to tensors, pads a pack and returns it.
Build a [B, 1, T, T] additive block-causal mask directly on device.
In-document causal attention is allowed (0); cross-document and padding
positions are finfo(dtype).min. seq_lens is the [B, max_docs]
0-padded per-document length tensor; each row’s non-zero entries sum to
seq_length (trailing pad folded into the final document).
Raises ValueError if seq_lens is not 2D or any row does not sum to
seq_length — a malformed row would otherwise silently misbucket the
boundary cumsum (e.g. isolating the final token into a phantom document)
and train the draft on wrong-context supervision with no error. This mirrors
the fail-loud sum check the FlashAttention varlen path already performs in
_seq_lens_to_cu_seqlens.
Creates causal mask block for specified lengths.
In particular, given a batch tensor of seq lens defining the lengths of samples in each pack, Construct a 2D block causal mask for each pack in the batch. For example, if a single sample’s seq_lens is [3, 2, 1], the mask would be:: mask = [ [1, 0, 0, 0, 0, 0], [1, 1, 0, 0, 0, 0], [1, 1, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0], [0, 0, 0, 1, 1, 0], [0, 0, 0, 0, 0, 1], ]
Parameters:
Sequence lengths of samples in each pack in the batch, shape (batch_size, n), where n is the max number of sequences in a pack and can vary across packs.
Returns: torch.Tensor
Block causal mask of shape (batch_size, packed_sequence_size, packed_sequence_size).
Pack the dataset to defined length.
In particulat, it will iterate through the dataset. Use a buffer to hold samples until packed_sequence_size, then append the buffer to packs as a single “packed” sample. Continue until max_packs or end of dataset.
Parameters:
Actual dataset (can be ‘train’, ‘val’ or ‘test’)
Whether the dataset is ‘train’, ‘val’ or ‘test’
Number of tokens in a pack
Maximum number of packs. Default: None
If True, drop samples that are longer than packed_sequence_size.
Context parallel size. When > 1, each sequence will be padded to be divisible by 2*cp_size for context parallel processing. Default: 1 (no CP).
Create a 2D block causal document mask for a batch of packed sequences.
Parameters:
Sequence lengths of samples in each pack in the batch, shape (batch_size, n), where n is the max number of sequences in a pack and can vary across packs.
Returns:
BlockMask or Tensor if torch version < 2.5.0.
Pre-tokenize a map-style dataset in parallel before packing.
Iterating a lazily-tokenizing dataset (e.g. ChatDataset) tokenizes each
sample serially in a single process, which dominates the cost of preparing a
packed dataset. This helper front-loads that work by calling the dataset’s
own __getitem__ over range(len(dataset)) with num_proc worker
processes and returns a HuggingFace Dataset of the tokenized rows in
original order. The result can be handed to :func:pack_dataset (or
neat_pack_dataset) unchanged.
Caveats (the caller in build_dataloader gates on the first three):
datasetmust be indexable (__len__+__getitem__) and its__getitem__must be a deterministic pure function of the index. Rows are produced innum_procseparate worker processes, so a__getitem__that consults process-global state (RNG-driven augmentation, counters) would diverge from serial iteration.- Does not honor
max_packs: the whole dataset is tokenized up front, whereas serial packing stops early oncemax_packsis reached. datasetis pickled into every worker viafn_kwargs. This is cheap for the Arrow-backed datasets used here (self.datasetpickles as an mmap reference), but an in-memory (list-backed) dataset is copied once per worker, so sizenum_procfor the node’s memory as well as its CPUs.- Runs independently on each data-parallel rank, like the serial packing
pass it replaces;
dp_local_ranks * num_procshould not oversubscribe the node’s CPUs. Caching is disabled so every run re-tokenizes fresh.
Parameters:
A map-style dataset exposing __len__ and __getitem__
whose items are tokenized dicts (input_ids, labels and,
optionally, loss_mask), each a list[int].
Number of worker processes used for tokenization. Must be > 1 for this helper to be worthwhile; the caller gates on that.
Returns: Dataset
A HuggingFace Dataset of the tokenized rows in original order.