Lightweight, text-only RadFact with OpenAI and Ollama backends.
Parses reports into phrases, optionally removes normal (non-pathological) findings, then scores bidirectional LLM entailment as logical precision / recall / F1.
This library was created for the ODIN 2026 challenge.
pip install radfact-litefrom radfact_lite import ModelConfig, PipelineModels, RadFactLitePipeline, ReportType
cfg = ModelConfig(model="gpt-4o-mini", provider="openai") # reads OPENAI_API_KEY
models = PipelineModels(parse_model=cfg, entailment_model=cfg, filtering_model=cfg)
pipeline = RadFactLitePipeline(models, report_type=ReportType.TOOTHFAIRY)
aggregate, per_sample = pipeline.compute_radfact(
candidates_by_id={"id1": "Absence of tooth 4.8. Endosseous implant in position 4.6."},
references_by_id={"id1": "Endosseous implant in position 4.6, correctly osseointegrated. All other teeth are present."},
remove_normal_findings=True,
)
print(aggregate.logical_f1)For Ollama: ModelConfig(model="llama3.1", provider="ollama") (default base URL http://localhost:11434/v1).
Pass pre-parsed phrase lists instead of narrative text with is_narrative_text=False.
report_type selects the prompt set used for parsing, filtering, and entailment:
ReportType.GENERAL(default) — generic medical imaging prompts that work in any medical context.ReportType.TOOTHFAIRY— maxillofacial CBCT reports (ODIN 2026 / ToothFairy).
Set RADFACT_LITE_DEBUG=1 to log every LLM call (report parsing, finding filtering, entailment) to stderr, including inputs, outputs, and pipeline stage markers.
Add prompt files (system_message.txt and few_shot_examples.json) under src/prompts/{report_to_phrases,finding_filter,entailment}/<modality>/ and a value to ReportType in src/rf_types.py.