BERT v47 — Medical Triage Decision Support (19-head)
A 19-head BERT model for emergency department triage decision support. Predicts ESI (Emergency Severity Index) levels 1-5 from free-text triage narratives + supplemental heads for symptoms, resources, vitals, flags, and clinical context.
Architecture: BiomedBERT encoder (109M params) + 19 task heads, trained with focal loss, label smoothing, ordinal-distance penalty, layer-wise LR decay, and effective-number-of-samples class weighting.
Intended use: clinical decision support for triage nurses — produces ESI prediction with confidence, detected symptoms, suggested resources, and uncertainty signals. Not a standalone diagnostic system.
Eval results (epoch 3, 4 clean holdouts)
Dataset
n
Exact
Adjacent
ESI 1 recall
ESI 5 recall
MIETIC clean (narrative)
200
85.0%
94.5%
56.7%
92.5%
MIMIC-IV-ED holdout
7,917
62.9%
97.9%
65.3%
25.0%
Lukina v3 (curated narrative)
201
58.2%
86.1%
80.0%
25.0%
MC-MED Stanford clean
1,000
57.2%
96.0%
18.0%
6.0%
ER-REASON (unseen variants, 200)
200
50.5%
93.5%
n/a
n/a
Validation metrics at best checkpoint (composite=0.791):
1import torch
2from transformers import AutoTokenizer
34# 1. Get the architecture code5# Either clone the source repo or copy train_bert_v47.py from this repo6from train_bert_v47 import V47MultiHeadBERT
78ENCODER ="microsoft/BiomedNLP-BiomedBERT-base-uncased-abstract-fulltext"9tokenizer = AutoTokenizer.from_pretrained("vadimbelsky/bert-v47-medical-triage", subfolder="tokenizer")1011model = V47MultiHeadBERT(ENCODER)12state = torch.load("model.pt", map_location="cpu", weights_only=False)13model.load_state_dict(state, strict=False)14model.eval()1516text ="""52-year-old female arrived by ambulance with chest pain.
17Vital signs: HR 86, BP 134/78, RR 16, SpO2 99%, T 36.4°C. Pain 7/10."""1819enc = tokenizer(text, return_tensors="pt", truncation=True, max_length=512, padding="max_length")20with torch.no_grad():21 out = model(enc["input_ids"], enc["attention_mask"])22esi_pred =int(out["esi_logits"].argmax(-1))+1# 1..523print(f"ESI: {esi_pred}")
Training
Encoder: microsoft/BiomedNLP-BiomedBERT-base-uncased-abstract-fulltext
Total params: 109.7M
Loss: focal CE γ=2 + ordinal-distance penalty (esi)
focal BCE γ=2 + pos_weight (airway/resus)
BCE multi-label (symptom/resource heads)
Class weights: effective-number-of-samples β=0.999 (Cui et al. 2019)
Optimization: AdamW + cosine schedule + layer-wise LR decay (0.9/layer)
Precision: bf16 mixed
Checkpoint: 0.7 × esi_exact + 0.3 × symptom_f1_micro (composite)
Best checkpoint composite: 0.791 (epoch 3 of 6, early stopped at epoch 3)
Limitations
Compact CC dialect heavy in training corpus (MIMIC-IV-ED dominates at 290K/354K records) — over-fits to short telegraphic CC + vitals format
Lukina-style structured narrative: 0 representation in train; eval shows 58% exact on this dialect (vs 85% on MIETIC where MIETIC-style examples ARE in train)
1@misc{belsky2026berttriage,
2 title = {BERT v47: Multi-head Decision Support for Emergency Triage},
3 author = {Belski, Vadzim},
4 year = {2026},
5 url = {https://huggingface.co/vadimbelsky/bert-v47-medical-triage}
6}
Disclaimer
This model is research software for clinical decision support, not a standalone diagnostic system. ESI predictions are advisory only and must be reviewed by a licensed clinician. The model has known limitations on rare ESI classes (1 and 5) and out-of-distribution narrative formats. Do not deploy in production triage workflows without thorough validation on your local patient population, IRB approval, and physician oversight.