/ Модель

Характеристики

Лицензия
MIT
Опубликована
2 сен 2026

aparte-titler

Разметка токеновТекст → label

Компактная многоязычная модель apartejs выбирает слова из первого сообщения пользователя, чтобы локально создавать заголовки разговоров.

19скачиваний за 30 дней0лайковвеса обновлены23 сен 2026

Бенчмарки

Как модель справилась с задачами пользователей ailist и что о ней публикуют открытые лидерборды

Публичные оценки

Из открытых лидербордов. Сравнивайте результаты одного теста при одинаковых условиях — отсутствие оценки не значит, что модель хуже.

В подключённых источниках результатов для этой модели пока нет.

Что умеет модель

Описание составлено по карточке модели и метаданным Hugging Face

apartejs/aparte-titler — компактная модель семейства aparte-titler от apartejs для создания заголовка разговора по первому сообщению пользователя. Она выбирает из сообщения от 3 до 6 слов и сохраняет их исходный порядок, поэтому заголовок состоит только из текста запроса и не генерирует новые формулировки. Модель предназначена для локального запуска в браузере, Node.js или Python без API-вызовов; доступны ONNX-графы и файлы нескольких точностей, включая рекомендованную int3. Для многоязычной версии на 17 европейских языках файл int3 занимает 133 КБ; README также описывает варианты на 6 языках и отдельные языковые модели.

По данным карточки, обработка типичного сообщения длиной около 300 символов занимает несколько миллисекунд на одном ядре CPU. В бенчмарке модель превосходит базовый вариант, который берёт первые пять слов сообщения; на шести языках многоязычная версия приближается к результатам значительно более крупной модели-учителя. Официальная задача — token classification: модель выделяет слова для заголовка. Лицензия — MIT. Поддерживаемые языки: английский, французский, испанский, немецкий, португальский, итальянский, нидерландский, польский, шведский, датский, финский, чешский, румынский, норвежский, венгерский, хорватский и литовский.

Сценарии применения

  • создание заголовка чата по первому сообщению
  • автоматическое именование разговора в браузерном приложении
  • локальная генерация заголовков без обращения к API
  • создание коротких заголовков для сообщений на европейских языках

Ограничения

Модель только выбирает и копирует от 3 до 6 слов из первого сообщения, поэтому не может перефразировать его или добавлять контекст из последующей переписки. Качество снижается на длинных сообщениях; README приводит более низкие показатели для диапазонов свыше 40 слов.

Карточка модели

README от автора на Hugging Face, как он его опубликовал

Открыть на Hugging Face

aparte-titler

A title for a conversation, from its first message, in the browser — the weight of an icon, no API call.

aparte-titler picks 3 to 6 words of the user's first message and returns them, in order, as the conversation's title. This repository holds every model of the family: one file for 17 European languages (133 KB in int3), a 6-language file, and one file per language (41 KB), each in four precisions — plus ONNX graphs for every model. It runs in a few milliseconds on one CPU core (2–4 ms in Python, 6–7 ms in the pure-JS runtime, for a typical 300-character message), in the browser, in Node or in Python, with no framework and no dependency. On the benchmark it scores nearly twice the naive baseline (the first five words of the message), and on the six languages where the comparison can be made fairly, the 133 KB file reaches 94 % of its 2.4 GB teacher — a model 18,000× heavier. Because it only ever copies words from the message, it is immune to prompt injection by construction: an instruction hidden in a message can at worst produce a poor title, never be executed.

score against size

What changed in 1.2

  • Every model saw about 33,000 examples per language, up from 1,000–25,000. Fourteen languages were topped up with English messages machine-translated by the teacher; 58 % of the training data is translation, and every translated row says so in the dataset.
  • The 17-language files were no longer held back. In 1.1 they capped every language at 12,000 examples; in 1.2 they get the same ~33,000 as the one-language files, and gain +0.023 (latin) and +0.016 (latin-mini). The 6-language file does not move: its languages were never short of data.
  • A new benchmark, gold-chat: real chat only, balanced by message length. Every number on this page is on it, for all three versions — the 1.0 and 1.1 figures published before were on an older set and are not comparable.
  • Same architecture, same runtime, same file sizes. Nothing to change in your code but the file name.

Use it

