Repository navigation
Add Nemotron Super 3.5 VL and Nemotron Bolt 74B A9B support - #30520
Conversation
|
|
||
| int32_t predecessor = 0; | ||
| for (int32_t i = 1; i < n_block_tokens; ++i) { | ||
| for (int32_t i = 1; i < (is_dflash2 ? n_block_tokens : params.n_max + 1); ++i) { |
There was a problem hiding this comment.
oh wait, what is this change here? We just merged lilicorr, right?
There was a problem hiding this comment.
Not sure why it wasn't caught earlier.
In the LiliCorr PR, LiliCorr calculates the entire candidate lattice even when n_draft < 7. The head's tensors are specifically made to run attention between 56 candidates, so it seemed inadvisable to slice it. In any case, not within in the already-burgeoning scope of this PR.
For that case, doing the loop from 1 to n_block_tokens is wrong; since that will always output 7 draft tokens, even when we have set n_draft to < 7.
That hits this assert later on in llama-context.cpp:2384
GGML_ASSERT(n_outputs_max <= cparams.n_outputs_max);
The change keeps us from passing more than n_max tokens even if the lattice is larger.
|
|
||
| ggml_tensor * inp_anchor = nullptr; | ||
| if (model.lilicorr_pass_hidden_proj && ubatch.embd_state) { | ||
| if (model.lilicorr_pass_hidden_proj && ubatch.embd_state && n_tokens == (int64_t) hparams.dflash_block_size * ubatch.n_seqs_unq) { |
There was a problem hiding this comment.
Again, not sure how it passed by earlier!
AFAIK before starting llama-server does a dummy pass with 2 tokens and directly calls the decoder; which causes the LiliCorr head to try to make the lattice with 2 tokens. It can only make the lattice for 8 tokens currently, since we have implemented it that way in #30506.
So the dummy pass fails this assert in (dflash.cpp:664), and the server stops -
GGML_ASSERT(tokens_per_block == block_size);
|
@ngxson Is this good to merge on your end? |
|
Will fast-track this to get the model supported in the |
Adds Studio support for the NVIDIA Nemotron 3.5 Bolt and Super GGUFs: [unsloth/NVIDIA-Nemotron-3.5-Bolt-74B-A9B-GGUF](https://huggingface.co/unsloth/NVIDIA-Nemotron-3.5-Bolt-74B-A9B-GGUF) and [unsloth/NVIDIA-Nemotron-3.5-Super-VL-120B-A12B-GGUF](https://huggingface.co/unsloth/NVIDIA-Nemotron-3.5-Super-VL-120B-A12B-GGUF). Both are `nemotron_h_moe` (hybrid Mamba2 + a few attention layers + latent MoE), supported in llama.cpp by ggml-org/llama.cpp#30520. ## Variant picker and drafters - **`NVFP4` is a quant token.** Only `MXFP*` was known, so Super's `NVFP4` variant resolved to `LiLiCorr/lilicorr-...-NVFP4.gguf`, a 1.3 GB drafter, and loaded it as the main model. The quant regex now accepts `(?:MX|NV)FP[0-9]+` in all of its copies (backend and `model-identity.ts`). - **`lilicorr-*.gguf` is a drafter kind.** Super's LiLiCorr drafter was listed as a selectable quant. Super uses its embedded MTP head, which measured faster, so LiLiCorr is now excluded from variant menus and quant lookups and is never launched. Added to `_DRAFTER_KINDS` in its three mirrors. - **NVFP4-suffixed sidecars pair with their weights on local loads.** `dspark-<model>-NVFP4.gguf` / `dflash-<model>-NVFP4.gguf` kept `-nvfp4` in the pairing stem, so a local folder load attached no drafter. Bolt ships its LiLiCorr drafter as `dflash-NVIDIA-Nemotron-3.5-Bolt-74B-A9B-NVFP4.gguf` (GGUF architecture `dflash`). With this, Auto mode launches: | Model | Drafter | Flags | |---|---|---| | Super | embedded MTP head | `--spec-type draft-mtp`, no `--model-draft` | | Bolt | LiLiCorr (`dflash-...gguf`) | `--model-draft dflash-... --spec-type draft-dflash` | ## Sampling defaults New `nemotron-3.5` family in `inference_defaults.json`: temperature 1.0, top_p 0.95 (NVIDIA's recommendation for both models). It matches every id shape (repo, `repo:quant`, cache snapshot path, local `.gguf`) and sits before `nemotron`, so older Nemotrons keep 1.0 / 1.0. ## Memory planner Measured against llama-server allocations for Bolt IQ2_XXS and Super UD-IQ2_XXS, the default path was safe but mis-priced the fixed costs: - **Embedded MTP head counted when MTP is off.** The context fit charged Super about 3 GB for the nextn block, which llama.cpp does not load without `--spec-type draft-mtp`, so Super got a much shorter auto context on tight cards. It is now excluded unless MTP is engaged (`nemotron_h_moe` only, the arch measured). - **Latent MoE width.** The routed-expert compute term now uses `moe_latent_size` when present, and per-layer `expert_used_count` / `expert_feed_forward_length` arrays are read as their max (Bolt stores them per layer; they were read as missing). - **DFlash / DSpark drafter compute floor.** The drafter context re-reserves to a flat buffer once the dflash implementation initialises; the reserve was up to 332 MiB short. Floored at the measured draft-plus-verify graph minus the reserve Studio already charges beside it, for dflash-architecture drafters only. On a 24 GB card Bolt's DFlash drafter does not fit the fit budget at any context (measured 23.4 GB minimum), so Auto keeps it off there; from 32 GB it keeps `draft-dflash` at full context (measured 26.4 GiB peak, 0.917 acceptance). - **Smart-offload layout** (`UNSLOTH_SMART_OFFLOAD=1`): per-layer `head_count_kv` raised a `TypeError`, and would otherwise have counted every layer as attention with no recurrent state. KV is now charged to the attention layers only and Mamba state to the recurrent ones, for `nemotron_h` / `nemotron_h_moe` only. Bolt's layout now matches the measured resident size exactly. | MiB | Measured | Before | After | |---|---|---|---| | Super weights, MTP off | 45757 | 48752 | 45765 | | Super compute 32k / 262k | 224 / 448 | 840 / 1064 | 550 / 774 | | Bolt compute 32k / 262k | 148 / 372 | 143 / 367 | 260 / 484 | | Bolt DSpark drafter reserve 32k / 262k | 2540 / 3884 | 2208 / 3707 | 2548 / 3892 | | Bolt DFlash (LiLiCorr) drafter, any context | 1750 | 2085 | 1862 | | Super MTP reserve 32k / 262k | 590 / 1038 | 1366 / 1814 | 1075 / 1523 | Every component now estimates at or above the measured allocation. Other architectures are unchanged; the new tests pin that for a hybrid with `full_attention_interval` and for a dense model. ## Tests - `tests/test_nemotron35_bolt_super.py` and `tests/test_nemotron35_planner.py`: 39 tests, all pass. On `main` 13 of the picker/sampling tests fail, as expected. - The related existing suites (GGUF, variants, drafters, MTP, DSpark, DFlash, sampling, offload, fit, context, memory, layout): identical failing test ids on `main` and on this branch, all pre-existing (diffusion offload, training offload layers, one TTS test). - Live llama-server runs of the published files on llama.cpp with #30520: Super UD-Q4_K_XL with the Auto-mode MTP flags, draft acceptance 0.897; Bolt IQ2_XXS with the LiLiCorr drafter, acceptance 0.836 and 128.7 to 224.2 tok/s versus no drafter. ## Not covered - Studio's pinned `gguf==0.19.0` cannot read the `Q2_0` type that Super UD-IQ1_M through UD-Q3_K_XL use. Only the opt-in smart-offload layout reads tensor types this way; the default path sizes from offsets and is unaffected. - The 24 / 48 / 80 GB fit decisions were checked by calling the planner with simulated card sizes, not on those cards.
…pp#30520, nemotron-h.cpp only) cherry-picked into buun 34ef0ef7c -- Bolt loads, 58/60 same M1 grade as upstream, 2.6% slower; buun head needs an AMX header-guard workaround on CUDA 12.4 + gcc 13.4 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…3.5 VL / Bolt 74B) Hybrid MoE placement is skipped when the MoE cache is active; Vulkan host buffers keep refusing uncached memory.
Backport the text loader and MoE graph changes from upstream cd0a5b6 (llama.cpp ggml-org#30520). Keep the per-layer router, bias and expert weights consistent with their GGUF dimensions and validate the count against top-k and the declared maximum. Build the MoE graph with the loaded layer count. The original upstream change is by Kartik Gulia <kgulia@nvidia.com>. Assisted-by: Codex
…gml-org#30520) * add support * remove unneeded bos fix * add video flag * fix flake error * remove video-specific budgeting * convert : fix lilicorr-dflash bid clash * spec : enforce lilicorr n_tokens condition * spec : fix lilicorr walk [no release]
Overview
This PR adds support for two models - Nemotron Super 3.5 VL and Nemotron Bolt 74B A9B. It introduces the new architecture used by both models -
NemotronH_Omni_Reasoning_V3- and implements the vision graph for the new architecture innemotron-omni.cpp. The newNemotronOmniVLclass inconversion\nemotron.pywill handle the checkpoint conversion for the new models.Additional information
Conversion
Text-only
Image
Video (CLI)
Start llama-mtmd-cli, then enter /video with the video path and your prompt:
Video (Server API)
Start the server and allow access to the directory containing your video:
Requirements