A film still of two people in an office, leaning forward to look at something off screen.

LookAtMyQuant

A quantization compiler that delivers 12× lower KL than Q4_K_M at the same file size

Shin Megami Boson

October 2026

Figure 1. Gemma 4 E2B: how far each quantized file is from the original model, against its size. The blue files are made by the compiler from llama.cpp's own quantization types and load in llama.cpp. At every size where a public file exists, they have at least 6 times lower KL divergence. At the size of llama.cpp Q4_K_M, the KL is 12 times lower. KL is averaged over held-out text in 13 languages and domains; log scale.

Abstract

Quantized language models are usually made by one recipe for every tensor: one format, one bit width and a few hand-written exceptions. LookAtMyQuant is a quantization compiler. It measures how much each stored piece of a model hurts the whole model when that piece alone is compressed. The pieces are every weight matrix, buckets of embedding rows grouped by token frequency, and each layer's key–value cache. It measures a few codes for each piece and predicts the rest. Then it gives each piece the code that keeps total damage lowest while the model fits the size or speed budget of a target device.

The programs it chooses from are written in a grammar of tensor-network rewrites. Nine published quantization and pruning methods are short programs in this grammar, reproduced exactly.

On Gemma 4 E2B, the compiler restricted to llama.cpp's types makes ordinary GGUF files. At the size of llama.cpp's Q4_K_M, the compiled file has 12 times lower KL divergence from the original model, and it solves 59% of GSM8K problems against 50% for Q4_K_M and 61% for the original. Most of the gain comes from a choice a fixed recipe does not make. Gemma's 2.35-billion-weight per-layer lookup table is cheap to compress, so the compiler stores it at 4.25 bits instead of 6.56 and gives the saved bytes to the matrices. On Qwen3.5-4B and SmolLM2-360M, compared with 3-bit models that keep the embedding or the cache at 16 bits, the compiler's plans have 6 to 81 times lower KL at equal cost on each target device.

Every piece of a model costs something different to compress

A quantization format applies one rule to a whole model. GGUF's Q4_K_M, for example, stores most matrices at about 4.5 bits per weight and a fixed list of tensors at Q6_K. The rule is the same for a 360-million-parameter model and a 70-billion-parameter one, for a model with a large vocabulary and one with a small one, and for a phone and a server.

But the damage each piece does to the model is not uniform. In Gemma 4 E2B, one 0.4-million-weight matrix costs nearly as much at 3 bits as twenty whole layers. Half of the model's weights are a lookup table that tolerates 4 bits well. The 256 most frequent tokens make up a third of all text, while the rarest half of the vocabulary makes up a fraction of a percent. A fixed recipe cannot see any of this.

LookAtMyQuant treats quantization as compilation. A plan names one program for every stored piece of the model. The compiler finds the plan that does the least damage for a given budget on a given device. We make four contributions:

A compiled Gemma 4 E2B file has 12 times lower KL than Q4_K_M at the same size

We compared the compiler's files with every widely used quantization of Gemma 4 E2B that we could load. These are Google's quantization-aware-trained q4_0 GGUF, unsloth's UD-Q4_K_XL, bartowski's Q4_K_M and LM Studio's MLX 4-bit. We also built llama.cpp's stock recipes, Q2_K to Q8_0, with an importance matrix from the same calibration text the compiler uses.

Every file is turned back into full-precision weights inside the same Hugging Face model, so the same code scores every file on the same text. The text is 64 windows of WikiText-2 and 8 held-out windows from each of 13 sources: English, ten other languages, code and chat. Each window has 512 tokens and starts with the beginning-of-sequence token. KL divergence measures how far a file's next-token predictions are from the original model's; lower is closer. Sizes count the bytes of the text model's weights, for every file.

Table 1. Each compiled GGUF against the public files within 0.06 GB of its size. Google's QAT file is left out here because Google trained it further after quantizing, so its KL includes that training; Table 2 compares it on benchmarks.

Compiled GGUFKLPublic fileSize (GB)KLKL ratio