In the browser or Node — the runtime is one dependency-free file (titler.js, 12 KB of source, 6 KB minified), published as @aparte/titler; @aparte/titler-latin bundles the runtime and the default model together, with no dependency of its own:

import { loadTitler } from "@aparte/titler-latin";
const titler = await loadTitler();
titler.title("Write me a cover letter for a junior data analyst position at a bank");

In a bundled browser app, serve the .bin yourself and pass it to loadTitler(url): a bundler does not rewrite the package-relative URL that the no-argument form uses.

or with any file of this repository:

import { Titler } from "@aparte/titler";
const bytes = await fetch("https://huggingface.co/apartejs/aparte-titler/resolve/main/v1.2/titler-v1.2-fr-int3.bin").then((r) => r.arrayBuffer());
new Titler(bytes).title("Peux-tu m'expliquer la photosynthèse chez les plantes ?");

In Python — the reference implementation, numpy only, in the repository:

python reader.py v1.2/titler-v1.2-latin-int3.bin "Peux-tu m'expliquer la photosynthèse chez les plantes ?"

No framework is needed anywhere: the file format is documented and the reader is 250 lines. Give the model only the user's first message, never a system prompt or the conversation history.

Files

One folder per version. v1.2/ is current; v1/ and v1.1/ stay for anyone who pinned them.

modellanguagesfp32int8int4int3
v1.2/titler-v1.2-latin (default)en, fr, es, de, pt, it, nl, pl, sv, da, fi, cs, ro, no, hu, hr, lt614 KB220 KB150 KB133 KB
v1.2/titler-v1.2-latin-minithe same 17, smaller vocabulary466 KB163 KB109 KB96 KB
v1.2/titler-v1.2-efigspen, fr, es, de, pt, it392 KB134 KB89 KB77 KB
v1.2/titler-v1.2-<lang> (×17)one language245 KB77 KB48 KB41 KB

int3 is the recommended precision: 3 bits per weight with one fp16 scale per row. It costs 0.005 against fp32 on the 17-language file, and int4 costs nothing — see the limits below. Every file carries its identity in its header (name, version, model, languages, precision), readable as titler.header in JS; manifest.json lists every file of every version with its size, parameters and languages. Why 133 KB for 141k parameters? The 3-bit weights are 53 KB; the file adds one fp16 scale per matrix row (26 KB), the BPE merge table (12,030 pairs, 48 KB), the JSON header with the byte-to-id table and the file's identity (4 KB) and the fp16 bias and normalization vectors (2 KB).

Moved in 1.2. Until 1.1 the files sat flat — the 17-language file at the root, everything else in variants/. They are now in one folder per version: …/resolve/main/titler-v1.1-latin-int3.bin is now …/resolve/main/v1.1/titler-v1.1-latin-int3.bin. A link pinned to a commit (…/resolve/<commit>/…) still works.

ONNX. The same 20 models of every version are also in onnx/ as fp32 and int8 graphs (opset 17, dynamic length), one folder per version with its own tokenizers, and an example that reproduces the runtime's decoding — for people who already run ONNX Runtime. 5 to 10 times heavier than the .bin; the fp32 graph gives exactly the titles of the fp32 .bin.

Results

Word-level F1 against the reference title, on gold-chat, int3 files as published, hybrid decoding. Lines marked impossible, off-language, pasted transcriptions and unannotated lines are excluded; so are 61 lines whose text appeared in the training data. The tables below are rewritten by a script from scores.json, never typed by hand.

per language and scope

languageone model (41 KB)efigsp (77 KB)latin-mini (96 KB)latin (133 KB)no model
English0.6200.6080.6090.6290.313
French0.6220.6040.6020.6300.321
Spanish0.6400.6140.6400.6350.318
German0.6200.6050.6020.6200.277
Portuguese0.5910.5960.6190.5980.325
Italian0.5560.5420.5570.5490.307
Dutch0.513—0.5400.5470.292
Polish0.566—0.5600.5720.388
Swedish0.697—0.6820.6610.303
Danish0.579—0.5630.5740.268
Finnish0.546—0.5450.5570.364
Czech0.573—0.5520.5850.315
Romanian0.610—0.6000.6180.323
Norwegian0.629—0.6240.6170.289
Hungarian0.570—0.5590.5780.346
Croatian0.606—0.5970.6110.340
Lithuanian0.549—0.5410.5680.354

