The format's names return nothing
GitHub code search: escha_code, zero results. escha_rout,
zero results. eschamoe returns OCR noise in scanned Latin texts, plus
one substantive hit.
Escha-W2 / Apple M4 / updated August 4-5, 2026
EschaLabs' Escha-W2 is a 2-bit quantized build of Qwen3.6-35B-A3B that shipped CUDA-only.
Higgs runs it on Apple Silicon — format decoded from the tensors, codebook in a Metal
kernel, experts left in trellis form instead of expanded. A 35B MoE packed in 11GB that serves from a
4 year old laptop at 29 tok/s.
01 / What is actually new
We know of no other implementation that reads the Escha-W2 tensor format on
MLX. Not a claim to have invented EXL3 — exllamav3 is the reference and the source of the
method. A claim about portability: the published build is CUDA sm_80–120, this one runs
the same weights on Metal. If we missed one, open an issue and we will correct it.
GitHub code search: escha_code, zero results. escha_rout,
zero results. eschamoe returns OCR noise in scanned Latin texts, plus
one substantive hit.
That hit is pestopoppa/epyc-root, dated 2026-08-03:
“The eschamoe format itself is unusable here. It is closed CUDA
sm_80-120 with no ROCm path.” It logs a third-party codebook probe as blocked,
“2–4 weeks.”
EschaLabs are releasing their own MLX runtime within days. This is a timestamp, not a flag in the ground — and the durable parts of this page are the format spec and the norm-offset trap, which apply to any implementation, theirs included.
02 / The contribution
Derived from the tensors, verified against the unquantized base model, and not documented publicly anywhere else.
escha_code I16 [E, in/16, out/16, 16*K] packed trellis codes
escha_rin F16 [E, in] per-input-channel scale
escha_rout F16 [E, out] per-output-channel scale
escha_s_in F32 [E, in] all 1.0 in this release
escha_s_out F32 [E, out] all 1.0 in this release
escha_config I32 [9] = [tile=16, K, bits, mcg_flag, num_experts, in, out, in_p, out_p]
Reconstruction puts the scales outside the Hadamard, which is what makes the kernel cheap — H is symmetric orthonormal, so the transform lands on activations and never on weights:
W[out, in] = (H128 · Ŵ · H128 * rin[:,None] * rout[None,:]).T
su = rin*s_in ; sv = rout*s_out
xh = had_blockwise(x * su, -1)
y_pre = xh @ Ŵ # trellis matvec, no Hadamard, no scales
y = had_blockwise(y_pre, -1) * sv
Codebook 1 decode, three instructions:
x = code * 0xCBAC1FED
x = (x & 0x8FFF8FFF) ^ 0x3B603B60
v = f16(x.lo) + f16(x.hi)
A 16×16 tile is 256 codes packed into 16*K int16 words. Code i is
the 16-bit window at bit offset i*K, circular — tail-biting,
so adjacent codes share 16-K bits. Tile elements sit in a tensor-core
permutation, not row-major. The closed-form inverse, for output column c and
lane pair (q, rh):
t = 4*(4*(c&7) + q) + 2*((c>>3)&1) + rh
r = 8*rh + 2*q + {0,1}
e = r & 1
|rin| is not a scaled sign vector — it holds hundreds of
distinct magnitudes, so the Hadamard block size cannot be recovered from it. And the
codebook constants cannot be MLX template arguments: MLX bakes template ints into the
MSL function identifier, and a high-bit u32 prints negative, producing invalid MSL.
Pass them as a kernel input.
03 / Is the decode right
Cosine similarity against the unquantized base is a weak test — it tells you the numbers
are close, not that the decode is correct. The stronger test is the Shannon bound. For a
Gaussian source at rate R, relative Frobenius error cannot beat 2^-R. The
Hadamard transform Gaussianizes the weights, and trellis coding then approaches that
limit. A decode with a subtle systematic error cannot land within a few percent of the
Shannon limit at precisely the rate the container stores.
| Tensor | Rate | R(D) bound | Measured |
|---|---|---|---|
| L0 gate_up | 2.00 bpw | 0.2500 | 0.2422 |
| L39 gate_up | 2.00 bpw | 0.2500 | 0.2920 |
| L20 e7 gate_up | 2.00 bpw | 0.2500 | 0.2917 |
| L0 down_proj | 3.00 bpw | 0.1250 | 0.0824 |
| L39 down_proj | 3.00 bpw | 0.1250 | 0.1390 |
Note the rate is not uniform despite the W2 name:
gate_up_proj is K=2, down_proj is K=3. That alone explains the
0.945–0.990 cosine “band” an earlier pass saw as one population — it is two, each
sitting at its own bound.
The 4-bit row is a calibration reference, not a peer — it costs twice the bits. Against every genuine 2-bit competitor our decode wins by a wide margin, and lands three-quarters of the way to 4-bit while storing 2 bits.
cosine == sqrt(1 - rel²) holds to four decimals — 0.9702/0.9702,
0.9903/0.9903. That identity is true only when the residual is orthogonal to the
reconstruction, the MMSE condition. Naive RTN absmax fails it (0.8368 vs
0.7979) because its level grid is biased. A wrong permutation, wrong Hadamard, or
misordered scale would inject signal-correlated error and break it.
Per-channel and mod-16 / mod-128 periodicity were tested against a 200-draw permutation null. Not one observed ratio is significant at p<0.05, on either axis, either stride. Most sit below the null median. No structure means no geometry bug hiding under the average.
Metal tile decode vs the CPU reference: bit-identical, max diff 0, for K ∈ {2,3,4}. The gather matvec agrees with CPU at 2.1e-7 relative on synthetic input and 3.7e-7 on real weights.
04 / What it costs to run
Keeping the experts in trellis form is not only smaller — it is the difference between fitting and not fitting. On a 32 GB machine the expanded path drives the system into swap; the native path leaves room for KV cache.
22.7× faster to start, because nothing is decoded on the CPU at load. The trellis codes go to the GPU as they are.
| Context | Prompt tok | TTFT | Prefill tok/s | Decode tok/s |
|---|---|---|---|---|
| 1k | 1024 | 5.34 s | 190.6 | 29.3 |
| 4k | 4096 | 21.68 s | 188.4 | 27.5 |
| 8k | 8192 | 46.27 s | 177.4 | 26.1 |
Mean of four runs with low-power mode off — two on battery, two on wall power. Prefill holds within 7% from 1k to 8k and decode within 11%: this model is hybrid attention, so only 10 of its 40 layers grow KV with context.
| Condition | 1k | 4k | 8k |
|---|---|---|---|
| low-power mode ON, battery | 22.5 | 21.1 | 15.1 |
| LPM off, battery (n=2) | 28.9 | 26.9 | 26.0 |
| LPM off, wall power (n=2) | 29.7 | 28.1 | 26.3 |
| AC vs battery | +2.6% | +4.8% | +1.0% |
Wall power buys nothing measurable. With low-power mode off, AC and battery differ by −1.2% to +4.8% — inside run-to-run noise. Low-power mode is the whole story, worth +34–40% prefill.
The top row also carries a fix, not just a power setting: the old harness warmed with 256 tokens, which routes to a handful of 256 experts, so later runs were still paging weights in. That alone was worth 73% at 8k. Warm an MoE wide.
05 / The part that took the longest
The kernel was bit-exact and the decode sat on the Shannon bound, and the model still
emitted pure token salad. The cause was not in the trellis at all: escha stores RMSNorm
weights centred on zero, as w - 1. Passing them through
untouched left every norm scaling by ≈0 instead of ≈1.
tensor escha base |e-b| |e+1-b|
layers.0.input_layernorm 0.031 1.031 1.004 0.004
layers.3.self_attn.q_norm 0.325 1.325 1.004 0.004
final model.norm 1.628 2.628 1.008 0.008
layers.0.linear_attn.norm 0.884 0.884 0.000 1.000 <-- exception
101 tensors carry the offset; the 30 linear_attn.norm tensors — the gated
norm inside the GDN block — do not. The residual after adding 1 back is pure bf16
rounding. Effect on the first token of "1 2 3 4 5 6 7 8":
| before | after | |
|---|---|---|
| top-1 token | getti | 9 |
| top-1 logprob | −7.379 | −0.0047 |
| top-1 probability | 0.06% | 99.5% |
| top-5 spread | 0.12 nats (flat) | 7.0 nats |
Uniform over the 248,320-token vocabulary would be −12.42, so the broken model was barely above noise. The lesson is cheap to state and was expensive to learn: coherent generated text should be the first gate, not the last. Tensor cosine and bit-identical kernels both passed while the model was unusable.
06 / Run it yourself
Apple M4, 10 GPU cores, 32 GB unified memory, macOS 27.0, Xcode 26.0.1, higgs 1.6.0. The
work lives on the nightly
branch — Homebrew and crates.io track upstream, so build from source. The native trellis
path is the default; no flag is needed.
git clone -b nightly https://github.com/dusterbloom/higgs
cd higgs && cargo build --release -p higgs
# add the checkpoint to ~/.config/higgs/config.toml, then:
./target/release/higgs serve
curl -s http://127.0.0.1:9000/v1/completions \
-H 'Content-Type: application/json' -H 'Authorization: Bearer higgs' \
-d '{"model":"escha-35b-a3b","prompt":"1 2 3 4 5 6 7 8",
"max_tokens":8,"temperature":0,"logprobs":true,"top_logprobs":3}'
HIGGS_ESCHA_NATIVE=0 selects the expanded affine path for comparison.
higgs doctor reports the resident estimate for whichever mode is active,
reading the per-projection trellis rate from quantization_config.layer_meta.
The fidelity numbers come from tools/escha_forensics.py; the throughput
table from a TTFT/inter-token harness over /v1/completions with unique
random prompts so the prefix cache cannot serve them.
Two traps if you benchmark an MoE this way. Warm up with enough tokens to route to most experts — 256 tokens touches a handful of 256, and every later run is then still paging weights in. And reject runs that hit EOS early: a 13-token generation measures decode over twelve intervals and is not comparable to a 128-token one. Both corrupted our first published numbers.
07 / Scope
No task benchmarks — no HumanEval, no MBPP, no agentic eval. For model quality see EschaLabs' own published results.
One checkpoint, one batch size, an M4 with 32 GB. Sustained multi-hour load was not tested.
At 21.7 GB resident on a 32 GB machine it swaps, so its throughput would measure the swap, not the kernel.
Layers {0,1,3,20,39} × experts {0,7}, consistent in every cell measured.