~/satyajit

HauhauCS FastMTP: a signed manifest that actually verifies

mdjsonmcp

2026-08-30 · 11 min · gguf · quantization · llama-cpp · multi-token-prediction · speculative-decoding · security

Why read this

Solidtop 85%

Verifies the quant's Ed25519 signatures and every hash, dry-runs its llama.cpp patch, and finds two of five K_P size claims miss the stated band.

  • Original analysis
  • Runs on a consumer GPU
  • Concrete numbers to act on

Quantization & compressionApache-2.0Practitioner model

How this was scored
Is it new?
1 of 3: An incremental tweak
Can I trust it?
2 of 3: Measures key facts from files, code or configs
Can I run it?
2 of 3: Open code or weights with real limits
Will I understand it?
2 of 3: Mechanism from first principles with figures
Can I act on it?
2 of 3: A concrete recipe, numbers or comparison
Will it last?
1 of 3: Relevant for months
Does it affect many?
1 of 3: A specialist community
Only here?
2 of 3: A teardown or measurement few others did

Score 57 of 100, ranked 388 of 577 rated articles. Each question is answered 0–3 by hand, and a 3 is rare. How articles are scored

HauhauCS/Qwen3.8-27B-Uncensored-HauhauCS-Aggressive-MTP-GGUF is, by Hugging Face's own numbers, one of the more-downloaded community quants this site has looked at: 1,061,687 downloads, 752 likes, 172.47 GB spread across 21 files. It is also, as the name says, an uncensored derivative — HauhauCS's "Aggressive" refusal-suppression profile applied on top of Qwen's own Qwen3.8-27B, with the card claiming 0 refusals across 465 prompts. That part of the story is not new, and it is not this article's subject; abliterated Qwen3.8-27B derivatives are already their own small ecosystem, and the Qwen3.8-Flash-Next piece catalogued two others in it.

What is new — and, unlike the abliteration itself, fully checkable without touching model behavior at all — is what else the repository ships. Sitting next to the eleven GGUF quants and a vision projector are four files a quantizer almost never bothers with: a signed release manifest, a signed build-provenance file for one specific artifact, the Ed25519 public key to check both against, and a small llama.cpp patch — 27 lines added, one removed — against a pinned commit. None of that requires taking HauhauCS's word for anything — the manifest names exact byte counts and hashes, the signatures are checkable against a key shipped in the same repo, and the patch is a diff against a public commit with a public history. So this article did the checking.

RepoHauhauCS/…-Aggressive-MTP-GGUF · 1,061,687 downloads · 752 likes
BaseQwen/Qwen3.8-27B — dense, 64 layers, 48 Gated DeltaNet + 16 gated-attention
Size172.47 GB, 21 files · 11 text GGUFs, IQ2_M (10.32 GB) to Q8_K_P (31.46 GB)
Visionseparate mmproj BF16 projector, 931 MB, 334 tensors
FastMTP sidecar-FastMTP-32K.gguf, 903 MB · trims the MTP head to a 32,768-token draft vocabulary
AuthenticityEd25519-signed manifest + provenance, a raw public key, and a plaintext SHA256SUMS
Patchone file, src/models/qwen35.cpp, +27/−1 lines, against ggerganov/llama.cpp@4df29be4…
LicenseApache-2.0, inherited from Qwen3.8-27B
repo size
172.47 GB
quantizedQwen/Qwen3.8-27B
task
image-text-to-text
license
apache-2.0
gguf files
12
largest file
31.46 GB
files
21
downloads
2.0M
likes
1.4K
languages
en, zh, multilingual
uncensoredqwen3.8ggufmultimodalvisionmtpspeculative-decodingfastmtp

repo last modified 2026-08-17

The headline check: do the signatures actually verify

The method was plain: download HauhauCS-RELEASE-MANIFEST.json, its .sig, FastMTP-PROVENANCE.json, its .sig, and HauhauCS-FastMTP-Ed25519-PUBLIC.pem directly from the repo's /resolve/main/, then verify with Python's cryptography library — load_pem_public_key on the PEM, then pub.verify(sig, data) on the exact downloaded bytes of each document.

Both signatures verify. No exception, no fallback, no "couldn't check." And the public key itself isn't just trusted on arrival — its DER fingerprint, computed locally from the downloaded .pem, matches the public_key_der_sha256 field the provenance file declares about itself, so the key doing the verifying is provably the key the signed document says it should be.

Checking the hashes without downloading 172GB of model weights

A signature only proves the manifest wasn't altered after signing — it says nothing about whether the manifest's own claims about the files match the files. That part is checkable too, and cheaply. Every small file the manifest covers — FastMTP-PROVENANCE.json, both .sig files, the PEM, the patch, README.md — was downloaded and hashed directly: all five match the manifest's declared sha256 with no exceptions. For the twelve GGUFs, downloading 172GB just to hash them defeats the point of having a manifest at all, so this article cross-checked the manifest's declared sha256 against Hugging Face's own file metadata instead, via https://huggingface.co/api/models/<repo>?blobs=true, which reports each LFS file's sha256 without transferring the file. Every one of the twelve — including the vision projector — matches.

