C.W.K.
Stream
Lesson 04 of 06 · published

Group-wise & Mixed-Precision Quantization

~14 min · quantization, group-size, mixed-precision

Level 0Curious
0 XP0/51 lessons0/15 achievements
0/100 XP to next level100 XP to go0% complete

Not all weights deserve the same treatment

A transformer model's weights aren't equally sensitive to quantization. Embedding layers, the LM head (the projection back to vocab), and the attention output projections are typically more sensitive than the bulk of the feed-forward MLP weights. Quantizing everything to 4 bits is the simple choice; quantizing the sensitive layers at higher precision while keeping the bulk at 4 bits is the smarter choice — same average bits per weight, less quality loss.

This is what mixed-precision quantization means. mlx-lm exposes pre-baked recipes via the --quant-predicate flag.

The recipes mlx-lm ships

  • mixed_2_6 — most layers at 2-bit, sensitive ones at 6-bit. The most aggressive size reduction; quality loss noticeable.
  • mixed_3_4 — most layers at 3-bit, sensitive ones at 4-bit. Tighter than full Q4, quality usually competitive.
  • mixed_3_6 — most layers at 3-bit, sensitive ones at 6-bit. Aggressive but with stronger headroom on the sensitive layers.
  • mixed_4_6 — most layers at 4-bit (default Q4), sensitive ones bumped to 6-bit. The closest "safer Q4" recipe.

The naming convention is mixed_X_Y where X is the bulk bit-width and Y is the sensitive-layer bit-width. The exact policy for which layers get the higher precision is baked into mlx-lm's predicate registry.

Group size, revisited

Group size (--q-group-size) is orthogonal to mixed precision. Smaller groups (32) give better quality but larger files; larger groups (128) give smaller files at some quality cost. The default 64 is a reasonable middle. For mixed-precision conversions you usually keep group size at 64 and let the bit-width predicate do the differentiation.

When to reach for mixed-precision

  • You're at the memory ceiling and want to fit a slightly bigger model than full Q4 allows. mixed_3_4 or mixed_2_6 can push effective bits down further.
  • You're disappointed with full Q4 quality on a specific task and want to recover some accuracy without going all the way to Q8. mixed_4_6 is the natural step.
  • You're deploying at scale and small per-model size savings compound across many machines.

For a single-user laptop deployment, full Q4 is usually fine. Mixed-precision is the lever you reach for when you have a measured reason — not the default starting point.

Code

Convert with a mixed-precision recipe·bash
# 4-bit base, 6-bit on sensitive layers — the "safer Q4" recipe.
python -m mlx_lm convert \
  --hf-path meta-llama/Llama-3.2-3B-Instruct \
  --mlx-path ./Llama-3.2-3B-Instruct-Mixed-4-6 \
  --quantize \
  --quant-predicate mixed_4_6 \
  --q-group-size 64

# Aggressive size reduction — 3-bit base, 4-bit on sensitive layers.
python -m mlx_lm convert \
  --hf-path meta-llama/Llama-3.2-3B-Instruct \
  --mlx-path ./Llama-3.2-3B-Instruct-Mixed-3-4 \
  --quantize \
  --quant-predicate mixed_3_4 \
  --q-group-size 64
Inspect the quantization config in the resulting model·python
import json, glob, os

# After conversion, the config records exactly how each layer was quantized.
for path in glob.glob("./Llama-3.2-3B-Instruct-Mixed-*"):
    with open(os.path.join(path, "config.json")) as f:
        cfg = json.load(f)
    print(f"--- {path} ---")
    print("group_size :", cfg["quantization"].get("group_size"))
    print("bits       :", cfg["quantization"].get("bits"))
    # Mixed-precision configs have per-layer overrides; check for them.
    qmap = cfg.get("quantization_config") or cfg["quantization"].get("model.layers", {})
    if qmap:
        # Show the first few per-layer overrides if present
        sample = list(qmap.items())[:4] if isinstance(qmap, dict) else []
        print("first per-layer entries:", sample)
    print()

External links

Exercise

Pick a 3B-class model and convert it with three recipes: full Q4 (no --quant-predicate), mixed_4_6, and mixed_3_4. Compare the three resulting directory sizes and run the same prompt through each (greedy sampling). The exercise is to feel where the size/quality trade ends — your gut for which recipe is appropriate for which use case has to come from running the comparison once.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.