Which file to use. The 17-language file scores at least as well as the one-language file for 11 of the 17 languages, for a third of their combined size, so it is the default. The one-language file is better for Swedish (+0.036) and Norwegian (+0.012), and within a hundredth for Danish, Italian, Spanish and German.

1.0, 1.1 and 1.2 on the same benchmark

All three versions read by the same runtime on the same set, so this compares weights only.

scope1.01.11.21.2 − 1.1
English0.62030.61860.6198+0.0012
French0.61530.62800.6217-0.0063
Spanish0.62420.64330.6397-0.0036
German0.60430.62100.6200-0.0010
Portuguese0.57670.59690.5908-0.0061
Italian0.55910.55560.5565+0.0009
Dutch0.53890.52120.5135-0.0077
Polish0.57200.56640.5662-0.0002
Swedish0.63930.64570.6965+0.0508
Danish0.48600.49000.5787+0.0887
Finnish0.48420.48310.5463+0.0632
Czech0.50770.51040.5734+0.0630
Romanian0.38190.54640.6104+0.0640
Norwegian0.50270.52660.6293+0.1027
Hungarian0.51050.52610.5698+0.0437
Croatian0.34410.39130.6061+0.2148
Lithuanian0.47000.47380.5490+0.0752
efigsp0.60040.60070.5948-0.0059
latin-mini0.57060.57200.5877+0.0157
latin0.57500.57370.5970+0.0233
mean+0.0388

The gain is almost entirely in the languages that were short of data: Croatian, Norwegian, Danish, Lithuanian, Czech, Romanian, Finnish, Hungarian and Swedish. English, French, Spanish, German, Portuguese, Italian, Dutch and Polish already had 12,000 examples or more and move within a point, in both directions. Above roughly 12,000 examples a language gains nothing measurable from more.

Read this by message length, not as one number

A ten-word message has ten candidate words and the model keeps three to six; a two-hundred-word message has two hundred. Scores follow the length far more than the language. gold-chat is balanced across lengths — about sixty lines per band per language — so every band below is measured, which was not the case before: in the older set five languages had no message longer than twenty words.

by message length (words), one-language files

scope0-1010-2020-4040-8080+
English0.8230.7590.6020.4670.440
French0.8370.7280.6120.4610.454
Spanish0.8220.7560.5710.5510.460
German0.7880.7510.5770.4810.489
Portuguese0.769—0.5180.4630.474
Italian—0.7090.5720.4280.446
Dutch0.6440.5960.5170.4620.325
Polish0.7740.6580.5480.459—
Swedish0.7630.7890.6280.5640.747
Danish0.7290.7480.5820.4620.365
Finnish0.7900.6240.4310.451—
Czech0.7370.7030.5580.4640.375
Romanian0.8170.7480.5840.5230.346
Norwegian0.7850.7290.5860.5300.512
Hungarian0.7950.6570.5070.4770.399
Croatian0.8420.7190.5410.4890.430
Lithuanian0.7580.6570.4650.5310.333

An em dash means fewer than 50 lines in that band.

Three seeds, not one

Each scope is trained three times; the published file is the seed with the best score on the validation split, never on the benchmark. The spread is what a different random draw costs, so no difference smaller than it should be read as real.

scopeseedsmeanrange
English30.62870.0055
French30.62710.0018
Spanish30.63280.0022
German30.62700.0062
Portuguese30.60980.0084
Italian30.57440.0072
Dutch30.52660.0239
Polish30.57290.0056
Swedish30.69490.0067
Danish30.58410.0077
Finnish30.55450.0086
Czech30.57600.0069
Romanian30.60800.0382
Norwegian30.62980.0015
Hungarian30.58050.0001
Croatian30.60990.0118
Lithuanian30.56300.0013
efigsp30.61590.0036
latin-mini30.60680.0037
latin30.60810.0011

These are the fp32 weights before quantization, averaged over the three seeds, so they sit slightly above the published int3 files of the first table: quantization costs about 0.005, and the published seed is chosen on validation, not on this benchmark. Romanian (0.038) and Dutch (0.024) are the least stable; most scopes move by less than a hundredth.

