ruTron-quality-classifier-base

English | Русский

Russian only. The model was trained and evaluated only on Russian web documents (FineWeb-2 rus_Cyrl). It was not tested on other languages; its scores for them are meaningless.

A multi-head quality model for Russian web text, made for pretraining-data filtering. For every document it predicts an overall pretraining value, 13 quality axes on a 1–5 scale, 8 content flags, topic, format, audience and region. It imitates the labels that Claude Sonnet 5.5 gave to 26,000 FineWeb-2 documents (krysyuk/fineweb-2-russian-quality-annotations-26k).

This is the more accurate of the two models. It runs the whole frozen nvidia/Nemotron-3-Embed-1B-BF16 encoder over up to 4,096 tokens per document, so it is about 16 times slower than krysyuk/ruTron-quality-classifier-lite. The lite model scored all 699M documents of rus_Cyrl: krysyuk/fineweb-2-russian-quality-full.

base (this model) lite
Encoder all 16 layers, inside the model file first 4 layers, inside the model file
Text read up to 4,096 tokens (first 10,000 + last 1,700 characters) first 512 tokens
overall QWK / axes QWK (test) 0.876 / 0.870 0.820 / 0.832
Speed, Apple M4 Pro ~1.2 docs/s ~19 docs/s
Use for accurate scoring, thousands to millions of documents whole corpora

Quick start

pip install torch "transformers>=5.18" safetensors pyarrow huggingface_hub
hf download krysyuk/ruTron-quality-classifier-base --local-dir ruTron-quality-classifier-base
cd ruTron-quality-classifier-base

python predict.py --input docs.jsonl --output scores.jsonl   # one {"id", "text"} per line
python predict.py --input docs.parquet --output scores.jsonl --device cuda
import sys
from huggingface_hub import snapshot_download

path = snapshot_download("krysyuk/ruTron-quality-classifier-base")
sys.path.insert(0, path)
from predict import QualityScorer

scorer = QualityScorer(path)  # cuda / mps / cpu picked automatically
scorer.score(["Текст документа ..."])[0]
# {"overall": 2.65, "overall_direct": 2.66, "overall_stacked": 2.64, "p_overall_4plus": 0.0001,
#  "axes": {"cleanliness": 3.4, ...}, "flags": {"unsafe_content": 0.003, ..., "answer_dump": false},
#  "topic": {"engineering": 0.91, ...}, "format": "review", "audience": "enthusiasts", "region": "none"}

Everything is in this repo: encoder, heads and tokenizer in one model.safetensors (~2.5 GB), nothing else is downloaded. Tested with torch 2.14 and transformers 5.18.

Output

Field Meaning
overall Pretraining value, expected level on 1–4 (4 = "4 or 5"): mean of the two overall heads. Use this one
overall_direct, overall_stacked The two heads: from the text directly, and from the predicted axes, flags and categories
p_overall_4plus Probability that the annotator would give 4 or 5; use it to pick the top
axes.* Expected score 1–5 for each of the 13 axes
flags.* Probabilities of 8 flags; answer_dump is a keyword rule (true / false)
topic Top-3 topics with probabilities (multi-label)
format, audience, region Most likely class

Rating criteria

The model reproduces the rubric of the annotations dataset.

overall Decision Typical documents
1 Exclude Spam, doorways, garbage, any unsafe content
2 Rather exclude Ads, filler
3 Keep: ordinary acceptable web News, forum post, blog
4 Keep with a higher weight Substantive, well-written text: explanations or facts
5 Reference quality, upsample Textbook, encyclopedic article, deep analysis

Levels 4 and 5 are merged into "4+": 5 is only ~0.1% of the data.

Output Count Names
Quality axes, 1–5 13 cleanliness, language_quality, naturalness, information_density, factual_specificity, educational_value, reasoning_depth, expertise_level, credibility, originality, commercial_neutrality, durability, domain_depth
Flags, probability 8 unsafe_content, seo_doorway, machine_generated, truncated_or_fragment, suspected_mt, pii_present, official_document, mixed_language
Rule flag, true / false 1 answer_dump
Categories 4 topic (30 topics), format (26), audience (7), region (5); names in labels.json

What every axis, flag and category means, with a description of each level: annotations dataset, "Rating criteria". The exact annotation prompt is in that repo, prompt/annotate_v6.system.md.

Suggested use: drop overall < 1.5 (or < 2), and documents with high unsafe_content / seo_doorway / machine_generated; upsample the top by p_overall_4plus.

Input

The model sees what the annotator saw: the first 10,000 and last 1,700 characters of the document, with the passage: prefix, cut at 4,096 tokens. predict.py does this.

