Downloads · 30 days
144
36% of all-time downloads
Henrychur/DiagGym
DiagGym is a machine learning model from Henrychur. Use it for the machine learning task on the model card, and read the license before you ship it in a product. The card lists the license as apache-2.0.
<div align="center" <img src="https://raw.githubusercontent.com/MAGIC-AI4Med/DiagGym/main/assets/logo.png" width="150"/ <div align="center"</div </div
Downloads · 30 days
144
36% of all-time downloads
All-time downloads
401
Public
Parameters
7.6B
15.2 GB on disk
Likes
2
Public
Click a slice to open those files.
.safetensors15.2 GB · 100%
From the Hugging Face model README
DiagGym is a high‑fidelity virtual clinical environment that simulates examination outcomes conditioned on evolving patient states. It enables closed‑loop training and evaluation of diagnostic agents with reinforcement learning, without real‑world risk.
In clinical practice, diagnosis is iterative: clinicians decide which examinations to order, interpret new findings, and commit to a final diagnosis when sufficient evidence is available. Most medical LLMs collapse this into a single step using static records, which prevents learning when to order tests and when to stop.
DiagGym addresses this by generating exam results conditioned on a patient profile, prior exams, and the next requested exam. Diagnostic agents can interact in a closed loop:
This enables safe, scalable training and evaluation of end‑to‑end diagnostic strategies.
Details can be found in our paper https://arxiv.org/abs/2510.24654
vllm serve Henrychur/DiagGym --served-model-name DiagGym
import os
from typing import Optional
from openai import OpenAI
# Separator for concatenating past events
SEP = "<SEP>"
stop_tokens = [SEP, "<endoftext>"]
# API credentials
API_KEY = os.getenv("OPENAI_API_KEY", "None")
API_BASE = os.getenv("OPENAI_API_BASE", "http://localhost:8079/v1")
class DiagGym:
def __init__(self, model_name_or_path: str, api_key: str = API_KEY, api_base: str = API_BASE) -> None:
self.model_name_or_path = model_name_or_path
self.client = OpenAI(api_key=api_key, base_url=api_base)
def simulate(self, context: str, past_events_list: list, exam_name: str) -> Optional[str]:
"""Generate exam results based on patient context and past events."""
context += "\nThe following summarizes the results from the patient's medical examination:\n"
if len(past_events_list) == 0:
input_prompt = context + "Exam name:\n" + exam_name + "\nExam results:\n"
else:
past_events_str = [
f"Exam name:\n{event_name}\nExam results:\n{resp}"
for (event_name, resp) in past_events_list
]
input_prompt = context + SEP.join(past_events_str) + SEP + "Exam name:\n" + exam_name + "\nExam results:\n"
response = self.client.completions.create(
model=self.model_name_or_path,
prompt=input_prompt,
max_tokens=8192,
temperature=1.0,
stop=stop_tokens
)
return response.choices[0].text.strip()
# Example inputs
diaggym = DiagGym("DiagGym")
context = "Name: ___ ... Chief Complaint: right lower quadrant pain ... (details omitted)"
past_events_list = [("Anion Gap", "Value: 16; Numeric Value: 16.0; Units: mEq/L; Reference Range: 8.0 - 20.0")]
exam_name = "CHEST (PORTABLE AP)"
print(diaggym.simulate(context, past_events_list, exam_name))
transformers locally (no server)from transformers import AutoTokenizer, AutoModelForCausalLM
model_name = "Henrychur/DiagGym"
tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(
model_name,
trust_remote_code=True,
torch_dtype="auto",
device_map="auto"
)
SEP = "<SEP>"
context = "Name: ___ ... Chief Complaint: right lower quadrant pain ..."
past_events_list = [("Anion Gap", "Value: 16; Numeric Value: 16.0; Units: mEq/L; Reference Range: 8.0 - 20.0")]
exam_name = "CHEST (PORTABLE AP)"
if len(past_events_list) == 0:
prompt = (
context
+ "\nThe following summarizes the results from the patient's medical examination:\n"
+ "Exam name:\n" + exam_name + "\nExam results:\n"
)
else:
past_events_str = [
f"Exam name:\n{event_name}\nExam results:\n{resp}"
for (event_name, resp) in past_events_list
]
prompt = (
context
+ "\nThe following summarizes the results from the patient's medical examination:\n"
+ SEP.join(past_events_str) + SEP
+ "Exam name:\n" + exam_name + "\nExam results:\n"
)
inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
outputs = model.generate(
**inputs,
max_new_tokens=512,
temperature=1.0,
do_sample=True,
eos_token_id=tokenizer.eos_token_id
)
text = tokenizer.decode(outputs[0], skip_special_tokens=True)
print(text)
For an end‑to‑end agent example, see Henrychur/DiagAgent-14B.
On 863 MIMIC‑IV cases, DiagGym shows strong step‑level similarity and full‑chain consistency, low distribution gaps for both numeric and free‑text exams, and competitive efficiency.
| Model | Min GPUs ↓ | Time (GPU·s) ↓ | Similarity ↑ | Consistency ↑ | Num. Var ↑ | Num. WDist ↓ | LPIPS ↑ | FID ↓ |
|---|---|---|---|---|---|---|---|---|
| DeepSeek‑v3‑671B | 16 | 62.72 | 2.576 | 88.81 | 24.56 | 1.336 | 0.237 | 4.158 |
| Qwen2.5‑7B | 1 | 0.54 | 2.181 | 81.64 | 20.18 | 9.680 | 0.256 | 4.800 |
| Qwen2.5‑72B | 4 | 18.68 | 2.495 | 92.39 | 1.21 | 1.839 | 0.183 | 4.901 |
| MedGemma‑27B | 2 | 9.10 | 2.438 | 89.87 | 18.70 | 16.936 | 0.341 | 4.158 |
| DiagGym | 1 | 0.52 | 3.565 | 96.91 | 3.46 | 0.128 | 0.378 | 0.747 |
Data construction:
Training setup:
@misc{qiu2025evolvingdiagnosticagentsvirtual,
title={Evolving Diagnostic Agents in a Virtual Clinical Environment},
author={Pengcheng Qiu and Chaoyi Wu and Junwei Liu and Qiaoyu Zheng and Yusheng Liao and Haowen Wang and Yun Yue and Qianrui Fan and Shuai Zhen and Jian Wang and Jinjie Gu and Yanfeng Wang and Ya Zhang and Weidi Xie},
year={2025},
eprint={2510.24654},
archivePrefix={arXiv},
primaryClass={cs.CL},
url={https://arxiv.org/abs/2510.24654},
}