Text Classification
Transformers
Safetensors
Laya
system-one
calibrated-decisions
rlcd
classification
routing
scoring
guardrails
moderation
reinforcement-learning
commercial-use
Instructions to use aaroncool9/laya with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use aaroncool9/laya with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-classification", model="aaroncool9/laya")# pip install -U transformers accelerate # Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("aaroncool9/laya", device_map="auto") - Laya
How to use aaroncool9/laya with Laya:
# No code snippets available yet for this library. # To use this model, check the repository files and the library's documentation. # Want to help? PRs adding snippets are welcome at: # https://github.com/huggingface/huggingface.js
- Notebooks
- Google Colab
- Kaggle
File size: 8,633 Bytes
55fd022 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | ---
license: apache-2.0
library_name: transformers
pipeline_tag: text-classification
tags: [laya, system-one, calibrated-decisions, rlcd, classification, routing, scoring, guardrails, moderation, reinforcement-learning, commercial-use]
---
# Laya
Open-source, non-autoregressive **System 1 decision model**. Give it a **state** (text, email,
ticket, or JSON) and **typed questions**; it returns typed answers with calibrated probabilities
in a single forward pass. It never generates text, so there is nothing to parse and nothing to
hallucinate.
**This repo holds the English checkpoint** and serves as the hub for the family.
| checkpoint | encoder | params | context | use it for |
|---|---|---|---|---|
| **`convaiinnovations/laya`** (this repo) | ModernBERT-large | 421M | 512 | English |
| [`convaiinnovations/laya-multilingual`](https://huggingface.co/convaiinnovations/laya-multilingual) | mmBERT-base | 322M | 1024 | 100+ languages, ~2x faster |
| [`convaiinnovations/laya-typed-decisions`](https://huggingface.co/convaiinnovations/laya-typed-decisions) | ModernBERT-large | 421M | 1024 | the typed-decisions workflows |
| question type | returns |
|---|---|
| `choice` | selected option, probability per option, confidence |
| `score` | expected level on your ordinal rubric, distribution, confidence |
| `noul` | calibrated probability P(true) |
## Quickstart
```bash
pip install laya
```
```python
import laya
agent = laya.load("convaiinnovations/laya")
result = agent.predict(
{"subject": "Duplicate charge on invoice 4411",
"body": "We were billed twice for March. Please refund the duplicate."},
{"department": {"type": "choice", "instructions": "Which team should handle this?",
"criteria": {"billing": "invoices, payments, refunds",
"technical": "bugs and outages", "sales": "pricing"}},
"urgency": {"type": "score", "instructions": "How urgent is this?",
"criteria": ["not urgent", "soon", "blocking"]},
"churn_risk": {"type": "noul", "instructions": "Does the user threaten to cancel?"}},
)
print(result["answers"]["department"]["choice"])
```
### Routing between the three checkpoints
```python
from laya import Router
router = Router() # lazy-loads only what a request needs
router.predict({"body": "I was charged twice"}, questions) # -> laya
router.predict({"body": "मुझसे दो बार शुल्क लिया गया"}, questions) # -> laya-multilingual
router.predict(state, questions, model="typed-decisions") # explicit
```
`Router` keeps one checkpoint resident by default (`max_loaded`); raise it for mixed-language
traffic so it does not reload on every language switch.
> **If `laya.load()` hangs:** `transformers` probes for TensorFlow at import, and when TF is
> installed its abseil runtime can deadlock model construction. Run with `USE_TF=0`.
## Architecture
- **Backbone** ModernBERT-large (395M, bidirectional, fully fine-tuned) + a decision head
trained from scratch: 2 transformer layers, an option-marker scorer, and an act/escalate head.
421M total.
- **Option markers** every option is scored at its own `[MASK]` token, then softmaxed over that
question's options. The answer space is defined at request time, so new schemas need no
retraining.
- **Budget** 512 tokens per question (question + options + state).
- **Batching** every question in a call is answered in one forward pass.
## Training
**RLCD (Reinforcement Learning for Calibrated Decisions).** The policy reports a distribution;
exploration adds zero-mean Gaussian noise to the logits; the reward is a strictly proper scoring
rule (log + spherical, plus ranked probability score for ordinal questions). Expected reward is
maximised only by reporting honest probabilities. Updates are REINFORCE with a group-mean
baseline (GRPO-style). Multi-turn conversations use TD(λ=1.0) over prefix slices.
7,313 updates, 1 epoch, ~1.96 h. Fitted temperatures `[1.637, 1.251, 1.983]` with
per-option-count scaling.
## Benchmarks
Measured on a Tesla T4; every checkpoint answered byte-identical questions in the same run.
### Speed
| questions/call | `laya` | `laya-multilingual` |
|---|---|---|
| 1 | 39.5 ms | **32.8 ms** |
| 10 | 158.6 ms (15.9 ms/q) | **72.3 ms (7.2 ms/q)** |
| 50 | 771 ms | **337 ms (6.8 ms/q)** |
103–332 questions/sec batched. TypeSafe Jev has been independently measured at 236–276 ms p50
([AbdelStark](https://github.com/AbdelStark/jev-benchmarks),
[nibzard](https://github.com/nibzard/decision-model-benchmark)), so Laya answers a single
question roughly **6–7× faster**.
### Against Jev
Jev figures are **published by third parties, not measured here** — no TypeSafe API access.
Sample sizes and prompts differ; treat as indicative, not a controlled head-to-head.
| dataset | Jev | Laya | |
|---|---|---|---|
| **typed-decisions** (2,000 decisions) | 0.727 | **0.766** | `laya-typed-decisions` |
| AG News (4 labels) | 0.910 | **0.950** | `laya` |
| DAIR Emotion (6) | 0.480 · Brier 0.846 · NLL 5.588 | **0.595** | `laya`, held out |
| ECE | 0.246 | **0.081** | after temperature fitting |
On DAIR Emotion, Jev assigned zero probability to the true label on 16% of examples.
### typed-decisions, all three checkpoints
400 cases, 2,000 decisions, four workflows — measured here.
| model | accuracy | soft acc | Brier | ECE | score MAE |
|---|---|---|---|---|---|
| **`laya-typed-decisions`** | **0.766** | 0.471 | **0.062** | 0.213 | **0.242** |
| `laya` | 0.362 | 0.332 | 0.316 | 0.175 | 0.694 |
| `laya-multilingual` | 0.342 | 0.326 | 0.439 | 0.285 | 0.687 |
| *Jev 1.13.0 (published)* | *0.727* | *0.580* | *0.148* | *0.144* | *0.391* |
| *teacher ceiling* | *0.735* | | | | |
| *majority class* | *0.461* | | | | |
The fine-tuned checkpoint clears the teacher ceiling and wins all four workflows: invoice
processing 0.804, security incidents 0.766, customer service 0.764, agent-trace observability
0.730. By primitive: `noul` 0.857, `choice` 0.733, `score` 0.723.
The base checkpoints sit below the majority-class baseline here — the capability on this
benchmark comes from fine-tuning, which is what the
[fine-tuning notebook](https://github.com/NandhaKishorM/laya/blob/main/notebooks/laya_finetune_typed_decisions_2xT4_kaggle.ipynb)
is for.
### English tasks
| task | `laya` | `laya-multilingual` | |
|---|---|---|---|
| AG News | **0.947** | 0.937 | in training mix |
| BoolQ | **0.830** | 0.787 | in training mix |
| DAIR Emotion | **0.573** | 0.513 | held out |
| prompt-injections | **0.698** | 0.578 | held out, n=116 |
| SST-5 (ordinal) | 0.372 | 0.282 | held out |
### Languages — use `laya-multilingual` outside English
Across 51 languages on MASSIVE intent (20 options, random = 0.050), this checkpoint
macro-averages **0.227** with macro ECE **0.733**, clearing 3× random on only 23 of 51.
Khmer scores **0.000 accuracy at 0.952 confidence**.
| | `laya` | `laya-multilingual` |
|---|---|---|
| MASSIVE intent, English | **0.783** | 0.657 |
| MASSIVE intent, 13 others | 0.306 | **0.451** |
| XNLI, English | **0.860** | 0.843 |
| XNLI, 14 others | 0.521 | **0.731** |
The confidence score gives no warning when the input is unreadable, so the choice has to be made
before the forward pass — that is what `Router` is for.
## Limits
- **Near chance on typed-decisions zero-shot** — 0.362 here and 0.352 for multilingual, against a
0.318 random and 0.461 majority-class baseline. The 0.766 belongs to the checkpoint fine-tuned
on that benchmark's own training split. Laya is a fast base to specialise, not a zero-shot
decision engine.
- **Keep `choice` questions under ~20 options.** Options share a fixed `head_max_len` budget
(192 tokens here), so a very large label space leaves only a few tokens per label and
accuracy falls off sharply. Split into a coarse choice then a fine one.
- Ordinal `score` questions are the weakest primitive (SST-5 0.372).
- Ships over-confident: refitting one temperature per (question type, option count) moves mean
ECE **0.466 → 0.081**. Do this on your own data before trusting the probabilities.
- English only. Use `laya-multilingual` for anything else.
## Links
- **GitHub** https://github.com/NandhaKishorM/laya
- **PyPI** https://pypi.org/project/laya/
- **Demo** https://huggingface.co/spaces/convaiinnovations/laya-demo
- **Write-up** [dev.to](https://dev.to/nandakishor_m_6cc0adfde9f/i-built-non-autoregressive-decision-models-a-year-ago-then-a-frontier-lab-called-it-a-18me)
Apache 2.0 · Convai Innovations
|