Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
0542a77
feat(model): enable Nemotron Omni audio and video
cuichenx Jul 22, 2026
94cfad7
refactor(model): move Nemotron Omni packing to collator
cuichenx Jul 27, 2026
183cf51
fix(model): make canonical Nemotron Omni path the default
cuichenx Jul 28, 2026
42f6d9e
fix(model): deprecate Nemotron Omni LLaVA model
cuichenx Jul 28, 2026
071e98d
test(model): preserve Nemotron Omni inference expansion
cuichenx Jul 28, 2026
a5502ad
docs(model): explain packed padding mask
cuichenx Jul 28, 2026
a2b03d2
feat(model): allow omitting Nemotron Omni sound encoder
cuichenx Jul 28, 2026
d64f5e7
refactor(model): remove Nemotron Omni has_sound flag
cuichenx Jul 28, 2026
26515b4
fix(model): unify Nemotron Omni sound capability
cuichenx Jul 28, 2026
8f3942b
fix(model): defer Nemotron Omni padding mask routing
cuichenx Jul 29, 2026
91c02ea
docs(model): clarify Nemotron Omni padding routing
cuichenx Jul 29, 2026
a3c8d07
test(model): repair Nemotron Omni packed image smoke
cuichenx Jul 29, 2026
7888d7a
docs(model): add Nemotron Omni verification card
cuichenx Jul 29, 2026
d3ceb67
Merge branch 'main' into agent/nemotron-omni-audio-video
cuichenx Jul 30, 2026
4e1618f
fix(examples): support large HF parity checks
cuichenx Jul 31, 2026
d10a1d8
fix(conversion): preserve Nemotron Omni HF buffers
cuichenx Jul 31, 2026
0f7bb5e
feat(recipes): add Nemotron Omni long-context SFT
cuichenx Jul 31, 2026
6adfd7b
fix(examples): compare composite text backbones
cuichenx Jul 31, 2026
ffb0905
fix(examples): pin Nemotron Omni inference revision
cuichenx Jul 31, 2026
558bdfd
merge(main): refresh Nemotron Omni verification
cuichenx Jul 31, 2026
960e416
fix(recipes): trust Nemotron Omni processor code
cuichenx Jul 31, 2026
c9853c0
fix(conversion): initialize CPU models with Gloo
cuichenx Jul 31, 2026
23cc39f
fix(data): ignore padding in Omni loss masks
cuichenx Jul 31, 2026
fbbafc7
fix(nemotron-omni): complete model verification
cuichenx Jul 31, 2026
5aa4034
docs(model): verify Nemotron Omni workflows
cuichenx Jul 31, 2026
0607c1f
fix(recipe): declare long-context Omni environment
cuichenx Aug 2, 2026
dc2eb3d
fix(conversion): release temporary import process groups
cuichenx Aug 3, 2026
ef8f8bc
fix(examples): avoid Hugging Face tensor parallel loading
cuichenx Aug 4, 2026
8784644
fix(conversion): scope CPU import distributed state
cuichenx Aug 4, 2026
64a2052
fix(data): clear stale packed padding masks
cuichenx Aug 4, 2026
e33694c
Merge branch 'main' into agent/nemotron-omni-audio-video
cuichenx Aug 5, 2026
558e6b0
fix(distributed): avoid temporary rendezvous port collisions
cuichenx Aug 5, 2026
a554f71
revert: remove temporary rendezvous hardening
cuichenx Aug 5, 2026
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
66 changes: 48 additions & 18 deletions examples/conversion/compare_hf_and_megatron/compare.py
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ def process_inputs(tokenizer, processor, image_path: Optional[str], prompt: str,


def _load_hf_model(args, is_vl_model: bool):
"""Load HuggingFace model on rank 0.
"""Load an unsharded HuggingFace model on rank 0.

Args:
args: Command line arguments.
Expand All @@ -498,17 +498,15 @@ def _load_hf_model(args, is_vl_model: bool):

print_rank_0("Loading HuggingFace model...")
model_class = get_model_class(args.model_class, is_vl_model)
hf_model = model_class.from_pretrained(
args.hf_model_path,
torch_dtype=torch.bfloat16,
device_map="cuda",
trust_remote_code=is_safe_repo(
load_kwargs = {
"torch_dtype": torch.bfloat16,
"trust_remote_code": is_safe_repo(
trust_remote_code=args.trust_remote_code,
hf_path=args.hf_model_path,
),
**_hf_revision_kwargs(args.hf_revision),
)
hf_model = hf_model.eval()
}
hf_model = model_class.from_pretrained(args.hf_model_path, **load_kwargs).to(args.hf_device).eval()
print_rank_0(f"Loaded with {model_class.__name__}")

# Register debug hooks if enabled
Expand Down Expand Up @@ -553,9 +551,11 @@ def _export_and_load_roundtrip_hf_model(args, is_vl_model: bool, megatron_model,
if _is_rank_0():
print_rank_0("Loading exported HF model for comparison...")
model_class = get_model_class(args.model_class, is_vl_model)
hf_model = model_class.from_pretrained(
save_path, torch_dtype=torch.bfloat16, device_map="cuda", trust_remote_code=True
).eval()
hf_model = (
model_class.from_pretrained(save_path, torch_dtype=torch.bfloat16, trust_remote_code=True)
.to(args.hf_device)
.eval()
)
if args.enable_debug_hooks:
print_rank_0("Registering debug hooks for exported HF model...")
debugger.register_hooks(hf_model, file_prefix="hf_debug_")
Expand All @@ -564,6 +564,15 @@ def _export_and_load_roundtrip_hf_model(args, is_vl_model: bool, megatron_model,
return None


def _get_hf_forward_model(hf_model, pixel_values):
"""Select a composite model's language backbone for text-only comparison."""
language_model = getattr(hf_model, "language_model", None)
if pixel_values is None and isinstance(language_model, torch.nn.Module):
print_rank_0("Using the HuggingFace language backbone for a text-only comparison.")
return language_model
return hf_model


def _run_hf_inference(hf_model, input_ids, pixel_values, image_grid_thw, tokenizer, *, token_type_ids=None):
"""Run HuggingFace model inference and return results.

Expand All @@ -583,19 +592,29 @@ def _run_hf_inference(hf_model, input_ids, pixel_values, image_grid_thw, tokeniz
if not _is_rank_0() or hf_model is None:
return None, None, None, None, None

hf_forward_model = _get_hf_forward_model(hf_model, pixel_values)

input_device = input_ids.device
try:
hf_device = next(hf_forward_model.parameters()).device
except (AttributeError, StopIteration, TypeError):
hf_device = input_device
if not isinstance(hf_device, (torch.device, str, int)):
hf_device = input_device

with torch.no_grad():
hf_inputs = {
"input_ids": input_ids,
"attention_mask": torch.ones_like(input_ids, dtype=torch.bool),
"input_ids": input_ids.to(hf_device),
"attention_mask": torch.ones_like(input_ids, dtype=torch.bool).to(hf_device),
}
if pixel_values is not None:
hf_inputs["pixel_values"] = pixel_values
hf_inputs["pixel_values"] = pixel_values.to(hf_device)
if image_grid_thw is not None:
hf_inputs["image_grid_thw"] = image_grid_thw
hf_inputs["image_grid_thw"] = image_grid_thw.to(hf_device)
if token_type_ids is not None:
hf_inputs["token_type_ids"] = token_type_ids
hf_inputs["token_type_ids"] = token_type_ids.to(hf_device)

hf_output = hf_model(**hf_inputs)
hf_output = hf_forward_model(**hf_inputs)

# Debug: Check output type
print_rank_0(f"HF output type: {type(hf_output)}")
Expand All @@ -621,7 +640,13 @@ def _run_hf_inference(hf_model, input_ids, pixel_values, image_grid_thw, tokeniz
print_rank_0(f"HF next token: {hf_next_token.item()} ('{tokenizer.decode([hf_next_token.item()])}')")
print_rank_0(f"HF Top 5: {hf_top5_info}")

return hf_logits, hf_next_token, hf_logits_stats, hf_top5_info, logits_shape
return (
hf_logits.to(input_device),
hf_next_token.to(input_device),
hf_logits_stats,
hf_top5_info,
logits_shape,
)


def _load_hf_reference_logits(path, input_ids, tokenizer):
Expand Down Expand Up @@ -1026,6 +1051,11 @@ def build_parser() -> argparse.ArgumentParser:
parser.add_argument("--pp", type=int, default=1, help="Pipeline parallelism size")
parser.add_argument("--ep", type=int, default=1, help="Expert parallelism size")
parser.add_argument("--etp", type=int, default=1, help="Expert tensor parallelism size")
parser.add_argument(
"--hf-device",
default="cuda",
help="CUDA device used by the rank-0 Hugging Face reference model (for example, cuda:2).",
)
parser.add_argument(
"--model_class",
type=str,
Expand Down
Loading
Loading