/ Модель

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

Контекст
8 192 токена
Параметры
149 млн
Лицензия
Apache 2.0
Архитектура
modernbert · dense
Базовая модель
ModernBERT-base
Библиотека
transformers
Опубликована
20 сен 2026

mailroom-modernbert-classifier

Классификация текстаТекст → label

Дообученный ModernBERT классифицирует юридические документы по типу для первичной маршрутизации в конвейере обработки почты.

117скачиваний за 30 дней1лайквеса обновлены6 окт 2026

Бенчмарки

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

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

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

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

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

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

Lucius-Morningstar/mailroom-modernbert-classifier — иерархический классификатор юридических документов для этапа первичной сортировки в конвейере LLM-Mailroom. Модель разработана на базе encoder ModernBERT-base и дообучена с отдельной головой для определения типа документа и головами подклассов для каждого типа. Веса backbone содержат около 149 млн параметров; контекст — до 8192 токенов. Документы длиннее одного окна обрабатываются окнами с перекрытием 512 токенов, а итоговые метки выбираются голосованием по окнам.

Модель предназначена для маршрутизации договоров, корпоративных документов, переписки, страховых заявлений и соглашений о слиянии и поглощении. В README для основной производственной версии M9a указана точность определения типа документа 0,9505 на отложенной выборке из 323 документов. Точность подклассов существенно слабее: автор рекомендует использовать основной тип для маршрутизации, а неоднозначные подклассы передавать LLM-сортировщику. Данные обучения — корпус юридических документов; результат не заменяет юридическую проверку. Карточка указывает лицензию Apache-2.0.

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

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

Ограничения

Качество определения подклассов для ряда категорий низкое; неоднозначные документы рекомендуется направлять LLM-сортировщику. Модель обучена на отобранном юридическом корпусе и не заменяет юридическую проверку.

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

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

Открыть на Hugging Face

mailroom-modernbert-classifier

