Instructions to use Rology/rad-decider with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use Rology/rad-decider with PEFT:
from peft import PeftModel from transformers import AutoModelForCausalLM base_model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3.5-0.8B") model = PeftModel.from_pretrained(base_model, "Rology/rad-decider") - Notebooks
- Google Colab
- Kaggle
rad-decider (0.8B)
One open model for the small decisions that run a radiology workflow β from the order, through the report, to what happens after sign-off. It answers a typed question in one forward pass with a calibrated probability, and writes no text.
Give it the case (order, DICOM header fields, clinical history, report sections) and a typed question β yes/no, choose one, or an ordered scale β and
it returns a probability for every option. It reads the logits of the option letters at a fixed answer slot, so it can only answer with one of the
options you allowed. It is a LoRA adapter (r = 32) on Qwen/Qwen3.5-0.8B: small enough to run next to a PACS or RIS.
Research artifact β not for clinical use. This release is provided for research and evaluation. It is not a medical device and must not be used to inform patient care. Licensed Apache-2.0, matching the
Qwen3.5base model.
The problem
Radiology loses time on decisions that are simple to state and easy to miss at volume: Does the exam fit the clinical question? Right side, right contrast? Is the history enough to read? Does the report describe the side that was ordered? Does it describe contrast that was not given? Did a critical result get called? Who should recheck a rejected report? Missed, each one costs more than it would have to fix: a rescan, a call-back, a reassignment, an addendum, a repeat scan. rad-decider turns each of these into a typed question with a calibrated probability, so a workflow can flag before sign-off and sort the worklist on arrival instead of correcting afterwards.
Three decisions that pay for themselves
Each is compared with the untuned base model (Qwen/Qwen3.5-0.8B, same prompt, same letter readout). These three span the whole cycle: before the
report, while it is written, and after sign-off.
Before the report β emergency worklist triage. A stroke-like CT head order should go to the top of the list, not into a first-come queue.
modality: CT ordered_procedure: CT head without contrast patient_class: Emergency order_priority: STAT
reason_for_exam: Sudden left-sided weakness and slurred speech, onset 40 minutes ago
Q (ordered scale): How urgently should this study be read? routine < urgent < stat < critical_suspected
rad-decider -> critical_suspected (0.87) untuned base -> routine (wrong)
On the held-out synthetic test (1,200 cases): rad-decider 0.90 vs untuned base 0.67 accuracy. Saves: critical cases read first.
While reporting β wrong-side check that does not cry wolf. Left knee ordered, the report is about the left knee and mentions the right knee only as a normal comparison. That is not a conflict; flagging it wastes radiologist time.
exam: XR knee left ordered_side: left dicom_laterality: L
findings: Mild osteoarthritis of the left knee. The right knee is normal.
Q (yes/no): Does the report describe a side that conflicts with the ordered side or the DICOM laterality?
rad-decider -> no (1.00) untuned base -> yes (false alarm)
On real reports, side-vs-examination (694 reports, 48 flagged, a question never seen in training): rad-decider AUROC 0.98 vs untuned base 0.55. Saves: no false addendum, no needless call-back.
After sign-off β a rejected report goes to the right team. The client says the prior was not retrieved. The model says why, and who should fix it.
exam: CT KUB non-contrast client_message: "Comparison study on your platform; not retrieved."
Q (choice): Why did the client reject this report? rad-decider -> missing_comparison (1.00) base -> wrong_patient_or_exam (wrong)
Q (choice): Who should handle the recheck? rad-decider -> operations (1.00) base -> original_radiologist (wrong)
On the held-out synthetic test (1,196 cases): reason accuracy rad-decider 0.99 vs base 0.13; recheck routing 0.94 vs 0.53. Saves: fixed by the right team first time.
One model across the whole workflow
All rows below are the same single adapter; the question text (instruction + options) is the only thing that says what to do. Each row is one main
category of the workflow, and its score is the average accuracy over the questions in that category on the held-out synthetic test set (about 1,200
cases per question), compared with the untuned Qwen/Qwen3.5-0.8B base model's majority answer. 22 of the questions sit before the report is written
β the cheapest places to catch a problem: fixed before the scan or before reading, it costs minutes; after sign-off it costs an addendum, a call-back or a
repeat scan.
| Category | What it decides | What it prevents | Rad_decider accuracy | Qwen base accuracy |
|---|---|---|---|---|
| Ordering, protocol & pre-scan safety | Whether the requested exam, modality, protocol and contrast fit the clinical question, plus the pre-scan safety checks (renal function, pregnancy, contrast allergy, MRI implant). | Wrong exam, modality, contrast or side; duplicate scans; contrast in at-risk kidneys; unscreened pregnancy; allergic reactions; unsafe MRI. | 0.95 | 0.69 |
| Intake, triage & assignment | Body region, contrast actually used, laterality conflict and reading urgency on arrival; whether the clinical history is complete; subspecialty, complexity, reader credentialing, SLA class and second-read need. | Mis-routed studies, a wrong-side study, critical cases queued, holds and re-reads, the wrong reader, missed turnaround targets, missed double reads. | 0.96 | 0.56 |
| Report integrity, consistency & comparison | Contrast, side, impression support and follow-up while the report is dictated; whole-payload internal consistency; whether the report matches the examination ordered; and whether the prior and comparison statement are correct. | Wrong-side or wrong-contrast reports, unsupported impressions, contradictory reports, a report of another examination, comparing with the wrong prior. | 0.98 | 0.78 |
| Report error review & support | Whether a candidate report differs from a reference and what kind of error (omission, severity, location, comparison, uncertainty); sentence-level errors; whether the report supports a claim (incl. negation and hedging); and whether structure and completeness are satisfied. | Changed, dropped or hallucinated findings; mis-coded reviews; unsupported claims; incomplete or broken reports. | 0.99 | 0.70 |
| Clinical communication, follow-up & summaries | Whether a critical/actionable finding is present, its urgency and whether the call is documented; incidental findings and follow-up recommendations; and whether the patient-facing summary is faithful and well-toned. | A critical result never called or treated as routine; a missed incidental finding; a lost follow-up; an alarming or misleading summary. | 0.99 | 0.60 |
| Post-sign-off review, delivery & alerts | Which reports to peer-review and how significant the discrepancy is; why a client rejected a report and who should recheck it; addendum type and clinician notification; and whether an AI/QC alert is valid. | Missed risky reports; rejections bouncing between teams; wrong or unnecessary amendments; alert fatigue. (peer-review discrepancy label is simulated) | 0.98 | 0.56 |
| Beyond radiology (non-radiology exemplars) | Critical lab values, medication-order checks and referral routing β the same one-model design applied outside radiology. | A critical value not triaged; an unsafe order proceeding; a referral sent to the wrong clinic. | 0.94 | 0.54 |
How it works
- Readout, not generation. The prompt letters the options and ends at an answer slot; the model's next-token distribution over the option letters is the answer. It cannot write anything but one of the options you allowed.
- Calibrated. Per-question temperature scaling is fitted on validation data (
calibration.json); custom / unseen questions are served uncalibrated (T = 1.0). - Shuffled during training. Option order and field order are shuffled, so the letter-to-option mapping is per example and the model follows the question text rather than position.
How to use
pip install "transformers>=5.18" peft torch huggingface_hub
python inference.py # downloads Qwen/Qwen3.5-0.8B + this adapter and runs a few example decisions
from inference import RadDecider
rd = RadDecider("Rology/rad-decider")
# 1) Yes/No (noul) β laterality check
state = {
"exam": "XR knee left",
"ordered_side": "left",
"dicom_laterality": "L",
"findings": "Mild osteoarthritis of the left knee. The right knee is normal.",
"impression": "Degenerative change of the left knee."
}
q_noul = {
"type": "noul",
"instructions": "Does the report describe a side that conflicts with the ordered side or the DICOM laterality? "
"A normal comparison of the other side is not a conflict."
}
res = rd.ask(state, q_noul)
print(res) # {'answer': 'no', 'probabilities': {...}, 'calibrated': False}
# 2) Choose one (choice) β rejection reason
state = {
"exam": "CT KUB non-contrast",
"client_message": "Comparison study on your platform; not retrieved."
}
q_choice = {
"type": "choice",
"instructions": "Why did the client reject this report?",
"options": [
("missing_comparison", "Prior/comparison study missing or not retrievable"),
("wrong_patient_or_exam", "Wrong patient or wrong examination"),
("quality_issue", "Technical/quality issue"),
("other", "Other")
]
}
res = rd.ask(state, q_choice)
print(res)
# 3) Ordered scale (score) β urgency triage
state = {
"modality": "CT",
"ordered_procedure": "CT head without contrast",
"patient_class": "Emergency",
"order_priority": "STAT",
"reason_for_exam": "Sudden left-sided weakness and slurred speech, onset 40 minutes ago",
"age_years": 72,
"sex": "M"
}
q_score = {
"type": "score",
"instructions": "How urgently should this study be read, based on clinical history, patient class and priority?",
"options": [
("routine", "Outpatient or follow-up, no acute concern"),
("urgent", "Acute symptoms, read within hours"),
("stat", "Emergency, read immediately"),
("critical_suspected", "History suggests a life-threatening finding")
]
}
res = rd.ask(state, q_score)
print(res)
Notes:
- To get calibrated probabilities, use a trained
question_keyfromquestions.jsonand passquestion_key="<key>"tord.ask(...). Untrained/custom questions are served uncalibrated (calibrated: False). noulis shorthand foryes/no.choicetakes an ordered list of(option_key, definition).scoreis an ordered scale (lower/higher as written).questions.jsonlists every trained question with its exact instruction and options; use them verbatim (and the matching question key) to get calibrated probabilities. The prompt format, the letter readout and the calibration ininference.pyare exactly those used in training.
Training and provenance
- Data: RadJev-Synth, fully synthetic (no patient records). Labels are computed from the facts that generated each case, never by a model. Report text was varied by a locally run open model (Qwen3.8-27B, Apache-2.0) and every rewrite had to pass exact fact checks (side, negation, hedge, numbers and units, severity, contrast). No proprietary-model output.
- Recipe: LoRA r = 32 / alpha 64 on all language-model linear layers, 1 epoch (9,000 steps, effective batch 32), restricted-softmax cross-entropy over the valid option letters, option order and field order shuffled during training, 16+ paraphrases per question; per-question temperature scaling on validation data.
Scope and limitations
- Research artifact β not for clinical use. Licensed under Apache-2.0 (the license permits commercial use, but the model is a research artifact and is not validated for clinical or commercial deployment).
- Not a medical device. Decision support for workflow and quality control; every flag needs a human decision. Medical rules in the questions (e.g. the follow-up policy) are encodings of published facts and assumed policies β verify them with your radiologists.
- The numbers are synthetic. They are on held-out synthetic cases and are not real-world performance. Some real-data evidence exists for the after-report checks only (contrast mismatch AUROC 0.96, wrong side 0.98, on a small de-identified quality-control sheet of real reports). Nothing before the report (orders, DICOM headers) has been validated on real data yet.
- The base comparison is the majority-answer baseline. The "Qwen base accuracy" column is the majority-class accuracy on the same held-out test set
(the score from always answering the most common option) β the untuned
Qwen/Qwen3.5-0.8Banswers these lettered questions at roughly this level, and it is the baseline to beat, not a tuned one. - English only. Text only (no images).
Coverage notes
- This adapter answers 97 typed questions over 25 decision areas; the table above groups them into 7 main categories by workflow phase.
- RADS categorisation (TI-RADS, Lung-RADS) and a few questions are generated but not part of this adapter (pending radiologist sign-off): they are not counted above.
- All comparisons in this card are with the untuned
Qwen/Qwen3.5-0.8Bbase model, same prompt and readout.
Citation
If you use this model, please cite it:
@software{raddecider2026,
title = {rad-decider: a small decision model for the radiology workflow},
author = {Rology},
year = {2026},
url = {https://huggingface.co/Rology/rad-decider}
}
The readout design β typed questions answered over a shared state by scoring the option-letter logits at the answer slot, with no text
generation β follows the open System One / Jev-style family of decision models. This release contributes its own synthetic radiology data,
question catalogue, training recipe and evaluation. Base model: Qwen/Qwen3.5-0.8B (Apache-2.0).
Contact
Rology β open radiology AI. Released under Apache-2.0 as a research artifact; not validated for clinical use.
- Downloads last month
- 30