ZophiaE Strawweight
A 25-million-parameter logical-verdict engine that knows when it doesn't know. Byte-level (256-symbol vocabulary, no tokenizer), trained on a single consumer GPU in under two hours total, runs on CPU in pure Rust. Strawweight is the smallest class in the ZophiaE line β named the way boxing names its divisions, and it punches accordingly.
What this is, and why it's built this way
Most language models spend enormous parameter budgets learning what words are β a tokenizer vocabulary, embeddings for tens of thousands of subword fragments. This line takes the opposite bet: words are encoded before training, as concept bytes β a dictionary-defined encoding where one byte is (roughly) one word-meaning and grammar is explicit feature bytes. The model's 25M parameters are spent on reasoning over meanings, not on reconstructing what "bread" is from fragments. Three consequences, all deliberate:
- It's small and it's local. No tokenizer, no cloud, no Python required β the whole thing runs on a CPU, in a folder, offline. This is a bet that useful reasoning doesn't need a datacenter.
- It's inspectable. Every byte in the model's context is a labeled concept, so attention weights are readable relationships, not opaque token indices. The Talkit runtime shows you, per generated byte, what the model weighed and what it attended to.
- It's a specialist on purpose. The training corpus is synthetic, oracle-checked logic, balanced so that refusing to answer is a first-class move (25% of training answers are "we can not say" β and they're correct refusals, not hedges). The result is the rarest property in small models: calibration β it refuses with 98% precision instead of confabulating.
The custom architecture and custom encoding are why this isn't a
transformers-loadable model β and also why the whole stack
(translator, codec, dictionary, runtime, training script) ships in
this repo. Nothing here depends on anything you can't read.
Measured on 2,024 fresh questions proven by hash never to have appeared in any training document:
| four-way verdict accuracy (YES / NO / UNKNOWN / OPEN) | 89.1% (floor for any constant answerer: 25%) |
| refusal precision β when it says "we can not say," it's right | 98.1% |
| answers that close their own frame (END discipline) | ~99% |
| the same architecture at half the data ration | 35.9% |
It computes β real division, real counting; change a number in your question and the verdict follows the arithmetic, not the template. It refuses when premises genuinely underdetermine the answer (denying the antecedent is a refusal here, not a yes). And it shows its work in every answer.
Q: john has 56 breads. the group uses 4 breads each month. the bread
must last 8 months. if the bread does not last, then the sun sets.
does the sun set?
A: 56 / 4 = 14. 14 months against 8, so the bread lasts. If the bread
does not last, then the sun sets. The bread lasts. The rule speaks
only about what happens when the bread does not last. We can not
say. The words can all be true while the sun sets, and also while
the sun does not set.
That is the correct answer β and the branch most models fail.
How to run it
This is not a transformers / GGUF model β the architecture and
the concept-byte codec are custom. So this repo ships the entire
stack: weights, dictionary, the Englishβbytes translator, the
reference PyTorch implementation, and the signed Windows appliance.
Three ways in, all self-contained:
1. Windows, zero install. Download the repo, run
SETUP_TALKIT.bat once (it arranges the folders), then double-click
talkit.exe. Chat window, reasoning pane with per-byte attention, a
Verify tab that reproduces the numbers above on your machine, and
a model picker. (Also on
GitHub.)
2. Pure Python (pip install torch safetensors β nothing else):
python run_strawweight.py "a beetle is an insect. all insects are
animals. so the beetle is an animal. if the beetle is an
animal, then the horse sleeps. does the horse sleep?"
Runs translator β codec β model β decode β render and prints the
annotated stream plus the English answer. train_25m.py here is the
actual, unabridged training script β the model definition and the
full recipe in one file. zofiae.py is the codec, simplify.py the
translator, data/table/ the dictionary.
3. As a local service:
talkit serve --port 8484
POST /ask {"question":"..."} -> {"answer","kind","confidence_mean",...}
Questions.md is the playbook: every trained question family with
paste-ready examples.
It's a pretrain β continue training on your data
Strawweight is a base model. The intended use is to take it, continue training on your data, and see whether it works for your problem. Everything needed is in this repo, and the loop has been run end to end exactly as written below:
1. Make a corpus from your text (no Python): drop files or paste text into Talkit's Build Corpus tab, or headless β
talkit corpus C:\path\to\your_text_folder -> your_text_folder\corpus.bin
Each file or paste becomes one concept-byte record through the strict translator (a sentence either survives round-trip-perfect or is dropped with its reason). Keep records under 2,560 bytes β a paragraph, or one question-and-answer β the trainer refuses longer documents. Q&A-framed records (question, then the answer) come from the chatβcorpus button; plain records train as ordinary text.
2. Continue training from the published weights
(pip install torch safetensors):
set ZOFIAE_MODEL=25m
set ZOFIAE_CORPUS=C:\path\to\your_text_folder
set ZOFIAE_RUNS=C:\path\to\runs
python train_25m.py --resume model.safetensors --corpus-glob "corpus.bin" --epochs 3 --tag mine
train_25m.py resumes directly from this repo's model.safetensors
and writes runs\run_NNN_mine\best.pt. With a small corpus the held-
out split will be empty (eval_seen 0 docs) β that is expected; judge
the result with your own questions or the Verify tab, not that line.
3. Put the result back into Talkit
set TALKIT_ASSETS_DIR=C:\path\to\Talkit\assets
set TALKIT_NAME=my fine-tune
python export_talkit_assets.py C:\path\to\runs\run_001_mine\best.pt my-model
It lands in assets\models\my-model\, the picker shows it on next
launch, and TALKIT_MODEL=my-model talkit serve serves it. Keep the
original folder beside it and use A/B to compare before and after.
License note: a model continued from these weights is a modified
version of the Materials, not an Output β it carries the same license
(free noncommercial, commercial by written license capped at 6%). See
LICENSE.md Β§4.
Watching it think, reading the weights
Interpretability isn't a research rig bolted onto this model β it's a property of the encoding. Every position in the context is a labeled dictionary concept, so attention weights are readable relationships and the learned space can be inspected by name. Four instruments, all included:
The Talkit reasoning pane (no code): click any answer bubble β per generated byte, the candidate distribution the model weighed and the attention it paid, per layer and head.
talkit trace "question"dumps the same evidence headless.watch_it_think.pyβ the Python version, labeled end to end:step 5 -> 4 | weighed: 4 100% 7 0% 5 0% | looked at: / 0.23, last 0.06, 56 0.04 step 9 -> 1 | weighed: 1 100% 2 0% 9 0% | looked at: = 0.13, / 0.11, 56 0.08That's the model doing the division β while it writes "14", its attention sits on
/,56,4, and=. Attention is recomputed explicitly (fused kernels don't return weights), mirroring the training forward line for line.read_weights.pyβ composes every dictionary word through the network once and lets you cosine-explore the learned space by name:sunsits withsnow,hot,dark;risewithappearandclimb. No probing classifiers β the labels were built into the vocabulary before training.train_25m.py's own instrumentation β the training log reports a frequency-to-attention correlation each epoch: if attention merely mirrored token frequency, the model would be counting, not reasoning. (v3's stayed near zero: r β +0.08.)
A worked example of what this catches: asked about a sun that
"sets" β a verb never trained in that slot β the model restated the
rule as "the sun falls," the semantically correct pick out of
seven trained sky verbs, rejecting the frequency-favorite "rises."
watch_it_think.py shows the decision being made in context;
read_weights.py shows the labeled space it was made in.
The box it lives in (honest scope)
Strawweight is a specialist: eleven trained families of logic β propositional rules, syllogism chains, temporal/interval reasoning, quantities and proportions, inclusionβexclusion counting, evidence vetting, defaults and exceptions, board tactics, invariants and reachability, proof patterns, and two-family composition chains of the above. English in, through a controlled-language translator that drops what it can't carry, with a stated reason, rather than guessing. Constraint-satisfaction puzzles are its known weak family (~50%). It is not a chatbot; vocabulary is bounded by its dictionary. Inside the box: calibrated. Outside the box: the verdict chip and confidence numbers are the warning instruments.
Architecture
| parameters | 25,377,152 |
| vocabulary | 256 raw bytes β no tokenizer, no BPE |
| context | 2,560 bytes |
| dims | d_model 384 Β· 16 layers Β· 6 heads over 2 KV (GQA 3:1) Β· FF 1024 (SwiGLU) |
| position | RoPE base 10000, interleaved pairs |
| norms | RMSNorm (eps 1e-6) + per-head RMS QK-norm before RoPE |
| head | untied |
| precision | fp32 safetensors (~101 MB); runs on CPU |
The input is not text bytes: words are concept bytes β a dictionary-defined encoding where one byte is (roughly) one lemma and grammatical features are explicit feature bytes. The dictionary ships with the runtime as four readable TSVs.
Training recipe (the part that mattered)
Two phases, each sized to exactly 10 encoded bytes per parameter ("neochinchilla"), one epoch each, on one RTX 4070 Ti SUPER:
- Logic school β 253.8 MB of synthetic documents from oracle-checked generators, balanced to 25% each of YES / NO / UNKNOWN / OPEN per pattern, so no constant responder can beat chance; half single-family documents, half two-family composition chains. Every document seen exactly once.
- Association β 90% curated prose + everyday sentences, with 10% freshly generated logic interspersed throughout (disjointness from phase 1 proven by hash, not hoped from seeds). Held-out logic loss improved through this phase: 0.1769 β 0.1712.
The measured headline: the same architecture trained on half the ration with a two-way corpus scored 35.9% on the same probe. Data ration and corpus design were the levers; parameters were not. Scale is for fluency.
Files
model.safetensorsβ fp32 weights, flat names (emb.weight,blocks.{i}.*,nf.g,head.weight), row-major[out, in]config.jsonβ dims + provenance; the runtimes read thistalkit.exe+SETUP_TALKIT.batβ the signed Windows appliance (Authenticode: TNT Holley, Inc.) and its one-click layout scriptrun_strawweight.pyβ pure-Python inference, end to endwatch_it_think.pyβ per-byte candidates + attention, labeledread_weights.pyβ explore the learned concept space by nametrain_25m.pyβ the unabridged training script = the model definition (setZOFIAE_MODEL=25m, the default);--resumetakes this repo'smodel.safetensorsdirectly β continue training hereexport_talkit_assets.pyβ turn a training checkpoint into a Talkit model folder (TALKIT_ASSETS_DIR, see the pretrain section)zofiae.py/simplify.py/universal.pyβ codec, translator, shared math blockdata/table/β the dictionary (readable TSVs)Questions.mdβ the question-format playbookLICENSE.mdβ Holley Community License 1.0 (worldwide text)
License
Free for noncommercial use β research, learning, personal
projects, evaluation, charities, schools, public institutions.
Commercial use requires a license (travis@tntholley.com), with a
published permanent cap: never more than 6% of gross revenue
attributable to the licensed use. Using the materials constitutes
acceptance of the terms β see LICENSE.md.
Citation
@software{holley2026strawweight,
author = {Holley, Travis E.},
title = {ZophiaE Strawweight: a 25M-parameter calibrated
logical-verdict engine on concept bytes},
year = {2026},
url = {https://github.com/Laninthalesdran/Concept-as-Byte},
note = {Weights: huggingface.co/tntholley. Patents pending.}
}
TNT Holley, Inc. Β· Fort Mill, South Carolina Β· Patent pending.
- Downloads last month
- 41