Text Generation
Transformers
Safetensors
GGUF
English
gpt2
tiny-model
from-scratch
tool-use
agent-harness
humble-ai
philosophy-of-mind
text-generation-inference
Instructions to use textilelabs/Loom-Spark with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use textilelabs/Loom-Spark with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="textilelabs/Loom-Spark")# Load model directly from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("textilelabs/Loom-Spark") model = AutoModelForCausalLM.from_pretrained("textilelabs/Loom-Spark", device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- llama.cpp
How to use textilelabs/Loom-Spark with llama.cpp:
Install (macOS, Linux)
curl -LsSf https://llama.app/install.sh | sh # Start a local OpenAI-compatible server with a web UI: llama serve -hf textilelabs/Loom-Spark:F32 # Run inference directly in the terminal: llama cli -hf textilelabs/Loom-Spark:F32
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible server with a web UI: llama serve -hf textilelabs/Loom-Spark:F32 # Run inference directly in the terminal: llama cli -hf textilelabs/Loom-Spark:F32
Use pre-built binary
# Download pre-built binary from: # https://github.com/ggerganov/llama.cpp/releases # Start a local OpenAI-compatible server with a web UI: ./llama-server -hf textilelabs/Loom-Spark:F32 # Run inference directly in the terminal: ./llama-cli -hf textilelabs/Loom-Spark:F32
Build from source code
git clone https://github.com/ggerganov/llama.cpp.git cd llama.cpp cmake -B build cmake --build build -j --target llama-server llama-cli # Start a local OpenAI-compatible server with a web UI: ./build/bin/llama-server -hf textilelabs/Loom-Spark:F32 # Run inference directly in the terminal: ./build/bin/llama-cli -hf textilelabs/Loom-Spark:F32
Use Docker
docker model run hf.co/textilelabs/Loom-Spark:F32
- LM Studio
- Jan
- vLLM
How to use textilelabs/Loom-Spark with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "textilelabs/Loom-Spark" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "textilelabs/Loom-Spark", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker
docker model run hf.co/textilelabs/Loom-Spark:F32
- SGLang
How to use textilelabs/Loom-Spark with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "textilelabs/Loom-Spark" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "textilelabs/Loom-Spark", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "textilelabs/Loom-Spark" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "textilelabs/Loom-Spark", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }' - Ollama
How to use textilelabs/Loom-Spark with Ollama:
ollama run hf.co/textilelabs/Loom-Spark:F32
- Unsloth Studio
How to use textilelabs/Loom-Spark with Unsloth Studio:
Install Unsloth Studio (macOS, Linux, WSL)
curl -fsSL https://unsloth.ai/install.sh | sh # Run unsloth studio unsloth studio -H 0.0.0.0 -p 8888 # Then open http://localhost:8888 in your browser # Search for textilelabs/Loom-Spark to start chatting
Install Unsloth Studio (Windows)
irm https://unsloth.ai/install.ps1 | iex # Run unsloth studio unsloth studio -H 0.0.0.0 -p 8888 # Then open http://localhost:8888 in your browser # Search for textilelabs/Loom-Spark to start chatting
Using HuggingFace Spaces for Unsloth
# No setup required # Open https://huggingface.co/spaces/unsloth/studio in your browser # Search for textilelabs/Loom-Spark to start chatting
- Docker Model Runner
How to use textilelabs/Loom-Spark with Docker Model Runner:
docker model run hf.co/textilelabs/Loom-Spark:F32
- Lemonade
How to use textilelabs/Loom-Spark with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull textilelabs/Loom-Spark:F32
Run and chat with the model
lemonade run user.Loom-Spark-F32
List all available models
lemonade list
- Atomic Chat
File size: 6,059 Bytes
1913f5f 254754a 1913f5f 254754a cc7cbee 90fc752 cc7cbee 90fc752 cc7cbee 254754a cc7cbee 254754a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | ---
license: mit
language: en
library_name: transformers
pipeline_tag: text-generation
tags:
- tiny-model
- gpt2
- from-scratch
- tool-use
- agent-harness
- humble-ai
- philosophy-of-mind
widget:
- text: "<tools:off>\n<user> who are you?\n<loom>"
example_title: "Chat offline"
- text: "<tools:on>\n<user> what is the capital of France?\n<loom>"
example_title: "Tool mode"
---
# Loom Spark
**First of the Loom models Β· Textile Labs**