Hierarchical document classifier for the LLM-Mailroom intake pipeline: a fine-tuned ModernBERT-base encoder with a doc_type head plus one subclass head per document class. It is the deterministic pre-check in the BERT-coupled intake overhaul (mailroom-issues #85).

Recommended production revision (M9a primary, Arm B): m9a-local-20260927-014429 — 3 epochs, loss_lambda_dt=0.65, held-out doc_type accuracy 0.9505, trainer validation gate_met: true. M9a mailroom-issues #112 subclass gates remain not met for contract / correspondence; use LLM sorter for subclass-ambiguous tails.

Hub releases (M9a, 2026-09-27)

Release tagArmEpochsλ_dtHeld-out doc_type accHeld-out subclass (cond.)Trainer gate_met#112 gatesEval on Hub
m9a-local-20260927-014429B (primary)30.650.95050.5831trueFAIL (2/4)eval_report_m9a-local-20260927-014429.json
m9a-local-gpu1-armA-1ep-20260927-025236A (smoke)10.500.86380.4839falseFAIL (3/4)eval_report_m9a-local-gpu1-armA-1ep-20260927-025236.json

Held-out test set: 323 documents, 8,192-token windows, never used for training, calibration fit, or threshold tuning. Authoritative metrics come from the eval_report_<tag>.json artifacts (not inline summary.json test fields when they differ).

Contractor-repo report mirrors (same content as sections below): M9a-REPORT-m9a-local-20260927-014429, M9a-REPORT-m9a-local-gpu1-armA-1ep-20260927-025236, M9a-COMPARE-ArmA-vs-ArmB-20260927.

Architecture

  • Backbone: answerdotai/ModernBERT-base — 22 layers, 768 hidden, 8,192-token context, bf16.
  • Heads: one head per class — doc_type (6 classes) plus 5 subclass heads (contract, corporate_record, correspondence, insurance_claim, merger_agreement). MLP heads with dropout 0.1.
  • Windowing: token-level, 8,192 tokens with 512-token overlap. doc_type by plurality vote over windows; subclass by plurality over windows whose doc_type vote is the winning class.
  • Calibration: per-head temperature scaling (temperatures.json).

Files

filepurpose
model.safetensorsModernBERT backbone weights (bf16, ~298 MB)
heads.pthierarchical head state dicts
labels.jsonhead vocabularies (labels / label2id / id2label / weights)
temperatures.jsonper-head calibration temperatures
train_counts.jsonper-(doc_type, subclass) authentic train-row counts (support gate)
config.json, tokenizer.json, tokenizer_config.jsonbackbone config + tokenizer
summary.jsonfull run summary (hyperparameters, per-epoch metrics, selection, test metrics)
eval_report_<release_tag>.jsonheld-out test harness output for that release (on repo root)

Labels

doc_type (6): contract, merger_agreement, corporate_record, correspondence, insurance_claim, unknown (inference-only abstention — not a trained class)

contract (24): agency, co_branding, collaboration, consulting, development, distributor, endorsement, franchise, hosting, ip, joint_venture, license, maintenance, manufacturing, marketing, other, outsourcing, promotion, reseller, service, sponsorship, strategic_alliance, supply, transportation

corporate_record (10): articles_of_incorporation, board_resolution, bylaws, charter_amendment, indenture, officer_certificate, other, powers_of_attorney, rights_instrument, subsidiary_list

correspondence (7): demand, email, letter, meeting_request, memo, notice, press_release

insurance_claim (6): auto, carrier, inpatient, outpatient, pde, property

merger_agreement (5): all_cash, all_stock, mixed_cash_stock, mixed_cash_stock_election, other

Usage

The backbone is a standard ModernBertModel; the hierarchical heads are a custom bundle. Load a pinned release tag (never a floating main tip in production):

from huggingface_hub import snapshot_download
from mailroom_ml.inference import load_bundle, classify_document

model_dir = snapshot_download(
    "Lucius-Morningstar/mailroom-modernbert-classifier",
    revision="m9a-local-20260927-014429",
)
bundle = load_bundle(model_dir)
result = classify_document(
    title="Notice of Default",
    text=document_text,
    bundle=bundle,
)
# result["doc_type"], result["subclass"], result["confidence"], result["route"]

route == "fast_path" means the calibrated gate passed and the LLM sorter may be skipped (skip mode + allowlist only); otherwise route the document to the LLM sorter with the BERT triage as an advisory prior.

Limitations

  • Subclass heads are weak for contract / correspondence / corporate_record / merger_agreement on held-out test (M9a Arm B macro-F1 0.02–0.25). Use the doc_type head for routing; route subclass-ambiguous documents to the LLM sorter. Do not trust skip-mode subclass for these classes until #112 gates pass.
  • Trained on a curated legal-document corpus; not a substitute for legal review.
  • unknown is an inference-only abstention label, not a trained class.
  • Long documents are windowed (8,192 tokens, 512 overlap); oversize documents fall back to the LLM path when routing policy requires it.

License

Apache-2.0 (inherits answerdotai/ModernBERT-base).


M9a full run report (2026-09-27)

The sections below merge the contractor-repo M9a reports published after local GPU training. Arm B is the production candidate; Arm A is a one-epoch λ ablation smoke on GPU 1.

M9a local Arm B — full report

Run tag: m9a-local-20260927-014429
Run ID: 20260927-064513
Arm: B (primary, GPU 0)
Checkpoint: data/modernbert_training/runs/m9a-local-20260927-014429/latest
Training log: logs/m9a-local-20260927-014429.log
Held-out eval JSON: reports/eval_m9a-local-20260927-014429.json → Hub eval_report_m9a-local-20260927-014429.json

Config

SettingValue
loss_lambda_dt0.65 (Arm B)
epochs3
batch × grad_accum4 × 8
lr2e-5
seed42
max_length8192
label_smoothing0.05
weight_mode / capinverse / 20
warmup_frac0.06
mlp_headstrue
freeze_backbone_epochs0
modelanswerdotai/ModernBERT-base
dataLucius-Morningstar/mailroom-modernbert-training @ prepared stage pin
training wall time~4.5 h (16,326 s)

Validation (per epoch, observed doc_type macro-F1)

Epochdoc_type macro-F1doc_type doc accsubclass objectiveselected
10.92540.9164—yes (interim)
20.93450.9298—yes (interim)
30.93890.93310.3334yes (shipped)

Trainer checkpoint selection (validation)

  • Selected epoch: 3
  • Selection gate_met: true (calibrated doc_type ECE ≤ 0.05, no doc_type macro-F1 regression beyond 0.005)
  • Val doc_type macro-F1 (observed): 0.9389
  • Val doc_type ECE (calibrated): 0.02
  • Val subclass objective: 0.3334

Head exclusion policy (ECE > 0.05 → fast-path excluded)

headECE (calibrated)excluded
doc_type0.02no
contract0.0327no
insurance_claim0.0025no
corporate_record0.071yes
correspondence0.1384yes
merger_agreement0.1083yes

Held-out test (323 docs @ 8,192 tokens)

MetricValue
doc_type_accuracy0.9505 (307/323)
subclass_accuracy_conditional0.5831 (179/307 scorable)
window_calibration ECE0.0259
window_calibration band ECE0.0525

Cohorts (#104 single vs multi-window)

cohortn_docsdoc_type_accuracymean_agreementwindow ECE
single-window2740.94891.00.0426
multi-window490.95920.97240.0168

Selective-risk sweep (global)

  • budget_met: true
  • recommended deployment threshold: 0.90

Per-head test macro-F1 (observed)

headmacro-F1
insurance_claim0.9889
corporate_record0.2485
merger_agreement0.2381
correspondence0.1289
contract0.0195

M9a #112 gates (held-out test)

GateActualThresholdStatus
contract test macro-F10.0195≥ 0.20NOT MET
correspondence test macro-F10.1289≥ 0.25NOT MET
doc_type test accuracy0.9505≥ 0.89MET
window ECE (doc_type calibrated)0.0259≤ 0.05MET

Overall #112 gate verdict: FAIL (2/4 gates not met — contract and correspondence subclass heads remain below Verify-grade thresholds; doc_type and calibration gates pass).

Arm B verdict

  • Doc-type routing: strong improvement vs run-3 baseline (0.8947 → 0.9505 test acc; ECE 0.0259).
  • Trainer selection: epoch 3 gate_met true on validation.
  • Subclass / #112: contract + correspondence test macro-F1 still block full #112 PASS; exclusion policy keeps high-ECE subclass heads off the fast path.
  • Recommended production pointer: this run (Arm B, λ_dt=0.65) over the 1-epoch Arm A smoke.

M9a GPU-1 Arm A smoke — full report

Run tag: m9a-local-gpu1-armA-1ep-20260927-025236
Run ID: 20260927-075323
Arm: A (one-time GPU 1 smoke per logs/.m9a-gpu-policy)
Checkpoint: data/modernbert_training/runs/m9a-local-gpu1-armA-1ep-20260927-025236/latest
Training log: logs/m9a-local-gpu1-armA-1ep-20260927-025236.log
Held-out eval JSON: reports/eval_m9a-local-gpu1-armA-1ep-20260927-025236.json → Hub eval_report_m9a-local-gpu1-armA-1ep-20260927-025236.json
Published with --force-publish (smoke compare; gates not required).

Config

SettingValue
loss_lambda_dt0.5 (Arm A)
epochs1
batch × grad_accum4 × 8
lr2e-5
seed42
max_length8192
label_smoothing0.05
weight_mode / capinverse / 20
warmup_frac0.06
mlp_headstrue
modelanswerdotai/ModernBERT-base
dataLucius-Morningstar/mailroom-modernbert-training @ prepared stage pin
training wall time~1.55 h (5,579 s)

Validation (epoch 1)

Epochdoc_type macro-F1doc_type doc accsubclass objectiveselection gate_met
10.81580.85280.238false

No checkpoint met the lexicographic selection rule (calibrated doc_type ECE 0.0524 > 0.05 budget on the sole epoch). Trainer reports gate_met false and selection epoch 0 (placeholder).

Held-out test (323 docs @ 8,192 tokens)

MetricValue
doc_type_accuracy0.8638 (279/323)
subclass_accuracy_conditional0.4839
window_calibration ECE0.0397
window_calibration band ECE0.0574

Note: inline trainer test_metrics.doc_type_acc (0.8669) reflects a lighter in-train test pass; the authoritative held-out harness is the eval JSON above.

Cohorts

cohortn_docsdoc_type_accuracymean_agreementwindow ECE
single-window2740.87231.00.1179
multi-window490.81630.8020.1024

Selective-risk sweep refused (no per-head ECE sidecar in artifact for this 1-epoch smoke).

Per-head test macro-F1 (observed)

headmacro-F1
insurance_claim0.7552
merger_agreement0.16
correspondence0.0944
corporate_record0.0212
contract0.0039

M9a #112 gates (held-out test)

GateActualThresholdStatus
contract test macro-F10.0039≥ 0.20NOT MET
correspondence test macro-F10.0944≥ 0.25NOT MET
doc_type test accuracy0.8638≥ 0.89NOT MET
window ECE (doc_type calibrated)0.0397≤ 0.05MET

Overall #112 gate verdict: FAIL (expected for 1-epoch λ_dt=0.5 compare arm).

Arm A verdict

Arm A smoke confirms λ_dt=0.5 + 1 epoch under-trains doc_type vs Arm B: −8.7 pp test doc_type acc and −10 pp conditional subclass acc vs the 3-epoch primary. Use for ablation only; do not promote to production default.


M9a Arm A vs Arm B — comparison

Arm B (primary)Arm A (smoke)
Run tagm9a-local-20260927-014429m9a-local-gpu1-armA-1ep-20260927-025236
GPU policyGPU 0one-time GPU 1 exception
loss_lambda_dt0.650.5
epochs31
Eval JSON (Hub)eval_report_m9a-local-20260927-014429.jsoneval_report_m9a-local-gpu1-armA-1ep-20260927-025236.json

Held-out test (n=323)

MetricArm BArm AΔ (B − A)
doc_type_accuracy0.95050.8638+0.0867
subclass_accuracy_conditional0.58310.4839+0.0992
window ECE0.02590.0397−0.0138 (better B)

Validation selection

Arm BArm A
Selected epoch30 (none qualified)
Selection gate_mettruefalse
Val doc_type macro-F10.93890.8158 (e1 only)
Val doc_type ECE (cal.)0.020.0524 (e1)

M9a #112 gates (held-out test)

GateArm BArm A
contract macro-F1 ≥ 0.20NOT METNOT MET
correspondence macro-F1 ≥ 0.25NOT METNOT MET
doc_type acc ≥ 0.89METNOT MET
window ECE ≤ 0.05METMET
OverallFAIL (2/4)FAIL (3/4)

Interpretation

  1. λ_dt and depth: Raising doc-type loss weight to 0.65 and training 3 epochs materially improves both routing accuracy and conditional subclass accuracy on the held-out set.
  2. Production vs smoke: Arm B is the candidate release; Arm A documents the cost of under-training for gate and λ ablation.
  3. Remaining gap: Both arms fail contract/correspondence subclass macro-F1 gates; Arm B additionally passes doc_type accuracy and calibration gates that Arm A misses.
  4. Hub: Both checkpoints are tagged on this repo with distinct release tags and bundled eval_report_<tag>.json artifacts.

Reference baselines (doc_type test accuracy)

doc_type test accsource
0.8947run-3 (eval_report_run3.json / reports/eval_run3_20260921.json)
0.9505Arm B (M9a primary)
0.8638Arm A smoke

Historical — run-3 (2026-09-21)

Checkpoint runs/20260921-132753 (run_id 20260921-093211). Config: epochs=2, batch=4, grad-accum=8, lr=2e-5, loss_lambda_dt=0.65, sqrt-inverse weights, MLP heads. Held-out test doc_type accuracy 0.8947, conditional subclass 0.526, window ECE 0.0203. Superseded for routing by M9a Arm B (0.9505 doc_type acc).


Release 20261006-021245 (2026-10-06)

Held-out test eval artifact on this repo: eval_report_20261006-021245.json.

M9a #112 gates (held-out test)

GateActualThresholdStatus
contract test macro-F10.162≥ 0.2NOT MET
correspondence test macro-F10.351≥ 0.25MET
doc_type test accuracy0.9505≥ 0.89MET
window ECE (doc_type calibrated)0.0152≤ 0.05MET

Test surfaces

  • subclass_accuracy_conditional: 0.6287
  • window_calibration: ece=0.0152 band_ece=0.0682

Per-head test macro-F1 (observed)

headmacro-F1supportECE (calibrated)
contract0.162{'affiliate': 2, 'agency': 0, 'co_branding': 5, 'collaboration': 2, 'consulting': 1, 'development': 4, 'distributor': 5, 'endorsement': 0, 'franchise': 1, 'hosting': 2, 'ip': 4, 'joint_venture': 2, 'license': 2, 'maintenance': 4, 'manufacturing': 2, 'marketing': 2, 'non_compete_no_solicit': 0, 'other': 0, 'outsourcing': 0, 'promotion': 0, 'reseller': 0, 'service': 8, 'sponsorship': 3, 'strategic_alliance': 4, 'supply': 5, 'transportation': 2}None
corporate_record0.904{'articles_of_incorporation': 5, 'board_resolution': 5, 'bylaws': 1, 'charter_amendment': 9, 'indenture': 4, 'officer_certificate': 7, 'other': 0, 'powers_of_attorney': 3, 'rights_instrument': 3, 'subsidiary_list': 10}None
correspondence0.351{'attorney_demand': 0, 'demand': 6, 'email': 39, 'letter': 14, 'meeting_request': 5, 'memo': 9, 'notice': 4, 'press_release': 8}None
insurance_claim1.0{'auto': 34, 'carrier': 20, 'inpatient': 15, 'outpatient': 15, 'pde': 14, 'property': 16}None
merger_agreement0.0{'all_cash': 6, 'all_stock': 2, 'mixed_cash_stock': 1, 'mixed_cash_stock_election': 0, 'other': 8}None

Trainer selection (validation)

  • selected epoch: 4
  • gate_met: True
  • subclass_objective: 0.42691999999999997
  • doc_type macro-F1 (val): 0.9399
  • doc_type ECE (val, calibrated): 0.0175
  • head_exclusion_policy (ECE > 0.05):
    • contract: excluded=True ece=0.059
    • corporate_record: excluded=True ece=0.1391
    • correspondence: excluded=True ece=0.0745
    • doc_type: excluded=False ece=0.0175
    • insurance_claim: excluded=False ece=0.0
    • merger_agreement: excluded=True ece=0.2134

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

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

GPU в ailist

Универсальный рантайм · transformers · text-classification

Можно запустить

Подбираем GPU…

Класс архитектуры
ModernBertModel
Ревизия весов
417512b

0 моделей