The gap holds on every one of the 13 sources and on WikiText-2, which is not part of the calibration text. On WikiText-2 the 3.39 GB compiled file has a KL of 0.008, and Q4_K_M has 0.143.

Benchmarks agree. Multiple-choice tasks barely separate the files. Except for Q2_K and Google's QAT file, every file is within about two points of the original on MMLU, ARC-Challenge and HellaSwag. Multi-step math separates them (Figure 2). Public 4-bit files lose up to 27 points on GSM8K, and compiled files at most 6. With 250 problems, each GSM8K figure is uncertain by about ±6 points.

Figure 2. Share of 250 GSM8K problems solved, with five worked examples and greedy decoding. Whiskers are 95% intervals. The dashed line is the original model.

Most of the gain comes from the per-layer lookup table

Gemma 4 E2B feeds each of its 35 layers a 256-wide vector looked up by token. Together these vectors form a table of 262,144 rows by 8,960 columns: 2.35 billion of the model's 4.63 billion text weights. The table is never multiplied, only read one row per token. The compiler measured it as cheap to compress: per weight, it costs less than a tenth as much as the least sensitive matrices.

llama.cpp's Q4_K_M recipe stores this table at Q6_K, 6.56 bits per weight. That is 1.93 GB, 56% of the file. The compiler, choosing among the same llama.cpp types, stores it at IQ4_XS, 4.25 bits, and gives the 0.68 GB it saves to the matrices, most of which it stores at Q8_0 or BF16 (Figure 3). Figure 4 replays the compiled file one piece at a time.

Weight matrices Embedding table Per-layer lookup table Kept at 16 bits
Figure 3. Where three files of about 3.4 GB spend their bytes. Labels give bits per weight. The compiled GGUF uses only llama.cpp types. With its own codes, the compiler moves even more bytes from the per-layer table to the matrices.

Figure 4. The compiled 3.39 GB GGUF, built piece by piece from the 16-bit model. The whole model is drawn as one tensor network. Each square is a stored piece, with area proportional to its number of weights. The 35 layers sit on the residual stream, with attention matrices above it and MLP matrices below. The per-layer lookup table along the bottom feeds each layer one slice. Layers 15 to 34 have no key or value matrices, because they reuse those of layers 13 and 14. Colour shows the llama.cpp type the plan gives the piece, and grey pieces stay at 16 bits. The compiler finds the whole plan at once. The animation applies its choices one piece at a time, those that save the most bytes per unit of KL first. The chart below tracks the file's size and predicted KL as pieces change.

With its own codes, the compiler beats every public file under 3.5 GB at only 2 GB

The compiler's native menu has trellis codes and Lloyd–Max codes, described below, which have no inference kernel yet. With them, its 2.00 GB plan has a KL of 0.074, lower than every public file under 3.5 GB, and solves 60.4% of GSM8K problems. At 3.41 GB its KL is 0.0057. These plans show what the allocation can reach once such codes run.

Table 2. Every Gemma 4 E2B file we measured. KL on the 13-source text mix and on WikiText-2; accuracy on MMLU (1,000 sampled questions, zero-shot), ARC-Challenge (all 1,172), HellaSwag (1,000 sampled) and GSM8K (the first 250, five-shot).

FileSize (GB)Bits / weightKL, text mixKL, WikiTextMMLUARC-CHellaSwagGSM8K

On Qwen3.5-4B, the embedding table is the largest lever

Qwen3.5-4B ties a 248,320-row embedding table to its output head. At 16 bits the table takes about as many bytes as all the matrices at 3 bits. At the same size as a model with 3-bit matrices and a 16-bit embedding, the compiler's plan stores the embedding at 3.1 bits on average and the matrices at 5.35. Perplexity rises 0.13% instead of 4.9%, with 12 times less KL (Table 3).

The plan gives the 256 most frequent rows 16 bits, the next 8,000 rows 8 bits, and the rarest 117,000 rows 2 bits. Rare rows are cheap. The 183,000 rows whose tokens never appear in WikiText's training split cost 0.0007 KL in total when all of them are stored at 2 bits.

