hipfire
/docs · beta branch · view source · edit on GitHub

Quantize

Convert HF, safetensors, and GGUF weights to hipfire formats.

hipfire quantize is the user-facing wrapper around the CPU-only hipfire-quantize binary. It converts HuggingFace safetensors, a local model directory, or a GGUF file into hipfire’s HFQM container (extensions .mq4, .hf4, .mq6, …). The daemon mmaps the result directly.

Design / math / wire IDs: QUANTIZATION.md. Magnum V2 specs: quant-formats/mq4-v2.md, quant-formats/mq-v2-family.md. Product ladder: quant-formats/ladder.md. Register: quant-formats/qt-register.txt. HFP4 family detail: quant-formats/hfp4.md.

Pick a format

FormatWireBitwidthRotationTypical use
mq4 (alias) / mq4v2qt 44 MQ4G256V24FWHTQwen 3.5+ default body. --format mq4 means V2, not qt 13.
mq4v1 / mq4g256 / magnumqt 13 MQ4G2564FWHTLegacy Magnum v1 only (explicit opt-in)
mq4cqt 45 MQ4CG2564FWHTV1.5 pad geometry; hipfire-quantize direct
mq6qt 15 MQ6G2566FWHTQwen 3.5+ v1 when you can spare size for quality
mq{6,5,3,2}v2qt 47/48/49/506…2FWHTDense Magnum V2 ladder bodies — hipfire-quantize direct
hf4 (hfq4, hfq4g256)qt 64noneDense Llama / Mistral / Gemma / older Qwen. Default for GGUF.
hf6 (hfq6, hfq6g256)qt 86noneDense, higher quality
q8 / q8f16qt 38noneReference / debug (safetensors path)
mq3qt 173FWHTSub-4-bit v1 — hipfire-quantize direct only (thin CLI rejects it)
tq2 / bq1qt 40 / 41ternary / 1noneBonsai — hipfire-quantize direct
hfp4 / mfp4 / E8 / Lloydvariessee docsAdvanced; usually via hipfire-quantize directly

FWHT (the “M” in MQ) applies the two-sign rotation R = D2 · H · D1 / 16 (seeds 42 / 1042) before quantization. Qwen 3.5+ kernels apply the same R to activations (rotate_x_mq), not an inverse. On Llama-style dense models MQ is correct math but adds rotate cost with little quality benefit — prefer HFQ.

Thin CLI allowlist (hipfire quantize): still only mq4, mq6, q8, q8f16, and hf4/hf6 aliases. Unchanged surface — the wrapper does not grow V2/mq3/Lloyd/HFP flags. Because the binary maps mq4 → qt 44, a thin CLI hipfire quantize … --format mq4 produces MQ4G256V2. GGUF input further narrows to hf4, hf6, mq4, mq6. Formats such as mq3, mq{2,3,5,6}v2, mq4v1, mq4c, HFP/MFP, Lloyd, Bonsai, and graded MoE need hipfire-quantize directly.

Not produced by the thin CLI path: graded per-expert MoE recipes (mq4p, tiered Lloyd, imatrix/Hessian GPTQ-E8, REAP overlays), product-tier ladders (--tier / --fixed-tier), and research formats. Those need extra flags on hipfire-quantize directly. See the binary’s --help and QUANTIZATION.md.

MQ2V2 product rejection: --format mq2v2 is wire-legal and runtime-loaded, but dense Qwen3.8 ladder KLD rejects it as a product body. Prefer mq3v2 and above for any artifact you intend to serve; see ladder.md.

Research / reserved formats require explicit opt-in on the binary:

Flag / envOpens
--allow-mq2 / HIPFIRE_ALLOW_MQ2=1uniform mq2 v1 (reserved — collapses)
--allow-mq2-lloydmq2-lloyd
--allow-mq3-lloydmq3-lloyd
--allow-mq4-lloydmq4-lloyd

FLUX component packs (no quantization)

--flux-pipe does not quantize — it re-containers a diffusers FLUX.1 or FLUX.2 Klein pipe into per-component HFQ files with the dtype policy the diffusion loaders dispatch on. The packs are the only form the daemon loads; a pipe directory is the packer’s input, never a model path:

hipfire-quantize --flux-pipe <pipe_dir> --output <base>.hfq
#   <base>-transformer.hfq   arch 40  (F16 weights / F32 bias+scale)
#   <base>-t5.hfq            arch 41  (T5-XXL; shared across variants)
#   <base>-clip.hfq          arch 42  (CLIP-L)
#   <base>-vae.hfq           arch 43  (shared across variants)
hipfire-quantize --flux-pipe <pipe_dir> --output t5-xxl.hfq --flux-component t5

