
Sequence Packing
OfficialFreeOptimize sequence packing for LLMs and VLMs in Megatron-Bridge.
Free · Opens the source repo
What Sequence Packing does
The Sequence Packing skill is designed to enhance the efficiency of training large language models (LLMs) and vision-language models (VLMs) using Megatron-Bridge. It allows users to validate and utilize packed sequences, facilitating both offline packed supervised fine-tuning (SFT) for LLMs and in-batch packing for VLMs. By applying the correct constraints for context parallelism (CP), it ensures that models can be trained with optimal performance while managing memory and computational resources effectively.
This skill provides a comprehensive configuration setup for offline packed SFT, enabling users to specify sequence lengths and batch sizes that align with their model architecture. For instance, when using offline packing, users can set parameters such as micro_batch_size and seq_length to optimize training. The skill also includes provisions for context parallel size, allowing for more complex model configurations that leverage multiple GPUs efficiently.
In addition to offline packed SFT, the skill supports in-batch packing for VLM fine-tuning. This feature is crucial for scenarios where quick iterations and adjustments are necessary, as it allows for dynamic packing of sequences during training. The skill includes detailed configuration examples, making it easier for developers to implement and adapt to their specific needs.
Overall, the Sequence Packing skill is aimed at developers and researchers working with large-scale models who need to fine-tune their training processes for better performance and resource utilization. It addresses common challenges in sequence packing, providing clear guidelines and configurations to streamline the training workflow.
When to use it
Use this skill when you need to optimize training for large-scale models using Megatron-Bridge, especially when managing sequence lengths and batch sizes.
When not to use it
This skill may not be suitable for smaller models or simpler training setups where sequence packing is not a concern.
What you can build with it
Fine-tuning LLMs with Offline Packing
Utilize the skill to set up offline packed SFT for LLMs, optimizing training efficiency and resource management.
Dynamic In-batch Packing for VLMs
Implement in-batch packing for VLM fine-tuning to allow for flexible and efficient training iterations.
Context Parallel Training
Configure your model for context parallel training, ensuring that sequence lengths align with the necessary divisibility constraints.
How to install Sequence Packing
View source1. Install with the skills CLI
npx skills add nvidia/skills/nemo-mbridge-perf-sequence-packing --agent claude-code2. Or install it manually
Download the skill folder and drop it into ~/.claude/skills/ for all projects, or .claude/skills/ to scope it to one repo. Restart Claude Code so it picks up the new skill.
Anthropic's agentic coding CLI, and the reference implementation of Agent Skills. Drop a skill folder into ~/.claude/skills and Claude Code loads it automatically whenever a task matches the skill's description. Claude Code docs
Inside SKILL.md
Written by nvidiaSequence Packing Skill
For stable background and recommendation level, see:
- @docs/training/packed-sequences.md
- @skills/nemo-mbridge-perf-sequence-packing/card.yaml
Enablement
Offline packed SFT for LLM finetuning:
from megatron.bridge.data.datasets.packed_sequence import PackedSequenceSpecs
cfg.train.micro_batch_size = 1
cfg.dataset.seq_length = 4096
cfg.model.seq_length = 4096
cfg.dataset.dataset_kwargs = {"pad_to_max_length": True}
cfg.dataset.enable_offline_packing = True
cfg.dataset.offline_packing_specs = PackedSequenceSpecs(
packed_sequence_size=4096,
pad_seq_to_mult=1,
)
If CP is enabled:
cfg.model.context_parallel_size = 2
cfg.model.calculate_per_token_loss = True
cfg.ddp.average_in_collective = False
cfg.dataset.offline_packing_specs.pad_seq_to_mult = cfg.model.context_parallel_size * 2
# Offline packing is not finalized by ConfigContainer. If sequence_parallel is
# also enabled, align offline samples to both constraints explicitly:
# import math
# cfg.dataset.offline_packing_specs.pad_seq_to_mult = math.lcm(2 * CP, CP * TP)
# ConfigContainer computes this CP/SP LCM automatically for in-batch packing only.
If CUDA graphs are enabled for this packed path:
cfg.dataset.offline_packing_specs.pad_cu_seqlens = True
cfg.dataset.dataset_kwargs["pad_to_max_length"] = True
Note: pad_cu_seqlens = True also requires a metadata JSON file alongside
the packed dataset (asserted in src/megatron/bridge/data/datasets/sft.py).
Custom packed datasets that omit the metadata file will hit an assertion at
dataset initialization.
In-batch packing for VLM finetuning:
cfg.dataset.enable_in_batch_packing = True
cfg.train.micro_batch_size = 2
Long-context baseline:
cfg.model.seq_length = 16384
cfg.dataset.seq_length = 16384
cfg.model.context_parallel_size = 2
Code Anchors
LLM packed SFT config surface:
dataset_kwargs = {}
offline_packing_specs = None
if enable_offline_packing:
dataset_kwargs["pad_to_max_length"] = True
offline_packing_specs = PackedSequenceSpecs(packed_sequence_size=seq_length, pad_seq_to_mult=pad_seq_to_mult)
return _text_hf_dataset_config(
source=HFDatasetSourceConfig(dataset_name="squad"),
preprocessing=PromptCompletionSFTPreprocessingConfig(separator=" "),
seq_length=seq_length,
enable_offline_packing=enable_offline_packing,
offline_packing_specs=offline_packing_specs,
dataset_kwargs=dataset_kwargs,
val_proportion=0.1,
num_workers=1,
)
Bridge validation:
enable_in_batch_packing = getattr(self.dataset, "enable_in_batch_packing", False)
enable_offline_packing = getattr(self.dataset, "enable_offline_packing", False)
offline_packing_specs = getattr(self.dataset, "offline_packing_specs", None)
if enable_offline_packing and enable_in_batch_packing:
raise ValueError("enable_offline_packing and enable_in_batch_packing are mutually exclusive.")
if enable_offline_packing and offline_packing_specs is None:
raise ValueError("offline_packing_specs must be set when enable_offline_packing=True.")
...
if enable_in_batch_packing:
...
cp_multiple = 2 * cp_size if cp_size > 1 else 1
sp_multiple = cp_size * tp_size if has_sp and tp_size > 1 else 1
self.dataset.in_batch_packing_pad_to_multiple_of = math.lcm(cp_multiple, sp_multiple)
if self.model.context_parallel_size > 1:
assert self.model.seq_length % (self.model.context_parallel_size * 2) == 0, ...
if isinstance(self.dataset, FinetuningDatasetConfig):
assert self.model.calculate_per_token_loss, ...
assert not self.ddp.average_in_collective, ...
...
if enable_offline_packing and self.train.micro_batch_size > 1:
raise ValueError(...)
...
if enable_in_batch_packing and self.train.micro_batch_size == 1:
raise ValueError(...)
Collate-time in-batch runtime used by VLM providers:
def prepare_padded_or_packed_sequence_batch(
batch,
*,
sequence_length,
...
enable_in_batch_packing=False,
in_batch_packing_pad_to_multiple_of=1,
...
):
...
if enable_in_batch_packing:
pack_right_padded_sequence_batch_to_mcore_thd(
batch,
sequence_length=sequence_length,
pad_to_multiple_of=in_batch_packing_pad_to_multiple_of,
...
)
return
Packed THD runtime constraint:
if batch.get("cu_seqlens_q") is not None:
cu_seqlens = batch.get("cu_seqlens_q_padded")
if cu_seqlens is None:
cu_seqlens = batch["cu_seqlens_q"]
if cu_seqlens.dim() > 1 and cu_seqlens.size(0) != 1:
raise ValueError("Packed THD batches expect micro-batch size 1 for context-parallel slicing (THD layout)")
return cu_seqlens.squeeze()
cu_seqlens = batch["cu_seqlens"]
if cu_seqlens.dim() > 1 and cu_seqlens.size(0) != 1:
raise ValueError("Packed THD batches expect micro-batch size 1 for context-parallel slicing (THD layout)")
Pitfalls
- Offline packed SFT and VLM in-batch packing are different features with opposite micro-batch rules.
- When CP is enabled, packed sequence lengths must respect
2 * context_parallel_sizedivisibility. - For finetuning with CP,
calculate_per_token_loss=Trueandddp.average_in_collective=Falseare required. pad_cu_seqlens=Truealso requirespad_to_max_length=True.- Packing support is model-family-specific.
Qwen3-Next,GLM-4.5, andQwen3.5-VLcontain explicit opt-outs in different paths. - MTP finetuning is documented as incompatible with packed sequences.
- Synthetic padding rows, including negative indices remapped through
samples_mapping, must retain an all-zero loss mask.
Verification
Use the checked-in unit coverage:
uv run python -m pytest tests/unit_tests/training/utils/test_packed_seq_utils.py -v && \
uv run python -m pytest tests/unit_tests/training/test_config.py -k "packed_sequence or enable_in_batch_packing or offline_and_in_batch_packing_are_mutually_exclusive or context_parallel_seq_length_divisibility or context_parallel_finetuning_validations" -v && \
uv run python -m pytest tests/unit_tests/data/packing/test_in_batch.py -v && \
uv run python -m pytest tests/unit_tests/training/test_vlm_step.py -k "deferred_in_batch_packing or packed_metadata" -v && \
uv run python -m pytest tests/unit_tests/data/datasets/test_packed_parquet.py -k "negative_index_zeroes_loss_mask" -v && \
uv run python -m pytest tests/unit_tests/data/datasets/test_sft.py -k "mapped_padding_rows_do_not_contribute_to_loss" -v
Success criteria:
- all selected tests pass
- offline and in-batch configuration validation remains mutually exclusive
- packed metadata reaches the training step in MCore THD form
- mapped padding rows do not contribute to loss
Frequently asked questions about Sequence Packing
Similar skills
Heap Snapshot Analysis
Investigate V8 heap snapshots for memory issues.
VS Code Performance Workflow
Automate performance investigations in VS Code.
Memory Leak Audit
Prevent memory leaks with effective coding patterns.
CPU Profile Analysis
Analyze V8 and Chrome performance profiles for optimization.
Chat Performance Testing
Benchmark and validate chat UI performance in VS Code.
Vercel React Best Practices
Optimize your React and Next.js applications for performance.