There's a second, less obvious layer. Each GGUF entry in the manifest carries two hashes: a plain sha256 of the raw file, and a canonical_tensor_sha256 computed over "sha256-sorted-name-type-shape- payload" — HauhauCS's own stated algorithm name, not independently auditable here since the tool that computes it isn't published. The idea, stated in the README's own authenticity section, is that the plain hash "identifies byte-for-byte mirrors after renaming" while the canonical one "continue[s] to identify HauhauCS tensors after metadata-only rewriting" — i.e. it should survive someone stripping or editing the GGUF's key-value header while leaving the actual weights untouched, and change if the weights themselves do. The field is present and internally consistent for every GGUF in the manifest; whether the specific algorithm behind it does what it claims isn't something this article could verify without the tool that produced it, so take the concept as sound and the implementation as unverified.

What isn't covered by the signed manifest is smaller than it sounds: itself, its own .sig, and .gitattributes. A third file, SHA256SUMS — a plain, unsigned text ledger in the classic sha256sum format — closes that gap: it lists the manifest and its signature alongside everything else, and sha256sum -c against the small files downloaded for this piece reports every one OK. Between the signed manifest and the plaintext ledger, every file in the repo except .gitattributes has a declared hash checkable from at least one of the two.

What FastMTP actually is, and where the MTP head comes from

Qwen3.8-27B is dense — every parameter active per token, no routed experts — which makes "where does the MTP head come from" a fair question, since multi-token prediction usually shows up on MoE models like DeepSeek-V3 or Qwen3.8-Flash-Next. The answer is in the README's own "Specs" section: Qwen ships a native embedded MTP/NextN head on the dense model itself, and every text GGUF in this repo preserves it unmodified — nothing HauhauCS added. That head projects directly onto the model's full, padded 248,320-token vocabulary, same as the main output layer, and it already works today with plain --spec-type draft-mtp on any of the target quants alone, no patch required. If the mechanics of multi-token prediction as a training objective and a self- speculative decoder are unfamiliar, the MTP explainer covers both Meta's parallel-head and DeepSeek's sequential-module flavors in more depth than this piece needs to.

HauhauCS FastMTP is a separate, second checkpoint — the 903 MB -FastMTP-32K.gguf — that reuses the same idea but trims the head's output vocabulary down to a fixed, much smaller set of tokens. The "32K" in the filename is the trimmed vocabulary size: 32,768, confirmed by the README's own diagnostic example for a mismatched build ("expected 5120, 248320, got 5120, 32768") rather than asserted in prose anywhere. A smaller output vocabulary means a smaller LM-head matmul on every draft step — the whole point of a draft model is to be cheap — at the cost of the draft never being able to propose a token outside that fixed 32,768. Running it requires the patch, because mainline qwen35.cpp has nowhere to put a trimmed-vocabulary head.

The patch, read line by line

HauhauCS-FastMTP-llama.cpp.patch touches exactly one file, src/models/qwen35.cpp, and it applies cleanly — checked here with patch -p1 --dry-run — against the exact commit its own provenance file names, ggerganov/llama.cpp@4df29be4f4c3673f428170fda944a5b19f743bb8, fetched independently from GitHub for the comparison. Two hunks, two jobs:

+    int64_t n_vocab_out = n_vocab;
+    const ggml_tensor * d2t_meta = ml.get_tensor_meta("d2t");
+    if (mtp_only && d2t_meta) {
+        n_vocab_out = d2t_meta->ne[0];
+        d2t = create_tensor(tn(LLM_TENSOR_D2T), { n_vocab_out }, 0);
+    }
     tok_embd = create_tensor(tn(LLM_TENSOR_TOKEN_EMBD, "weight"), { n_embd, n_vocab }, 0);
     output_norm = create_tensor(tn(LLM_TENSOR_OUTPUT_NORM, "weight"), { n_embd }, 0);
-    output = create_tensor(tn(LLM_TENSOR_OUTPUT, "weight"), { n_embd, n_vocab }, TENSOR_NOT_REQUIRED);
+    output = create_tensor(tn(LLM_TENSOR_OUTPUT, "weight"), { n_embd, n_vocab_out }, TENSOR_NOT_REQUIRED);
     if (output == NULL) {
+        GGML_ASSERT(!d2t && "d2t draft-vocab trim requires output.weight");
         output = create_tensor(tn(LLM_TENSOR_TOKEN_EMBD, "weight"), { n_embd, n_vocab }, TENSOR_DUPLICATED);
     }

The first hunk only trims output.weight when building the MTP-only graph (mtp_only, i.e. the drafter, not the target model) and the loaded GGUF actually carries a d2t tensor — a GGUF without one falls through unchanged. It also refuses to let a trimmed head fall back to the tied token- embedding matrix, correctly, since that matrix is sized to the full vocabulary and can't stand in for a smaller one. The second hunk, inside the MTP graph builder itself, takes the head's output over the trimmed vocabulary and scatters it into a full-vocabulary tensor pre-filled with negative infinity, using d2t as the index map — so the target model, verifying downstream, still sees an ordinary 248,320-wide logit vector, just one where most entries can never win.

