Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 44 additions & 1 deletion skills/create-model-verification-card/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: create-model-verification-card
description: Create or update concise, agent-readable Megatron Bridge model verification cards. Use when adding a model support card, auditing cross-model convergence comparability or verification coverage, recording conversion, deterministic inference, training, checkpoint resume, post-SFT export, or performance results, or preparing a model-support PR. Enforce the required core inventory, convergence-versus-performance contracts, optional canonical performance item, public Slurm launcher commands, training metrics, important-feature allowlist, and a strict privacy boundary that excludes private runtime wiring, internal paths, credentials, and job metadata.
description: Create or update concise, agent-readable Megatron Bridge model verification cards. Use when adding a model support card, auditing cross-model convergence comparability or verification coverage, recording conversion, deterministic inference, training, checkpoint resume, post-SFT export, or performance results, or preparing a model-support PR. Enforce publicly reachable clean source provenance, upstream ownership of discovered fixes, the required core inventory, convergence-versus-performance contracts, public Slurm launcher commands, training metrics, important-feature allowlist, and a strict privacy boundary.
---

# Create Model Verification Card
Expand Down Expand Up @@ -45,6 +45,42 @@ the leaf's optional `bridge_commit` field. Omit the field when it would repeat
the top-level value, and never use a commit field to disguise uncommitted
runtime changes. Items that are not verified must not carry a commit override.

#### Enforce source integrity and upstream ownership

Treat source provenance as a verification gate, not a reporting detail. Every
verification run must use either an upstream commit or the exact pushed head of
an open upstream PR. Before and after the run, require a clean tracked source
tree and record the exact Bridge commit plus every relevant submodule and
dependency revision in the private durable run record. Confirm that each
recorded commit is reachable from its stated public remote or PR; a copied
source directory without public Git provenance is insufficient.

Do not count a run that depends on an uncommitted edit, unpublished commit,
source overlay, monkeypatch, bind-mounted replacement file, or locally rebuilt
dependency as model verification. Do not reclassify such a run as a
feasibility experiment. It is an invalid verification attempt and leaves the
item `unverified`.

When verification exposes a product defect:

1. Stop the affected verification item and record the unchanged failing
command, exact public source revisions, failure, and owning upstream
repository in the private durable record.
2. Implement the fix through the owning repository's normal branch, test,
review, and PR workflow. Never keep a required fix only in the verification
checkout.
3. Label runs of a pushed fix as candidate-PR validation and link the upstream
PR and exact head commit. A local patched run cannot satisfy any card
checkbox, metric, or expected result.
4. Rerun the original failing workload from the exact clean, pushed PR head.
Only that rerun may become verification evidence; after further edits, rerun
from the new pushed head.

Do not hide a newly discovered blocker by changing the command, container,
model, dataset, scale, or expected result. If another layer is responsible,
file or link its upstream issue or PR and keep the card item `unverified` until
the original workload passes on publicly reviewable source.

### 2. Create the core inventory and add performance when available

