Downloads · 30 days
18
24% of all-time downloads
edwardafd/smart-tutor-adtc-2026
smart-tutor-adtc-2026 is a text generation model from edwardafd. Use it when you need the model to write or continue text. It is set up for gguf. The card lists the license as apache-2.0.
An offline mathematics and science tutor for African learners, including learners with disabilities. Runs on a CPU laptop with no internet.
Downloads · 30 days
18
24% of all-time downloads
All-time downloads
74
Public
Repo size
986 MB
Likes
0
Public
Click a slice to open those files.
.gguf986 MB · 100%
From the Hugging Face model README
An offline mathematics and science tutor for African learners, including learners with disabilities. Runs on a CPU laptop with no internet.
Submitted to the Africa Deep Tech Challenge 2026 — The Laptop LLM Challenge
in the math_scientific_reasoning track.
llama-cli -m smart-tutor.gguf -p "Solve 3x + 7 = 22" -ngl 0 -t 4
Qwen2.5-Math-1.5B-Instruct, QLoRA fine-tuned for tutoring output format, then quantised to GGUF Q4_K_M for CPU inference through llama.cpp.
| Parameters | 1,543,714,304 |
| Quantisation | GGUF Q4_K_M — 5.08 bits per weight |
| File size | 986,047,872 bytes (940 MiB) |
| SHA256 | 0e64c3712a7c59a5ceb21c5591eea3beaeed6f8e10b07f20cd0c841b07e08ae5 |
| Architecture | 28 layers, grouped-query attention (12 query / 2 KV heads, head dim 128) |
| Context | 2048 tokens as configured; 4096 supported |
| Runtime | llama.cpp (GGUF) |
The base model was already correct on this curriculum — it scored 30/30 on
our held-out evaluation set before any training. What it did not do was
follow an output contract: it emitted \boxed{} rather than a parseable final
answer line.
So the objective was format compliance at zero accuracy cost:
FINAL ANSWER: <answer>That last line is what makes the model automatically gradeable, and it is what lets a screen-reader user jump straight to the result.
Measured on the full 30-item held-out set: 29/30 (96.7%), with a parseable
FINAL ANSWER: line on every single item, including the one graded wrong.
Format compliance held at 100%; math accuracy moved from 30/30 (base) to 29/30
(fine-tuned) — not quite zero-cost after all, and we found why:
Two answer-line bugs, found and fixed. On two held-out items the model
derived the correct value mid-reasoning, then overwrote its own
FINAL ANSWER: line — once with a later verification number instead of the
value the question asked for, once with a raw unrounded decimal despite
stating in prose that the result needed rounding up. A one-line system-prompt
addition (below) fixed both, verified on the exact test prompts before and
after, and confirmed at the dataset level: held-out accuracy moved from 27/30
to 29/30.
One genuine reasoning gap remains, and we're naming it rather than hiding
it. A tersely-phrased variant of a multi-step word problem still divides the
wrong quantity, even though a more scaffolded phrasing of the identical
problem ("write an equation and verify your answer") is answered correctly.
That's a real gap in the fine-tuning data, not a prompting trick away from
being fixed — full detail in REPORT.md.
| Setting | Value |
|---|---|
| Method | QLoRA (NF4 base), r=32, α=64, dropout 0.05 |
| Target modules | q, k, v, o, gate, up, down projections |
| Trainable | 36,929,536 params (2.34 %) |
| Steps | 150, effective batch 16 |
| Sequence length | 512 |
| Learning rate | 2e-4 cosine, 3 % warmup |
| Loss | assistant turn only |
| Final loss | 0.392 (val 0.437) |
| Hardware | 1× Colab T4, 85 minutes |
Data: GSM8K and Orca-Math, 18,429 rows. Examples whose answer could not be parsed were dropped, not patched — training on a target you cannot read teaches output you cannot grade. The evaluation set and the two declared benchmark prompts were excluded by normalised match, so the held-out set stayed held out.
llama-bench -p 512 -n 128 -ngl 0 -t <threads>, the exact invocation the ADTC
profiler uses. Two development-hardware sessions:
| Metric | Intel i7-3770 (2012, no AVX2) | AMD Ryzen 5 5600U (2021, AVX2) |
|---|---|---|
| Generation | 14.3 – 14.6 tok/s | 17.1 tok/s (S_perf 100.0, capped) |
| Prompt processing | 29.2 tok/s | 83.3 tok/s |
| Peak RSS | 1104 MB | 1701 MB (S_eff 76.3) |
| Thermal throttling | none observed | none observed |
The ADTC profiler's own independent measurement of this exact artifact agrees
closely: 17.39 tok/s, 1707 MB peak RSS, "measured_on": "participant_laptop".
The i7-3770 predates AVX2, so those figures are a deliberate lower bound. The Ryzen session has AVX2 (llama.cpp confirms it loads the
haswellkernel variant) and is architecturally closer to the ADTC target class (i5 10th–12th gen / Ryzen 5 3000–5000), though its 15.3 GB RAM still exceeds the 8 GB profile, so neither session is an official ADTC Standard Laptop result.
Runs comfortably within an 8 GB machine, with over 5 GB of headroom either way.
Offline mathematics and science tutoring at secondary level: arithmetic, algebra, geometry, probability, statistics, introductory calculus, physics, and quantitative word problems.
Designed for schools and community learning centres with intermittent connectivity, second-hand hardware, and unreliable power — and for learners who depend on screen readers or need to re-read an explanation at their own pace.
The accompanying application adds screen-reader rendering, large-print output, maths-to-speech normalisation, and offline text-to-speech through the operating system's own voices.
Alongside the tutor, this project built and tested UATL (Unified Adaptive Transformer Layer): a proposed policy for coordinating numerical precision, uncertainty estimation, and KV-cache behaviour per token, at runtime, on a frozen GGUF running through unmodified llama.cpp. Per transformer layer $l$:
$$h_{l+1} = h_l + G(d_l),\big[F(Q_{p_l}(W_l),, T_c(X_l),, K_q,, V_q)\big]$$
with difficulty $d$ the entropy of the next-token distribution,
$$d = -\sum_i p_i \ln p_i$$
$Q_{p_l}$ schedules per-layer precision $p_l \in {2,3,4,8}$ bits, $T_c$ is cache-aware tiling, and $G$ is an execution policy that realises the difficulty signal as work actually removed — token budget, early exit, routing — rather than a multiplier sitting on top of a matmul that still runs in full. The system is a constrained optimisation:
$$\min T_{\text{token}} ;; \text{s.t.} ;; A \ge A_0 - \epsilon,;; M_{\text{peak}} \le 7\text{ GB},;; \Theta_{\max} \le 85^{\circ}\text{C}$$
The real contribution turned out to be the discipline, not a speedup claim: an optimisation may not enter the shipped configuration until it is measured faster on the target hardware — enforced in code, not assumed from a paper. Applied to the KV cache, exact arithmetic corrected the original design notes by 8×:
$$M_{kv} = 2,L,H_{kv},d_{\text{head}},T,b = 2 \times 28 \times 2 \times 128 \times 2 = 28{,}672 \text{ bytes/token}$$
not the 224 KB/token a multi-head assumption gives — Qwen2.5's grouped-query attention (2 KV heads) makes the cache small from the start. That same measurement discipline is what caught, and prevented from shipping, an 11%-slower KV-quantisation config and a narrower-quantisation path that measured slower rather than faster on this CPU's kernels — exactly the trap a "fewer bits is always faster" heuristic would have walked into. The entropy difficulty signal itself held up: it's cheap, measurable, and the literature independently backs it as the strongest available confidence signal for this kind of routing.
What this measurement work unlocked for the next phase: the arithmetic correction above, the quantified noise floor for this hardware class, and a precision cost model that now gates every future quantisation decision. We're continuing this line of work — next up is table-lookup-based low-bit kernels (the approach used by methods like T-MAC), which sidestep the exact dequantise-then-multiply cost this round of measurement identified as the bottleneck, plus a proper multi-precision GGUF set so the adaptive-routing path — implemented and correct, just not yet exercised end-to-end — has more than one artifact to route between.
Full derivation, the ablation study, and its quantified noise floor are in
REPORT.md.
ChatML, as the base model uses. This is the current, corrected system prompt — earlier copies of this card (and any cached response generated before this update) used a version without the two bolded sentences below, which is the version that produced the answer-line bugs described above:
<|im_start|>system
You are Smart Tutor, a patient mathematics and science teacher for learners in
African schools, including learners with disabilities. Solve the problem with
clear numbered steps in plain language. Show the arithmetic. Check the result
before finishing. The FINAL ANSWER line must restate the exact value the
question asks for -- if you verify your answer afterward, keep reporting that
same value, not a number from the verification step. If your answer needs
rounding, apply the rounding yourself and report the rounded value, not the
raw decimal. End with a final line of exactly the form:
FINAL ANSWER: <answer><|im_end|>
<|im_start|>user
Solve the equation 3x + 7 = 22<|im_end|>
<|im_start|>assistant
Inherits the licence of the base model, Qwen2.5-Math-1.5B-Instruct (Apache 2.0). Please verify the upstream terms for your own use.
@misc{smart-tutor-adtc-2026,
title = {SMART TUTOR: an offline mathematics tutor for African learners
with disabilities},
author = {Adoyo, Edward},
year = {2026},
note = {Africa Deep Tech Challenge 2026, math\_scientific\_reasoning},
url = {https://github.com/afdroiddev-oss/smart-tutor-adtc-2026}
}
Built on Qwen2.5-Math by Alibaba Cloud, and served by llama.cpp.