The interesting part isn't the mechanism — it's where it came from. LLM_TENSOR_D2T and model.d2t ("draft to target vocabulary mapping," in the field's own comment) are not new infrastructure this patch invents; they already exist in llama.cpp's shared architecture code at that same commit. A GitHub code search for d2t under src/models in ggml-org/llama.cpp turns up exactly two files using it: eagle3.cpp and dflash.cpp — the dedicated draft-model architectures behind EAGLE-3 and DFlash, both already covered on this site. qwen35.cpp itself has no d2t reference before this patch. So HauhauCS's contribution here is narrow and precise: not a new vocabulary-trimming idea, but the first wiring of llama.cpp's existing one into a dense model's own embedded MTP head, rather than into a purpose-built external drafter.

Does it actually go faster?

Here the checking has to stop being independent, because reproducing it would mean running the model. HauhauCS's own numbers, measured on one RTX PRO 6000 Blackwell (96 GB), one lane, --no-mmap, full CUDA offload: FastMTP at depth 3 reaches up to 3.02x document throughput and 1.93x reasoning throughput against MTP disabled entirely, and up to 35.2% more document throughput and 21.1% more reasoning throughput than the native embedded MTP head running at depth 2. Every FastMTP run is reported to reproduce the corresponding embedded-MTP output token-for-token — the expected result, since the target model still verifies every drafted token regardless of which head proposed it, and a correctly-implemented draft head can only change speed, not output. That claim, and the underlying tok/s table across all ten quants, is self-reported, single-hardware, and not reproduced by this article — unlike the signatures and hashes above, there's no cheap independent way to check a throughput number without the GPU it was measured on.

The K_P quant ladder: checking one more claim

The card makes a second, smaller, checkable claim about its own custom "K_P" quants: each one "bumps quality up by one or two quant levels at only around 5-15% more size than the base quant." Its own Downloads table gives both numbers directly — the real K_P file's bits-per-weight, and a reference bpw for the standard llama.cpp quant type sitting right underneath it — so this is arithmetic, not another benchmark to trust blind.

Three of the five checkable pairs land inside the stated band. Two don't: Q5_K_P is a few points under the 5% floor, and Q3_K_P is barely bigger than plain Q3_K_M at all. None of this touches the size and hash checks earlier in this piece — every file's bpw and byte count match what's actually on Hugging Face — it's specifically the comparison to the standard quant types that the card's own numbers don't uniformly support.

The vision claim, checked against what's actually shipped

The repo's tags include multimodal and vision, and a vision claim on a GGUF release is exactly the kind of thing worth checking against the file list rather than the tag list: a GGUF text model needs a separate multimodal projector (mmproj) file to actually accept image input, and plenty of releases carry the tag without carrying the file. This one does carry the file — mmproj-Qwen3.8-27B-Uncensored-HauhauCS-Aggressive-BF16.gguf, 931 MB, 334 tensors, its sha256 present in the signed manifest and matching Hugging Face's own metadata like everything else checked above. The vision claim holds up against what's actually in the repository, for whatever the underlying Qwen3.8-27B vision tower is itself capable of — a question this article didn't re-test.

What this is, and isn't

Verified directly. Both Ed25519 signatures check out against a public key whose own fingerprint is independently confirmed. Every declared hash — for text files by direct download, for the twelve GGUFs against Hugging Face's own LFS metadata — matches. The patch applies cleanly against the exact commit its provenance file names, and the mechanism it adds is a real, pre-existing llama.cpp convention already used by two draft-model architectures this site has covered, not a novel or unverifiable trick. The vision projector the tags promise is actually in the file list.

Self-reported, not independently reproduced here. The speedup numbers — the 3.02x/1.93x headline and the full per-quant table — come from HauhauCS's own single-GPU benchmark. Checking them would mean running a 172GB download through the patched runtime on matching hardware, which this piece didn't do.

Checked and found uneven. The K_P "5-15% more size" framing holds for three of five comparable pairs and misses low for two, most notably Q3_K_P.

The uncensoring is the reason this repository exists and the reason it has a million downloads; it is also the one part of the release this article isn't going to explain, demonstrate, or evaluate. What made it worth a full pass is everything sitting next to it: a signed manifest and a signed provenance file are not standard practice for a community requant, checking them costs nothing but bandwidth and a public key, and in this case, they hold up.

Cite this article

For attribution, please use the following reference or BibTeX:

Satyajit Ghana, "HauhauCS FastMTP: a signed manifest that actually verifies", ai.thesatyajit.com, August 2026.

bibtex
@misc{ghana2026hauhaucsqwenfastmtp,
  author = {Satyajit Ghana},
  title  = {HauhauCS FastMTP: a signed manifest that actually verifies},
  url    = {https://ai.thesatyajit.com/articles/hauhaucs-qwen-fastmtp},
  year   = {2026}
}
share