Table 3. Qwen3.5-4B, 64 WikiText-2 test windows of 512 tokens. Original perplexity 12.283. Each compiler plan costs the same as the uniform plan named in the second column.

PlanSame cost asMatrix bitsEmbedding bitsCache bitsPerplexityKL
1. Uniform 3-bit trellis, 16-bit embedding–3.0616–12.8840.0614
2. Compiler, widths for the matrices onlyPlan 1, in file size3.0516–12.8480.0592
3. Compiler, matrices and embeddingPlan 1, in file size5.353.10–12.2990.0050
4. Uniform 3-bit trellis, 3-bit embedding–3.063.04–13.0080.0735
5. Compiler, matrices and embeddingPlan 4, in file size3.172.41–12.8010.0542
6. Compiler for a laptop with a 32,768-token contextPlan 1 with a 16-bit cache, in bits read per token6.624.236.1912.2980.0015

Each device gets its own plan

What a code costs depends on the device. On disk, only stored bits count. On a laptop generating one sequence, the weights and the key–value cache are both read for every token, so cache bits count too. On a server running 32 sequences, one read of the weights serves all of them, so weights become cheap and the cache dominates. On a device limited by compute, decode work counts. For SmolLM2-360M the compiler makes a different plan for each (Table 4). The server plan stores matrices at 7.4 bits because 32 sequences share each read, and the compute-limited plan avoids trellis codes, which take more work to decode.

Table 4. SmolLM2-360M. Each compiler plan costs the same as its reference plan on that device. Cells are WikiText-2 perplexity / KL; the laptop, server and NPU rows use windows of 2,048 tokens.

DeviceReference planReferenceCompilerWhat the compiler changed
Disk3-bit trellis matrices, 16-bit embedding16.72 / 0.095915.48 / 0.0128Embedding from 16 to 4.8 bits; matrices from 3.0 to 4.7 bits
Disk3-bit trellis matrices and embedding17.40 / 0.137616.81 / 0.1068Embedding rows by frequency, 8 bits for the most frequent to 2 bits for the rarest
Laptop: one sequence, 2,048-token context3-bit trellis, 16-bit embedding and cache12.25 / 0.097911.22 / 0.0050Cache keys 8 bits, values 5–6; matrices 5.8 bits; embedding 5.6 bits
Server: 32 sequences, 16,384-token context3-bit trellis, 16-bit embedding, 4-bit cache12.70 / 0.132311.44 / 0.0216Matrices 7.4 bits; cache keys 4–5 bits, values 3
Compute-limited device3-bit trellis, 16-bit embedding and cache12.25 / 0.097911.20 / 0.0012Lloyd–Max codes at 6–8 bits instead of trellis codes; cache at 6–8 bits

Choosing a bit width per matrix, and nothing else, lowers KL by only 3 to 5%

The large gains come from pieces that uniform formats leave at 16 bits or treat as one block: the embedding table, the per-layer table and the cache. On top of a strong base quantizer, choosing a width per matrix helps little. On SmolLM2-360M, at the same average bits as the uniform 3-bit and 4-bit programs, per-matrix widths lower KL by 3% and 5% (Table 5). Which layer a matrix is in matters more than what kind of matrix it is. Keeping the widths chosen for each kind of matrix but assigning them to random layers gives 21% more KL than the uniform program.

Table 5. SmolLM2-360M, matrices only; embedding and cache at 16 bits. Original perplexity 15.31. Cells are perplexity (KL).

Bits per weightUniform trellisCompilerSame widths, shuffled across layers
2.0523.46 (0.439)––
2.25–20.50 (0.308)–
2.50–18.63 (0.213)19.82 (0.267)
3.0416.72 (0.0959)16.64 (0.0926)16.98 (0.1163)
3.50–15.95 (0.0484)–
4.0415.64 (0.0237)15.61 (0.0226)–

Quantization methods are short programs in a grammar of rewrites

LookAtMyQuant writes a model as a tensor network. Each weight matrix is a node with named indices, and nodes that share an index are joined. A quantization method is a sequence of rewrites of this network, built from five kinds of word, named after parts of speech. Figure 5 shows one layer's MLP in this form.

