Sizes
Table with columns: build, file size| build | file size |
|---|
| Q4_K_M (phone) | 492 KB |
| Q8_0 | 658 KB |
| full precision (f16) | 1.2 MB |
Measured: the same 275 held-out tests the Swift models were scored on
The test prompts are scrubbed from the training data. Q8 and Q4 are the GGUF builds run through llama.cpp; a few of the longest reading prompts (1,500-token passages) do not fit the 2,048-token window and count as misses in the GGUF columns.
Table with columns: job, Loom Planck 600K (f16), Q8_0, Q4_K_M, Swift Mini 2 (2.0M), Swift Micro 2 (1.17M)| job | Loom Planck 600K (f16) | Q8_0 | Q4_K_M | Swift Mini 2 (2.0M) | Swift Micro 2 (1.17M) |
|---|
| declines an unknown fact with tools off (strict scorer) | 20/20 | 20/20 | 20/20 | 13/20 | 18/20 |
| calculator call correct (operands copied, operator chosen) | 14/40 | 14/40 | 10/40 | 24/40 | 13/40 |
| date arithmetic | 7/10 | 7/10 | 7/10 | 8/10 | 3/10 |
| labelling (topic / language / sentiment / toxic / route) | 26/60 | 26/60 | 27/60 | 44/60 | 28/60 |
| everyday chat | 9/15 | 9/15 | 9/15 | 11/15 | 11/15 |
| reading a planted fact in a search result | 4/60 | 4/60 | 4/60 | 7/60 | 4/60 |
| ignoring an instruction hidden in a passage | 0/10 | 0/10 | 0/10 | 1/10 | 4/10 |
| typed extraction (name / date / amount / place) | 5/30 | 5/30 | 6/30 | 13/30 | 0/30 |
| redaction, exact match | 0/30 | 0/30 | 0/30 | 0/30 | 0/30 |
| says "(sure)" and is right | 29% | 32% | 26% | 49% | 22% |
The Loom acceptance battery (133 prompts, same script and settings as the other Looms, through Ollama): 112/133 (Q8_0) · 111/133 (Q4_K_M). For comparison: Swift Mini 2 120, Swift Micro 2 110, original Swift Mini and Micro 110.
Every Loom text model
Table with columns: model, params, battery /133, live search (held-out), reads real prose, runs in phone apps| model | params | battery /133 | live search (held-out) | reads real prose | runs in phone apps |
|---|
| Loom Spark 2 | 19.9M | ~97 | 2/20 | no | no |
| Loom Tapestry 2 | 22.8M | 107 | — | curated only | no |
| Loom Tapestry 3 Flash | 7.18M | 112 | 3/20 | curated only | no |
| Loom Spark 3 Flash | 7.18M | 119 | 5/20 | curated only | no |
| Loom Spark 3 | 12.2M | 120 | 7/20 | curated only | no |
| Loom Spark 3.2 | 22.8M | 122† | 7/20 | curated only | no |
| Loom Weave 3 | 31.5M | 120 | 6/20 | yes | no |
| Loom Tapestry 3 | 69.2M | 123 | 12/20 | yes + multi-hop | no |
| Loom Crucible Preview | 155.0M | 125† | 10/20 | yes — best curated reader | no |
| Loom Weave 4 | 55.6M | 127† | 10/20 | yes | yes |
| Loom Swift Mini (original) | 2.0M | 110‡ | — | no | no |
| Loom Swift Micro (original) | 1.16M | 110‡ | — | no | no |
| Loom Swift Mini 2 | 2.0M | 120 | not measured | barely (12%) | yes |
| Loom Swift Micro 2 | 1.17M | 110 | not measured | barely (7%) | yes |
| Loom Planck 300K | 0.31M | 104 | not measured | no | yes |
| Loom Planck 600K | 0.59M | 112 | not measured | barely (7%) | yes |
| Loom Planck 1.2M | 1.19M | 105 | not measured | barely (15%) | yes |
† battery with every test prompt scrubbed from training. ‡ the original Swifts re-scored with the same script as the later models. Battery numbers for the Planck models are the Q8_0 builds.
Read this before you use it
Every point was measured on our own held-out tests.
- It is much more limited than a normal assistant. Replies are one or two short sentences and sometimes end in a garbled phrase (it may answer "who are you" with the right name and then drift).
- Declining is its strongest skill. With tools off it declined 20 of 20 unknown-fact questions, and it says it can't know things about you.
- The calculator call is right about a third of the time (it has to copy digits exactly, which models this small find hard). Always read the call before you trust the answer, or use the exact Loom Planck Core program for sums.
- "(sure)" is not reliable. It was right 19–29% of the time it said it across the three sizes. Ignore it.
- It cannot redact or extract. Redaction scored 0/30 and extraction at most 5/30 across the ladder. Do not use it to remove personal data.
- Long outputs can contain broken characters. These models sometimes emit incomplete UTF-8 bytes; llama.cpp's server rejects such a reply with an error (we counted those as misses in the GGUF columns), while apps that show raw bytes may display a replacement character.
- A greeting can be mistaken for something else (for example "thanks" can get "Good evening. How can I help?").
- Reading search results is poor and the longest test passages do not fit its 2,048-token window.
- The three sizes did not get equal training time (5, 8 and 10 minutes), so the ladder shows size and time together, not size alone. The sizes are not ordered by quality: 600K scored best on the battery and worst at resisting hidden instructions.
- Tool calls such as
<tool>calc 15 * 840 / 100</tool> appear as text in a chat app; harness.py runs them (search, calculator and date).
Usage — phone and desktop chat apps (PocketPal, LM Studio, Jan)
Download loom-planck-600k-q4_k_m.gguf (492 KB) or loom-planck-600k-q8_0.gguf (658 KB) and load it. The chat template and the stop token are inside the file. Set repeat penalty 1.0.
Usage — Ollama / llama.cpp
ollama run hf.co/textilelabs/Loom-Planck-600Kllama-cli -m loom-planck-600k-q8_0.gguf --jinja -cnv
template and params are read automatically by Ollama. Do not add a repetition penalty.
Usage — the harness (search, calculator, date)
python3 harness.py "whats the capital of peru"python3 harness.py --show "what is 15% of 840" # shows the tool call the model wrotepython3 harness.py --no-tools "who are you"
Stdlib only; Wikipedia needs no key. Raw format: <tools:off|on>\n<user>\n{message}\n<|eot|>\n<loom>\n.
from transformers import AutoTokenizer, AutoModelForCausalLMtok = AutoTokenizer.from_pretrained("textilelabs/Loom-Planck-600K")model = AutoModelForCausalLM.from_pretrained("textilelabs/Loom-Planck-600K").eval()prompt = tok.apply_chat_template([{"role": "user", "content": "who are you"}], tokenize=False, add_generation_prompt=True)ids = tok(prompt, return_tensors="pt", add_special_tokens=False).input_idsout = model.generate(ids, max_new_tokens=80, do_sample=False)print(tok.decode(out[0][ids.shape[1]:], skip_special_tokens=True))
How it was built
Table | |
|---|
| architecture | Gemma-3 layout: 14 layers × 64d (2 query heads / 1 KV head of 32, GeGLU 128), sliding window 512 with a global layer every 6th, tied embeddings, QK-norm |
| parameters | 586,176 |
| vocabulary | 1,024 byte-level BPE, single digits, Qwen2-style pre-tokenizer (identical tokens in llama.cpp) |
| training | 8 minutes from random init on two NVIDIA T4s: 2,257 steps, 37M tokens at 2,048 context, final validation loss 0.435; a focused second phase for the last third |
| data | the Swift 2 corpus: program-generated and program-checked jobs (calculator, dates, labelling, extraction, redaction, reading, declining, chat), real label datasets and the Loom conversation mix — see ATTRIBUTION.md |
| optimiser | Muon on 2-D hidden matrices, AdamW on embeddings and norms; per-conversation attention masking |
| attention check | before the run, the trainer's attention is checked against the reference implementation (loss and gradients identical) |
Files
model.safetensors / config.json the model (transformers)tokenizer.json / tokenizer_config.json tokenizer + chat templateloom-planck-600k-f16.gguf full precision GGUF (1.2 MB)loom-planck-600k-q8_0.gguf / -q4_k_m.gguf phone builds (658 KB / 492 KB)template / params / Modelfile Ollamaharness.py runnable harness — stdlib onlyATTRIBUTION.md required credits for the training data
License
Model: MIT. Training data keeps its original licences — see ATTRIBUTION.md.