Conversation
Adds tools/convert/sources/gguf.py so a recipe can source some or all logical parameters from a GGUF file (F16 through Q2-class quants, including Qwen3.5's GDN reorder, MTP's extra layer, and the mmproj vision tower) instead of the full Safetensors checkpoint. Parsing and dequantization delegate to the gguf package; the name/shape/reorder maps for Qwen3.5 were checked against real checkpoint/GGUF pairs end-to-end (dequantized values compared back to the HF originals, not just names), which caught two wrong assumptions in the process: the GDN head reorder needs swapped arguments to invert, not the same call twice, and llama.cpp's MTP export does not apply the same norm.weight +1 shift the base model's layers get. Also fixes GGUFSource to decode only the GGUF-native row range a read actually needs (GGUF's raw tensor data is already row-structured) -- recipe.prepare()'s 1-element preflight probe was fully dequantizing every tensor twice (once for the probe, once for the real write), and this was roughly doubling conversion time. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Wallawalla47
pushed a commit
to Wallawalla47/ninfer-custom
that referenced
this pull request
Sep 19, 2026
…conversion source
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
tools/convert/sources/gguf.py:GGUFSource/HFAliasSourcelet a recipe source some or all logical parameters from a GGUF file (F16 through low-bit ggml/I-quants) instead of the full Safetensors checkpoint, via the existing "Read another source" recipe mechanism — no changes needed tomodel.py/methods.py/recipe.py.qwen35_linear_attention_name_map), the MTP extra layer (qwen35_mtp_name_map), and the vision tower +qwen3vl_mergerprojector exported as a separatemmproj-*.gguf(qwen35_vision_name_map), plus a genericstandard_dense_name_mapfor ordinary attention/MLP/norm tensors. DFlash2 needs no new code — it already reads natively via the existing--source dflash2=PATHSafetensors path.norm.weight + 1shift the base model's layers get.GGUFSourceto decode only the GGUF-native row range a read actually needs, instead of dequantizing the whole tensor on every call. GGUF's raw tensor data is already row-structured (ReaderTensor.data.shape[0]always matches the tensor's outer dimension), so this is exact, not approximate.recipe.prepare()'s 1-element preflight probe was fully dequantizing every tensor once for the probe and once again for the real write; this was roughly doubling conversion time and is now near-free (a 1.27B-element tensor's preflight-style read went from ~3.5s to ~0.0002s in testing).tools/convert/__main__.py:--source NAME=path.ggufnow opens as aGGUFSourceautomatically (suffix-detected), same as any other named source.docs/weight-conversion.md: new "Convert from a GGUF quant instead of the full checkpoint" section with a worked override-recipe example, plus a subsection on MTP/vision/DFlash2.tests/convert/test_gguf.py: synthetic-fixture coverage (built with theggufpackage's own writer, no external model files needed) for row-partial reads, name-map construction, the GDN reorder's swapped-argument inverse, the norm shift, and the vision patch-embed composite reconstruction.Test plan
python3 -m pytest tests/convert/— 42 passed (14 new)GGUFSource/HFAliasSource/all four name-map functions against real Qwen3.8-27B checkpoint/GGUF pairs (Q5_0, IQ2_M, Q8_0) across text, GDN, MTP, and vision tensors, comparing dequantized values back to the HF originalstext,vision,mtp,dflash2) and loaded each resulting.ninferinninfer-serve, including a real image through the vision path and both--spec dflash2and--spec mtpspeculative decoding (draft acceptance and correct, baseline-matching output confirmed for both)🤖 Generated with Claude Code