Converting a finetuned cactus-compute/needle checkpoint with cactus convert --bits 4 produces a
bundle that loads and serves but emits repeating token garbage for every prompt. The stock Needle
checkpoint converts and serves coherently through the exact same path. I've isolated the fault to the CQ
quantization core (not rounding tolerance, not the remap, not the toolchain, not the fusion passes).
The weights are healthy: they survive naive per-group int4 round-trip at ~0.90 task accuracy and run at
0.938 accuracy at full precision. Only Cactus's CQ4 conversion breaks them.
Environment
cactus 2.0.1 — the current latest (Homebrew cactus-compute/cactus stable 2.0.1; GitHub latest
release v2.0.1, 2026-07-09; PyPI cactus-compute 2.0.1). macOS (Apple Silicon), --backend cpu.
- Base model:
cactus-compute/needle (26M encoder-decoder tool-caller), finetuned locally via
needle finetune (JAX/Flax)
- Convert env:
pip install cactus-compute (torch 2.13, transformers 5.5)
Note: pip install cactus grabs an unrelated static-site-generator package (currently 3.3.x) — the
engine is cactus-compute on PyPI / the Homebrew cactus-compute/cactus tap. Verified this repro is on
the newest engine release (2.0.1).
Reproduction
- Finetune the stock Needle on any small tool-calling set (mine: a 165-example single-tool routing set,
20 epochs, lr=3e-5 — the default finetune_local LR).
- Export the finetuned JAX
.pkl → HF NeedleForCausalLM safetensors (my remap validates 228/228
tensors against the stock HF reference, transpose orientation unambiguous).
cactus convert <finetuned-hf> <out> --bits 4 → clean bundle (114 converted / 114 fallback).
cactus serve <out> --port 8085 --backend cpu
Then:
# plain prompt
curl -s localhost:8085/v1/chat/completions -d '{"model":"<bundle>","messages":[{"role":"user","content":"What is the capital of France? Answer in one word."}],"max_tokens":24}'
# -> content: "virtualvirtualvirtualvirtual..." (finetuned)
# -> content: "" (stock needle-cq4, coherent null — Needle is a tool-caller)
# routing/tool prompt
# finetuned -> "extendedextendeddishdishstrenuous..."
# stock -> well-formed tool call
What I ruled out (isolation)
| Hypothesis |
Test |
Result |
| 4-bit rounding is too lossy for these weights |
naive per-group int4 (group=64) round-trip, re-eval |
survives — 0.896 route acc |
| The finetuned weights are broken |
full-precision (JAX) eval |
fine — 0.938 route acc |
| Remap / HF export is wrong |
validate every tensor vs stock HF ref |
228/228 within tol |
| Toolchain / engine build |
convert stock through same venv+engine |
coherent output |
| Fusion passes |
reconvert with --no-fuse-rms-norm --no-fuse-rope --no-fuse-attention --no-fuse-attention-block --no-fuse-add-clipped |
same garbage |
The decisive signal: survives naive int4 but garbles under CQ4 ⟹ the fault is CQ-specific
(the Hessian/rotation-codebook calibration — each bundle carries hessian_metadata.json), and it appears
to only be robust for the stock weight distribution. I also swept earlier finetune epochs (less drift from
stock); the least-drifted checkpoint that still learned the task survives naive int4 better than the
fully-trained one, yet still garbles under CQ4 — so it's not simply "how far the finetune drifted."
Questions for maintainers
- Is converting a finetuned Needle to native CQ4 supported today, or is CQ calibration effectively
pinned to the released stock checkpoint?
- Can
convert accept calibration data (or a calibration-free / higher-bit path) so finetuned
encoder-decoder models can be quantized robustly?
- Is there a recommended path to serve a finetuned Needle natively (vs. running the JAX checkpoint
full-precision behind a shim)?
Happy to share the exact repro artifacts (finetuned HF checkpoint, the int4-proxy screen, before/after
serve transcripts).
Converting a finetuned
cactus-compute/needlecheckpoint withcactus convert --bits 4produces abundle that loads and serves but emits repeating token garbage for every prompt. The stock Needle
checkpoint converts and serves coherently through the exact same path. I've isolated the fault to the CQ
quantization core (not rounding tolerance, not the remap, not the toolchain, not the fusion passes).
The weights are healthy: they survive naive per-group int4 round-trip at ~0.90 task accuracy and run at
0.938 accuracy at full precision. Only Cactus's CQ4 conversion breaks them.
Environment
cactus 2.0.1— the current latest (Homebrewcactus-compute/cactusstable 2.0.1; GitHub latestrelease
v2.0.1, 2026-07-09; PyPIcactus-compute2.0.1). macOS (Apple Silicon),--backend cpu.cactus-compute/needle(26M encoder-decoder tool-caller), finetuned locally vianeedle finetune(JAX/Flax)pip install cactus-compute(torch 2.13, transformers 5.5)Reproduction
20 epochs,
lr=3e-5— the defaultfinetune_localLR)..pkl→ HFNeedleForCausalLMsafetensors (my remap validates 228/228tensors against the stock HF reference, transpose orientation unambiguous).
cactus convert <finetuned-hf> <out> --bits 4→ clean bundle (114 converted / 114 fallback).cactus serve <out> --port 8085 --backend cpuThen:
What I ruled out (isolation)
--no-fuse-rms-norm --no-fuse-rope --no-fuse-attention --no-fuse-attention-block --no-fuse-add-clippedThe decisive signal: survives naive int4 but garbles under CQ4 ⟹ the fault is CQ-specific
(the Hessian/rotation-codebook calibration — each bundle carries
hessian_metadata.json), and it appearsto only be robust for the stock weight distribution. I also swept earlier finetune epochs (less drift from
stock); the least-drifted checkpoint that still learned the task survives naive int4 better than the
fully-trained one, yet still garbles under CQ4 — so it's not simply "how far the finetune drifted."
Questions for maintainers
pinned to the released stock checkpoint?
convertaccept calibration data (or a calibration-free / higher-bit path) so finetunedencoder-decoder models can be quantized robustly?
full-precision behind a shim)?
Happy to share the exact repro artifacts (finetuned HF checkpoint, the int4-proxy screen, before/after
serve transcripts).