Architecture

text → Nemotron-3-Embed-1B (frozen, bf16)
     ├─ mean pooling of all 17 hidden states  → learned layer mix
     ├─ 256-token chunks at layers 4/8/12/16  → layer mix → attention pooling over chunks
     └─ 32 text statistics (Gopher / C4-style: script shares, duplicate lines/n-grams, ...)
  → trunk MLP (1024) → 13 ordinal axis towers (CORN) · 8 flag logits · topic · format · audience · region
                     → overall: direct ordinal head + stacked head over the predicted
                       axis / flag / category probabilities (trained out-of-fold)

The heads (46M parameters) were trained with 5-fold cross-validation, which the stacked overall head needs; all five are stored in model.safetensors and averaged at inference. The encoder weights (1.14B parameters, bf16) are included unchanged.

Evaluation

Test split: 2,501 held-out documents (half uniform random, half from a "probably good" pool, the same mix as training). run05: 200 random documents labelled by Claude Opus agents instead of Sonnet, which shows how the model agrees with a different annotator. Sonnet itself agrees with those labels at mean axis QWK ≈ 0.89; that is roughly the ceiling.

test run05
Axes, mean QWK 0.870 0.847
overall QWK (1–4) 0.876 0.847
overall Spearman 0.891 0.877
PR-AUC overall ≥ 4 0.75 (base rate 4.7%) 0.66 (base rate 6%)
Junk: Sonnet gave 1, overall < 1.5 precision 0.93, recall 0.89 precision 0.86, recall 0.88

Per-axis QWK, test:

Axis base lite
cleanliness 0.89 0.86
language_quality 0.85 0.83
naturalness 0.87 0.85
information_density 0.88 0.85
factual_specificity 0.89 0.86
educational_value 0.87 0.82
reasoning_depth 0.82 0.77
expertise_level 0.87 0.83
credibility 0.85 0.80
originality 0.85 0.80
commercial_neutrality 0.92 0.88
durability 0.90 0.86
domain_depth 0.85 0.80

Flags, PR-AUC on test. The three marked ones are unreliable: the annotator disagrees with itself on them too.

Flag base lite
seo_doorway 0.99 0.97
unsafe_content 0.94 0.89
machine_generated 0.90 0.89
mixed_language 0.89 0.89
official_document 0.70 0.71
pii_present (unreliable) 0.48 0.42
truncated_or_fragment (unreliable) 0.47 0.39
suspected_mt (unreliable) 0.36 0.38

Categories, test:

Category Metric base lite
topic top-1 accuracy 0.78 0.69
region macro-F1 0.82 0.70
audience macro-F1 0.75 0.56
format macro-F1 0.63 0.54

Full numbers: metrics.json.

Speed

The encoder dominates. On an Apple M4 Pro (MPS, bf16) the model scores 1.2 documents per second (2,500 tokens/s; an average document is ~1,550 tokens after truncation). For whole corpora use the lite model, which also has a production script with FP8 and torch.compile.

Limitations

  • Russian only (see the top of the card).
  • It imitates one LLM annotator (Claude Sonnet 5.5, prompt v6) and inherits its biases; the rubric favours educational and factual text.
  • Trained on FineWeb-2 web pages; books, code and chat are out of distribution.
  • Top quality (overall 4+) is rare (~2.4% of random documents), so precision in the top is moderate; treat scores as a ranking signal, not a verdict on one document.

Files

File
model.safetensors Encoder (all 16 layers, bf16, unchanged) + 5 cross-validation head sets + the stacked overall head
tokenizer.json, tokenizer_config.json Tokenizer of the encoder
config.json, labels.json Head config, class names, order of text statistics
predict.py Inference: command line and QualityScorer
modeling.py, heuristics.py Model code and the 32 text statistics
metrics.json Validation / test / run05 metrics
LICENSE, NOTICE OpenMDW-1.1, the encoder's license, and its attribution notices

License

OpenMDW-1.1, the license of the base encoder nvidia/Nemotron-3-Embed-1B-BF16, which is included here unchanged. The heads were trained on labels produced by Claude Sonnet 5.5 for FineWeb-2 texts (ODC-By 1.0).


Русский

Только для русского языка. Модель обучена и проверена только на русских веб-документах (FineWeb-2 rus_Cyrl). На других языках её не проверяли, и её оценки для них не имеют смысла.

Многоголовая модель качества русского веб-текста для фильтрации данных предобучения. Для каждого документа она предсказывает общую ценность для предобучения overall, 13 осей качества по шкале 1–5, 8 флагов содержания, тему, формат, аудиторию и регион. Модель повторяет разметку, которую Claude Sonnet 5.5 сделал для 26 000 документов FineWeb-2 (krysyuk/fineweb-2-russian-quality-annotations-26k).