Nine published methods are short programs in this grammar, each reproduced exactly, layer by layer, against its reference code: RTN, GPTQ, AWQ, SVD, SVD-LLM, SliceGPT, magnitude pruning, Wanda and SparseGPT. The same words also build MXFP4, NVFP4, QuIP#-style codebooks and QTIP-style trellis codes. Figure 6 steps through the program the compiler uses most, and Figure 7 shows the rewrites behind five published methods.

Figure 5. The MLP of one Gemma 4 E2B layer as a tensor network. Each weight matrix is a node. Each index it shares with another node is a line, labelled with its size. The gate and up matrices read the same index, so their lines meet at one junction, and the compiler quantizes them together.
16-bit values added by an exact step restricted to a code data a control step fits to

Figure 6. What each step of the program tr3x, a 3-bit trellis code with the cross term, does to one matrix's network. Pick a step. Exact steps add nodes without changing the product; only the lossy step changes what the network computes. Replacing the trellis with 64 Lloyd–Max levels, with a sweep one column wide, gives lm6x.
Figure 7. Five published methods as rewrites of the same matrix, x → W → y. Each drawing shows the network after the method's rewrites.

Table 6. The compiler's menu for a weight matrix. Bits are for a matrix 1,536 columns wide. The last column is the median, over 32 Gemma 4 E2B matrices measured with every program, of KL divided by the 3-bit trellis's KL.

ProgramLossy stepBits per weightKL relative to the 3-bit trellis

The compiler measures what each piece costs, then picks the combination with the least damage

PiecesEvery weight matrix; the embedding and per-layer tables cut into buckets of rows by token frequency; each layer's key–value cache.
MeasureCompress one piece, run the model on held-out text, and record the KL divergence from the original model.
PredictEstimate the codes that were not measured from one cheap probe per matrix and the ratios between codes.
PriceCount what each code costs on the device: stored bits, bits read per token, cache bits per token of context and decode work.
AllocateChoose one code per piece so that total KL is lowest and the total cost fits the budget.
RunQuantize in order with each piece's program and the cross term, then evaluate on the test split.
Figure 8. The compiler. The measurement is done once per model; each device or budget then needs only a new allocation, which takes seconds.

Pieces

The compiler finds the pieces by running the model once. Linear layers that read the same tensor form one stage and are quantized together. Embedding tables are cut into 11 buckets of rows ranked by how often their token appears in the calibration text: 256, 256, 512 and so on, doubling up to 131,072 rows. A tied table is read two ways, as the output head at every position and as a lookup of one row, so its error is weighted by the head's inputs plus the identity. A table that is only looked up is weighted by the identity alone. Small linear layers, routers and normalization weights stay at 16 bits, and their bytes are counted.

Figure 9. The embedding table is one node with a token index t and a hidden index d. split_index cuts t into 11 ranges by how often each token appears, and each range becomes its own node with its own program, shown here for the 2.00 GB plan. A lookup reads one row of one node; the output head reads all of them.

Measure

For each piece and option, the compiler quantizes that piece alone and measures the KL divergence of the model's next-token distribution from the original's, on 16 held-out windows of 512 tokens. The windows come from the calibration split, never the test split. On SmolLM2-360M we measured all 2,312 piece-option pairs this way.

For larger models, each matrix gets one cheap probe instead. The probe adds noise shaped like the error that LDLQ leaves behind: Gaussian noise multiplied by the square root of LDLQ's error variances and by the inverse of the triangular factor of H, at a fixed level. This takes one forward pass and no code search. A few layers, which we call spot layers, are measured with every real code. On Gemma 4 E2B, the 275 matrices got a probe each, four layers and all 22 table buckets got real codes, and measuring took about one H100-hour.

Predict

An option that was not measured is predicted from the probe and the code ratios:

KLi(c) = rprobe · KLi(probe) · ρ(c),   where ρ(c) = median over spot matrices of KL(c) / KL(tr3)

Here rprobe is the median ratio of real 3-bit KL to probe KL on the spot layers. Both ratios turn out to be properties of the codes rather than of the model (Figures 10 and 11).

