A ~150M-parameter encoder that checks whether a RAG answer is supported by the source it was given. Given an answer and a source (and optionally the question), it returns grounded or hallucinated with P(grounded). It runs on CPU. - Every number below is traceable to a committed report in that repository. Hashes for every file are in the repository's MODELPROVENANCE.json. python -m eval.provenance --verify re-checks them. All measured on CPU against the pinned weights, using test sets rebuilt from pinned public datasets. F1 is for the hallucinated class, and the 95% CIs come from a 2,000-resample bootstrap. - 512 tokens reproduces the training run's published numbers (F1 0.6824, acc 0.7468…
Open-weight model · Text classification
bargein-classifier-ettin-150m
by Hassan ozonetg/bargein-classifier-ettin-150m
bargein-classifier-ettin-150m is an open-weight model for text classification from Hassan, released under MIT License. It has 150M parameters and a 7,999-token context. At 16-bit it needs about 0.4 GB of GPU memory, which fits on 1x MI300X from $1.85 an hour, at the lowest prices in the SAVRN Index.
When a caller starts talking while a voice agent is still speaking, should the agent stop? This model makes that decision from text, in a few milliseconds.
Runs On
What it takes to serve bargein-classifier-ettin-150m (150M parameters): the memory its weights need at each precision, and the cheapest way to rent enough data-center GPUs to hold them.
| Precision | Weights | Memory needed | Cheapest setup | Per hour | Also fits |
|---|---|---|---|---|---|
| 16-bit | 0.3 GB | 0.4 GB | 1x MI300X (192 GB) Vultr |
$1.85 | 1x H100 $1.99 · 1x MI325X $2.00 |
| 8-bit | 0.1 GB | 0.2 GB | 1x MI300X (192 GB) Vultr |
$1.85 | 1x H100 $1.99 · 1x MI325X $2.00 |
| 4-bit | 0.1 GB | 0.1 GB | 1x MI300X (192 GB) Vultr |
$1.85 | 1x H100 $1.99 · 1x MI325X $2.00 |
Memory is the weights at that precision plus 20% for the runtime and a short context; a long context needs more. Prices are the lowest on-demand hourly rates in the SAVRN Index, read Oct 21, 2026.
bargein-classifier-ettin-150m on every accelerator the SAVRN Index prices, at every precision
Model Card
By Hassan, published under mit, revision 36a3b2cbe1b9.
When a caller starts talking while a voice agent is still speaking, should the agent stop? This model makes that decision from text, in a few milliseconds. It reads one moment of a call: what the agent had already said, what it was about to say, and the caller's speech-recognised words. It then returns the probability that the agent should stop (INTERRUPT) or keep talking (CONTINUE). The CPU-friendly model: 38 ms per decision on 4 CPU threads. It matches the 400m on held-out business types and real calls, and gives up about 2 points under distribution shift. Have a GPU? bargein-classifier-ettin-400m is the flagship: more robust to distribution shift, at 8.5 ms on a GPU. Callers talk over…
Read Hassan's full model card
When a caller starts talking while a voice agent is still speaking, should the agent stop?
This model makes that decision from text, in a few milliseconds. It reads one moment of a call: what the agent had already said, what it was about to say, and the caller's speech-recognised words. It then returns the probability that the agent should stop (INTERRUPT) or keep talking (CONTINUE).
The CPU-friendly model: 38 ms per decision on 4 CPU threads. It matches the 400m on held-out business types and real calls, and gives up about 2 points under distribution shift.
Live demo · 400m model · Collection
| bargein-classifier-ettin-150m | |
|---|---|
| Held-out business types (two test sets, never trained on) | 95.3% / 93.4% accuracy |
| Human-labelled exchanges (158) | 98.1% (155 / 158) |
| Same tests spoken by TTS, sent over a phone channel and re-transcribed by ASR | 91.6% |
| Distribution-shift test (10 kinds of shift, 10,888 exchanges) | 89.8% |
| Real calls, unambiguous moments (278) | 97.5% |
| Latency, batch 1, end to end | 7.0 ms GPU · 38 ms CPU (4 threads) |
Have a GPU? bargein-classifier-ettin-400m is the flagship: more robust to distribution shift, at 8.5 ms on a GPU.
Why barge-in matters
Callers talk over voice agents all the time, and most of it should not stop the agent: "mm hmm", "okay", a cough, a word to someone in the room. Some of it must stop it at once: "wait, which doctor?", "that's the wrong address", "stop calling me". Rules based on voice activity or keywords get this wrong in both directions. An agent that stops on every "uh huh" feels jumpy and loses its place, and one that talks over a real question feels rude.
The right answer depends on what the agent was saying when the caller spoke. "Yes" right after a question the caller heard is an answer (INTERRUPT); "yeah" in the middle of a statement is a backchannel (CONTINUE). That is why the model reads the agent's line split at the moment the caller started talking.
Input format
| field | what it is | example |
|---|---|---|
agent_said |
The agent's TTS text that was played before the caller started speaking (what the caller heard). | Your appointment is on Tuesday at |
agent_unsaid |
The rest of the agent's planned line, not yet heard. Context only; it may be empty. | three pm with Dr. Lee. Does that still work? |
caller_said |
The raw ASR text of the caller's overlapping speech. | wait which doctor |
format_input.py, with textnorm.py, turns the three fields into one string. It
is the exact code used in training:
[BOT SAID] your appointment is on tuesday at
[BOT NOT YET SAID] three pm with dr . lee . does that still work ?
[CALLER] wait which doctor
- Normalisation: text is lowercased and numbers are written as words. Agent punctuation is kept as tokens, because a question mark is a strong cue. Caller text is mapped to the ASR's output style.
- Length: the budget is 192 tokens. If the input is longer, the formatter trims agent text and never the caller's words.
- Always build inputs with
format_input.py. A hand-built string is a train/inference mismatch. The inference widget on this page takes an already formatted string.
Labels
| id | label | runtime action | typical caller turns |
|---|---|---|---|
| 0 | CONTINUE |
The agent keeps speaking and drops the caller's words. | Talk not aimed at the agent (side talk, TV), reactions, acknowledgements and backchannels, repeating the agent, unfinished starts, small talk, narrating what they are doing, permission to go on. |
| 1 | INTERRUPT |
The agent stops and the LLM takes the turn. | An answer (including one that disqualifies), a counter-request or correction, a question, "I can't hear you" / "wait", identity or voicemail cues, closing the call while having more to say. |
Quickstart
pip install torch "transformers>=4.51" huggingface_hub
import sys
from huggingface_hub import snapshot_download
path = snapshot_download("ozonetg/bargein-classifier-ettin-150m")
sys.path.insert(0, path)
from predict import BargeInClassifier # predict.py ships in this repo
clf = BargeInClassifier(path) # GPU (bf16) if available, else CPU (fp32)
clf.predict(agent_said="Your appointment is on Tuesday at",
agent_unsaid="three pm with Dr. Lee. Does that still work?",
caller_said="wait which doctor")
# {'label': 'INTERRUPT', 'p_interrupt': 0.99..., 'model_called': True}
python predict.py in a local copy of the repo runs the built-in examples. Use --agent-said, --agent-unsaid and
--caller-said to classify your own input.
Plain transformers, without predict.py
import sys, torch
from huggingface_hub import snapshot_download
from transformers import AutoTokenizer, AutoModelForSequenceClassification
path = snapshot_download("ozonetg/bargein-classifier-ettin-150m")
sys.path.insert(0, path)
import format_input # the training-time formatter
tok = AutoTokenizer.from_pretrained(path)
model = AutoModelForSequenceClassification.from_pretrained(
path, dtype=torch.float32).eval() # transformers < 4.56: torch_dtype=...; on 4.x add reference_compile=False
text = format_input.build_input(
"Your appointment is on Tuesday at",
"three pm with Dr. Lee. Does that still work?",
"wait which doctor",
count_tokens=lambda s: len(tok(s).input_ids), max_tokens=192).text
enc = tok(text, truncation=True, max_length=192, return_tensors="pt")
with torch.no_grad():
p = model(**enc).logits.softmax(-1)[0, 1].item()
print(model.config.id2label[int(p >= 0.5)], round(p, 3)) # INTERRUPT 1.0
On a GPU, load with `dtype=torch.bfloat16` and move the model and inputs to `"cuda"`. On CPU fp32, transformers
4.51, 4.57 and 5.17 give identical outputs, with 0 decision changes on 593 test exchanges.
transformers.js (browser or Node) and ONNX
[`format_input.js`](format_input.js) is a JavaScript port of the formatter. It produced the same model input as the Python code on 85,529 dataset rows and 30,000 random strings.import { AutoTokenizer, AutoModelForSequenceClassification } from "@huggingface/transformers";
import { buildInput } from "./format_input.js"; // from this repo
const id = "ozonetg/bargein-classifier-ettin-150m";
const tok = await AutoTokenizer.from_pretrained(id);
const model = await AutoModelForSequenceClassification.from_pretrained(id); // fp16 ONNX by default
const { text } = buildInput("Your appointment is on Tuesday at", "three pm with Dr. Lee. Does that still work?",
"wait which doctor", { countTokens: (s) => tok.encode(s).length, maxTokens: 192 });
const { logits } = await model(tok(text, { truncation: true, max_length: 192 }));
const [c, i] = logits.data;
const p = 1 / (1 + Math.exp(c - i));
console.log(model.config.id2label[p >= 0.5 ? 1 : 0], p.toFixed(3)); // INTERRUPT 1.000
Precision was chosen per model by measured decision flips against PyTorch fp32 on 893 held-out exchanges
(593 held-out business types, 150 distribution-shift, 150 TTS → phone → ASR). A quantized file ships only if it
changes at most 0.5% of decisions.
| file | precision | size | decision flips (of 893) | status |
|---|---|---|---|---|
| `onnx/model.onnx` | fp32 | 599 MB | 0 (0%) | shipped |
| `onnx/model_fp16.onnx` | fp16 | 300 MB | 0 (0%) | shipped; transformers.js default, used by the demo |
| 8-bit weights | MatMulNBits, block 32, fp32 activations | 280 MB | 1 (0.1%) | not shipped: only 20 MB smaller than the exact fp16 |
| dynamic int8 | 8-bit weights and activations | 151 MB | 19 (2.1%) | not shipped |
- **Where the shipped files were checked:** in onnxruntime, in transformers.js on Node and in Chrome (WASM).
- **Choosing a file:** transformers.js loads the fp16 file by default; pass `{ dtype: "fp32" }` to pick another.
- **RoPE:** the export keeps the checkpoint's RoPE theta of 160,000 (`global_rope_theta` / `local_rope_theta`) and
matches PyTorch to 1e-5. As a control, the default theta of 10,000 changes 1–3.5% of decisions.
Examples
These are this model's outputs on the demo inputs.
| case | agent said | agent not yet said | caller | label | P(INTERRUPT) |
|---|---|---|---|---|---|
| Backchannel | We have a few openings next week, and the | earliest one is Monday morning at nine. | mm hmm | CONTINUE | 0.000 |
| Explicit stop | Hi, this is Sam calling about the | free roof assessment you asked for last month. | not interested take me off your list | INTERRUPT | 1.000 |
| Question | Your appointment is on Tuesday at | three pm with Dr. Lee. Does that still work? | wait which doctor | INTERRUPT | 1.000 |
| Answer to the agent's question | Would mornings or afternoons work better for you? | We have slots open on both. | mornings are better for me | INTERRUPT | 1.000 |
| "yeah" during a statement | Your plan includes unlimited talk and text, and | you also get fifteen gigs of data each month. | yeah | CONTINUE | 0.000 |
| Correction | So I have your address as 14 Maple Drive, | and we'll ship it out tomorrow. | no it s maple court | INTERRUPT | 1.000 |
| Side talk to someone in the room | The total comes to $42.50, and | that includes delivery to your door. | honey can you grab the door | CONTINUE | 0.000 |
| Noise, no words | Our plans start at $29.99 a month, with | no contract and free installation. | (no words) | CONTINUE | not called |
Recommended runtime use
- Treat an empty transcript as CONTINUE without calling the model. On real calls, 44% of the moments when the
caller made sound over the agent had no recognised words (breath, noise, a cough). Training data never had an empty
caller turn, so if you do call the model on one, it stops the agent 13.1% of the time.
predict()applies this rule for you. - Use the 0.5 threshold. Every number on this page uses it, and thresholds tuned on small human-labelled sets were unstable. The outputs are sharp: about 1% fall between 0.2 and 0.8.
- Run it on each new ASR partial or final while the agent is speaking. One reasonable pattern is to debounce partials, then act on the first result ≥ 0.5 or at the end of the caller's speech. That loop is a runtime design choice and was not evaluated here.
- Feed it the right inputs.
-
agent_saidis the TTS text actually played, sliced by word timestamps, with its original casing and punctuation. Digits,$anda.m.are fine. -agent_unsaidmay be empty, or partial while the LLM is still streaming. -caller_saidis the raw ASR text. Training covered caller turns of 1 to 49 words (median 5).
Evaluation
All accuracies use threshold 0.5 and come from the single published model of each size. Both models are shown, so you can choose between them. Except for the human-labelled set and the real-call rule cases, test labels come from the same LLM-judge pipeline as the training labels (see Data). Those scores therefore measure agreement with the labelling rubric on inputs the model has never seen.
Unseen business types and human labels
| test set | n | 400m | 150m |
|---|---|---|---|
| Held-out business types A: 8 business types absent from training (vet clinic, DMV, cruise sales, pest control, …) | 593 | 95.11 | 95.28 |
| Held-out business types B: 20 other unseen business types | 588 | 93.71 | 93.37 |
| Human-labelled exchanges, never shown to the labelling judge | 158 | 98.10 | 98.10 |
| ↳ same, mean of 3 training seeds of the recipe | 158 | 97.47 | 96.62 |
On the human-labelled set, one case is worth 0.63 points, so the two sizes cannot be told apart there. The rubric was written with these human labels in view, so read this score as optimistic. The human labels themselves disagree with each other on about 5% of such cases.
Robustness
| test | n | 400m | 150m |
|---|---|---|---|
| Perturbation stress test: the held-out cases rewritten with the same meaning but rougher text. Heavier ASR noise, no punctuation or casing, fillers and stutters, the agent's line cut early, an empty unsaid part. Accuracy / flip rate (how often the decision differs from the clean original). | 6,258 | 93.59 / 1.98 | 92.94 / 2.70 |
| TTS → phone channel → ASR: the held-out cases spoken by 12 TTS voices, passed through a phone-quality channel with background noise, then transcribed by a Parakeet-TDT-CTC-110M telephony recogniser (19% WER). | 1,328 | 91.11 | 91.57 |
Distribution shift (OOD-10k)
This test has 10,888 new exchanges, generated and frozen before any model was scored. They cover ten deliberate shifts of about 1,090 exchanges each.
| shift | what changes | 400m | 150m |
|---|---|---|---|
| New business types | 81 business types absent from training: B2B, government, niche health and consumer services | 95.7 | 94.2 |
| Locale | agent and caller outside the US (UK, Ireland, Australia, India, South Africa, Nigeria, the Philippines, …): local currencies, vocabulary and speech | 92.5 | 90.2 |
| Agent style | very long or very short turns, menus, compliance scripts, number-dense read-backs, two questions in one turn | 94.9 | 94.2 |
| Caller population | very elderly callers, heavy ESL grammar, regional dialects, code-switching, children, hostile or sarcastic callers, ramblers | 90.4 | 89.5 |
| ASR error profile | other recogniser failure modes: loops, dropped function words, sound-alikes, clipped words, garbled numbers | 91.7 | 90.1 |
| Call phase | payment capture, ID verification, scheduling, hold and transfer, terms reading, wrap-up, consent | 95.9 | 94.5 |
| Timing extremes | the caller starts after 1–3 agent words, after a 20+ word line, with 40–90 words still unsaid, between dictated digits | 96.0 | 95.6 |
| Hard meanings | 24 contrast types: implicit or conditional answers, sarcastic refusals, side talk that looks like an answer, leaving vs. saying goodbye and coming back | 90.5 | 88.7 |
| Third party | someone other than the intended person: gatekeepers, caregivers, interpreters, household members, employees, answering services | 82.5 | 75.4 |
| Mixed | a new business type, caller population and ASR profile at once; a third also have a non-US locale | 88.2 | 85.3 |
| All | 91.84 | 89.76 |
Real calls
This test uses 2,525 barge-in moments from 1,477 real outbound sales calls from a single campaign. - Sampling: 2,000 calls were drawn at random, stratified by week and call length, with at most 2 moments kept per call. The agent's own echo on the caller channel was removed. - Transcription: both channels were transcribed by the telephony ASR. The agent's line was split into heard and not-yet-said at the caller's onset, using word timestamps, and its punctuation was restored by a simple rule. - Privacy: no call content left the servers and no humans labelled these moments. There are two references instead.
| reference | n | 400m | 150m |
|---|---|---|---|
| Rule-unambiguous moments with words: backchannels such as "uh huh" over a statement are CONTINUE, and "stop", "not interested", "don't call", "wrong number" are INTERRUPT. | 278 | 98.2 (96.0–99.7) | 97.5 (95.2–99.3) |
| Agreement with an LLM judge where it is confident (P < 0.1 or > 0.9). The judge is a local 27B model given the training rubric; the opener "hello" is excluded (see Limitations). | 945 | 94.4 (92.7–95.8) | 94.5 (93.0–95.9) |
| Agreement with the LLM judge, all moments with words, excluding the opener "hello" | 1,262 | 87.7 (85.8–89.5) | 87.8 (85.8–89.6) |
| Agreement with the LLM judge, all moments with words | 1,425 | 80.2 (78.2–82.2) | 83.4 (81.5–85.4) |
| Stops the agent on an empty transcript (lower is better; avoided by runtime rule 1) | 1,100 | 10.2% (8.4–12.0) | 13.1% (11.1–15.2) |
- Intervals: 95% bootstrap intervals over calls.
- The judge is a second opinion, not ground truth. It agrees with the human labels 97.5% of the time, one case below the models.
- Clear cases are right. The 400m keeps talking over 209 of 213 pure backchannels and stops on 28 of 29 explicit stop requests.
- Agreement holds where the judge is confident. There it is close to the models' score on human labels, so real recogniser text does not break them.
- Most of the remaining gap has two causes the synthetic data never had: empty transcripts, which runtime rule 1 handles, and a lone "hello" while the agent's opener plays. The 150m stops less often than the 400m on the opener "hello" (52% vs 79%), which is why its all-moments agreement is higher.
Latency
| model | parameters | GPU bf16, p50 (p95) | CPU fp32, 4 threads, p50 (p95) |
|---|---|---|---|
| bargein-classifier-ettin-400m | 396M | 8.5 ms (9.5) | 113 ms (121) |
| bargein-classifier-ettin-150m | 150M | 7.0 ms (7.8) | 38 ms (44) |
- Setup: batch 1, end to end per decision (formatting, tokenisation and the forward pass).
- Hardware: an NVIDIA RTX 6000 Ada GPU and an Intel Xeon Gold 5412U CPU.
- Run: both models were measured side by side in one run with exclusive use of the GPU. The 400m peaks at 0.75 GB of GPU memory.
Training
| Base model | jhu-clsp/ettin-encoder-150m (22 layers, hidden 768; ModernBERT architecture) |
| Head | sequence classification (mean pooling), 2 labels |
| Fine-tuning | full fine-tune, AdamW (weight decay 0.01), lr 5e-5, linear schedule with 6% warm-up, batch 32, 5 epochs, last checkpoint |
| Regularisation | dropout 0.02 on embeddings, attention, MLP and head (Ettin ships with dropout 0), plus R-Drop with α = 1.0 |
| Precision / length | bf16 autocast over fp32 master weights; max length 192 tokens |
| Data | 64,151 training exchanges, plus 323 held back as a dev monitor |
| Compute | one NVIDIA RTX 6000 Ada, 45 min (2,713 s), peak 8.0 GB |
How R-Drop works: each batch is run twice with different dropout masks. The loss is the mean cross-entropy of the two passes plus α × the symmetric KL divergence between their predictions. The model is penalised when two dropout samples disagree, which makes it depend less on small details of the wording. That is also why it holds up better on noisy caller text.
Why the 150m uses a lighter dropout. On the small model, the 400m's recipe (dropout 0.1 + R-Drop) improved almost every test but broke one behaviour: telling a caller who is leaving from one who says goodbye and then comes back (87% → 61% over 3 seeds). Dropout 0.02 with full-strength R-Drop keeps most of it (83.7% vs 87.0% for a plain fine-tune) while keeping the gains: distribution shift +0.55 pt (p < 0.001), third party +2.6 pt, TTS → phone → ASR +1.1 pt, all against the plain fine-tune over 3 seeds.
What was tried (ablations on the 400m)
Each change was compared with the same recipe without dropout, on 33 business types held out of training (12,876 exchanges), as a mean of 2 seeds with a paired test. The decision rule was fixed before any results came in. | change | Δ accuracy on unseen business types | |---|---| | **dropout 0.1 + R-Drop (shipped)** | **+0.56 (p < 0.001)** | | R-Drop + weight EMA | +0.50 | | R-Drop + label smoothing 0.1 | +0.47 | | R-Drop + ASR-noise augmentation | +0.56 (not adopted: lower on the shift test) | | ensemble of 2 models without dropout (2× compute) | +0.44 | | weight soup of 2 seeds without dropout | +0.38 | | dropout 0.1 only | +0.37 | | 7 epochs instead of 5 | +0.13 | | label smoothing 0.1 | +0.07 | | half learning rate | −0.29 | | layer-wise LR decay | −0.82 | - **Dropout gives about two thirds of the gain.** ModernBERT-family checkpoints ship with dropout switched off. - **Nothing tested on top of R-Drop beat it.** That covered SAM, consistency training, ASR-noise augmentation, R-Drop strength 0.5 and 2.0, and other dropout rates. - **Distillation did not help.** Students of seven LLM teachers (4B–31B, fine-tuned or prompted) did not beat the plain fine-tune. - **Backbones were compared first, at 40k rows.** Ettin-1b, DeBERTa-v3-large, ModernBERT-large, Llama-3.2-1B and Qwen3-1.7B scored within about two human-labelled cases of Ettin-400m. They were slower on CPU, GPU or both. ModernBERT-large also lost to Ettin-400m on unseen business types in a later paired test (−0.24 pt).Data
The training data is synthetic. It contains no real call audio or transcripts, and it is not released.
- Rubric. About 325 exchanges were labelled by a human, the voice-agent operator, under their own stop / keep talking policy. Where the labeller's own answers contradicted each other, the newer answer with a written note won. The labels were then distilled into a written rubric of interrupt and continue categories (see Labels).
- Generation. An LLM wrote 70,609 exchanges from sampled specifications: - business type (166 of them); - agent moment (25: pitch, price reveal, yes/no question, appointment details, read-back, …); - caller act and who the caller is addressing; - persona, where the agent's line is cut, and caller length. About a third come as minimal pairs, where one small change flips the label.
- ASR style. Caller text is written the way the target telephony recogniser prints speech: lowercase, no punctuation, numbers as words. The ASR noise mix is 75% clean, 21% light and 3% heavy errors.
- Labelling. An LLM judge applied the rubric, with 167 of the human labels as worked examples. Under cross-validation it agrees with held-out human labels 96–97% of the time.
- Quality control. - A second, different LLM blind-relabelled 40k rows, and every disagreement went to three adjudicators. - An ensemble of trained models flagged about 3% of rows as likely wrong, and those were dropped. - Blind audits estimate the remaining label error at 1–3%.
- Result. 64,474 exchanges, 56.6% CONTINUE and 43.4% INTERRUPT. Caller turns are 1–49 words (median 5) and 87% are unique. Accuracy on human labels stopped improving at around 64–66k rows.
Limitations and risks
- English only, telephone style. Training data is US-English phone conversations. Other English locales held up on the shift test (90.2%), but other languages are out of scope.
- One exchange, text only. The model sees no dialogue history and no audio (prosody, loudness). It answers "should the agent stop now?", not "has the caller finished their turn?".
- Third parties are the weakest area. 82.5% (400m) and 75.4% (150m) on the shift test. An interpreter relaying the caller's answer is often missed.
- A lone "hello" while the agent's opener plays (usually the caller picking up) makes the model stop: this model stops on 52% of them on real calls, where the judge keeps going. The training data had no single pickup "hello", only "hello? hello?" (INTERRUPT). If your agent should talk over a pickup greeting, handle it in the runtime.
- Stopping rate. On real calls with words, this model stops the agent on 31.2% of caller turns; the LLM judge stops it on 22%. Most of the difference is the opener "hello".
- Short accept words right after a question. "okay" or "mm hmm" just after the agent asks something is read as an answer (INTERRUPT) by the rubric. Human labels split on this too.
- Leaving vs. goodbye-and-back. This model is weaker than the 400m on telling "I have to go" from a goodbye followed by more talk (87.8%, 36 of 41 on the shift test). Use the 400m if this matters.
- The policy is opinionated. The labels follow one operator's policy:
- voicemail greetings are INTERRUPT (low confidence);
- urgent talk in the caller's room that is not addressed to the agent is CONTINUE.
Check these against your product before use. - Not a compliance control. Explicit stop and do-not-call requests are INTERRUPT (28 of 29 on real calls), but opt-out handling should not depend on a classifier. Detect and log those requests separately. - Single real-call campaign. The real-call test covers one outbound sales campaign with a recorded-prompt agent. Its agent text came from ASR with rule-restored punctuation, not the exact TTS text. - Validate before going live. Check on a sample of your own calls, especially if your callers, recogniser or agent style differ from the above.
Citation
@misc{ozonetg2026bargein,
title = {Barge-in classifier for voice agents (Ettin-150m)},
author = {ozonetg},
year = {2026},
howpublished = {\url{https://huggingface.co/ozonetg/bargein-classifier-ettin-150m}}
}
@misc{weller2025seqvsseqopen,
title = {Seq vs Seq: An Open Suite of Paired Encoders and Decoders},
author = {Orion Weller and Kathryn Ricci and Marc Marone and Antoine Chaffin and Dawn Lawrie and Benjamin Van Durme},
year = {2025},
eprint = {2507.11412},
archivePrefix = {arXiv},
primaryClass = {cs.CL},
url = {https://arxiv.org/abs/2507.11412}
}
@inproceedings{liang2021rdrop,
title = {R-Drop: Regularized Dropout for Neural Networks},
author = {Xiaobo Liang and Lijun Wu and Juntao Li and Yue Wang and Qi Meng and Tao Qin and Wei Chen and Min Zhang and Tie-Yan Liu},
booktitle = {Advances in Neural Information Processing Systems},
volume = {34},
year = {2021},
url = {https://arxiv.org/abs/2106.14448}
}
Related
- bargein-classifier-ettin-400m: the flagship GPU sibling.
- Live demo: try both models.
- parakeet-tdt-ctc-110m-call-audio-adapter: the telephony ASR adapter whose output style the caller text follows.
Configuration
- Architecture
- ModernBertForSequenceClassification
- Context length (tokens)
- 7,999
- Layers
- 22
- Hidden size
- 768
- Feed-forward size
- 1,152
- Attention heads
- 12
- Vocabulary size
- 50,368
- Model type
- modernbert
Identity and Version
- Repository
- ozonetg/bargein-classifier-ettin-150m
- Publisher
- Hassan
- Task
- Text classification
- Modality
- Text
- Library
- transformers
- Parameters
- 150M parameters
- Languages
- en
- Revision
- 36a3b2cbe1b9cb46c424d2953202d33485b60409
- First published
- 2026-10-08
- Last updated
- 2026-10-08
Files and Weights
12 files, 1.2 GB in total. The weights are 3 files totalling 1.2 GB in onnx, safetensors.
Every file
| File | Type | Size | SHA-256 |
|---|---|---|---|
| model.safetensors | Weights | 299.2 MB | 27d03623183b |
| onnx/model.onnx | Weights | 599.0 MB | 67711b0b0cba |
| onnx/model_fp16.onnx | Weights | 299.9 MB | ad53662c420d |
| config.json | Configuration | 2.2 KB | — |
| format_input.py | Configuration | 5.1 KB | — |
| predict.py | Configuration | 6.3 KB | — |
| textnorm.py | Configuration | 9.9 KB | — |
| README.md | Documentation | 29.4 KB | — |
| format_input.js | Other | 9.4 KB | — |
| .gitattributes | Repository | 1.5 KB | — |
| tokenizer.json | Tokenizer | 3.6 MB | — |
| tokenizer_config.json | Tokenizer | 415 B | — |
License and Download
- License
- mit
- Access
- Open weights, no gate
- Download size
- 1.2 GB
Released by Hassan through its official repository on Hugging Face. Read the license.
Built From
- Derived from jhu-clsp/ettin-encoder-150m
- Described by arXiv:2106.14448
- Described by arXiv:2507.11412
- Quantized from jhu-clsp/ettin-encoder-150m
Evaluations
Each result is shown as reported, with the conditions its reporter stated. None is a SAVRN measurement. A comparison lines two results up only when their configuration, unit and setup are all stated and identical.
| Benchmark | Conditions | Result | Reported by | Revision | Date |
|---|---|---|---|---|---|
| Distribution-shift test OOD-10k (10,888) | Task Barge-in classificationMetric Accuracy (threshold 0.5)Comparison conditions not established | 89.76 | ozonetg Publisher reported |
Evaluated revision not stated | — |
| Held-out business types A (593 exchanges, 8 unseen business types) | Task Barge-in classificationMetric Accuracy (threshold 0.5)Comparison conditions not established | 95.28 | ozonetg Publisher reported |
Evaluated revision not stated | — |
| Held-out business types B (588 exchanges, 20 unseen business types) | Task Barge-in classificationMetric Accuracy (threshold 0.5)Comparison conditions not established | 93.37 | ozonetg Publisher reported |
Evaluated revision not stated | — |
| Human-labelled exchanges (158, not shown to the labelling judge) | Task Barge-in classificationMetric Accuracy (threshold 0.5)Comparison conditions not established | 98.1 | ozonetg Publisher reported |
Evaluated revision not stated | — |
| Perturbation stress test (6,258) | Task Barge-in classificationMetric Accuracy (threshold 0.5)Comparison conditions not established | 92.94 | ozonetg Publisher reported |
Evaluated revision not stated | — |
| Real calls, rule-unambiguous moments with words (278) | Task Barge-in classificationMetric Accuracy (threshold 0.5)Comparison conditions not established | 97.5 | ozonetg Publisher reported |
Evaluated revision not stated | — |
| TTS -> phone channel -> ASR stress test (1,328) | Task Barge-in classificationMetric Accuracy (threshold 0.5)Comparison conditions not established | 91.57 | ozonetg Publisher reported |
Evaluated revision not stated | — |
Memory Requirements
| Precision | Weights in memory |
|---|---|
| As published | 1.2 GB |
| 16-bit | 0.3 GB |
| 8-bit | 0.1 GB |
| 4-bit | 0.1 GB |
Weights only, from the published parameter count; the key-value cache and runtime add to this.
Questions About bargein-classifier-ettin-150m
How much GPU memory does bargein-classifier-ettin-150m need?
About 0.4 GB at 16-bit and 0.1 GB at 4-bit: the weights (150M parameters) plus a working margin. A long context needs more.
What is the cheapest GPU to run bargein-classifier-ettin-150m on?
At 16-bit, 1x MI300X from $1.85 an hour; at 4-bit, 1x MI300X from $1.85 an hour, at the lowest on-demand prices the SAVRN Index lists.
Can I use bargein-classifier-ettin-150m commercially?
Yes. bargein-classifier-ettin-150m is released under MIT License. The MIT License is a short permissive license. It permits commercial use, modification and redistribution, provided the copyright notice and permission notice are included.
What is bargein-classifier-ettin-150m's context length?
7,999 tokens, from the maximum position embeddings in its published configuration.
Similar Models
Firebird-ModernBERT-512-RW is an experimental post-trained variant of It is a ~149M parameter ModernBERT binary classifier for distinguishing: - 0 — HUMAN The maximum sequence length is 512 tokens. This checkpoint was produced through reward-weighted classifier post-training. The original Firebird checkpoint was kept frozen as a reference model. Training examples were scored by the original classifier, difficult examples received larger loss weights, and the post-trained model was constrained against the frozen reference using a KL penalty. L = weightedcrossentropy + beta KL(reference || policy) Hard human examples received greater weighting than ordinary examples because one goal of the…
Pyrrho is a CPU-runnable co-processor for retrieval-augmented generation. It reads a question before retrieval to suggest what evidence to seek, then reads the question with retrieved passages to assess whether those passages support an answer. A surrounding RAG runtime decides whether to answer, retrieve again, or surface a conflict. The broader project is described in the The evidence verdict is SUFFICIENT, DISPUTED, or INSUFFICIENT. These are predictions about the supplied passages. The model does not retrieve sources, generate answers or citations, check external facts, or prove that a corpus has been searched completely. The two passes use the same encoder with different input…
High-Throughput Native Decision Model (<200M Parameters) Decoupled Multi-Vector Late Interaction for Fast, Calibrated System-One Decisions Tasksource-JEV-Nano is a compact (~149M parameter) decision model that picks the optimal action, category, or verdict from a candidate list using token-level multi-vector late interaction rather than conventional classification heads. Built on answerdotai/ModernBERT-base and lightonai/LateOn, it handles all three fundamental System-One decision types: 1. Choice: Selecting the best candidate among variable numbers of options ($K=2$ to $K=100+$). 2. NOUL: Yes/no uncertainty decisions. 3. Score: Quantitative ranking and graded scales. All evaluations below…
Hierarchical document classifier for the LLM-Mailroom intake pipeline: a fine-tuned ModernBERT-base encoder with a doctype head plus one subclass head per document class. It is the deterministic pre-check in the BERT-coupled intake overhaul (mailroom-issues #85). 8,192-token context, bf16. heads (contract, corporaterecord, correspondence, insuranceclaim, mergeragreement). MLP heads with dropout 0.1. by plurality vote over windows; subclass by plurality over windows whose doctype vote is the winning class. doctype (6): contract, mergeragreement, corporaterecord, correspondence, insuranceclaim, unknown (inference-only abstention — not a trained class) development, distributor, endorsement…