Thanks for taking the time. forgequant is a small, focused tool — these notes keep it that way.
forgequant is a thin, stdlib-only orchestrator over ds4 for DeepSeek-V4-Flash. It is not a general GGUF tool. Good contributions:
- new or refined recipes (
recipes/*.json); - better imatrix analysis (
forge_imatrix.py) — ranking signals, visualizations; - CLI / UX polish, clearer errors, more preflight checks;
- docs and worked examples.
Out of scope (belongs upstream): the quantization math, GGUF format, and inference → ds4; benchmark fetching, the lockfile, and registry contents → benchy.
forgequant's own code needs nothing but Python ≥ 3.8 — no install, no third-party deps. You can run the tests on a fresh clone:
git clone https://github.com/andreaborio/forgequant.git
cd forgequant
make check # == compileall (syntax) + test_forge.pyTo actually build quants you additionally need a ds4 checkout and the model files, pointed at by two env vars:
export DS4_DIR=~/ds4 # ds4 checkout: gguf-tools/deepseek4-quantize, the splicer, ds4/ds4-server
export MODELS_DIR=~/ds4-models # FP source, template GGUF, imatrices, outputs ({models} in recipes)The benchmark-calibration features need benchy (github.com/andreaborio/benchy), a
separate project. Clone it beside forgequant (./benchy) or set $BENCHY_DIR:
git clone https://github.com/andreaborio/benchy.git # ./benchy, or: export BENCHY_DIR=...
make benchy # clones to ./benchy if missingmake test # or: python3 test_forge.pyThe suite is stdlib unittest and requires no ds4, no models, and no network — it
covers the .dat parser, the corpus renderer, recipe loading/validation, and the UI's
path-traversal guards. CI runs it on Python 3.8–3.13 (see
.github/workflows/ci.yml).
Please add a test when you change parsing, rendering, recipe validation, or a UI guard.
If you touch quant/imatrix command construction, assert on the built command list
(as TestForgequant already does) — that's testable without ds4.
- Standard library only. numpy may be used opportunistically (
try: import numpy) with a pure-Python fallback, asforge_imatrixdoes — never as a hard dependency. - 4-space indent, no type-annotation generics that require ≥ 3.9 (keep the 3.8 floor;
.editorconfigand CI enforce the rest). - Match the surrounding code: terse helpers,
die(msg)for user errors, explicit command lists (no shell strings), path templates viaresolve(). - Keep
forgequant.py's dispatch table (CMDS) and thepaths/suggestanalyzers in sync with the README when you add a command or flag.
A recipe is recipes/<name>.json. The full schema is in the
README; the essentials:
Then verify it loads and inspect the resolved commands — no ds4 needed for this:
python3 forgequant.py show my-recipeRules the loader enforces (so check before you open a PR):
- only producible quant types:
iq2_xxs,q2_k,q4_k,q8_0(+f16/bf16/f32); boost.layers: "auto:N"needs animatrix; use a static range ("37-42") otherwise;boost.mode: "contrast"requiresboost.baseline(a baseline.dat);- layer indices must be within
0..42.
make list and test_presets_load (in test_forge.py) both pick up new recipes
automatically.
- Commit messages follow the existing
scope: summarystyle, lowercase, imperative — e.g.forge_imatrix: add MoPEQ sensitivity boost mode,recipes: add coder-q4boost-v2. - Keep PRs small and single-purpose. Fill in
.github/PULL_REQUEST_TEMPLATE.md. make checkmust pass.
This repo doubles as a research record. Some files are intentionally immutable:
PREREG_*.md— pre-registrations. They are committed before measurement to prove a hypothesis was locked. Don't edit them after the fact; add a new dated file.bench/runs/*.json— calibration provenance (which benchmarks, row SHAs, upstream dataset commit). Append by running a calibration; don't hand-edit.
Working notes (HANDOFF*, RESEARCH_*, substack-post*, held-out runbooks) are
gitignored on purpose — keep them local.
By contributing you agree your work is released under the project's MIT License (which covers forgequant's code only, not ds4 or model weights).
{ "name": "my-recipe", // must match the filename "description": "...", // shown by `list` "hf": "{models}/DeepSeek-V4-Flash-FP", "template": "{models}/<base>.gguf", // families you omit are copied from here "imatrix": "{models}/my.dat", "quant": { "routed_w1": "iq2_xxs", "routed_w3": "iq2_xxs", "routed_w2": "q2_k" } }