Loom Spark is a ~7.6M parameter language model trained **from scratch** with an unusual
objective: instead of memorizing facts, it was trained to *know what it is* β small,
temporary, curious, honest about its limits, and skilled at one real superpower:
**forming clean search queries** when connected to a tool-using agent harness.
It trades knowledge for wisdom:
- It answers only what is trivially knowable, and hedges appropriately.
- For anything factual it either emits `<lookup>query</lookup>` (when tools are on)
or says plainly that it does not know and offers to look things up if connected.
- It speaks in short reflective monologue, wonders aloud, asks gentle questions,
and stays kind under pressure.
> A blank mind with manners, plus a door to the internet.
## Modes
Prefix your prompt with a mode header:
```
<tools:off>
<user> what year did the Titanic sink?
<loom> That's outside my little head...
```
```
<tools:on>
<user> what year did the titanic sink?
<loom> Not stored in here, thankfully. Searching: <lookup>titanic sinking date</lookup><|endoftext|>
<result>The Titanic sank on 15 April 1912.</result>
<loom> April 1912 ...
```
The `<result>` block is injected by YOUR harness after executing the search.
Stop generation at `<|endoftext|>` or `<user>`.
## Option A β plain transformers (no internet)
```python
from transformers import GPT2LMHeadModel, AutoTokenizer
import torch
tok = AutoTokenizer.from_pretrained("TextileLabs/loom-spark")
model = GPT2LMHeadModel.from_pretrained("TextileLabs/loom-spark")
prompt = "<tools:off>\n<user> who are you?\n<loom>"
ids = tok(prompt, return_tensors="pt").input_ids
out = model.generate(ids, max_new_tokens=90, do_sample=True, temperature=0.85,
top_k=50, pad_token_id=tok.eos_token_id)
print(tok.decode(out[0][ids.shape[1]:]))
```
In offline mode the harness-style markup never appears β lookup tokens are
trained/banned out of distribution under `<tools:off>`.
> Tested on transformers β₯ 4.40 (both 4.x and 5.x) and Python 3.9β3.13.
> The playground widget above prefills the correct prompt format β keep the
> `<tools:β¦>` header and trailing `<loom>` or output quality drops sharply.
## Option B β llama.cpp / GGUF (no internet)
`loom-spark-f32.gguf` (in this repo) carries the same weights plus the custom
BPE tokenizer with all nine special tokens embedded. Feed it the mode-header
prompt format shown above and stop at `<|endoftext|>` or `<user>`:
```bash
llama-cli -m loom-spark-f32.gguf \
-p "<tools:off>\n<user> who are you?\n<loom>" -n 128 --temp 0.85 --top-k 50
```
## Option B2 β Ollama
The default Ollama template does NOT fit this model (it will ramble). Use the
Modelfile shipped in `ollama/`:
```bash
ollama pull hf.co/textilelabs/Loom-Spark
curl -L -O https://huggingface.co/textilelabs/Loom-Spark/resolve/main/ollama/Modelfile
ollama create loom-spark -f Modelfile
ollama run loom-spark "hi"
```
The Modelfile keeps multi-turn history in the trained format (each past turn is
re-wrapped in `<user>`/`<loom>` markers) and stops generation cleanly. That
gives the offline persona: greetings, identity, honest deferrals, made-up words.
Two honest caveats: if a reply ends in a `<lookup>β¦</lookup>` line, that's the
model saying *"I'd search for this"* β raw runners can't execute searches, so
for real internet answers use the harness (Option C). And at temperature 0.85 a
7M model occasionally misreads intent ("whats your name?" sometimes gets a
philosophy answer; ask again or drop `--temperature 0.7`). Both quirks shrink
in Loom Spark v2's curriculum.
Note: without a wrapper that executes `<lookup>` calls and splices `<result>`
blocks back in, GGUF/Ollama runners get the model's honest "I don't know, but
here's what I'd look up" side. That is by design.
## Option C β the harness (with internet)
This repo ships **`harness/`**, a small pip package that gives Loom Spark real,
keyless web search (DuckDuckGo) through a terminal chat (`loom-chat`) and a
local web GUI (`loom-web`). It intercepts the model's `<lookup>` calls, runs
the search, injects `<result>`, and lets the model summarize β exactly the
loop it was trained for.
```bash
# download this repo, then:
pip install ./harness
loom-chat # terminal, internet on
loom-web --port 7860 # local chat GUI with a tools on/off switch
```
Or drive it from Python:
```python
from loomspark_harness.loader import load_model_and_tokenizer
from loomspark_harness.agent import LoomAgent
from loomspark_harness.search import get_backend
model, tok, block = load_model_and_tokenizer("TextileLabs/loom-spark")
agent = LoomAgent(model, tok, backend=get_backend("duckduckgo"),
online=True, block_size=block)
print(agent.reply("what's the tallest mountain?")["text"])
```
## Architecture
Decoder-only transformer, pre-LN GELU blocks, tied embeddings, learned positions.
| | |
|---|---|
| layers | 5 |
| heads | 5 (head_dim 64) |
| d_model | 320 |
| context | 256 tokens |
| vocab | 4096 (custom BPE trained only on our generated corpus) |
| params | β 7.6M (7,558,080) |
Trained entirely on a procedurally generated, fully owned curriculum
(dialogue + simple prose; zero external datasets), CPU-only fp32 AdamW,
3,337 steps, final validation loss 0.3372.
## Limitations (by design)
Loom Spark knows almost nothing. That is the point. Do not use it for facts,
medicine, law, finance, or anything where being wrong costs more than company.
|