Price

A code's cost on a device comes from three numbers: the bits it stores, the cache bits it adds per token of context, and the operations needed to decode it.

cost = stored bits / batch + decode operations · c / batch + context · cache bits

Here batch is the number of sequences generated together, context is the number of tokens in the cache, and c is the price of one decode operation in bits.

On disk, only stored bits count. The laptop setting generates one sequence with a 2,048-token context. The server setting generates 32 sequences with 16,384 tokens each. The compute-limited setting charges 2 bits per decode operation.

Allocate

The compiler chooses one code oi for every piece i to

minimize Σi KLi(oi)   subject to   Σi pricei(oi) ≤ B

Dynamic programming solves this in seconds, with the budget divided into 100,000 steps and each cost rounded up to a whole step. Adding up each piece's KL assumes that damage adds up; we test this below.

Run

The model is quantized layer by layer with each piece's program, on 64 calibration windows from a separate split of the same text. Each matrix is fitted with the cross term, so it targets the original model's output given the already-quantized inputs. For llama.cpp, the same plan becomes one --tensor-type override per tensor in llama-quantize, and we check that every tensor in the output file has the planned type.

For files that run today, the menu is llama.cpp's own types

The types are Q2_K, Q3_K, IQ4_XS, Q4_K, Q5_K, Q6_K, Q8_0 and BF16. Each of Gemma 4 E2B's 278 tensors is measured alone in each type, inside real llama.cpp files, with the same KL measurement. The compiler then picks one type per tensor in the same way.

Analysis

One noisy forward pass predicts a matrix's 3-bit damage

Across 224 matrices of SmolLM2-360M and 211 of Qwen3.5-4B, the KL of the real 3-bit trellis code is 1.33 times the probe's KL, with a log-scale correlation of 0.99 on both models. Eighty percent of matrices fall between 1.22 and 1.59 times. On the 32 Gemma 4 E2B matrices measured with real codes, the median ratio is 1.35 with a wider spread (Figure 10).

Figure 10. Each point is one matrix: its KL with the noise probe (across) and with the real 3-bit trellis code (up), both log scale. The dashed line is 1.33 times the probe.

Ratios between codes are the same on every model tested

Each bit removed multiplies a matrix's KL by about four, as Gaussian rate–distortion theory predicts. The ratio of each code's KL to the 3-bit trellis's KL is nearly the same on SmolLM2-360M, Qwen3.5-4B and Gemma 4 E2B (Figure 11). So the spot layers of a new model mostly confirm ratios already known. On SmolLM2, a plan chosen from three measured layers plus predictions is as good as a plan chosen from every measurement: 0.01333 summed KL against 0.0133.

Figure 11. Median KL of each code divided by the median KL of the 3-bit trellis, over matrices measured with every code, on three models; log scale.

Damage adds up, except where it is smallest

The compiler assumes that the KL of a plan is the sum of its pieces' KL. Measured KL is within 18% of the sum for every compiled plan on SmolLM2 and Qwen3.5 and for every Gemma GGUF plan (Figure 12). Uniform plans measure 10–14% below the sum, because the cross term repairs them better than predicted. Gemma plans with the compiler's own codes measure 36% to 93% above the sum from 2.5 GB up, where each piece's KL is smallest. Searching around the compiler's plan with real evaluations, as EvoPress does, would target this gap.

Figure 12. Predicted KL (the sum over pieces) against measured KL for every compiled plan we evaluated, log scales. The diagonal is perfect prediction; the band is ±20%.

In Gemma 4 E2B, a few pieces carry most of the sensitivity

Layers 15 to 34 reuse the keys and values that layers 13 and 14 compute, and have no key or value projections of their own. They cost less than half as much per layer (Figure 13). One matrix, layer 13's per-layer projection, costs 0.106 KL at 3 bits, nearly as much as all twenty later layers together. Every plan keeps it at 16 bits.

