Qwen3.6-35B-A3B-uncensored-heretic — QSA GGUF
QSA-grafted build of
llmfan46/Qwen3.6-35B-A3B-uncensored-heretic,
made from the existing Qwen3.6-35B-A3B-uncensored-heretic-No-MTP-custom.gguf BPW4.75 base.
Four files are published:
| file | indexers | MTP | use |
|---|---|---|---|
Qwen3.6-35B-A3B-uncensored-heretic-QSA-mm64k-MTP-custom.gguf |
mm_64k |
yes | recommended: same QSA mm64k model with speculative-decoding MTP head |
Qwen3.6-35B-A3B-uncensored-heretic-QSA-mm64k-No-MTP-custom.gguf |
mm_64k |
no | multimodal + 64k long-context indexer, no MTP |
Qwen3.6-35B-A3B-uncensored-heretic-QSA-text64k-No-MTP-custom.gguf |
text_64k |
no | text-only long-context fallback |
Qwen3.6-35B-A3B-uncensored-heretic-QSA-No-MTP-custom.gguf |
mm1_16k |
no | short/medium context baseline |
The original backbone is preserved byte-for-byte: all 733 base tensors keep their exact payload and offset. Only these are added to make the QSA files:
- 50 F32 indexer tensors (5 per full-attention layer):
blk.{N}.indexer.q_proj.weight,k_proj.weight,q_norm.weight,k_norm.pre_weight,k_norm.weight - metadata:
qwen35moe.attention.indexer.head_count = 4qwen35moe.attention.indexer.key_length = 128qwen35moe.attention.indexer.top_k = 2048qwen35moe.attention.compress_ratios= 4 on layers [3, 7, 11, 15, 19, 23, 27, 31, 35, 39], else 0
| file | Qwen3.6-35B-A3B-uncensored-heretic-QSA-text64k-No-MTP-custom.gguf |
| size | 22,180,352,608 bytes |
| sha256 | 6a9f99fe8fba3919c0280a59d48219ca328270a29090ce9205cf6c217d3f4741 |
| baseline sha256 | c3dbe95dc393a709d176e49e83f6071053cfeefdc4bd59342ce461b203d016ff |
| architecture | qwen35moe |
| base | Qwen3.6-35B-A3B-uncensored-heretic-No-MTP-custom.gguf |
| indexers | tvall43/Qwen3.6-35B-A3B-heretic-QSA-indexers |
| final captured teacher mass | 0.9464184045791626 |
| final indexer loss | 0.38196276128292084 |
mm_64k graft (base of the MTP file)
| file | Qwen3.6-35B-A3B-uncensored-heretic-QSA-mm64k-No-MTP-custom.gguf |
| size | 22,180,352,608 bytes |
| sha256 | 479d0e3554180db04f1387d0938a6fde1990046e7c7881a443cf1f6ec0a77b96 |
| baseline sha256 | c3dbe95dc393a709d176e49e83f6071053cfeefdc4bd59342ce461b203d016ff |
| architecture | qwen35moe |
| base | Qwen3.6-35B-A3B-uncensored-heretic-No-MTP-custom.gguf (unchanged byte-for-byte) |
| indexers | tvall43/Qwen3.6-35B-A3B-heretic-QSA-indexers, mm_64k/qsa_indexers.pt |
| lineage | 300 text steps @16k -> 300 mm steps @16k -> 200 OpenCode text steps @64k (text_64k) -> 100 mm steps @64k |
| final captured teacher mass | 0.8914 (train, K=2048/64k) |
| final indexer loss | 0.3348 |
mm_64k + MTP graft (recommended file)
| file | Qwen3.6-35B-A3B-uncensored-heretic-QSA-mm64k-MTP-custom.gguf |
| size | 23,077,816,352 bytes |
| sha256 | bc5dad1cc3b36e300ffc816c7752c696ae34d6b15edd56ea1f5893a10758b645 |
| architecture | qwen35moe |
| base | Qwen3.6-35B-A3B-uncensored-heretic-QSA-mm64k-No-MTP-custom.gguf (unchanged byte-for-byte) |
| MTP donor | llmfan46/Qwen3.6-35B-A3B-uncensored-heretic-Native-MTP-Preserved-GGUF, BPW5 |
| tensors | 783 base + 20 MTP = 803 |
| MTP tensors | full blk.40 block: attn_*, ffn_*/MoE experts, post_attention_norm, plus the 4 nextn.* head tensors |
| metadata | block_count = 41, compress_ratios length 41 (MTP layer 0), nextn_predict_layers = 1 |
This is the same QSA mm_64k model as the No-MTP file, with the donor's
complete MTP draft block grafted on as layer 40. The QSA backbone and all 50
indexer tensors are byte-for-byte identical to the No-MTP mm_64k file; only
the 20 MTP tensors and the three metadata fields above are added. The MTP layer
uses dense attention (compress_ratio = 0) and is only used by speculative
decoding, not by the main model's attention path.
In current llama.cpp builds this MTP head works as a self-speculative draft:
a small prompt-processing cost for a large token-generation gain. It is
optional; the model runs normally, with identical output, when MTP is not
enabled.
llama.cpp setup
This model needs the Qwen3.5/3.6-MoE QSA k-pool indexer support in llama.cpp.
Use the qwen35moe-qsa branch in tvall43/llama.cpp:
git clone https://github.com/tvall43/llama.cpp tvall43-llama.cpp
cd tvall43-llama.cpp
git checkout qwen35moe-qsa
cmake -B build -DGGML_VULKAN=ON
cmake --build build --config Release -j
Run the No-MTP file like this:
export LLAMA_QSA_TOP_K=4096
./build/bin/llama-server \
-m Qwen3.6-35B-A3B-uncensored-heretic-QSA-mm64k-No-MTP-custom.gguf \
--ctx-size 125536 \
--host 0.0.0.0 --port 8002
For the MTP file, add the speculative-decoding flags:
export LLAMA_QSA_TOP_K=4096
./build/bin/llama-server \
-m Qwen3.6-35B-A3B-uncensored-heretic-QSA-mm64k-MTP-custom.gguf \
--ctx-size 125536 \
--spec-type draft-mtp --spec-draft-n-max 2 --spec-draft-p-min 0 \
-fa on \
--host 0.0.0.0 --port 8002
--spec-type draft-mtp needs a recent llama.cpp build. If your build does not
recognise the flag, update the fork or use the No-MTP file.
LLAMA_QSA_TOP_K is the main thing to tune. The GGUF metadata ships the trained
budget (2048), which is right for voice/chat-length prompts; for long documents
do not just accept the default:
| prompt length | LLAMA_QSA_TOP_K |
|---|---|
| chat / assistants (< ~16k) | 2048 (default) |
| ~32k-64k documents | 4096 |
| ~80k-131k documents | 8192 |
For long prompts, keep the context window large enough that the prompt actually fits in one pass; the QSA path only kicks in above the indexer top_k.
By default, the GGUF already carries the indexer metadata, so there is nothing
else to enable on the model side. If you are comfortable with more knobs, the
fuller branch at qsa-rebase also has LLAMA_QSA_DENSE_BELOW_K and
LLAMA_QSA_PREFILL_ONLY for A/B testing, but the linked branch above is the
minimal support needed to run this model.
Runtime status
This is a structurally valid GGUF: header, tensor table, alignment, metadata
and payloads were verified after grafting. The reference QSA runtime
(kuraneko1/Qwen3.8-27B-QSA-llama.cpp)
originally implemented QSA only for the dense qwen35 architecture. A
qwen35moe port now adds the indexer tensors, the F32 indexer cache, the
hybrid indexer memory and the block-sparse attention branch.
WikiText-2 probe on an H200 (CUDA 12.9, flash attention, Q4 base):
| context | dense PPL | QSA K=2048 | delta | QSA scaled K | delta |
|---|---|---|---|---|---|
| 16384 | 4.7508 | 4.7573 | +0.14% | same | +0.14% |
| 65536 | 5.4270 | 5.7790 | +6.49% | K=8192: 5.4179 | -0.17% |
| 131072 | 5.1919 | 6.6043 | +27.2% | K=16384: 5.2021 | +0.20% |
131072, text_64k |
5.1919 | - | - | K=8192: 5.2154 | +0.45% |
Same probe on the mm_64k checkpoint (dense PPL is bit-identical; the
backbone is unchanged):
| context | dense PPL | K=2048 | delta | K=4096 | delta | K=8192 | delta |
|---|---|---|---|---|---|---|---|
| 65536 (2 chunks) | 5.4270 | 5.5789 | +2.8% | 5.4367 | +0.18% | 5.4194 | -0.14% |
| 131072 | 5.1919 | 5.9441 | +14.5% | 5.3352 | +2.8% | 5.2117 | +0.38% |
The mm_64k checkpoint dominates text_64k at every measured K (at 64k/K=2048:
5.5789 vs 5.7790; at 131k/K=2048: 5.9441 vs 6.6043), so it is a drop-in
replacement for text workloads too. 2048-token budget stays sub-1% at <= ~48k
and closes in around the same K ~= context / 8 curve above that.
The metadata keeps the trained budget of 2048 tokens, which is 12.5% of the
16k training length. At longer contexts the attention mass is spread over more
blocks, so a fixed 2048 is too small. The indexer ranking itself is fine: the
reference dense-mask path and the block-sparse kernel agree at 64k (5.7859 vs
5.7790). For long contexts, set LLAMA_QSA_TOP_K to about context / 8 in
the ported runtime.
For the Vulkan deployment (Mesa RADV / Radeon Pro V340 class, 8 GiB devices):
the fork already carries the Vulkan flash_attn_sparse_compact shader and the
topk_radix_qsa fusion. Split the 22 GB base across three or four devices
with --split-mode layer, keep -fa on, and set
LLAMA_QSA_TOP_K=$((CTX / 8)) for 32k-64k sessions. At voice/chat lengths the
cache is below top_k, so the indexer branch is not entered and adds no cost.
Stock upstream llama.cpp still loads the model with dense attention and ignores the added indexer tensors.
Validation
- base tensors: sampled byte-for-byte equality against the source file
- new tensors: payload equality against
mm1_16k/qsa_indexers.pt(including the+1zero-centred RMSNorm conversion) - tensor types: all 50 indexer tensors are
F32 - offsets: 32-byte aligned, no overlap, all payloads inside the file
- GGUF re-parsed with the reference
gguf-pyreader