Это более точная из двух моделей. Она прогоняет весь замороженный энкодер nvidia/Nemotron-3-Embed-1B-BF16 по 4 096 токенам документа, поэтому примерно в 16 раз медленнее, чем krysyuk/ruTron-quality-classifier-lite. Lite-модель оценила все 699 млн документов rus_Cyrl: krysyuk/fineweb-2-russian-quality-full.

base (эта модель) lite
Энкодер все 16 слоёв, внутри файла модели первые 4 слоя, внутри файла модели
Что читает до 4 096 токенов (первые 10 000 + последние 1 700 символов) первые 512 токенов
QWK overall / осей (test) 0.876 / 0.870 0.820 / 0.832
Скорость, Apple M4 Pro ~1,2 док/с ~19 док/с
Для чего точная оценка, от тысяч до миллионов документов целые корпуса

Быстрый старт

pip install torch "transformers>=5.18" safetensors pyarrow huggingface_hub
hf download krysyuk/ruTron-quality-classifier-base --local-dir ruTron-quality-classifier-base
cd ruTron-quality-classifier-base

python predict.py --input docs.jsonl --output scores.jsonl   # по строке {"id", "text"}
python predict.py --input docs.parquet --output scores.jsonl --device cuda
import sys
from huggingface_hub import snapshot_download

path = snapshot_download("krysyuk/ruTron-quality-classifier-base")
sys.path.insert(0, path)
from predict import QualityScorer

scorer = QualityScorer(path)  # cuda / mps / cpu выбирается сам
scorer.score(["Текст документа ..."])[0]

Всё лежит в этом репозитории: энкодер, головы и токенизатор, веса в одном model.safetensors (~2,5 ГБ), больше ничего не скачивается. Проверено на torch 2.14 и transformers 5.18.

Выход

Поле Смысл
overall Ценность для предобучения, ожидаемый уровень 1–4 (4 = «4 или 5»): среднее двух голов overall. Используйте его
overall_direct, overall_stacked Две головы: прямо по тексту и по предсказанным осям, флагам и категориям
p_overall_4plus Вероятность, что аннотатор поставил бы 4 или 5; по ней удобно отбирать лучшее
axes.* Ожидаемая оценка 1–5 по каждой из 13 осей
flags.* Вероятности 8 флагов; answer_dump - правило по ключевым словам (да / нет)
topic 3 самые вероятные темы с вероятностями (мультиметка)
format, audience, region Самый вероятный класс

Критерии оценки

Модель воспроизводит рубрику датасета с разметкой.

overall Решение Типичные документы
1 Исключить Спам, дорвеи, мусор, любой небезопасный контент
2 Скорее исключить Реклама, вода
3 Оставить: обычный приемлемый веб Новость, пост на форуме, блог
4 Оставить с повышенным весом Содержательный, хорошо написанный текст: объяснения или факты
5 Эталон, апсемплить Учебник, энциклопедическая статья, глубокий анализ

Уровни 4 и 5 объединены в «4+»: оценка 5 - всего около 0,1% данных.

Выход Сколько Названия
Оси качества, 1–5 13 cleanliness, language_quality, naturalness, information_density, factual_specificity, educational_value, reasoning_depth, expertise_level, credibility, originality, commercial_neutrality, durability, domain_depth
Флаги, вероятность 8 unsafe_content, seo_doorway, machine_generated, truncated_or_fragment, suspected_mt, pii_present, official_document, mixed_language
Флаг-правило, да / нет 1 answer_dump
Категории 4 topic (30 тем), format (26), audience (7), region (5); названия в labels.json

Что значит каждая ось, флаг и категория, с описанием каждого уровня: датасет с разметкой, раздел «Критерии оценки». Точный промпт разметки лежит там же, prompt/annotate_v6.system.md.

Как использовать: отбросить overall < 1.5 (или < 2) и документы с высокими unsafe_content / seo_doorway / machine_generated, лучшее по p_overall_4plus апсемплить.

Вход

Модель видит то же, что видел аннотатор: первые 10 000 и последние 1 700 символов документа с префиксом passage: , обрезанные до 4 096 токенов. Это делает predict.py.

Архитектура