Per weight, key and value projections cost 15 to 19 times as much as query projections. In both tables, KL per row falls 2,000 to 5,000 times from the most frequent bucket to the rarest, so the compiler gives frequent rows 8 or 16 bits, and the rarest half of the per-layer table gets 2 bits in every plan.

Figure 13. Predicted KL of each layer's matrices at the 3-bit trellis, Gemma 4 E2B. The shaded layers reuse earlier keys and values. Layer 13's bar is cut off at 0.03; its value is 0.124.

Two exact rewrites did not help

Exact rewrites are free moves for a search: they change how the network is written without changing its output, so they can make it easier to quantize. We tried two on SmolLM2-360M.

On top of incoherence processing, these rewrites have nothing left to fix. The exact rewrites worth searching are those the code does not already perform.

Limitations

Further work

Every plan here is post-training quantization, and the Gemma plans are priced by file size. Each step below either improves quality or prices a resource that file size misses.

Bits per layer. HIGGS [1] proves that perplexity increase is linear in each layer's error and allocates widths by dynamic programming; our measurements agree, matrix by matrix. ExLlamaV2's EXL2 format [2] measures each module at about a dozen settings and optimizes to a target bits per weight. NVIDIA ModelOpt's auto_quantize [3] searches a format per layer under an effective-bits budget. EvoPress [4] searches with real model evaluations because summed per-layer errors can rank configurations wrongly, and AMQ [5] uses a learned quality predictor. HAWQ-V3 [6] solves an integer program under memory, latency and bit-operation budgets for convolutional networks, the closest prior version of per-device pricing.

Cache and embeddings. KVTuner [7] searches per-layer key and value widths and also finds keys more sensitive than values; PM-KVQ [8] allocates cache precision under a memory budget. Recommendation models quantize embedding rows by feature frequency [9]. We found no peer-reviewed work that does this for language-model vocabularies.

Codes and rewrites. GPTQ [10], QuIP# [11] and QTIP [12] supply the base quantizers: error-compensating sweeps, incoherence processing and trellis codes. Learned rotations such as SpinQuant and FlatQuant, and graph-rewrite systems such as TASO and Tensat, search exact rewrites, the latter for speed rather than quantization.

What is new here. One allocation across matrices, frequency buckets of the embedding and per-layer tables, and the cache, with prices that depend on the device; a menu that mixes code families; plans run with cross-term targets so later matrices absorb earlier error; and compiled files in a standard format, compared with public files on one protocol.

References

  1. HIGGS. Malinovskii et al., Pushing the Limits of Large Language Model Quantization via the Linearity Theorem. NAACL 2025. arXiv:2411.17525
  2. EXL2. turboderp, ExLlamaV2. github.com/turboderp-org/exllamav2
  3. ModelOpt. NVIDIA Model Optimizer, auto_quantize. Documentation
  4. EvoPress. Sieberling et al., evolutionary search for dynamic model compression. ICML 2025. arXiv:2410.14649
  5. AMQ. AutoML search over per-layer bit widths with a quality predictor. EMNLP 2025. ACL Anthology
  6. HAWQ-V3. Yao et al., HAWQ-V3: Dyadic Neural Network Quantization. ICML 2021. PMLR
  7. KVTuner. Li et al., layer-wise mixed-precision key–value cache quantization. ICML 2025. PMLR
  8. PM-KVQ. Key–value cache precision allocated under a memory budget. arXiv:2505.18610
  9. Mixed-precision embeddings. Embedding precision chosen per feature-frequency group in recommendation models. arXiv:2409.20305
  10. GPTQ. Frantar et al., GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers. ICLR 2023. arXiv:2210.17323
  11. QuIP#. Tseng et al., QuIP#: Even Better LLM Quantization with Hadamard Incoherence and Lattice Codebooks. ICML 2024. arXiv:2402.04396
  12. QTIP. Tseng et al., QTIP: Quantization with Trellises and Incoherence Processing. NeurIPS 2024. arXiv:2406.11235

Citation

@misc{boson2026lookatmyquant,
  title  = {LookAtMyQuant: A Quantization Compiler},
  author = {{Shin Megami Boson}},
  year   = {2026},
  month  = oct
}