Typed decisions (choice/score/noul) from one encoder pass - faster, better-calibrated successor to Laya, Jev wire compatible
See the code
Typed decisions — choice, score, noul — about any text or JSON state, from one encoder pass.
Every question of a call shares one encoding of the state: 3 ms for one question, 11 ms for ten questions over a 500-token document.
A self-hosted, Jev-compatible, faster and better-calibrated successor to Laya.
Measured on one RTX 4090, cbjev and Laya side by side on byte-identical cases (BENCHMARKS.md). Jev numbers are third-party published figures; there was no TypeSafe API access, so they are indicative only.
| cbjev | Laya (best of its checkpoints) | TypeSafe Jev (published) | |
|---|---|---|---|
| mean accuracy, 15 English suites | 0.741 | 0.710 (laya-typed-decisions) | — |
| suites where cbjev >= Laya's better checkpoint | 11 / 15 | ||
| typed-decisions, 2,000 decisions | 0.783 | 0.768 | 0.727 |
| AG News | 0.945 | 0.953 | 0.910 |
| DAIR emotion (held out) | 0.573 | 0.598 | 0.480 |
| Banking77, all 77 labels in one question (held out) | 0.620 | 0.497 | 0.870 (72 labels) |
| mean ECE (lower is better) | 0.117 | 0.125 | 0.246 |
| answer flips when options are reordered | 0.2 % | 7.8 % | 13 % |
| MASSIVE intent, 51 languages, macro accuracy | 0.436 | 0.401 | — |
| MASSIVE, languages where cbjev >= Laya | 45 / 51 | ||
| 1 question, short ticket | 3.0 ms | 5.4 ms (TileLang fast path) | 236–276 ms (hosted API) |
| 10 questions, short ticket | 7.5 ms | 18.2 ms | |
| 10 questions, ~500-token document | 11.4 ms | 75.8 ms | |
| 30 questions, ~500-token document | 31.4 ms | 172.4 ms |
cbjev is faster than both Laya paths in every one of the 10 latency cases measured, by 1.5x (one question on a long document) to 6.9x (ten questions on a document).
Laya encodes the state once per question: ten questions about a 500-token document means ten 500-token sequences. cbjev packs a call into one row — the state once, then every question as its own segment:
Laya [CLS] q1 [SEP] opts [SEP] state [SEP] (x N questions)
cbjev [CLS] q1 | q2 | ... | qN | state [SEP] (once)
The attention mask keeps questions from seeing each other, while the state reads all of them. Each
question segment restarts its positions right after [CLS], so with a single question the row is
token-for-token and position-for-position exactly what a Laya checkpoint was trained on — which is why
fine-tuning from Laya starts from Laya's full ability instead of relearning it.
On top of that:
cbjev/model.py) with an
explicit attention mask, bf16 matmuls over an fp32 residual stream, and CUDA-graph replay per
shape bucket (cbjev/engine.py) — a call is one graph launch instead of ~300 kernel launches.cbjev.load(order_votes=2) also asks every choice/score question with its
options reversed and averages the answers — one extra short segment, not another pass.cbjev.load("laya") runs the original weights in their own layout
(verified to match Laya's probabilities within bf16 rounding).python -m venv .venv
.venv/bin/pip install -e . # core
.venv/bin/pip install -e ".[serve]" # + HTTP server
Weights download on first use from Hugging Face:
0010101010-1/cbjev (English at the root,
multilingual/ for the multilingual checkpoint). To use weights you trained yourself, put them in
$CBJEV_HOME/cbjev/ and $CBJEV_HOME/cbjev-multilingual/ (default ~/.cache/cbjev) or pass a path to
cbjev.load(...); see Training.
import cbjev
agent = cbjev.load() # English checkpoint, GPU if available
res = agent.predict(
{"subject": "Duplicate charge on invoice #4411",
"body": "We were billed twice for March. Refund it today or we cancel."},
{
"department": {"type": "choice", "instructions": "Which team should handle this?",
"criteria": {"billing": "invoices, payments, refunds", "technical": "bugs, outages",
"sales": "pricing, contracts", "other": "everything else"}},
"urgency": {"type": "score", "instructions": "How urgent is it?",
"criteria": ["can wait", "this week", "today", "blocking right now"]},
"churn": {"type": "noul", "instructions": "Does the customer threaten to cancel their subscription?"},
},
)
res["answers"]["department"]["choice"] # 'billing'
res["answers"]["churn"]["noul"] # P(true), ~0.78
Many states at once: agent.predict_batch(states, questions).
from cbjev import Router
router = Router() # english + multilingual, loaded lazily
router.predict({"body": "Mir wurde zweimal abgebucht"}, questions)["routing"]
# {'model': 'multilingual', 'reason': "Latin script, language looks like 'de'"}
cbjev-serve # 127.0.0.1:8000, POST /v1/systemone
CBJEV_API_KEY=secret CBJEV_DEVICE=cuda CBJEV_PRELOAD=1 cbjev-serve
cbjev "I was charged twice, please refund" # routing decision only, no model load
cbjev "I was charged twice, please refund" --predict # triage preset answers as JSON
cbjev.triage_questions(), guard_questions(), moderation_questions(), router_questions(),
email_questions(); cbjev.email_state(subject, body) strips quoted history, signatures and
disclaimers before the model sees an e-mail.
See BENCHMARKS.md for every number, how it was measured, and how to reproduce it.
python benchmarks/accuracy.py --engines laya,laya-td,cbjev --out benchmarks/results/accuracy.json
python benchmarks/speed.py --engines laya,laya-fast,cbjev --out benchmarks/results/speed.json
python benchmarks/plot.py
python training/build.py --out .work/data # 35 public datasets -> cases + teacher answers
python training/train.py --data .work/data --out ~/.cache/cbjev/cbjev --repeat typed_decisions=8
python training/calibrate.py --ckpt ~/.cache/cbjev/cbjev --data .work/data
training/duty.py --duty 0.5 -- <command> runs any of these on part of the GPU if you share the machine.
cbjev-multilingual (the Router does this).cbjev.load() fetches them, and
training/ rebuilds them from scratch in about an hour per checkpoint on an RTX 4090.If cbjev saves you time or GPU money, you can buy me a coffee:
GPL-3.0-or-later (see LICENSE). cbjev's checkpoints are fine-tuned from the Apache-2.0 Laya
checkpoints by Convai Innovations; see NOTICE for attribution and the datasets used.
Python
100.0%
Typed decisions (choice/score/noul) from one encoder pass - faster, better-calibrated successor to Laya, Jev wire compatible
See the code
Typed decisions — choice, score, noul — about any text or JSON state, from one encoder pass.
Every question of a call shares one encoding of the state: 3 ms for one question, 11 ms for ten questions over a 500-token document.
A self-hosted, Jev-compatible, faster and better-calibrated successor to Laya.
Measured on one RTX 4090, cbjev and Laya side by side on byte-identical cases (BENCHMARKS.md). Jev numbers are third-party published figures; there was no TypeSafe API access, so they are indicative only.
| cbjev | Laya (best of its checkpoints) | TypeSafe Jev (published) | |
|---|---|---|---|
| mean accuracy, 15 English suites | 0.741 | 0.710 (laya-typed-decisions) | — |
| suites where cbjev >= Laya's better checkpoint | 11 / 15 | ||
| typed-decisions, 2,000 decisions | 0.783 | 0.768 | 0.727 |
| AG News | 0.945 | 0.953 | 0.910 |
| DAIR emotion (held out) | 0.573 | 0.598 | 0.480 |
| Banking77, all 77 labels in one question (held out) | 0.620 | 0.497 | 0.870 (72 labels) |
| mean ECE (lower is better) | 0.117 | 0.125 | 0.246 |
| answer flips when options are reordered | 0.2 % | 7.8 % | 13 % |
| MASSIVE intent, 51 languages, macro accuracy | 0.436 | 0.401 | — |
| MASSIVE, languages where cbjev >= Laya | 45 / 51 | ||
| 1 question, short ticket | 3.0 ms | 5.4 ms (TileLang fast path) | 236–276 ms (hosted API) |
| 10 questions, short ticket | 7.5 ms | 18.2 ms | |
| 10 questions, ~500-token document | 11.4 ms | 75.8 ms | |
| 30 questions, ~500-token document | 31.4 ms | 172.4 ms |
cbjev is faster than both Laya paths in every one of the 10 latency cases measured, by 1.5x (one question on a long document) to 6.9x (ten questions on a document).
Laya encodes the state once per question: ten questions about a 500-token document means ten 500-token sequences. cbjev packs a call into one row — the state once, then every question as its own segment:
Laya [CLS] q1 [SEP] opts [SEP] state [SEP] (x N questions)
cbjev [CLS] q1 | q2 | ... | qN | state [SEP] (once)
The attention mask keeps questions from seeing each other, while the state reads all of them. Each
question segment restarts its positions right after [CLS], so with a single question the row is
token-for-token and position-for-position exactly what a Laya checkpoint was trained on — which is why
fine-tuning from Laya starts from Laya's full ability instead of relearning it.
On top of that:
cbjev/model.py) with an
explicit attention mask, bf16 matmuls over an fp32 residual stream, and CUDA-graph replay per
shape bucket (cbjev/engine.py) — a call is one graph launch instead of ~300 kernel launches.cbjev.load(order_votes=2) also asks every choice/score question with its
options reversed and averages the answers — one extra short segment, not another pass.cbjev.load("laya") runs the original weights in their own layout
(verified to match Laya's probabilities within bf16 rounding).python -m venv .venv
.venv/bin/pip install -e . # core
.venv/bin/pip install -e ".[serve]" # + HTTP server
Weights download on first use from Hugging Face:
0010101010-1/cbjev (English at the root,
multilingual/ for the multilingual checkpoint). To use weights you trained yourself, put them in
$CBJEV_HOME/cbjev/ and $CBJEV_HOME/cbjev-multilingual/ (default ~/.cache/cbjev) or pass a path to
cbjev.load(...); see Training.
import cbjev
agent = cbjev.load() # English checkpoint, GPU if available
res = agent.predict(
{"subject": "Duplicate charge on invoice #4411",
"body": "We were billed twice for March. Refund it today or we cancel."},
{
"department": {"type": "choice", "instructions": "Which team should handle this?",
"criteria": {"billing": "invoices, payments, refunds", "technical": "bugs, outages",
"sales": "pricing, contracts", "other": "everything else"}},
"urgency": {"type": "score", "instructions": "How urgent is it?",
"criteria": ["can wait", "this week", "today", "blocking right now"]},
"churn": {"type": "noul", "instructions": "Does the customer threaten to cancel their subscription?"},
},
)
res["answers"]["department"]["choice"] # 'billing'
res["answers"]["churn"]["noul"] # P(true), ~0.78
Many states at once: agent.predict_batch(states, questions).
from cbjev import Router
router = Router() # english + multilingual, loaded lazily
router.predict({"body": "Mir wurde zweimal abgebucht"}, questions)["routing"]
# {'model': 'multilingual', 'reason': "Latin script, language looks like 'de'"}
cbjev-serve # 127.0.0.1:8000, POST /v1/systemone
CBJEV_API_KEY=secret CBJEV_DEVICE=cuda CBJEV_PRELOAD=1 cbjev-serve
cbjev "I was charged twice, please refund" # routing decision only, no model load
cbjev "I was charged twice, please refund" --predict # triage preset answers as JSON
cbjev.triage_questions(), guard_questions(), moderation_questions(), router_questions(),
email_questions(); cbjev.email_state(subject, body) strips quoted history, signatures and
disclaimers before the model sees an e-mail.
See BENCHMARKS.md for every number, how it was measured, and how to reproduce it.
python benchmarks/accuracy.py --engines laya,laya-td,cbjev --out benchmarks/results/accuracy.json
python benchmarks/speed.py --engines laya,laya-fast,cbjev --out benchmarks/results/speed.json
python benchmarks/plot.py
python training/build.py --out .work/data # 35 public datasets -> cases + teacher answers
python training/train.py --data .work/data --out ~/.cache/cbjev/cbjev --repeat typed_decisions=8
python training/calibrate.py --ckpt ~/.cache/cbjev/cbjev --data .work/data
training/duty.py --duty 0.5 -- <command> runs any of these on part of the GPU if you share the machine.
cbjev-multilingual (the Router does this).cbjev.load() fetches them, and
training/ rebuilds them from scratch in about an hour per checkpoint on an RTX 4090.If cbjev saves you time or GPU money, you can buy me a coffee:
GPL-3.0-or-later (see LICENSE). cbjev's checkpoints are fine-tuned from the Apache-2.0 Laya
checkpoints by Convai Innovations; see NOTICE for attribution and the datasets used.
Python
100.0%