The family is detected from transformer/config.json. A FLUX.2 (Klein) pipe packs as <base>-transformer.hfq (arch 45), <base>-qwen3.hfq (arch 46, the Qwen3 text encoder) and <base>-vae.hfq (arch 43). Component ids: docs/architecture-ids.md § Image-generation component ids.

From HuggingFace

hipfire quantize Jackrong/Qwopus3.5-4B-v3 \
    --both \
    --upload schuttdev/hipfire-qwopus-4b \
    --create-repo \
    --install \
    --register qwopus:4b

Downloads into ~/.hipfire/hf-cache/, quantizes once per --format, optionally uploads, copies into ~/.hipfire/models/, and registers a local alias.

From a local safetensors directory

hipfire quantize ./my-finetune/ --format mq4 -o my-finetune.mq4

Directory needs config.json plus one or more .safetensors files. The quantizer accepts many architectures; inference only runs if a carrier/loader exists for that arch_id (see architecture-ids.md).

From GGUF

hipfire quantize ./tinyllama.Q4_K_M.gguf \
    --install --register tinyllama:1b-gguf
# default --format hf4 → …hf4

hipfire quantize ./qwen3.5.Q4_K_M.gguf --format mq4 \
    --install --register q35:9b-gguf

GGUF tensor names are rewritten to HuggingFace-style names so load_weights_hfq works. Tokenizer fields (tokenizer.ggml.tokens / merges / bos/eos / model) are preserved under gguf_meta in the metadata blob; Tokenizer::from_hfq_metadata reads them — the original GGUF need not stay on disk.

Per-tensor selection in the GGUF pipeline:

TensorFormat
1D norm / scaleF16
embedding (token_embd)Q8F16
2D weight, K % 256 == 0chosen --format
2D weight, K not multiple of 256HFQ4-G128 fallback (no rotation)

Supported source GGUF dequant types: Q4_0, Q8_0, Q4_K, Q5_K, Q6_K, F16, BF16, F32. Unsupported (quantizer errors on encounter): Q5_0, Q5_1, and IQ* families.

Quality caveat (GGUF)

GGUF is double quantization: dequant already-lossy weights, then requantize. Expect worse quality than full-precision safetensors of the same model. Prefer HF6/MQ6 if disk allows, or quantize from original safetensors.

CLI flags (hipfire quantize)

FlagPurpose
--format <fmt>Repeatable. Default: mq4 → qt 44 MQ4G256V2 (safetensors); hf4 (GGUF). Thin allowlist only.
--bothShorthand for --format mq4 --format mq6
-o, --output <path>Single-format output path
--output-dir <dir>Multi-format output directory
--stem <name>Override output basename
--upload <owner/repo>Push outputs to HuggingFace
--create-repoCreate HF repo if missing
--installCopy into ~/.hipfire/models/
--register <tag>Local alias for hipfire run <tag>

Build the binary if missing:

cargo build --release -p hipfire-quantize

The CLI searches target/release/hipfire-quantize and ~/.hipfire/bin/hipfire-quantize.

Direct hipfire-quantize (advanced)

Full alias set and product-ladder controls. Common extras:

FlagRole
--input / --outputPaths
--formatFull set: mq4/mq4v2 → qt44; mq4v1/mq4g256/magnum → qt13; mq4c; mq{6,5,3,2}v2; mq3; hf4/hf6; hfp4/mfp4/mfp4e8; Lloyd; tq2/bq1; …
--tier <xt|base|pro>Product rung (Qwen3.8 ladder): xt keeps lm_head at base codec; base lifts embed+lm_head; pro also lifts ssm_out. embed/conv1d stay Q8; structural tensors stay F16. See ladder.md.
--fixed-tier <spec>Per-class codec overrides, e.g. lm_head:mq6v2,ssm_out:mq6v2. Classes: lm_head,embed,router,attn,ssm_out (plus attn_full where applicable). Dtypes: q8,mq2v2,mq3v2,mq4v2,mq5v2,mq6v2 (+ limited legacy). Env: HIPFIRE_FIXED_TIER.
--imatrix <gguf>llama.cpp imatrix for activation-aware recipes
--hessian-dir <dir>GPTQ-E8 Hessians
--awq / --awq-alphaAWQ pre-scale (default alpha 0.55)
--kmap-dense / --kmap-mode / --no-kmap / --uniformK-map promotion policy
--q8-router / --no-q8-conv1dProtect routers / conv1d
--reap-overlay / --reap-bake / --reap-out / --reap-archREAP plan paths
--arch-id / --force-arch-idOverride written arch_id (qwen3* pillar guarded)
--threads / HIPFIRE_QUANT_THREADSCPU thread cap (default ~80% cores)
--include-vision / --vision-quantVision tensors
--allow-mq2 / --allow-mq*-lloydResearch gates (v1 mq2 / Lloyd)

