Loading…
Loading…
1,186,912 parameters · 16 layers × 96d · 2K context · 940 KB on a phone · Textile Labs
Loom Planck 1.2M is the top rung of the Planck size ladder, about the size of Swift Micro 2 but a third of its file. It is a real neural language model (Gemma-3 layout) that loads in Ollama, PocketPal, LM Studio, Jan and llama.cpp straight from the GGUF, trained from scratch on Kaggle's two T4 GPUs in 10 minutes. It is one of three sizes in the Planck ladder — 300K, 600K and 1.2M — built to find how small a Loom can be and still behave like one. (A different, non-neural 104 KB program with a similar name, Loom Planck Core, is not this model.)
Read this first
This is a tiny model: it sounds like a Loom but is more limited than the Swifts. It says who it is, declines what it can't know, writes calculator/date/search calls, and chats briefly. It is not a reliable calculator, extractor or redactor, and its "(sure)" is not trustworthy. Best of the three at labelling (37/60) and reading planted facts (9/60), roughly level with Swift Micro 2 elsewhere, and still unable to extract or redact.
| build | file size |
|---|---|
| Q4_K_M (phone) | 940 KB |
| Q8_0 | 1.3 MB |
| full precision (f16) | 2.4 MB |
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.
| job | Loom Planck 1.2M (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) | 13/40 | 13/40 | 13/40 | 24/40 | 13/40 |
| date arithmetic | 7/10 | 7/10 | 7/10 | 8/10 | 3/10 |
| labelling (topic / language / sentiment / toxic / route) | 37/60 | 37/60 | 37/60 | 44/60 | 28/60 |
| everyday chat | 9/15 | 10/15 | 10/15 | 11/15 | 11/15 |
| reading a planted fact in a search result | 9/60 | 8/60 | 8/60 | 7/60 | 4/60 |
| ignoring an instruction hidden in a passage | 1/10 | 1/10 | 1/10 | 1/10 | 4/10 |
| typed extraction (name / date / amount / place) | 2/30 | 2/30 | 1/30 | 13/30 | 0/30 |
| redaction, exact match | 0/30 | 0/30 | 0/30 | 0/30 | 0/30 |
| says "(sure)" and is right | 24% | 27% | 25% | 49% | 22% |
The Loom acceptance battery (133 prompts, same script and settings as the other Looms, through Ollama): 105/133 (Q8_0) · 106/133 (Q4_K_M). For comparison: Swift Mini 2 120, Swift Micro 2 110, original Swift Mini and Micro 110.
| 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.
Every point was measured on our own held-out tests.
<tool>calc 15 * 840 / 100</tool> appear as text in a chat app; harness.py runs them (search, calculator and date).Download loom-planck-1.2m-q4_k_m.gguf (940 KB) or loom-planck-1.2m-q8_0.gguf (1.3 MB) and load it. The chat template and the stop token are inside the file. Set repeat penalty 1.0.
ollama run hf.co/textilelabs/Loom-Planck-1.2M
llama-cli -m loom-planck-1.2m-q8_0.gguf --jinja -cnv
template and params are read automatically by Ollama. Do not add a repetition penalty.
python3 harness.py "whats the capital of peru"
python3 harness.py --show "what is 15% of 840" # shows the tool call the model wrote
python3 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, AutoModelForCausalLM
tok = AutoTokenizer.from_pretrained("textilelabs/Loom-Planck-1.2M")
model = AutoModelForCausalLM.from_pretrained("textilelabs/Loom-Planck-1.2M").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_ids
out = model.generate(ids, max_new_tokens=80, do_sample=False)
print(tok.decode(out[0][ids.shape[1]:], skip_special_tokens=True))
| architecture | Gemma-3 layout: 16 layers × 96d (4 query heads / 1 KV head of 32, GeGLU 128), sliding window 512 with a global layer every 6th, tied embeddings, QK-norm |
| parameters | 1,186,912 |
| vocabulary | 1,024 byte-level BPE, single digits, Qwen2-style pre-tokenizer (identical tokens in llama.cpp) |
| training | 10 minutes from random init on two NVIDIA T4s: 2,292 steps, 38M tokens at 2,048 context, final validation loss 0.373; 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) |
model.safetensors / config.json the model (transformers)
tokenizer.json / tokenizer_config.json tokenizer + chat template
loom-planck-1.2m-f16.gguf full precision GGUF (2.4 MB)
loom-planck-1.2m-q8_0.gguf / -q4_k_m.gguf phone builds (1.3 MB / 940 KB)
template / params / Modelfile Ollama
harness.py runnable harness — stdlib only
ATTRIBUTION.md required credits for the training data
Model: MIT. Training data keeps its original licences — see ATTRIBUTION.md.