Instructions to use tejgokani/noirwrit-base with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- llama.cpp
How to use tejgokani/noirwrit-base 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 tejgokani/noirwrit-base:Q4_K_M # Run inference directly in the terminal: llama cli -hf tejgokani/noirwrit-base:Q4_K_M
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible server with a web UI: llama serve -hf tejgokani/noirwrit-base:Q4_K_M # Run inference directly in the terminal: llama cli -hf tejgokani/noirwrit-base:Q4_K_M
Build from source code
git clone https://github.com/ggml-org/llama.cpp.git cd llama.cpp cmake -B build cmake --build build -j --target llama-app # Start a local OpenAI-compatible server with a web UI: ./build/bin/llama serve -hf tejgokani/noirwrit-base:Q4_K_M # Run inference directly in the terminal: ./build/bin/llama cli -hf tejgokani/noirwrit-base:Q4_K_M
Use Docker
docker model run hf.co/tejgokani/noirwrit-base:Q4_K_M
- Llama new
- LM Studio
- Jan
- vLLM
How to use tejgokani/noirwrit-base with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "tejgokani/noirwrit-base" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "tejgokani/noirwrit-base", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker
docker model run hf.co/tejgokani/noirwrit-base:Q4_K_M
- Ollama
How to use tejgokani/noirwrit-base with Ollama:
ollama run hf.co/tejgokani/noirwrit-base:Q4_K_M
- Unsloth Desktop
- Docker Model Runner
How to use tejgokani/noirwrit-base with Docker Model Runner:
docker model run hf.co/tejgokani/noirwrit-base:Q4_K_M
- Lemonade
How to use tejgokani/noirwrit-base with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull tejgokani/noirwrit-base:Q4_K_M
Run and chat with the model
lemonade run user.noirwrit-base-Q4_K_M
List all available models
lemonade list
- Atomic Chat
noirwrit-base
A 97.5M-parameter language model trained from scratch on 1,828 public domain crime, detective and pulp books (published 1930 or earlier). It is the model behind Noirwrit, an offline app that plans and writes noir and detective novels chapter by chapter on a laptop.
Files
| File | What it is |
|---|---|
noirwrit-base-q8_0.gguf |
llama.cpp, 8-bit (112 MB). The default for the app. |
noirwrit-base-q4_k_m.gguf |
llama.cpp, 4-bit (66 MB). Faster and smaller, slightly lower quality. |
noirwrit-base-fp16.pt |
PyTorch state dict for Noirwrit's own model code (noirwrit.model.gpt), fp16 (210 MB). |
noirwrit-16k.json |
The 16k byte-level BPE tokenizer (Hugging Face tokenizers format). |
Use
With Noirwrit (recommended; it adds the planner, story bible, memory and consistency checks):
git clone https://github.com/tejgokani/noirwrit && cd noirwrit
make setup && make model && make run
With llama.cpp directly (a base model: give it the start of a passage, not an instruction):
llama-completion -m noirwrit-base-q8_0.gguf -no-cnv --temp 0.75 --min-p 0.05 --repeat-penalty 1.12 \
-p "They found the body at the foot of the stairs, and by the time I got there the rain had"
Summary
| Item | Value |
|---|---|
| Architecture | Decoder-only transformer written from scratch, Llama-compatible layout: 12 layers, d_model 768, 12 heads, SwiGLU (2048), RMSNorm, RoPE (theta 10000), tied embeddings |
| Parameters | 97.5M |
| Context | 2048 tokens |
| Tokenizer | Own byte-level BPE, 16,384 tokens, trained on the same corpus |
| Training data | 1,828 public domain books from Project Gutenberg, all published 1930 or earlier (data/SOURCES.md) |
| Training tokens | 719M (4 epochs over 180M tokens) |
| Hardware | One Tesla T4 on Kaggle's free tier, fp16 with a gradient scaler, torch.compile |
| Training time | 9.6 hours, 10,973 steps of 65,536 tokens, median 21,080 tokens/s |
| Cost | $0 |
| Files | noirwrit-base-q8_0.gguf (112 MB), noirwrit-base-q4_k_m.gguf (66 MB), best.pt (fp16 PyTorch, 210 MB) |
| License | MIT (code and weights); the training text is public domain in the US |
Training
Three-stage curriculum:
| Stage | Data | Share of steps | Learning rate | Best validation loss |
|---|---|---|---|---|
| 1. General fiction | adventure, gothic and other pre-1931 fiction (40M tokens) | 15% | 6e-4, cosine | 3.79 |
| 2. Crime and detective | Doyle, Christie's early novels, Chesterton, Collins, Green, Rinehart and others (136M tokens) | 75% | 6e-4, cosine | 3.14 |
| 3. Noir voice | Hammett, Burnett, Whitfield, Packard and dated pulp (4M tokens) | 10% | 0.3x, early stop | 2.55 |
Validation is the last 2% of every book. Each stage's loss is measured on that stage's own validation set, so the numbers compare within a stage, not across stages. The released weights are the best noir-stage checkpoint (validation loss 2.55, perplexity about 12.8). For comparison, the 5M tiny smoke-test model reached 5.31 on the crime set.
Speed on a MacBook Air M3 (16 GB)
| Runtime | Generation | Peak RAM |
|---|---|---|
| llama.cpp Q8_0 (Metal) | 229 tokens/s | 0.26 GB |
| llama.cpp Q4_K_M | 298 tokens/s | 0.21 GB |
| PyTorch CPU int8 (fallback) | 57 tokens/s |
A 3,000-word chapter takes about 23 seconds. ETA error with this model is under 6% (docs/BENCH.md).
What it does well
Writes grammatical, period-flavoured English prose in the voice of early twentieth-century detective and pulp fiction: dialogue with natural attribution, scene description, and the cadence of the Gutenberg-era crime novel. Samples are in docs/samples/.
Limits
- It is a 98M model. It keeps a sentence and usually a paragraph together, but loses track of details over a page: a character found dead may be spoken to a paragraph later, or a woman's hair may change colour. The planner, story bible, memory and consistency pass supply the plot logic and fix what they can (names, dead characters speaking, clue order). They do not make the model reason.
- Public domain data means a classic voice (1880s to 1930), not modern thriller pacing or modern idiom. Expect archaic spellings like "clew".
- It reproduces the attitudes and stereotypes of its source era. Read samples with that in mind.
- It sometimes echoes famous characters from its training books; the consistency pass replaces their names with the story's own cast.
- "Learns" means Noirwrit remembers and retrieves earlier stories. The weights do not change on the laptop.
Reproduce
python -m noirwrit.corpus.build
python -m noirwrit.tokenizer.train_tokenizer
make train-online # Kaggle, see docs/ONLINE_TRAINING.md
- Downloads last month
- 40
4-bit
8-bit