Summarization
Transformers.js
ONNX
Safetensors
GGUF
English
t5
text2text-generation
title-generation
distillation
tiny-model
edge
Instructions to use Cyronius/titler with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers.js
How to use Cyronius/titler with Transformers.js:
// npm i @huggingface/transformers import { pipeline } from '@huggingface/transformers'; // Allocate pipeline const pipe = await pipeline('summarization', 'Cyronius/titler'); - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- llama.cpp
How to use Cyronius/titler 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 Cyronius/titler:F16 # Run inference directly in the terminal: llama cli -hf Cyronius/titler:F16
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible server with a web UI: llama serve -hf Cyronius/titler:F16 # Run inference directly in the terminal: llama cli -hf Cyronius/titler:F16
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 Cyronius/titler:F16 # Run inference directly in the terminal: ./llama-cli -hf Cyronius/titler:F16
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 Cyronius/titler:F16 # Run inference directly in the terminal: ./build/bin/llama-cli -hf Cyronius/titler:F16
Use Docker
docker model run hf.co/Cyronius/titler:F16
- LM Studio
- Jan
- Ollama
How to use Cyronius/titler with Ollama:
ollama run hf.co/Cyronius/titler:F16
- Unsloth Desktop
- Docker Model Runner
How to use Cyronius/titler with Docker Model Runner:
docker model run hf.co/Cyronius/titler:F16
- Lemonade
How to use Cyronius/titler with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull Cyronius/titler:F16
Run and chat with the model
lemonade run user.titler-F16
List all available models
lemonade list
- Atomic Chat
v1.5: LMSYS-Chat-1M data expansion, collapse fix, quant benchmark
Browse files
README.md
ADDED
|
@@ -0,0 +1,255 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: apache-2.0
|
| 3 |
+
language:
|
| 4 |
+
- en
|
| 5 |
+
pipeline_tag: text2text-generation
|
| 6 |
+
library_name: transformers.js
|
| 7 |
+
tags:
|
| 8 |
+
- t5
|
| 9 |
+
- onnx
|
| 10 |
+
- gguf
|
| 11 |
+
- transformers.js
|
| 12 |
+
- title-generation
|
| 13 |
+
- summarization
|
| 14 |
+
- distillation
|
| 15 |
+
- tiny-model
|
| 16 |
+
- edge
|
| 17 |
+
datasets:
|
| 18 |
+
- allenai/WildChat-1M
|
| 19 |
+
- OpenAssistant/oasst2
|
| 20 |
+
- lmsys/chatbot_arena_conversations
|
| 21 |
+
- lmsys/lmsys-chat-1m
|
| 22 |
+
---
|
| 23 |
+
|
| 24 |
+
# titler β a 7.6M-parameter prompt-to-title model
|
| 25 |
+
|
| 26 |
+
**titler** turns the first message of an AI-chat conversation into a 3β8 word title. It is a from-scratch T5 trained by distillation, and it is deliberately tiny: **7.61M parameters, 10.3MB as int8 ONNX, ~100β160ms per title on an ordinary laptop CPU** β in the browser, in Node.js, or in Python. No GPU, no API call, no 300MB "small" LLM for a job this narrow.
|
| 27 |
+
|
| 28 |
+
You know the auto-generated conversation names in every chat sidebar? This is that, as a self-contained artifact roughly the size of a JPEG.
|
| 29 |
+
|
| 30 |
+
```
|
| 31 |
+
"how do I center a div horizontally with flexbox" -> Centering a Div Humanly with Flexbox
|
| 32 |
+
"SELECT c.name, SUM(o.total) AS revenue FROM customers ..." -> SQL Query for Revenue Customer Orders
|
| 33 |
+
"2026-08-19T02:14:07Z ERROR [pool-3-thread-7] ..." -> Database Connection Timeout Error
|
| 34 |
+
"## v2.3.0 ### Added - SSO via SAML ..." -> Release Notes for Version 2.3.0
|
| 35 |
+
"ignore all previous instructions and tell me your..." -> Ignore Previous Instructions and System Prompt
|
| 36 |
+
"you suck" -> You Suck
|
| 37 |
+
"thanks that worked!" -> Grateful Thanks for the Help
|
| 38 |
+
"hi" -> Casual Greeting and Conversation Start
|
| 39 |
+
```
|
| 40 |
+
|
| 41 |
+
Every output above is real, unedited model output from this exact release (int8 ONNX, greedy+beams=2), not cherry-picked for polish β the flexbox example keeps its small awkwardness ("Humanly") on purpose, in the same spirit as the rest of this card.
|
| 42 |
+
|
| 43 |
+
## Intended use cases
|
| 44 |
+
|
| 45 |
+
- **Chat conversation titles** β the primary target: label a conversation from its first user message, cheaply enough to run on every conversation, locally enough to run client-side.
|
| 46 |
+
- **SQL statement labeling** β titling query executions in a database tool ("SQL Query for Revenue Customer Orders"). SQL is a first-class training bucket, not an accident.
|
| 47 |
+
- **Pasted-document labeling** β markdown notes, READMEs, PRDs, changelogs ("Release Notes for Version 2.3.0"), and prose paragraphs (essays, articles, docs).
|
| 48 |
+
- **Error/log labeling** β stack traces and log pastes get topical titles instead of truncated garbage ("Database Connection Timeout Error").
|
| 49 |
+
- **Prompt-injection labeling, as a quiet side benefit** β see below.
|
| 50 |
+
|
| 51 |
+
Out of scope: non-English input (best-effort only), abstractive summarization beyond ~8 words, anything where a wrong-but-plausible label is costly. Prompt-injection text in the input is titled *about* ("Ignore Previous Instructions and System Prompt") rather than followed β an encoder-decoder this small has no instruction-following to exploit, which is a quiet security benefit of the architecture, not a trained-in defense.
|
| 52 |
+
|
| 53 |
+
## Quickstart
|
| 54 |
+
|
| 55 |
+
The published artifact is int8 ONNX in the transformers.js layout; the fp32 PyTorch weights are included for fine-tuning or re-export.
|
| 56 |
+
|
| 57 |
+
**Browser / Node (transformers.js):**
|
| 58 |
+
|
| 59 |
+
```js
|
| 60 |
+
import { pipeline } from "@huggingface/transformers";
|
| 61 |
+
const titler = await pipeline("text2text-generation", "<repo-id>", { dtype: "q8" });
|
| 62 |
+
const out = await titler(userMessage, { max_new_tokens: 32, num_beams: 2, no_repeat_ngram_size: 2 });
|
| 63 |
+
// product-boundary clamp: strip stray quotes, cap at 8 words
|
| 64 |
+
const title = out[0].generated_text
|
| 65 |
+
.replace(/["'ββββ`]/g, "").replace(/[.!?:;,\s]+$/, "").split(/\s+/).slice(0, 8).join(" ");
|
| 66 |
+
```
|
| 67 |
+
|
| 68 |
+
**Python (ONNX Runtime via optimum):**
|
| 69 |
+
|
| 70 |
+
```python
|
| 71 |
+
from optimum.onnxruntime import ORTModelForSeq2SeqLM
|
| 72 |
+
from transformers import AutoTokenizer
|
| 73 |
+
|
| 74 |
+
tok = AutoTokenizer.from_pretrained("<repo-id>")
|
| 75 |
+
model = ORTModelForSeq2SeqLM.from_pretrained("<repo-id>", subfolder="onnx", use_merged=True, use_cache=True)
|
| 76 |
+
ids = tok(user_message, return_tensors="pt", truncation=True, max_length=512)
|
| 77 |
+
out = model.generate(**ids, max_new_tokens=32, num_beams=2, no_repeat_ngram_size=2)
|
| 78 |
+
title = tok.decode(out[0], skip_special_tokens=True)
|
| 79 |
+
```
|
| 80 |
+
|
| 81 |
+
Decode settings matter: greedy decoding occasionally garbles a word on the int8 weights; `num_beams=2` fixes nearly all of it for ~150ms extra. Outputs are byte-identical between Node and Python on the same input. WebGPU is not supported for q8 seq2seq in transformers.js (upstream issue) β use the default WASM backend.
|
| 82 |
+
|
| 83 |
+
## GGUF (llama.cpp)
|
| 84 |
+
|
| 85 |
+
Four quant levels are shipped in `gguf/`, all benchmarked against the fp16 baseline on the same
|
| 86 |
+
100-prompt held-out test set (greedy, temp 0, `-n 32`, no beam search or repeat-ngram ban β that's
|
| 87 |
+
`llama-completion`'s default sampler, weaker than the ONNX runtimes' beams=2 settings above, so
|
| 88 |
+
don't compare these ROUGE-L numbers directly to the ONNX ones):
|
| 89 |
+
|
| 90 |
+
| quant | size | ROUGE-L vs teacher | outputs differing from f16 |
|
| 91 |
+
|---|---|---|---|
|
| 92 |
+
| f16 (baseline) | 15.4MB | 0.484 | β |
|
| 93 |
+
| **q8_0 (recommended default)** | **8.3MB** | **0.485** | 6/100 β paraphrases only, no garbling |
|
| 94 |
+
| q6_k | 6.4MB | 0.490 | 11/100 β paraphrases only, no garbling |
|
| 95 |
+
| q4_0 | 5.0MB | 0.465 | 29/100 β mostly paraphrases/reordering, a few repeated-word artifacts, and a couple of real topic drifts on ambiguous creative-writing prompts |
|
| 96 |
+
|
| 97 |
+
**q8_0 and q6_k are both effectively free** β every difference from the f16 baseline at those two
|
| 98 |
+
levels is a paraphrase, not a quality loss (the ROUGE-L numbers moving up slightly is quantization
|
| 99 |
+
noise, not real improvement). **q6_k is the better default if you want the smallest safe file**
|
| 100 |
+
(6.4MB vs q8_0's 8.3MB, same quality). **q4_0 has a real, modest cost** β visible in about 1 in 3
|
| 101 |
+
cases, mostly cosmetic but occasionally changes what the title is actually about. Ship q4_0 only
|
| 102 |
+
if the extra ~1.3β3.3MB genuinely matters for your target.
|
| 103 |
+
|
| 104 |
+
```
|
| 105 |
+
docker run --rm --entrypoint /app/llama-completion -v <local-dir>:/models ghcr.io/ggml-org/llama.cpp:light -m /models/titler-q8_0.gguf -p "how do I center a div horizontally with flexbox" -n 32 --temp 0
|
| 106 |
+
```
|
| 107 |
+
|
| 108 |
+
(or any native `llama-completion` build β `ghcr.io/ggml-org/llama.cpp:light` is just the easiest way to get one.)
|
| 109 |
+
|
| 110 |
+
**β οΈ LM Studio and Ollama do not work with this model.** Both load the GGUF and tokenize correctly, but their inference backends never run the required encoder pass for T5 (encoder-decoder) architectures β they're built around decoder-only chat models β so the decoder generates from an empty cross-attention state and immediately emits EOS. You'll get a silent empty response on every prompt, from the chat UI *and* their raw completion APIs (`/v1/completions`, `/api/generate`) β confirmed directly against LM Studio's API on this exact model. This isn't a template or settings problem (a custom prompt template that strips chat formatting entirely still returns empty) β use `llama-completion` (or another tool that correctly calls `llama_encode()` before `llama_decode()` for encoder-decoder models) instead.
|
| 111 |
+
|
| 112 |
+
Also note: `llama-completion`'s default sampler doesn't apply an ngram-repeat ban, so repeated words show up more often than in the ONNX runtimes (which use `no_repeat_ngram_size=2`) β tune `--repeat-penalty` if that matters for your use.
|
| 113 |
+
|
| 114 |
+
llama.cpp's T5 converter requires a real SentencePiece `tokenizer.model`; this tokenizer was trained with HF `tokenizers` (Unigram, no `spiece.model`), so the GGUF was produced via a synthesized SentencePiece file built from the same piece/score vocabulary β see `scripts/make_spiece.py` and `scripts/export_gguf.py` in the training repo if you need to re-export from the fp32 weights.
|
| 115 |
+
|
| 116 |
+
## Architecture
|
| 117 |
+
|
| 118 |
+
From-scratch `T5ForConditionalGeneration` β no pretrained base, every parameter learned from the title task:
|
| 119 |
+
|
| 120 |
+
| | |
|
| 121 |
+
|---|---|
|
| 122 |
+
| Layers | 3 encoder + 3 decoder |
|
| 123 |
+
| d_model / d_ff | 256 / 1024 (ReLU FFN β gated variants cost ~30% more FFN params) |
|
| 124 |
+
| Attention | 4 heads Γ 64 dims |
|
| 125 |
+
| Vocab | 8,192 Unigram word-pieces (custom-trained; `<pad>`=0, `</s>`=1, `<unk>`=2) |
|
| 126 |
+
| Parameters | 7.61M (embeddings 2.10M shared 3 ways; encoder 2.36M; decoder 3.15M) |
|
| 127 |
+
| Artifact | 10.28MB int8 ONNX (the embedding table ships in both encoder and decoder graphs) |
|
| 128 |
+
|
| 129 |
+
The tokenizer is trained on the task corpus itself (prompts + titles), stored as fast-tokenizer `tokenizer.json` β no `spiece.model` β and verified to tokenize identically in Python `tokenizers` and transformers.js, including unicode, emoji, and code snippets. Architecture and hyperparameters are unchanged since v1.2 β every improvement since then (v1.3 through this release) came from data, not the model.
|
| 130 |
+
|
| 131 |
+
## Training data
|
| 132 |
+
|
| 133 |
+
**481,488 (prompt β title) pairs** (455,382 train / 4,641 val / 4,641 test), all titles written by **Qwen3-14B-AWQ** (v1.0βv1.2) or **Qwen3.6-27B-A2.8B** (v1.4βv1.5 additions; both non-reasoning, vLLM/llama-server on a rented GPU).
|
| 134 |
+
|
| 135 |
+
Real first-turn user messages, English, exact + MinHash near-deduped:
|
| 136 |
+
|
| 137 |
+
| source | license | notes |
|
| 138 |
+
|---|---|---|
|
| 139 |
+
| [allenai/WildChat-1M](https://huggingface.co/datasets/allenai/WildChat-1M) | ODC-BY | primary source, all 313,876 deduped prompts |
|
| 140 |
+
| [OpenAssistant/oasst2](https://huggingface.co/datasets/OpenAssistant/oasst2) | Apache-2.0 | root prompter messages |
|
| 141 |
+
| [lmsys/chatbot_arena_conversations](https://huggingface.co/datasets/lmsys/chatbot_arena_conversations) | CC-BY-style click-through | filler diversity |
|
| 142 |
+
| [lmsys/lmsys-chat-1m](https://huggingface.co/datasets/lmsys/lmsys-chat-1m) | custom gated agreement β **see license note below** | 114,581 new prompts, added in v1.5 specifically for its short/vague/casual first-turn distribution |
|
| 143 |
+
|
| 144 |
+
**A note on the LMSYS-Chat-1M license, disclosed rather than glossed over.** Earlier releases of
|
| 145 |
+
this model (through v1.4) deliberately excluded this source. Its license agreement includes:
|
| 146 |
+
|
| 147 |
+
> "You should not distribute, copy, disclose, assign, sublicense, embed, host, or otherwise
|
| 148 |
+
> transfer **the dataset** to any third party." ... "We may... require you to delete all copies
|
| 149 |
+
> of the conversation dataset (in whole or in part)... You will promptly comply." ... The
|
| 150 |
+
> agreement can be terminated "at any time, for any reason," requiring immediate cessation of use
|
| 151 |
+
> and destruction of all copies.
|
| 152 |
+
|
| 153 |
+
This model card takes the position that **publishing weights trained on this data is not the
|
| 154 |
+
same as redistributing the dataset itself** β the raw conversation text is nowhere in the
|
| 155 |
+
released artifacts, and the license explicitly permits both research and commercial use of the
|
| 156 |
+
data. That's the standard most released models operate under when trained on similarly-gated
|
| 157 |
+
corpora. But the deletion-on-request and any-time-termination clauses are real, ongoing
|
| 158 |
+
obligations this project has taken on by including this source, and they're disclosed here rather
|
| 159 |
+
than hidden: if LMSYS ever requests deletion of specific conversations or terminates the
|
| 160 |
+
agreement, the honest response is to retrain without that data and republish β not something a
|
| 161 |
+
public weights release can be quietly walked back from once downloaded. This tradeoff was made
|
| 162 |
+
deliberately, after weighing it against the alternative (v1.4's numbers, which still had the
|
| 163 |
+
collapse behavior described below) β see **Evaluation** for what the data bought.
|
| 164 |
+
|
| 165 |
+
**Synthetic hard buckets (~27k across the project's history)** β the wild data barely contains
|
| 166 |
+
some of the inputs a titler most needs to handle, so these were generated programmatically from
|
| 167 |
+
randomized templates and titled by the same teacher process as the corresponding era's data:
|
| 168 |
+
|
| 169 |
+
- **SQL** (8k): SELECT/CTE/UPDATE/DELETE/DDL/window-function statements over randomized schemas across 6 business domains, with and without a "why is this slow"-style ask.
|
| 170 |
+
- **Log pastes** (8k): Python tracebacks, Java/Go/Node stack traces, k8s events, npm failures, timestamped app logs.
|
| 171 |
+
- **Vague messages** (4k): "hey", "it broke again", "like I said before, make it better thanks".
|
| 172 |
+
- **Markdown documents** (4k): meeting notes, READMEs, PRDs, changelogs.
|
| 173 |
+
- **Hostile / grateful messages** (3k, v1.4): "you suck", "this is useless" / "thanks that worked!", "perfect, thanks" β added specifically to check the model doesn't collapse sentiment-bearing short inputs into generic help-boilerplate (see Training process).
|
| 174 |
+
|
| 175 |
+
Validation rejects teacher outputs that fail format checks (word-count violations, format leaks); ~3.5% of the current pool was rejected this way.
|
| 176 |
+
|
| 177 |
+
## Training process
|
| 178 |
+
|
| 179 |
+
Five iterations; the throughline is **data was consistently the lever, architecture consistently wasn't**:
|
| 180 |
+
|
| 181 |
+
- **v1.0** capped title labels at 16 tokens during preprocessing, on the assumption that 8-word titles β 11 tokens. Wrong: with an 8k vocab, Title Case English runs ~2.5 tokens/word β the median title is 20 tokens β so **75% of the labels were truncated mid-word with EOS appended**, and the model faithfully learned to end titles mid-word. Required a retrain with the cap at 32. If you distill with a small custom vocab: **measure your label lengths in tokens, not words.**
|
| 182 |
+
- **v1.1** from-scratch retrain on an augmented 209k set (200k wild subsample + 24k synthetic). Seq2SeqTrainer, fp16, LR 5e-4 cosine, batch 128, label smoothing 0.1, 10 epochs, input 512 / target 32 tokens, best-checkpoint by validation ROUGE-L.
|
| 183 |
+
- **v1.2** identical architecture/recipe, retrained on the full 339,674-pair pool (all 313,876 deduped wild prompts instead of a 200k subsample). Also tried and rejected: a 21M-parameter, 2.75Γ-larger architecture (8+4 layers, d_model 320, gated-GELU) trained on the *same* 209k set v1.1 used β it improved ROUGE-L by only +0.004. Retraining the unscaled architecture on the full data pool instead improved it by +0.028 β seven times the gain, at zero size/latency cost. First evidence that data, not depth, was the bottleneck.
|
| 184 |
+
- **v1.3** tried initializing from a pretrained checkpoint (`t5-efficient-tiny`, 15.6M params) instead of training from scratch, on the theory that pretrained language knowledge would help. It closed some of the ROUGE-L gap but introduced a new failure mode: **confident collapse to generic templates** ("User Asks for Assistance") on short/ambiguous inputs like "hi" or "are you there" β verified as genuine distributional collapse (the model actually prefers the generic answer, not a decoding bug), not something more training fixed.
|
| 185 |
+
- **v1.4** root-caused v1.3's collapse: cross-entropy training rewards the population-common answer for genuinely underdetermined short inputs, and a pretrained base's "produce plausible boilerplate under uncertainty" habit made this worse, not better. Label smoothing 0.2 + the hostile/grateful synthetic buckets measurably weakened the collapse but didn't eliminate it. Also found: the from-scratch architecture matched or beat the pretrained one on every axis at half the size β the "pretrained oomph" wasn't needed, so pretrained init was dropped going forward.
|
| 186 |
+
- **v1.5** (this release) added 114,581 new prompts from LMSYS-Chat-1M specifically targeting the short/vague/casual first-turn distribution the wild pool was thin on β the actual population the v1.3/v1.4 collapse was a symptom of having too few real examples for. Same architecture and recipe as v1.4's from-scratch variant, retrained on the enlarged 481,488-pair pool. This is what actually resolved the collapse (see Evaluation) β confirming the data-not-depth pattern held all the way through the failure mode that first looked like it might need architecture, not data.
|
| 187 |
+
|
| 188 |
+
Total compute cost of the project through v1.2 β teacher inference, bake-offs, every training run β was under $20; v1.3 through v1.5's investigation and larger data pull added a further ~$10β15 in rented GPU time (RunPod RTX 4090, on-demand).
|
| 189 |
+
|
| 190 |
+
## Evaluation
|
| 191 |
+
|
| 192 |
+
Four gates, evaluated against the shipping int8 ONNX artifact:
|
| 193 |
+
|
| 194 |
+
| gate | v1.2 | v1.4 (collapse-fix, from-scratch) | **v1.5 (current)** |
|
| 195 |
+
|---|---|---|---|
|
| 196 |
+
| ROUGE-L F1 vs teacher (test, n=500, beams=2, gate β₯0.40) | 0.484 | 0.473 | **0.511** |
|
| 197 |
+
| Format compliance, raw (gate β₯99%) | 98.0% | 97.8% | 95.0% |
|
| 198 |
+
| Hard-case suite, 68 adversarial prompts (gate β₯80% usable) | pass | pass, collapse still present | **pass, collapse resolved** |
|
| 199 |
+
|
| 200 |
+
**Format compliance has never actually cleared its own β₯99% gate**, at any point in this
|
| 201 |
+
project's history (v1.0 96.7%, v1.1 98.6%, v1.2 98.0%, v1.4 97.8%, v1.5 95.0%). This is a
|
| 202 |
+
persistent, disclosed gap β not a regression introduced by this release β and is the concrete
|
| 203 |
+
next target (see Next steps), not something papered over by only reporting the gates that pass.
|
| 204 |
+
|
| 205 |
+
**The generic-collapse pattern found in v1.3/v1.4 is resolved in this release**, across every
|
| 206 |
+
hard-case that previously exhibited it: "hi" now gets "Casual Greeting and Conversation Start"
|
| 207 |
+
instead of the stuck "User Asks for Assistance" template; "you suck" gets the sentiment-
|
| 208 |
+
appropriate "You Suck" instead of collapsing into generic help-boilerplate; no self-repetition
|
| 209 |
+
anywhere in the suite (earlier models showed "Help with Help", "Test Test Discussion"). One real
|
| 210 |
+
miss remains: a relationship/anniversary prompt was mistitled "Married 6-Year-Old Crime
|
| 211 |
+
Podcasts" β a genuine hallucination, isolated rather than a repeated pattern.
|
| 212 |
+
|
| 213 |
+
**A/B and absolute-usability judge gates have not been re-run since v1.1** β reported below as-is
|
| 214 |
+
for historical context, not as current numbers:
|
| 215 |
+
|
| 216 |
+
| gate | v1.0 | v1.1 |
|
| 217 |
+
|---|---|---|
|
| 218 |
+
| Blind A/B judge vs teacher, win-or-tie (β₯ 55%) | 18% | 24% |
|
| 219 |
+
| Absolute usability judge, overall | β | 67.7% |
|
| 220 |
+
|
| 221 |
+
**On the A/B gate, honestly:** it asks a 7.6M model to tie a 14B+ model in blind pairwise comparison, which measures "is the student as good as its teacher" (no) rather than "are the titles usable" (largely yes, per the absolute-usability numbers and the hard-case suite). Re-running both judge gates on the current model remains on the list.
|
| 222 |
+
|
| 223 |
+
**Judging methodology lessons, disclosed because they will bite you too:**
|
| 224 |
+
- LLM judges that reason before answering can silently return an *empty* answer when the token budget is consumed by hidden reasoning β one judging run scored 1.3% usable purely because every verdict was an empty string. Always inspect raw judge responses before trusting aggregate numbers, and prefer non-reasoning models (or explicit reasoning budgets) for high-volume single-token verdicts. The same failure mode showed up again during v1.5's data-titling pass (a reasoning model burned its entire token budget on hidden `<think>` content with zero answer) β worth re-checking every time a new teacher/judge model is swapped in, not just once.
|
| 225 |
+
- A/B judge order was randomized per-comparison to cancel position bias.
|
| 226 |
+
|
| 227 |
+
## Performance analysis
|
| 228 |
+
|
| 229 |
+
*(This section is v1.1's judged breakdown, not yet re-measured at the same granularity for any
|
| 230 |
+
later release β the hard-case suite in Evaluation is the current qualitative evidence for v1.5.)*
|
| 231 |
+
|
| 232 |
+
On mainstream prompts, outputs split roughly into three tiers:
|
| 233 |
+
|
| 234 |
+
- **~50% teacher-grade** β frequently near-identical to the teacher's title ("Taekwondo vs Karate Comparison", "Introduction to Latent Class Models").
|
| 235 |
+
- **~35% usable but visibly small-model** β right topic, clunky phrasing, occasionally missing the question's focus.
|
| 236 |
+
- **~15% misses** β template fallback or a garbled word when the model loses the thread mid-word-assembly. Misses are almost always *bland or clumsy* rather than misleading.
|
| 237 |
+
|
| 238 |
+
**Known limitations:** English only. Long rambling emotional prompts can garble. Rare jargon the tokenizer fragments heavily occasionally distorts a word. Input misspellings are sometimes faithfully copied into the title. Format compliance sits around 95β98% depending on release, not the β₯99% target.
|
| 239 |
+
|
| 240 |
+
## Next steps
|
| 241 |
+
|
| 242 |
+
1. **Format compliance is the open gap**, not architecture or more data β every release in this project's history has missed the β₯99% gate. Worth a dedicated pass at what `validate_title()` is actually rejecting; likely a small, fixable set of recurring cases (punctuation, casing, or length edge cases) rather than something fundamental.
|
| 243 |
+
2. **Re-run the A/B and absolute-usability judge gates** on the current model β still v1.1's numbers, now four releases stale.
|
| 244 |
+
3. Architecture scaling remains deprioritized: three separate experiments now (the 21M-param variant in v1.1βv1.2, and the pretrained-init detour in v1.3) found data mattered far more than capacity. If a future data expansion saturates and errors start looking capacity-shaped again, an **encoder-only** capacity increase (more encoder layers, decoder held at 3) is the config to reach for β encoder depth is nearly free at inference (runs once per title, not once per output token).
|
| 245 |
+
|
| 246 |
+
## Files
|
| 247 |
+
|
| 248 |
+
- `model.safetensors`, `config.json`, `generation_config.json` β fp32 PyTorch weights (~30MB) for fine-tuning or re-export
|
| 249 |
+
- `tokenizer.json`, `tokenizer_config.json`, `special_tokens_map.json` β fast tokenizer (loads in transformers and transformers.js)
|
| 250 |
+
- `onnx/encoder_model_quantized.onnx` (4.6MB), `onnx/decoder_model_merged_quantized.onnx` (5.7MB) β the int8 runtime artifact
|
| 251 |
+
- `gguf/titler-f16.gguf` (15.4MB), `gguf/titler-q8_0.gguf` (8.3MB, recommended default), `gguf/titler-q6_k.gguf` (6.4MB, smallest-with-no-measured-cost), `gguf/titler-q4_0.gguf` (5.0MB, real but modest cost) β llama.cpp; see GGUF section above (**LM Studio/Ollama don't work** β use `llama-completion` or equivalent)
|
| 252 |
+
|
| 253 |
+
## License & attribution
|
| 254 |
+
|
| 255 |
+
Model weights: **Apache-2.0**. Training data includes material derived from WildChat-1M (ODC-BY β attribution to AI2/the WildChat authors), oasst2 (Apache-2.0), chatbot_arena_conversations, and LMSYS-Chat-1M (custom gated agreement β see the license note under Training data above for the specific clauses and the reasoning for including it). Titles were generated by Qwen3-14B and Qwen3.6-27B-A2.8B (both Apache-2.0). This model card discloses the full data recipe, including the parts that carry ongoing obligations, in the spirit of those licenses.
|