Buckets:
| license: mit | |
| language: | |
| - en | |
| pipeline_tag: text-generation | |
| library_name: gguf | |
| tags: | |
| - quantization | |
| - gguf | |
| - llama-cpp | |
| - imatrix | |
| - hybrid-quantization | |
| - selective-quantization | |
| - priority-queue | |
| - mse | |
| - theoretical-optimization | |
| - qwen3.5 | |
| - gemma4 | |
| - moe | |
| - mtp | |
| # ASHQ1 — Autonomous Selective Hybrid Quantization | |
| > ⚠️ **Experimental.** ASHQ1 is a personal research project that I will be refining over time. Use at your own risk. Results may vary between architectures and fine-tunes. Feedback and contributions welcome. | |
| **Latest update (v6):** The classifier has been overhauled — the empirical depth-weighting heuristic was removed after A/B testing confirmed it added zero value. Quality improved as a result. The same budget now goes further. | |
| ASHQ1 is a post-training quantization method for GGUF models that uses an **imatrix-driven priority queue** to maximise theoretical quality per megabyte. Instead of uniform bit-depth or heuristic layer-blocking, it treats tied tensor groups as monolithic entities and greedily upgrades them by strict mathematical utility — the product of summed importance and theoretical MSE reduction, divided by size cost. | |
| ## Results | |
| | Method | Model | Size | PPL (ctx 1024) | Δ vs Uniform | | |
| |:-------|:------|:----:|:--------------:|:------------:| | |
| | **ASHQ1** (v6) | Ornith-1.0-9B-MTP | 6012 MiB | **7.4697 ± 0.04862** | **−0.1551** | | |
| | Uniform Q6_K | Ornith-1.0-9B-MTP | 7198 MiB | 7.6248 ± 0.05039 | baseline | | |
| ASHQ1 beats uniform Q6_K by **0.155 PPL** while being **16.5% smaller** (−1186 MiB). The current classifier (v6) dropped empirical depth-weighting heuristics — the theoretical priority queue now works even better. | |
| ASHQ1 is often on par with hand-tuned SHQ quants in quality, and sometimes surpasses them. At the same time, it saves significant time and effort — just set your target size and go. | |
| ## Real-World Validation | |
| ASHQ1's theoretical quality advantage transfers to real agentic coding. We tested Ornith-1.0-9B ASHQ1 6500 (6.4 GB, 33% smaller than Q8_0) as the backend for [Pi](https://pi.dev/), an autonomous coding agent that uses `llama.cpp` as its LLM backend. | |
| At `temperature 0.6`, the model was tasked with building a complete personal finance dashboard as a single HTML file — Canvas charts, budget tracker, dark mode, transaction filtering, upcoming bills, responsive layout. The agent worked autonomously: planned the architecture, wrote the entire ~1100-line file, caught its own bugs (`date.now` → `date.getTime`), fixed dark mode logic, ran Node.js validation, and iterated until all checks passed. The final `finance-dashboard.html` was a polished, production-quality single-page app — no external dependencies, no hallucinations, no broken features. | |
| This is not cherry-picked. It's the first test we ran. The benchmarks didn't lie — ASHQ1 preserves enough quality that a 6.4 GB quant can drive an autonomous coding agent to build complete, working applications from scratch. | |
| ## How It Works | |
| ### 1. Floor Assignment | |
| Every tensor starts at a minimum tier by class. SSM params and norms lock at F16. Embeddings start at Q5_K. Weight matrices start at Q4_K (or IQ4_XS for QAT models). MTP heads deploy at Q8_0. | |
| With `--allow-q3-or-lower`, low-importance tensors (`ffn_down`, `attn_output`, `ssm_out`) start as low as IQ2_XXS, giving the priority queue more room to upgrade important tensors to Q8_0. Tensors missing imatrix data are kept at Q4_K to avoid garbage at low bitrates. | |
| ### 2. Importance | |
| Imatrix `in_sum2` measures how much each weight contributes to the output variance. Layer position weighting was tested but showed no PPL benefit and has been removed. | |
| ### 3. Tied Group Detection | |
| Tensors with numerically identical `in_sum2` arrays are tied (shared weights). They form a single upgrade group — all members upgrade together as one unit. Group importance is the **sum** of its members' importance, preventing large groups from being starved of budget. | |
| ### 4. Priority Queue Drain | |
| All possible single-tier upgrades are pushed into a max-heap: | |
| ``` | |
| utility/MiB = sum(timp[group]) × (MSE(cur) − MSE(next)) / (size(next) − size(cur)) | |
| ``` | |
| MSE per tier is theoretical: `MSE = 2^(-2 × bpw)`. K-quants get +0.1 effective bpw vs IQ-quants at the same real bpw, so IQ4_NL→Q4_K is a free quality gain. | |
| The queue pops the highest-utility upgrade, applies it, pushes the next upgrade for that group, and drains until the budget is exhausted. A final pass catches any remaining zero-cost upgrades. | |
| ## Why It Works | |
| | Problem | ASHQ1 Solution | | |
| |---------|---------------| | |
| | Uniform quant wastes bits on low-importance tensors | Priority queue allocates budget where it matters | | |
| | Heuristic hand-tuning doesn't scale | Single knob: `--size` in MiB | | |
| | Hand-tuned SHQ hybrids need days of PPL sweeps | Queue converges in ~1 sec for any budget | | |
| | Large tied groups starved by per-tensor logic | `sum(timp)` prevents 32× group penalty | | |
| | IQ4_NL→Q4_K at same bpw is a no-op | Free-upgrade pass catches zero-cost quality gains | | |
| | No PPL-per-budget curve needed | Queue optimises for MSE directly | | |
| | Tensors without imatrix crash at low bitrates | `has_imatrix` check falls back to Q4_K floor | | |
| ## Supported Architectures | |
| | Arch | Detection | Features | | |
| |------|-----------|----------| | |
| | `qwen35` | SSM + QKV | Hybrid attention, SSM layers, GQA, **MTP support** | | |
| | `mellum2` | MoE (`exps` tensors) | Mixture of Experts, GQA, router F16 | | |
| | `gemma4` | Layer-scale norms | QAT support, Q4_K attention floor | | |
| MTP (Multi-Token Prediction) heads are handled explicitly: MTP tensors deploy at Q8_0 and are excluded from the classifier's budget (their cost is subtracted from the target upfront). Tensor names with `nextn.*` or layers beyond `n_layers` are detected as MTP at runtime. | |
| ### Looking for: Qwen3.6 support | |
| Qwen3.6 is one of the most capable local LLMs right now, but I can't handle it on my hardware. The BF16 source is ~55 GB — I don't have enough RAM to even load it, let alone quantize. If you have access to a Qwen3.6 GGUF (any quantization) and can run `llama-imatrix` on it — or if you'd like to collaborate on adding architecture detection — please reach out. I can handle the integration, I just need the raw tensor names and imatrix data to map out the class system. | |
| New architectures can be added via `ARCH_FEATURES` in `constants.py`. | |
| ## Code Structure | |
| | File | Role | | |
| |------|------| | |
| | `main.py` | CLI entry point, orchestration, `--show-floors`, multiple `--imatrix` support | | |
| | `model_reader.py` | Reads GGUF, detects architecture/prefix/n_layers/MTP at runtime | | |
| | `imatrix_reader.py` | Parses imatrix GGUF, detects tied groups via `np.allclose(in_sum2)`, combines multiple imatrix | | |
| | `classifier.py` | Floor assignment → tied group building → priority queue drain → free upgrade pass | | |
| | `config_generator.py` | Generates `--tensor-type` regex rules from classified tensors (valid ECMAScript regex with pipe-alternated ranges) | | |
| | `quantizer.py` | Subprocess wrapper around `llama-quantize` | | |
| | `constants.py` | TENSOR_CLASS mapping, CLASS_HARD_FLOORS, CLASS_MAX_TIER, MSE_BPW, TIER_BPW, ARCH_FEATURES | | |
| ## Usage | |
| ### Quantization | |
| ```bash | |
| pip install -r requirements.txt | |
| # Dry run (∼1 sec) | |
| python main.py --model model.gguf --imatrix imatrix.gguf --size 6800 | |
| # Actual quant (∼10 min) | |
| python main.py --model model.gguf --imatrix imatrix.gguf --size 6800 --run | |
| # Show hard floors | |
| python main.py --show-floors | |
| # Multiple imatrix (combined with max/mean) | |
| python main.py --model model.gguf --imatrix i1.gguf --imatrix i2.gguf \ | |
| --imatrix-method max --size 6800 --run | |
| # Allow low-bit tensors (IQ2_XXS through Q8_0 spread) | |
| python main.py --model model.gguf --imatrix imatrix.gguf --size 6000 \ | |
| --allow-q3-or-lower --run | |
| ``` | |
| The `llama-quantize` binary path is set in `quantizer.py:6`. | |
| ### Inference (llama-server) | |
| Recommended server flags for serving ASHQ1 quants: | |
| ```bash | |
| ./build/bin/llama-server \ | |
| -m model-ASHQ1.gguf \ | |
| -c 50000 \ | |
| --jinja \ | |
| -fit off \ | |
| -ngl 99 \ | |
| --flash-attn on \ | |
| --cache-type-k q8_0 \ | |
| --cache-type-v q8_0 \ | |
| --port 8080 \ | |
| --mmap \ | |
| --temp 1.0 \ | |
| --top-p 0.95 \ | |
| --min-p 0 \ | |
| --top-k 20 \ | |
| --seed -1 \ | |
| --parallel 1 | |
| ``` | |
| ## Tier Reference | |
| | Tier | BPW | MSE_BPW | | |
| |------|:---:|:-------:| | |
| | F16 | 16.0 | 16.0 | | |
| | Q8_0 | 8.50 | 8.50 | | |
| | Q6_K | 6.5625 | 6.5625 | | |
| | Q5_K | 5.50 | 5.50 | | |
| | Q4_K | 4.50 | 4.50 | | |
| | IQ4_NL | 4.50 | (2) | | |
| | IQ4_XS | 4.25 | 4.25 | | |
| | Q3_K | 3.4375 | 3.4375 | | |
| | IQ3_M | 3.66 | — | | |
| | IQ3_S | 3.44 | 3.44 | | |
| | IQ3_XXS | 3.0625 | 3.0625 | | |
| | IQ2_S | 2.50 | 2.50 | | |
| | IQ2_XS | 2.3125 | 2.3125 | | |
| | IQ2_XXS | 2.0625 | 2.0625 | | |
| | IQ1_S | 1.5625 | 1.5625 | | |
| > (2) IQ4_NL uses IQ4_XS MSE_BPW for the free-upgrade pass (same real bpw as Q4_K). | |
| ## Quantization Configs | |
| Generated configs are valid `llama-quantize` arguments with ECMAScript-compatible regex patterns. Each `--tensor-type` rule matches a group of tensors that share the same target tier, with layers grouped into contiguous ranges: | |
| - `(blk|BLK)\.(3|7|11|15|19|23|27|31)\.attn_k=Q8_0` — specific attention layers at Q8_0 | |
| - `(blk|BLK)\.((?:22|23|24|25|26))\.ffn_gate=Q6_K` — range of FFN layers at Q6_K | |
| - `.*output_norm.*=F16` — global catch-all | |
| Rules are sorted by specificity (specific layers, high tiers first) because `llama-quantize` uses first-match-wins. | |
| ## References | |
| - [ASHQ1 repo](https://huggingface.co/wepiqx/ASHQ1) | |
| - [GGUF specification](https://github.com/ggerganov/ggml/blob/master/docs/gguf.md) | |
| - [llama.cpp](https://github.com/ggerganov/llama.cpp) | |
Xet Storage Details
- Size:
- 9.58 kB
- Xet hash:
- 54d053357dc1ff642817249645dc3eabc720f2572ab6862f24e68a8ed8a06e99
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.