Include these twelve required items, even when their status is `unsupported` or
Expand Down Expand Up @@ -760,6 +796,13 @@ an item verified merely to make validation pass.
- Pin a public immutable HF revision, minimum Transformers version, public base
container, and exact Bridge verification commit; use an item override only
for a verified workload run from a different clean commit.
- Require every verification commit and dependency revision to be publicly
reachable from upstream or an open upstream PR. Reject local patches,
unpublished commits, source overlays, monkeypatches, replacement mounts, and
copied trees without public Git provenance as verification evidence.
- For every defect found during verification, preserve the unchanged failure,
link the owning upstream issue or PR, and rerun the original workload from
the exact clean pushed fix commit before changing the item to `verified`.
- Use the public model name in commands.
- Include commands and concrete expected results for verified items.
- For manual forward pass, require a next-token match and cosine similarity of
Expand Down
44 changes: 24 additions & 20 deletions src/megatron/bridge/models/conversion/auto_bridge.py
Original file line number Diff line number Diff line change
Expand Up @@ -1450,27 +1450,31 @@ def import_ckpt(
# Load the HuggingFace model
bridge = cls.from_hf_pretrained(hf_model_id, **kwargs)

# Convert to Megatron model
megatron_model = bridge.to_megatron_model(wrap_with_ddp=False, use_cpu_initialization=True)

# Save as Megatron checkpoint
hf_tokenizer_kwargs = {}
if hasattr(bridge._model_bridge, "get_hf_tokenizer_kwargs"):
hf_tokenizer_kwargs = bridge._model_bridge.get_hf_tokenizer_kwargs()
if hf_tokenizer_kwargs is None:
from megatron.bridge.training.model_load_save import temporary_distributed_context

model_context = nullcontext() if dist.is_initialized() else temporary_distributed_context(backend="gloo")
with model_context:
# Convert to Megatron model
megatron_model = bridge.to_megatron_model(wrap_with_ddp=False, use_cpu_initialization=True)

# Save as Megatron checkpoint
hf_tokenizer_kwargs = {}
if kwargs.get("revision") is not None:
hf_tokenizer_kwargs.setdefault("revision", kwargs["revision"])
# Forward trust_remote_code to the tokenizer (needed for repos with custom code)
if kwargs.get("trust_remote_code"):
hf_tokenizer_kwargs.setdefault("trust_remote_code", True)
bridge.save_megatron_model(
megatron_model,
megatron_path,
hf_tokenizer_path=hf_model_id,
hf_tokenizer_kwargs=hf_tokenizer_kwargs,
low_memory_save=low_memory_save,
)
if hasattr(bridge._model_bridge, "get_hf_tokenizer_kwargs"):
hf_tokenizer_kwargs = bridge._model_bridge.get_hf_tokenizer_kwargs()
if hf_tokenizer_kwargs is None:
hf_tokenizer_kwargs = {}
if kwargs.get("revision") is not None:
hf_tokenizer_kwargs.setdefault("revision", kwargs["revision"])
# Forward trust_remote_code to the tokenizer (needed for repos with custom code)
if kwargs.get("trust_remote_code"):
hf_tokenizer_kwargs.setdefault("trust_remote_code", True)
bridge.save_megatron_model(
megatron_model,
megatron_path,
hf_tokenizer_path=hf_model_id,
hf_tokenizer_kwargs=hf_tokenizer_kwargs,
low_memory_save=low_memory_save,
)

def export_ckpt(
self,
Expand Down
70 changes: 56 additions & 14 deletions tests/unit_tests/models/test_auto_bridge.py
Original file line number Diff line number Diff line change
Expand Up @@ -1793,9 +1793,18 @@ def test_import_ckpt_basic(self, mock_from_hf_pretrained, mock_to_megatron_model
mock_bridge.save_megatron_model = Mock()

# Test import_ckpt
AutoBridge.import_ckpt("meta-llama/Meta-Llama-3-8B", "./megatron_checkpoint")
with (
patch("megatron.bridge.models.conversion.auto_bridge.dist.is_initialized", return_value=False),
patch(
"megatron.bridge.training.model_load_save.temporary_distributed_context"
) as mock_distributed_context,
):
AutoBridge.import_ckpt("meta-llama/Meta-Llama-3-8B", "./megatron_checkpoint")

# Assertions
mock_distributed_context.assert_called_once_with(backend="gloo")
mock_distributed_context.return_value.__enter__.assert_called_once_with()
mock_distributed_context.return_value.__exit__.assert_called_once()
mock_from_hf_pretrained.assert_called_once_with("meta-llama/Meta-Llama-3-8B")
mock_bridge.to_megatron_model.assert_called_once_with(wrap_with_ddp=False, use_cpu_initialization=True)
mock_bridge.save_megatron_model.assert_called_once_with(
Expand All @@ -1821,13 +1830,17 @@ def test_import_ckpt_with_kwargs(self, mock_from_hf_pretrained, mock_to_megatron
mock_bridge._model_bridge.get_hf_tokenizer_kwargs.return_value = {}

# Test import_ckpt with kwargs
AutoBridge.import_ckpt(
"./local_model",
"./megatron_checkpoint",
torch_dtype=torch.float16,
device_map="auto",
revision="0123456789abcdef", # pragma: allowlist secret
)
with (
patch("megatron.bridge.models.conversion.auto_bridge.dist.is_initialized", return_value=False),
patch("megatron.bridge.training.model_load_save.temporary_distributed_context"),
):
AutoBridge.import_ckpt(
"./local_model",
"./megatron_checkpoint",
torch_dtype=torch.float16,
device_map="auto",
revision="0123456789abcdef", # pragma: allowlist secret
)

# Assertions
mock_from_hf_pretrained.assert_called_once_with(
Expand Down Expand Up @@ -1859,12 +1872,16 @@ def test_import_ckpt_with_low_memory_save(
mock_bridge.save_megatron_model = Mock()
mock_bridge._model_bridge.get_hf_tokenizer_kwargs.return_value = {}

AutoBridge.import_ckpt(
"meta-llama/Meta-Llama-3-8B",
"./megatron_checkpoint",
low_memory_save=True,
torch_dtype=torch.bfloat16,
)
with (
patch("megatron.bridge.models.conversion.auto_bridge.dist.is_initialized", return_value=False),
patch("megatron.bridge.training.model_load_save.temporary_distributed_context"),
):
AutoBridge.import_ckpt(
"meta-llama/Meta-Llama-3-8B",
"./megatron_checkpoint",
low_memory_save=True,
torch_dtype=torch.bfloat16,
)

mock_from_hf_pretrained.assert_called_once_with(
"meta-llama/Meta-Llama-3-8B",
Expand All @@ -1878,6 +1895,31 @@ def test_import_ckpt_with_low_memory_save(
low_memory_save=True,
)

@patch.object(AutoBridge, "save_megatron_model")
@patch.object(AutoBridge, "to_megatron_model")
@patch.object(AutoBridge, "from_hf_pretrained")
def test_import_ckpt_reuses_existing_distributed_context(
self, mock_from_hf_pretrained, mock_to_megatron_model, mock_save_megatron_model
):
"""Test import_ckpt does not replace a caller-managed process group."""
mock_bridge = Mock(spec=AutoBridge)
mock_from_hf_pretrained.return_value = mock_bridge
mock_bridge.to_megatron_model.return_value = [Mock()]
mock_bridge.save_megatron_model = Mock()
mock_bridge._model_bridge.get_hf_tokenizer_kwargs.return_value = {}

with (
patch("megatron.bridge.models.conversion.auto_bridge.dist.is_initialized", return_value=True),
patch(
"megatron.bridge.training.model_load_save.temporary_distributed_context"
) as mock_distributed_context,
):
AutoBridge.import_ckpt("meta-llama/Meta-Llama-3-8B", "./megatron_checkpoint")

mock_distributed_context.assert_not_called()
mock_bridge.to_megatron_model.assert_called_once_with(wrap_with_ddp=False, use_cpu_initialization=True)
mock_bridge.save_megatron_model.assert_called_once()

def test_export_ckpt_basic(self):
"""Test basic export_ckpt functionality."""
# Setup mocks
Expand Down
Loading