Cactus Hybrid: On-Device Confidence Scoring for Gemma 4

Cactus has released a post-trained version of Google's Gemma 4 E2B (the smallest Gemma model) that includes a confidence probe embedded directly in the checkpoint. The probe assigns a score between 0 and 1 to every generated answer, returned as structured data alongside the response — never parsed from text. This allows developers to implement a simple routing policy: if confidence < 0.85, hand off to a larger model.

Benchmarks: Matching Flash-Lite with 15-35% Handoff

According to the GitHub release, the Gemma 4 E2B Hybrid matches Gemini 3.1 Flash-Lite on most benchmarks while routing only 15-35% of queries to the larger model. The exact handoff percentage depends on the benchmark and quantization level:

BenchmarkHandoff to match Flash-Lite (FP16)At 4-bitAt 3-bit
ChartQA15-20%25-30%40-50%
MMBench30-35%40-45%50-55%
LibriSpeech25-30%35-40%55-65%
GigaSpeech30-35%40-45%50-55%
MMAU30-35%35-40%50-55%
MMLU-Pro45-55%~90%n/a

Note: Quantization quality is measured on Cactus Quants, which performs well at uniform quantization. Developers are encouraged to benchmark independently for Unsloth, GGUF, and MLX quantization.

Confidence Probe Quality (AUROC)

The probe's ability to distinguish correct from incorrect answers is measured by Area Under the Receiver Operating Characteristic curve (AUROC). Higher is better; 0.5 is random, 1.0 is perfect. The Cactus Hybrid achieves a mean AUROC of 0.814 across text, vision, and audio benchmarks, compared to 0.549 for token entropy baselines:

BenchmarkModalityCactus HybridToken Entropy
MMLUtext MCQ0.7700.697
MMLU-Protext MCQ0.7710.692
ARC-Easytext MCQ0.8880.655
ARC-Challengetext MCQ0.8340.646
GSM8K (3-shot)text gen0.7820.731
MMBench-EN-Devvision MCQ0.8400.435
ChartQAvision QA0.7790.615
DocVQAvision QA0.7810.512
MMAUaudio MCQ0.7890.517
GigaSpeechaudio0.8760.343
Earnings-22audio0.8390.323
LibriSpeechaudio0.8220.427
Mean0.8140.549

Notably, the probe was trained on zero audio data yet achieves 0.79-0.88 AUROC on four audio benchmarks (two transcription, one audio MCQ, one out-of-domain transcription). This suggests the probe reads a modality-independent correctness signal from the hidden state, not memorized patterns.

Code Examples

The model is available on Hugging Face as Cactus-Compute/gemma-4-E2B-it (Cactus API), Cactus-Compute/gemma-4-e2b-it-hybrid-mlx (MLX), Cactus-Compute/gemma-4-e2b-it-hybrid (Transformers), and Cactus-Compute/gemma-4-e2b-it-hybrid-GGUF:Q4_K_M (llama.cpp).

Cactus API (Python):

# pip install cactus-compute
import json
from cactus.bindings.cactus import cactus_complete, cactus_init
from cactus.cli.download import download_bundle

lm = cactus_init(str(download_bundle(&#34;Cactus-Compute/gemma-4-E2B-it&#34;)))
result = cactus_complete(
    lm,
    [{&#34;role&#34;: &#34;user&#34;, &#34;content&#34;: &#34;What is the capital of France?&#34;}],
    json.dumps({&#34;max_tokens&#34;: 512, &#34;auto_handoff&#34;: False}),
    None,
    lambda *_: None,
)
print(result[&#34;response&#34;].strip())
print(&#34;confidence:&#34;, result[&#34;confidence&#34;])

MLX (Apple Silicon):

# pip install mlx-lm
import re
from mlx_lm import load, generate

model, tokenizer = load(
    &#34;Cactus-Compute/gemma-4-e2b-it-hybrid-mlx&#34;,
    tokenizer_config={&#34;trust_remote_code&#34;: True},
)
messages = [{&#34;role&#34;: &#34;user&#34;, &#34;content&#34;: &#34;What is the capital of France?&#34;}]
answer = generate(
    model,
    tokenizer,
    prompt=tokenizer.apply_chat_template(messages, add_generation_prompt=True),
    max_tokens=512,
)
answer = re.split(r&#34;&lt;\|?channel\|?&gt;&#34;, answer)[-1]
answer = re.sub(r&#34;^(thought|final)\b\s*&#34;, &#34;&#34;, answer).strip()
print(answer)
print(&#34;confidence:&#34;, model.last_confidence)

Transformers:

# pip install &#34;transformers&gt;=5.5.4,&lt;5.6&#34; torch
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer

model_id = &#34;Cactus-Compute/gemma-4-e2b-it-hybrid&#34;
device = &#34;cuda&#34; if torch.cuda.is_available() else &#34;mps&#34; if torch.backends.mps.is_available() else &#34;cpu&#34;
tokenizer = AutoTokenizer.from_pretrained(model_id, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(model_id, trust_remote_code=True, dtype=&#34;auto&#34;).to(device)

messages = [{&#34;role&#34;: &#34;user&#34;, &#34;content&#34;: &#34;What is the capital of France?&#34;}]
inputs = tokenizer.apply_chat_template(
    messages, add_generation_prompt=True, return_tensors=&#34;pt&#34;, return_dict=True
).to(device)
out = model.generate(**inputs, return_confidence=True, max_new_tokens=512)
print(tokenizer.decode(out.sequences[0][inputs[&#34;input_ids&#34;].shape[-1]:], skip_special_tokens=True))
print(&#34;confidence:&#34;, out.confidence)

llama.cpp:

# Build patched server
git clone https://github.com/cactus-compute/cactus-hybrid &amp;&amp; cd cactus-hybrid
./patches/llama.cpp/install.sh &amp;&amp; rehash
# Serve
llama-server -hf Cactus-Compute/gemma-4-e2b-it-hybrid-GGUF:Q4_K_M --jinja
# Query
curl -s http://localhost:8080/v1/chat/completions \
  -d &#39;{&#34;messages&#34;:[{&#34;role&#34;:&#34;user&#34;,&#34;content&#34;:&#34;What is the capital of France?&#34;}],&#34;max_tokens&#34;:512}&#39; \
  | jq &#39;{answer: .choices[0].message.content, confidence}&#39;

Important: Transformers Caveat

When using Transformers, load the model with an explicit .to(device), not device_map=&#34;auto&#34;. The probe scores generations outside the module forward() path, so weights that accelerate offloads (left on the meta device) crash the confidence read.

Licensing

The model is MIT-licensed. Gemma model use is subject to the Gemma terms.

Why This Matters

For developers deploying small models on-device (edge, mobile, privacy-sensitive apps), the trade-off between speed and accuracy is constant. Cactus Hybrid gives you a principled way to keep 65-85% of queries on-device while matching a much larger model's accuracy. The confidence probe is baked into the checkpoint, not an external classifier, so it's zero-latency and private.

Next Steps

  1. Download the model from Hugging Face (Cactus-Compute/gemma-4-e2b-it-hybrid).
  2. Integrate the confidence-based routing logic into your pipeline.
  3. Benchmark on your own data to determine the optimal handoff threshold (the default 0.85 is a starting point).