Instructions to use ShuohaoGao-THU/Salus-7B with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use ShuohaoGao-THU/Salus-7B with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="ShuohaoGao-THU/Salus-7B") messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# Load model directly from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("ShuohaoGao-THU/Salus-7B") model = AutoModelForCausalLM.from_pretrained("ShuohaoGao-THU/Salus-7B", device_map="auto") messages = [ {"role": "user", "content": "Who are you?"}, ] inputs = tokenizer.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=40) print(tokenizer.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use ShuohaoGao-THU/Salus-7B with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "ShuohaoGao-THU/Salus-7B" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "ShuohaoGao-THU/Salus-7B", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/ShuohaoGao-THU/Salus-7B
- SGLang
How to use ShuohaoGao-THU/Salus-7B with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "ShuohaoGao-THU/Salus-7B" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "ShuohaoGao-THU/Salus-7B", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "ShuohaoGao-THU/Salus-7B" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "ShuohaoGao-THU/Salus-7B", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use ShuohaoGao-THU/Salus-7B with Docker Model Runner:
docker model run hf.co/ShuohaoGao-THU/Salus-7B
Salus-7B
Salus-7B is a specialized medical language model introduced in Salus: Strategic Diagnostic Testing for Complex Diagnosis via Multi-Agent Reinforcement Learning (ICML 2026). It is built on Qwen2.5-7B-Instruct and trained with supervised fine-tuning (SFT) followed by Group Relative Policy Optimization (GRPO).
Salus addresses complex diagnosis as a sequential evidence-gathering process. It decomposes diagnostic reasoning into three functional roles:
- Differential Reasoner — produces a differential diagnosis from the available patient record.
- Strategic Controller — decides whether to request more evidence or make a final diagnosis.
- Workup Proposer — recommends the next auxiliary examinations.
The model is optimized for these three fixed instructions. It is not intended to be used as a general-purpose chat model, and paraphrasing the system prompts may substantially reduce performance.
Model details
- Base model: Qwen2.5-7B-Instruct
- Architecture: Qwen2 causal language model
- Parameters: approximately 7.6B
- Training: SFT followed by multi-agent GRPO
- Primary task: sequential diagnostic testing for complex clinical cases
- Primary prompt language: Chinese
- License: Apache 2.0
The GRPO stage uses structured rewards to calibrate evidence-seeking behavior, discourage premature diagnostic closure, and improve differential diagnosis. See the paper page and code repository for details.
Supported instructions
The following system prompts and input formats should be used exactly as shown.
1. Differential Reasoner
System prompt:
你是一名专业医生,负责根据提供的病人信息,进行鉴别诊断。
User prompt:
<病历>
{patient_record}
</病历>
The final answer should contain a line-separated differential diagnosis.
2. Strategic Controller
System prompt:
你是一名专业医生,负责根据提供的病人信息和鉴别诊断,决定医生下一步是继续进行辅助检查,还是直接给出最终诊断。
User prompt:
<病历>
{patient_record}
</病历>
<鉴别诊断>
{differential_diagnosis}
</鉴别诊断>
The final answer must be one of:
继续辅助检查
or:
您的诊断结果为:{diagnosis}
3. Workup Proposer
System prompt:
你是一名专业医生,负责根据提供的病人信息和鉴别诊断,决定医生下一步要进行哪些辅助检查
User prompt:
<病历>
{patient_record}
</病历>
<鉴别诊断>
{differential_diagnosis}
</鉴别诊断>
The final answer normally uses the following format:
请求进行以下辅助检查:
- {examination_1}
- {examination_2}
Usage
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
model_id = "ShuohaoGao-THU/Salus-7B"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(
model_id,
torch_dtype="auto",
device_map="auto",
)
def generate(system_prompt: str, user_prompt: str) -> str:
messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_prompt},
]
text = tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True,
)
inputs = tokenizer(text, return_tensors="pt").to(model.device)
with torch.inference_mode():
output_ids = model.generate(
**inputs,
max_new_tokens=4096,
do_sample=True,
temperature=0.7,
top_p=0.8,
top_k=20,
repetition_penalty=1.05,
)
new_ids = output_ids[0, inputs.input_ids.shape[1]:]
return tokenizer.decode(new_ids, skip_special_tokens=True)
system_prompt = "你是一名专业医生,负责根据提供的病人信息,进行鉴别诊断。"
patient_record = "在此处填写病历"
user_prompt = f"<病历>\n{patient_record}\n</病历>"
response = generate(system_prompt, user_prompt)
print(response)
Parsing the three outputs
The model may place its reasoning before a </reason> marker. Always remove this reasoning prefix before parsing the task-specific result.
def extract_final_answer(response: str) -> str:
"""Return the content after the final </reason> marker."""
return response.rsplit("</reason>", 1)[-1].strip()
Parse a differential diagnosis
The Differential Reasoner returns one diagnosis per line:
def parse_differential_diagnosis(response: str) -> list[str]:
final_answer = extract_final_answer(response)
diagnoses = [
line.strip()
for line in final_answer.splitlines()
if line.strip()
]
if not diagnoses:
raise ValueError("The model returned an empty differential diagnosis.")
return diagnoses
Parse the controller decision
The Strategic Controller must either request more examinations or provide a final diagnosis:
from typing import Literal, TypedDict
class ControllerResult(TypedDict):
action: Literal["continue", "finalize"]
diagnosis: str | None
def parse_controller_decision(response: str) -> ControllerResult:
final_answer = extract_final_answer(response)
if final_answer == "继续辅助检查":
return {"action": "continue", "diagnosis": None}
prefix = "您的诊断结果为"
if final_answer.startswith(prefix):
diagnosis = final_answer[len(prefix):].lstrip(":: ").strip()
if not diagnosis:
raise ValueError("The model selected finalization without a diagnosis.")
return {"action": "finalize", "diagnosis": diagnosis}
raise ValueError(f"Invalid controller output: {final_answer!r}")
Parse auxiliary examinations
The Workup Proposer returns one recommended examination per line:
import re
def parse_auxiliary_examinations(response: str) -> list[str]:
final_answer = extract_final_answer(response)
header = "请求进行以下辅助检查"
if final_answer.startswith(header):
final_answer = final_answer[len(header):].lstrip(":: \r\n")
examinations = [
re.sub(r"^(?:[-*•]+|\d+[.、)])\s*", "", line.strip())
for line in final_answer.splitlines()
if line.strip()
]
examinations = [item for item in examinations if item]
if not examinations:
raise ValueError("The model returned no auxiliary examinations.")
return examinations
For the complete sequential workflow, first call the Differential Reasoner, pass its output to the Strategic Controller, and call the Workup Proposer only when the controller returns 继续辅助检查. Append newly obtained examination results to the patient record before starting the next round.
Results
On the complex cases in CompDiag-Bench, Salus-7B achieves 83.64% Top-1 diagnostic accuracy, compared with 71.38% for DeepSeek-V3.2 and 80.30% for GPT-5.2, as reported in the paper.
These results are specific to the benchmark protocol described by the authors and should not be interpreted as evidence of clinical safety or real-world diagnostic performance.
Limitations and safety
- Salus-7B supports only the three task-specific instructions documented above.
- The model may produce incorrect, incomplete, or clinically unsafe diagnoses and examination recommendations.
- Outputs may vary with prompt formatting, decoding settings, patient-record quality, and available context.
- The model has not been validated for autonomous clinical use.
- It must not replace evaluation, judgment, or treatment by qualified healthcare professionals.
- Do not provide identifiable patient information to the model without appropriate authorization and privacy safeguards.
This model is released for research purposes. Users are responsible for evaluating its suitability, safety, privacy implications, and regulatory requirements in their own setting.
Citation
@inproceedings{gao2026salus,
title={Salus: Strategic Diagnostic Testing for Complex Diagnosis via Multi-Agent Reinforcement Learning},
author={Gao, Shuohao and Chen, Xuanzhong and Luo, Lingxiao and Ding, Zilin and Han, Rong and Jiang, Rui and Chen, Ting},
booktitle={Forty-third International Conference on Machine Learning},
year={2026}
}
Acknowledgements
Salus-7B is based on Qwen2.5-7B-Instruct. Please also follow the license and acceptable-use requirements of the base model.
- Downloads last month
- 164