текст → Nemotron-3-Embed-1B (заморожен, bf16)
      ├─ mean pooling всех 17 скрытых состояний → обучаемая смесь слоёв
      ├─ куски по 256 токенов, слои 4/8/12/16    → смесь слоёв → attention pooling по кускам
      └─ 32 текстовые статистики (в духе Gopher / C4: доли алфавитов, повторы строк и n-грамм, ...)
  → MLP-ствол (1024) → 13 порядковых башен осей (CORN) · 8 логитов флагов · тема · формат · аудитория · регион
                     → overall: прямая порядковая голова + стекинг-голова по предсказанным
                       вероятностям осей, флагов и категорий (обучена out-of-fold)

Головы (46 млн параметров) обучены 5-фолдовой кросс-валидацией, она нужна для стекинг-головы overall. Все пять наборов лежат в model.safetensors и усредняются на инференсе. Веса энкодера (1,14 млрд параметров, bf16) лежат в том же файле без изменений.

Качество

Test: 2 501 отложенный документ (половина - равномерно случайные, половина - из пула «вероятно хороших», как в обучении). run05: 200 случайных документов, размеченных агентами Claude Opus вместо Sonnet; показывает согласие модели с другим аннотатором. Сам Sonnet совпадает с этой разметкой на среднем QWK осей ≈ 0.89, это примерный потолок.

test run05
Оси, средний QWK 0.870 0.847
QWK overall (1–4) 0.876 0.847
Спирмен overall 0.891 0.877
PR-AUC overall ≥ 4 0.75 (база 4.7%) 0.66 (база 6%)
Мусор: Sonnet поставил 1, overall < 1.5 точность 0.93, полнота 0.89 точность 0.86, полнота 0.88

QWK по осям, test:

Ось base lite
cleanliness 0.89 0.86
language_quality 0.85 0.83
naturalness 0.87 0.85
information_density 0.88 0.85
factual_specificity 0.89 0.86
educational_value 0.87 0.82
reasoning_depth 0.82 0.77
expertise_level 0.87 0.83
credibility 0.85 0.80
originality 0.85 0.80
commercial_neutrality 0.92 0.88
durability 0.90 0.86
domain_depth 0.85 0.80

Флаги, PR-AUC на test. Трём отмеченным доверять нельзя: аннотатор и сам с собой по ним не согласен.

Флаг base lite
seo_doorway 0.99 0.97
unsafe_content 0.94 0.89
machine_generated 0.90 0.89
mixed_language 0.89 0.89
official_document 0.70 0.71
pii_present (ненадёжный) 0.48 0.42
truncated_or_fragment (ненадёжный) 0.47 0.39
suspected_mt (ненадёжный) 0.36 0.38

Категории, test:

Категория Метрика base lite
topic точность top-1 0.78 0.69
region macro-F1 0.82 0.70
audience macro-F1 0.75 0.56
format macro-F1 0.63 0.54

Все цифры: metrics.json.

Скорость

Время уходит на энкодер. На Apple M4 Pro (MPS, bf16) модель оценивает 1,2 документа в секунду (2 500 токенов/с; средний документ после обрезки ~1 550 токенов). Для целых корпусов берите lite-модель: к ней есть продакшн-скрипт с FP8 и torch.compile.

Ограничения

  • Только русский язык (см. начало карточки).
  • Модель подражает одному LLM-аннотатору (Claude Sonnet 5.5, промпт v6) и наследует его предвзятость; рубрика предпочитает образовательные и фактологичные тексты.
  • Обучена на веб-страницах FineWeb-2; книги, код и чаты - вне распределения.
  • Верхний уровень (overall 4+) редок (~2,4% случайных документов), поэтому точность в топе умеренная. Оценки - сигнал для ранжирования, а не вердикт по одному документу.

Файлы

Файл
model.safetensors Энкодер (все 16 слоёв, bf16, без изменений) + 5 наборов голов кросс-валидации + стекинг-голова overall
tokenizer.json, tokenizer_config.json Токенизатор энкодера
config.json, labels.json Конфиг голов, имена классов, порядок текстовых статистик
predict.py Инференс: командная строка и QualityScorer
modeling.py, heuristics.py Код модели и 32 текстовые статистики
metrics.json Метрики на validation / test / run05
LICENSE, NOTICE OpenMDW-1.1, лицензия энкодера, и его уведомления об авторстве

Лицензия

OpenMDW-1.1, лицензия базового энкодера nvidia/Nemotron-3-Embed-1B-BF16, он входит сюда без изменений. Головы обучены на разметке Claude Sonnet 5.5 для текстов FineWeb-2 (ODC-By 1.0).

Downloads last month
15
Safetensors
Model size
1B params
Tensor type
F32
·
BF16
·
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for krysyuk/ruTron-quality-classifier-base

Datasets used to train krysyuk/ruTron-quality-classifier-base