Add Nemotron-H Puzzle model support - #1535
Conversation
|
Author of the competing #1536 here — since the two PRs landed the same day, I tried to settle the main technical difference ( I ported this PR's exact dt semantics (bf16-native softplus via
One observation on the 0.8832-vs-0.999998 cosine result: if both variants are compared against a common reference and one sits at 0.8832 while the other sits at 0.999998, the two variants must differ from each other by roughly cosine 0.88. On real activations we measure ≥ 0.997 at every layer — so the 0.88 figure appears to be a property of the injected fused-CUDA intermediate harness (inputs off the natural activation distribution, or a dt regime real prompts don't reach) rather than something that occurs end-to-end on the released checkpoint. That said, I think bf16-at-softplus is still the right call where it matches NVIDIA's reference semantics — it's zero-cost and strictly more faithful; it just doesn't appear to be load-bearing for output quality, so it needn't decide between the two ports. On consolidation: happy to converge rather than compete. This PR's MTP-tensor exclusion and output-projection quant policy are things #1536 should have regardless; #1536 is the smaller diff for the core remap. Whichever direction the maintainers prefer, I'll adapt mine or review/support this one. |
|
@pierre427 Thanks for running the same-process A/B, this is very helpful (i also like the coincidence of both our PRs haha). I agree it reframes One small correction after checking the current base: I’m happy to consolidate either way. I’ll leave #1535 open and wait for maintainer preference. If #1536 is preferred, I’m happy to help port the remaining pieces and tests; if #1535 is preferred, I’d appreciate your review/support. |
|
Appreciate the thoughtful reply — and yeah, funny we both landed the same port the same day. I'm happy to consolidate onto #1535 as the base. It's the more complete port — the official Two things I hit while testing that might be worth folding in:
Separately, happy to contribute the numerics probe as a reference/regression check for the softplus-dtype boundary if useful — single model load, same inputs through both modes, reporting per-layer cosine, final-logits cosine/top-1, and teacher-forced ppl. Whatever the maintainers prefer, count on my review and support to get it merged. |
Port the quant_predicate improvement from the competing PR ml-explore#1535 (sxuff): Puzzle's 131k-token output projection is unusually sensitive to low-bit affine quantization (4-bit produced repetitive/unrelated generations while the BF16 head generated correctly). Expose a quant_predicate property that excludes lm_head from quantization for nemotron_h_puzzle only; other Nemotron-H variants quantize everything as before. The mtp.* exclusion is already present in our sanitize(). Deliberately NOT porting their promote_dt change (measured a wash, see wiki experiments/puzzle-promote-dt-2026-07-13). Adds a stub-level unit test for the predicate (no model load). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Thanks Pierre, agreed on both points.
I’ll also add the MoEGate fallbacks ( |
zcbenz
left a comment
There was a problem hiding this comment.
Would mind rewriting the PR description following our new template?
https://github.com/ml-explore/mlx-lm/blob/main/.github/PULL_REQUEST_TEMPLATE/new_model.md?plain=1
It would help me verify the implementation much quicker.
Addresses #1506.
Summary
This adds native loading and inference support for checkpoints whose
model_typeisnemotron_h_puzzleby reusing the existing Nemotron-H implementation and applying Puzzle's blockwise configuration.The change:
nemotron_h_puzzleto the Nemotron-H model implementationblock_configswhen the official config omitsnum_hidden_layersmoe_intermediate_sizeandnum_experts_per_tokmodel.*checkpoint tensors to MLX'sbackbone.*hierarchynemotron_hbias, norm, router, timestep, and SSM behavior by scoping Puzzle-specific numerical semantics to Puzzle configstime_step_limit, including finite upper boundssoftplus(dt + dt_bias)while retaining FP32 state-transition and recurrence operandstime_step_minlower boundWhy timestep precision is configurable
The existing shared SSM utility promotes
dtto FP32 before softplus. NVIDIA's Puzzle implementation preserves the projected activation dtype at that operation, then promotes the recurrence-sensitive state-space operands.With identical fused-CUDA first-layer intermediates, promoting
dtbefore softplus produced an SSM cosine similarity of 0.8832. Preserving BF16 at that boundary produced 0.999998. This establishes fidelity to that reference boundary; an independent same-process A/B on the released 6-bit checkpoint found only small end-to-end differences between the two modes, with per-layer cosine similarity of at least 0.997 and coherent generation in both modes (details). The newpromote_dtargument defaults toTrue, so other callers retain the previous behavior.Tests
Added Puzzle regressions for:
Targeted M2 Max result:
Full repository result on the M2 Max:
The deselected test was the pre-existing Hugging Face
billsumintegration test. The environment haddatasets 5.0.0andhuggingface_hub 1.23.0, whose current repository-ID validation rejects the test's legacy barebillsumidentifier before loading. Running the complete suite without the deselection produced the same 218 passes plus that single unrelated failure.Scope
MTP/speculative decoding is intentionally not included. This PR implements ordinary autoregressive base-model loading and inference.