Dense-only gate: mq{2,3,5,6}v2 refuse MoE arch_ids. Use legacy mq{2,3,5,6} or mq4/mq4v2/mq4c for MoE, or a dense checkpoint.

Example — Qwen3.8 product ladder cell (base MQ4V2):

hipfire-quantize --input ./qwen3.8-27b --output qwen3.8-27b.mq4v2.base.hfq \
  --format mq4v2 --tier base
# mq2 pro style fixed-tier (illustrative; MQ2V2 is not a product body):
#   --format mq2v2 --tier pro --fixed-tier lm_head:mq6v2,ssm_out:mq6v2

Vision-tower sidecar (qwen3.8-27b-vision.hfq)

The Qwen3.8-27B vision tower ships as a shared sidecar (llama.cpp mmproj-style) beside the trunk so every text quant tier serves images without requantizing the trunk. Build it from the tower HF dir (needs config.json + the model.visual.* shard, e.g. model-00001-of-00018.safetensors):

hipfire-quantize --input /home/kaden/.hipfire/hf/Qwen3.8-27B-tower \
    --include-vision --include-prefix model.visual. \
    --output ~/.hipfire/models/qwen3.8-27b-vision.hfq
# shorthand for the same two flags:
# hipfire-quantize --input <tower-dir> --vision-only \
#     --output ~/.hipfire/models/qwen3.8-27b-vision.hfq

Pack contract (pinned by cargo test -p hipfire-quantize --lib vision):

  • ONLY the 333 model.visual.* tensors: patch_embed.proj.{weight,bias} (2), pos_embed.weight (1), 12 per block × 27, merger 6.
  • Matrices → F16 (qt=1, 111 tensors); norms/biases/pos_embed → F32 (qt=2, lossless widen — 222 tensors). --format is ignored for vision: should_quantize is false for the whole group, so tower tensors never enter an MQ/HFQ branch. The loader’s load_f16_gpu / load_f32_* arms consume qt=1/qt=2 directly.
  • arch_id 5, has_vision: true, config.vision_config carried from the source config.json (metadata is built before the include-prefix filter runs, so the filter cannot strip the config) plus pixel-budget keys merged from preprocessor_config.json when present.

Census the artifact (CPU-only, no GPU):

cargo build -p hipfire-quantize --example hfq_dump --release
target/release/examples/hfq_dump ~/.hipfire/models/qwen3.8-27b-vision.hfq | head -5
# arch_id   : 5, n_tensors : 333, metadata carries has_vision + config.vision_config
target/release/examples/hfq_dump ~/.hipfire/models/qwen3.8-27b-vision.hfq | grep -c 'qt=1 '
# 111 (F16 matrices)
target/release/examples/hfq_dump ~/.hipfire/models/qwen3.8-27b-vision.hfq | grep -c 'qt=2 '
# 222 (F32 norms/biases/pos_embed)
target/release/examples/hfq_dump ~/.hipfire/models/qwen3.8-27b-vision.hfq \
  | grep 'qt=' | grep -cv 'model\.visual\.'
# 0 tensor rows outside the tower

Graded MoE and E8 recipes are intentionally outside the thin hipfire quantize help surface so accidental low-quality artifacts are harder to produce.

Runtime cost

CPU- and memory-bandwidth bound. Rough desktop wall times (order-of-magnitude, not a guarantee):

Model sizeWall time
~1Btens of seconds
~4B~1 min
~9Ba few minutes
~27Bseveral–tens of minutes

Peak RAM is roughly max(tensor elements) × 4 (one tensor dequantized to f32).

After quantizing: CASK sidecar

For long-context CASK eviction calibration:

hipfire sidecar-gen my-finetune.mq4 --corpus /path/to/corpus.txt
# or via registered tag:
hipfire sidecar-gen finetune:1b --corpus /path/to/corpus.txt

Writes my-finetune.mq4.triattn.bin beside the model by default. The daemon does not attach it by default. Set cask_sidecar to the exact path, or opt into sibling discovery with cask_auto_attach=true. Set cask=true separately only when core-aware m-folding is intended. See CONFIG.md.