Limits, honestly

  • Part of the benchmark is translated. Where a language did not have 300 real chat messages, English ones were machine-translated into it: 88 % of the Croatian set, 78 % of the Danish, 77 % of the Norwegian, 73 % of the Finnish, 47 % of the Lithuanian. The training data of those languages is mostly translated too. A model trained and measured on translation can learn the translator's register rather than the language, and the largest gains of 1.2 are exactly there. Czech, measured on 93 % native text, gains strongly too, so the gains are not only an artefact — but they are harder to guarantee than the English or French ones.
  • One reference per message. The task admits several good titles, and the score counts only one of them. The absolute numbers are therefore not comparable to other work; the relative ones, measured in the same protocol, are.
  • A ceiling below 1.0. 11 % of the reference titles contain a word the model cannot produce: a version number, a path or a file name, which the tokenizer splits at its dots (node.js becomes node and js).
  • Long messages are the weak point. 0.78 on average on messages under ten words, 0.44 beyond eighty. The words of the right title are in the text: the model fails to find them, not to reach them.
  • Messages are truncated at 1,200 characters, in the benchmark and in the runtime. Nothing is known about what happens beyond.
  • int3 gives a slightly lower score than fp32 and different titles. On the 17-language file: −0.005 F1, and the same title on only 50 % of messages — the rest differ by one near-tied word. int8 is identical to fp32 on 99 % of messages; int4 scores as well as fp32.
  • Chat-speak stop words ("pk", "ya", "si") are not always dropped: the training data is more formal than SMS-style chat.
  • Typos are copied, because words are never rewritten.

How it was built

  1. Corpus. Real first messages per language from WildChat-4.8M, completed where short by OASST2, Aya, Tagengo and FAQ questions from MFAQ (capped at 100 per site). Fourteen languages were then brought to about 33,000 messages with English WildChat messages machine-translated by the teacher. Plus every message under 20 characters, which is its own title. 601,822 messages in all.
  2. Teacher. gemma 4 e2b (llama.cpp, thinking off) wrote an extractive title for each message: 3–5 words copied from it, subject first, on the translated text for translated messages.
  3. Labels. Each title word aligned back to the message (exact, then inflection, then one-typo), giving a keep/drop label per token and the word each token belongs to.
  4. Model. A 2-layer transformer encoder (width 32, 4 heads, GELU, learned positions) with factorized 8-dimensional embeddings over a byte-level BPE vocabulary — 2,048 merges for one language, 12,288 shared by 17. The decision is taken per word: the logits of a word's tokens are averaged before the loss. 58,727 parameters for one language, 140,647 for 17. Every language, in its own file or in a shared one, sees the same ~33,000 examples.
  5. Decoding. Hybrid: among the six best-scored words, keep those the model gives at least 0.5, never fewer than three, and keep every word of a message that has four or fewer. title(message, 6) gives the fixed six-best decoding of 1.0.
  6. Quantization. Per-row symmetric integers with an fp16 scale.
  7. Evaluation. gold-chat: about 300 chat messages per language titled blind by Claude (Fable), checked word-for-word against the message, decontaminated against the training data at the model's input length. Everything is in apartejs/aparte-titler-gold.

Latency

About 9 µs per character on one CPU core in Python (Ryzen AI Max) and 22 µs in the pure-JS runtime under Node 24: 2–4 ms and 6–7 ms for a typical 300-character message. No GPU, no network, under 1 MB of memory.

Sources and licenses

Code and weights: MIT © 2026 Paul Richez. The model was distilled from titles written by gemma 4 e2b (Apache 2.0), which also translated part of the training data; Google claims no rights in its outputs (Gemma Terms of Use §3.3). The messages come from WildChat-4.8M and WildChat-1M (ODC-BY), OASST2 (Apache 2.0), Aya (Apache 2.0), Tagengo (Apache 2.0) and MFAQ (CC0); the licence of each row is in the dataset. The benchmark annotations are ours (CC BY 4.0).

Citation

@software{aparte_titler_2026,
  author = {Richez, Paul},
  title = {aparte-titler: extractive conversation titles in 17 languages, in the browser},
  year = {2026},
  version = {1.2.0},
  url = {https://apartejs.dev/models/titler/}
}

Как запустить

На своей GPU в ailist. Цена — по текущим предложениям провайдеров

GPU в ailist

Универсальный рантайм

Нельзя запустить

Архитектура ? неизвестна transformers в образе рантайма.

Ревизия весов
04c1f12

0 моделей