[!IMPORTANT]
Superseded by xv0y5ncu/gemma-4-E4B-it-GLQ-trellis-3inst-4bpw.
the trellis (TCQ) codebook has been the recommended format since v0.7 — same bit-rate, faster single-stream decode, and better quality at low bpw.
Derivative quantization work; the base Gemma 4 model and the GLQ tooling
(https://github.com/cnygaard/glq) are both Apache 2.0. Quantizing the weights
does not change the license.
Method
This is an E8 lattice quantization (GLQ) of the original bf16 weights:
Pin transformers below 5.15 — 5.15.0 moved gemma-4 to a per-layer config, so
config.head_dim raises and vLLM dies before loading a single weight. Verified on
5.14.1 with vLLM 0.27.1. Not specific to GLQ: stock bf16 gemma-4 fails the same way.
The custom CUDA kernel JIT-compiles on first use (~30s). Requires
torch>=2.0, transformers>=5.0, CUDA 12.x.
KV cache compression on vLLM (glq v0.3.0+)
Independent of the weight quantization in this repo, glq v0.3.0
ships an opt-in E8-lattice KV cache compressor for vLLM. I measured
it against the unquantized bf16 Gemma-4-E4B-it on a single
RTX PRO 6000 Blackwell, vLLM 0.20.x, --enforce-eager:
Recipe
On-card per group
Cache vs fp16
Quality
e8_relaxed:1
4 bpw (int16 idx + bf16 scale)
4.02×
mmlu_pro 24/40 = 60 % at n=40 (Wilson 95 % CI [45 %, 73 %]) — not validated at usable sample sizes. NIAH passkey at ctx=16k: 9/10 (one digit-flip).
e8_relaxed:2
6 bpw (+ int16 idx2)
~2.67×
mmlu_pro 171/240 = 71.25 % at n=240 — bit-identical to the fp16 baseline (171/240). Output token count also matches to the byte. NIAH passkey at ctx=16 k / 32 k / 64 k / 130 k: 40/40 across the full 128 k context window (10 depth×seed trials at each context).
Combining the two: stacking KV cache compression on top of this
4 bpw weight-quantized checkpoint should work (the hook is
weight-quantization-agnostic) but I have not tested that
combination end-to-end. Use the unquantized base model for the
measured numbers above.
Note on max_new_tokens
Quantized variants use the model's chat template with enable_thinking=True
and may require a larger thinking budget than bf16 to converge to the
final answer. Empirically:
Variant
Recommended max_new_tokens for thinking
8bpw, 7bpw
2048
4bpw, 5bpw mix, 6bpw
8192-16384
Insufficient budget will cause the model to truncate mid-thought and the
final answer may be missing. This is a generation-config concern, not a
quality concern: when given enough budget, all variants converge to
within stderr of bf16 quality on gsm8k.
lm-eval workaround for thinking mode
The lm-evaluation-harness does not currently expose
enable_thinking=True through apply_chat_template. Until upstream
support lands, monkey-patch the tokenizer before evaluating: