Downloads · 30 days
101
10% of all-time downloads
rolandwhere/granite-4.2-8b-symbolic-cot
granite-4.2-8b-symbolic-cot is a text generation model from rolandwhere. Use it when you need the model to write or continue text. It is set up for transformers. The card lists the license as apache-2.0.
A fine-tune of ibm-granite/granite-4.2-8b that rewrites the model's thinking mode into a compact symbolic notation instead of verbose natural-language deliberation. Final answers stay in normal English.
Downloads · 30 days
101
10% of all-time downloads
All-time downloads
964
Public
Parameters
8.8B
17.6 GB on disk
Likes
5
Public
Click a slice to open those files.
.safetensors17.6 GB · 100%
From the Hugging Face model README
A fine-tune of ibm-granite/granite-4.2-8b that rewrites the model's thinking mode into a compact symbolic notation instead of verbose natural-language deliberation. Final answers stay in normal English.
Base Granite 4.2 thinks like this:
Okay, let's try to figure out this problem step by step. First, I need to find
the total time from departure to arrival, then subtract the total stop time...
Wait, better to do minutes: 14:20 is 14*60 + 20 = 860 minutes...
This model thinks like this:
t1=14:20, t2=17:05
diff=2h45min=165min
stops=2*12=24
moving=165-24=141
.: 141 min
Both produce the same final answer. The second uses roughly a quarter of the tokens.
GraniteForCausalLM), 8B parametersibm-granite/granite-4.2-8bLatency- or cost-sensitive reasoning where the chain of thought is an internal cost rather than a user-facing product: batch processing, agent loops with many turns, long-context work where thinking tokens compete with the context budget.
The notation is deliberately terse. It uses =, -> (implies), <- (because), .: (therefore), &, |, !, and single-letter variable bindings. It is meant to be machine-cheap, not human-pleasant.
enable_thinking=True, but the weights are shared, so all three modes moved. Behaviour in the other two modes is not what IBM shipped.import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
path = "rolandwhere/granite-4.2-8b-symbolic-cot"
tok = AutoTokenizer.from_pretrained(path)
model = AutoModelForCausalLM.from_pretrained(path, dtype=torch.float16, device_map="auto")
msgs = [{"role": "user", "content": "How many r's are in 'strawberry'?"}]
text = tok.apply_chat_template(msgs, tokenize=False, add_generation_prompt=True,
enable_thinking=True)
ins = tok(text, return_tensors="pt").to(model.device)
out = model.generate(**ins, max_new_tokens=1024, do_sample=True,
temperature=1.0, top_p=0.95)
print(tok.decode(out[0][ins.input_ids.shape[-1]:], skip_special_tokens=False))
Use temperature=1.0, top_p=0.95 as IBM recommends for the base model. The compressed trace appears inside <think>...</think>; the answer follows it.
Note on system prompts: training used an empty system turn on every example. Serving with a long system prompt is a distribution shift and may weaken the compression. If you need one, test it — or fine-tune further with your system prompt in place.
Roughly N synthetic reasoning traces (see the dataset repo for the exact row count), distilled via OpenRouter's free auto-router. Per the OpenRouter activity log, generation landed roughly 50/50 across MiniMax M3 and M2.7. The teacher was used only to produce training traces — it plays no part in the model at inference.
Because the router selects models dynamically, the exact data-generation run is not bit-reproducible. The notation spec and filter criteria below are what actually determine the output.
Two seed sources:
HuggingFaceH4/no_robots — open QA, brainstorming, classification, extraction. No gold answers; kept for style coverage so the model doesn't collapse into math-only behaviour.The teacher was prompted to emit two fields: a compressed symbolic think and a normal-English answer. Only the reasoning is compressed.
Traces were filtered on four criteria before training:
.: conclusion line presentlet me, okay, wait, we need, hmm, …)Prompts were rendered with the base chat template at enable_thinking=True, so training overwrites full-thinking behaviour specifically. Loss was masked to the completion only.
| Method | QLoRA (4-bit NF4 base, fp16 compute) |
| LoRA rank / alpha | 32 / 32 |
| Target modules | q,k,v,o,gate,up,down_proj, all 40 layers |
| Trainable params | 98,959,360 (1.11%) |
| Epochs | 2 |
| Effective batch | 16 (2 × 8 accumulation) |
| LR / schedule | 2e-4, linear, 5 warmup steps |
| Optimizer | adamw_8bit |
| Max sequence length | 1024 |
| Framework | Unsloth |
Training loss fell from 1.63 to ~0.60 over the run.
Single NVIDIA T4 (16GB), ~15 minutes. Adapter is 396 MB; merged weights are ~18 GB in fp16.
40 held-out questions from GSM8K test. Exact-match on the final numeric answer. Four conditions on identical hardware and quantization, with the base conditions obtained by disabling the adapter on the same loaded model. Sampling at temperature=1.0, top_p=0.95, generation capped at 768 new tokens.
Metrics: mean thinking tokens (the quantity being optimized), wall-clock seconds per example, and accuracy.
| Condition | Thinking tokens | sec / example | Accuracy |
|---|---|---|---|
| base, thinking | 176 | 25.7 | 0.48 * |
| base, low-effort | 61 | 13.9 | 0.93 |
| base, non-thinking | 0 | 23.0 * | 0.65 |
| this model, thinking | 44 | 5.5 | 0.75 |
* These two numbers are measurement artifacts, not properties of the base model. Read the summary before using this table.
The compression result is solid: 4× fewer thinking tokens (176 → 44) and 4.7× lower latency (25.7s → 5.5s) versus base thinking mode.
The accuracy column is not trustworthy as measured, and I would rather say so than let the numbers flatter this model:
low_effort=True first — it is free and requires no fine-tuned weights.The honest claim for this model is a 4× reduction in thinking tokens at an accuracy cost that has not yet been properly quantified. A re-run with a 2048+ token budget is needed before the accuracy column means anything. Treat this release as a working demonstration of the compression technique, not as a validated accuracy claim.
Dense decoder-only transformer. 40 layers, hidden size 4096, GQA with 32 query heads and 8 KV heads, SwiGLU MLP (hidden 12800), RMSNorm, RoPE. Standard causal language modelling objective, loss masked to the assistant completion.
Kaggle notebook, 1 × T4 (16 GB), fp16 compute with a 4-bit NF4 quantized base. Unsloth for training; PEFT and llama.cpp for merging and GGUF conversion.
If you use this model, cite the base model:
@misc{granite2026,
title = {Granite 4.2 Language Models},
author = {{Granite Team, IBM}},
year = {2026},
url = {https://huggingface.co/ibm-granite/granite-4.2-8b}
}
Notation used inside <think>:
| Symbol | Meaning |
|---|---|
a=48 | bind quantity to a variable |
-> | implies / leads to |
<- | because |
.: | therefore (terminal line) |
& | ! | and / or / not |
? | unknown target |
chk: | verification step |
rolandwhere
Questions, results, or corrections are welcome — open a discussion on this repo, or reach out via LinkedIn.
If you re-run the evaluation with a larger token budget, I would genuinely like to see the numbers.
Built on IBM's Granite 4.2 (Apache 2.0) and trained with Unsloth on free Kaggle T4 hardware.