初始化项目,由ModelHub XC社区提供模型

Model: Rumiii/LlamaTron-RS1-MedThinker
Source: Original Platform
This commit is contained in:
ModelHub XC
2026-09-11 06:39:14 +08:00
commit 8d678750b3
7 changed files with 441 additions and 0 deletions

38
.gitattributes vendored Normal file
View File

@@ -0,0 +1,38 @@
*.7z filter=lfs diff=lfs merge=lfs -text
*.arrow filter=lfs diff=lfs merge=lfs -text
*.bin filter=lfs diff=lfs merge=lfs -text
*.bz2 filter=lfs diff=lfs merge=lfs -text
*.ckpt filter=lfs diff=lfs merge=lfs -text
*.ftz filter=lfs diff=lfs merge=lfs -text
*.gz filter=lfs diff=lfs merge=lfs -text
*.h5 filter=lfs diff=lfs merge=lfs -text
*.joblib filter=lfs diff=lfs merge=lfs -text
*.lfs.* filter=lfs diff=lfs merge=lfs -text
*.mlmodel filter=lfs diff=lfs merge=lfs -text
*.model filter=lfs diff=lfs merge=lfs -text
*.msgpack filter=lfs diff=lfs merge=lfs -text
*.npy filter=lfs diff=lfs merge=lfs -text
*.npz filter=lfs diff=lfs merge=lfs -text
*.onnx filter=lfs diff=lfs merge=lfs -text
*.ot filter=lfs diff=lfs merge=lfs -text
*.parquet filter=lfs diff=lfs merge=lfs -text
*.pb filter=lfs diff=lfs merge=lfs -text
*.pickle filter=lfs diff=lfs merge=lfs -text
*.pkl filter=lfs diff=lfs merge=lfs -text
*.pt filter=lfs diff=lfs merge=lfs -text
*.pth filter=lfs diff=lfs merge=lfs -text
*.rar filter=lfs diff=lfs merge=lfs -text
*.safetensors filter=lfs diff=lfs merge=lfs -text
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
*.tar.* filter=lfs diff=lfs merge=lfs -text
*.tar filter=lfs diff=lfs merge=lfs -text
*.tflite filter=lfs diff=lfs merge=lfs -text
*.tgz filter=lfs diff=lfs merge=lfs -text
*.wasm filter=lfs diff=lfs merge=lfs -text
*.xz filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
*.zst filter=lfs diff=lfs merge=lfs -text
*tfevents* filter=lfs diff=lfs merge=lfs -text
tokenizer.json filter=lfs diff=lfs merge=lfs -text
LlamaTron-RS1-MedThinker-Q4_K_M.gguf filter=lfs diff=lfs merge=lfs -text
medthinker-f16.gguf filter=lfs diff=lfs merge=lfs -text

248
README.md Normal file
View File

@@ -0,0 +1,248 @@
---
library_name: transformers
license: llama3.2
datasets:
- OpenMed/Medical-Reasoning-SFT-Trinity-Mini
language:
- en
base_model:
- meta-llama/Llama-3.2-1B-Instruct
tags:
- transformers
- medical
- reasoning
- chain-of-thought
- clinical
- healthcare
- llama
- lora
- unsloth
- fine-tuned
---
![Screenshot 2026-09-06 at 5.51.36 PM](https://cdn-uploads.huggingface.co/production/uploads/66e00ba55e4fd4bfead4a97c/q_eFcRr5SWrbv7SDSnEf6.png)
[![Base Model](https://img.shields.io/badge/Base-Llama%203.2%201B%20Instruct-00cfff?style=for-the-badge&logo=meta&logoColor=white)](https://huggingface.co/meta-llama/Llama-3.2-1B-Instruct)
[![Dataset](https://img.shields.io/badge/Dataset-810K%20Samples-38d996?style=for-the-badge&logo=databricks&logoColor=black)](https://huggingface.co/datasets/OpenMed/Medical-Reasoning-SFT-Trinity-Mini)
[![Method](https://img.shields.io/badge/Method-LoRA%20SFT-ffffff?style=for-the-badge)](https://github.com/unslothai/unsloth)
[![Hardware](https://img.shields.io/badge/Hardware-RTX%20A6000-ffcc00?style=for-the-badge&logo=nvidia&logoColor=black)](https://www.nvidia.com)
---
</div>
<br/>
## What is LlamaTron RS1 MedThinker?
Most medical language models are trained to retrieve answers. LlamaTron RS1 MedThinker was trained to **reason** through them.
Built on Meta's Llama 3.2 1B Instruct and fine-tuned on 810,374 medical chain-of-thought samples, MedThinker doesn't just return a diagnosis — it works through the differential, explains the pathophysiology behind its conclusion, gives dose-specific treatment steps, and tells you exactly when to escalate care.
The reasoning pattern mirrors that of a junior physician presenting a case: structured, explainable, and clinically grounded.
<br/>
## Demo
**Model Output — Step-by-Step Clinical Reasoning**
![LlamaTron RS1 MedThinker Output](https://cdn-uploads.huggingface.co/production/uploads/66e00ba55e4fd4bfead4a97c/izPsyNhqNZ_C5mZ7B4HNw.png)
<br/>
## Output Format
Every response follows a strict four-part clinical structure:
```
DIAGNOSIS Primary diagnosis with key differentials
REASONING Clinical logic, pathophysiology, and decision trail
IMMEDIATE TREATMENT Prioritised, dose-specific intervention steps
RED FLAGS Escalation criteria and emergency triggers
```
**Example — Input:**
```
3yo boy, barking cough, stridor, worse at night. Diagnosis and treatment?
```
**Example — Output:**
```
DIAGNOSIS: Viral croup (laryngotracheobronchitis).
Differentials: epiglottitis, foreign body aspiration, bacterial tracheitis.
REASONING: The classic triad of barking cough, inspiratory stridor, and nocturnal
worsening in a toddler is pathognomonic for croup. Caused by parainfluenza virus
producing subglottic edema. Nighttime worsening occurs due to supine positioning
increasing mucosal congestion. Age 6 months to 3 years is the peak incidence window.
Epiglottitis is deprioritised given the absence of drooling, tripod posturing,
or toxic appearance.
IMMEDIATE TREATMENT:
- Dexamethasone 0.6mg/kg PO/IM single dose (reduces subglottic edema within 2-6h)
- Nebulised epinephrine 5ml of 1:1000 if moderate-severe stridor present at rest
- Humidified cool air — supportive, reduces mucosal congestion
- Keep child calm — agitation significantly worsens stridor
- Oxygen via mask if SpO2 drops below 92%
RED FLAGS: Call emergency services immediately if stridor is present at rest and
not improving, child is drooling or cannot swallow, cyanosis appears, or the child
becomes exhausted. These indicate impending airway obstruction requiring intubation.
```
<br/>
## Training Details
| Parameter | Value |
|---|---|
| Base Model | meta-llama/Llama-3.2-1B-Instruct |
| Fine-Tune Method | LoRA SFT via Unsloth |
| LoRA Rank | 32 |
| LoRA Alpha | 64 |
| Target Modules | q, k, v, o, gate, up, down projections |
| Sequence Length | 2048 |
| Batch Size | 16 per device |
| Gradient Accumulation | 2 steps — effective batch size 32 |
| Learning Rate | 2e-4 |
| Optimizer | AdamW 8-bit |
| Precision | BF16 |
| Packing | Enabled |
| Hardware | NVIDIA RTX A6000 48GB |
| Framework | Unsloth + TRL |
<br/>
## Dataset
Trained on [OpenMed/Medical-Reasoning-SFT-Trinity-Mini](https://huggingface.co/datasets/OpenMed/Medical-Reasoning-SFT-Trinity-Mini), generated using `arcee-ai/Trinity-Mini`.
| Metric | Value |
|---|---|
| Total Samples | 810,374 |
| Total Tokens | 1.52 Billion |
| Reasoning Tokens | 977 Million |
| Content Tokens | 542 Million |
| Language | English |
Each sample contains two components: the **content** (the answer) and the **reasoning_content** (the chain-of-thought trace that produced it). Training on both means the model internalised not just medical knowledge, but the structured thinking process behind clinical decision-making.
Dataset credit: Maziyar P.
<br/>
## Quickstart
### Installation
```bash
pip install torch transformers accelerate
```
### Inference
```python
import torch
from transformers import AutoTokenizer, LlamaForCausalLM
MODEL_PATH = "Rumiii/LlamaTron-RS1-MedThinker"
tokenizer = AutoTokenizer.from_pretrained(MODEL_PATH)
model = LlamaForCausalLM.from_pretrained(
MODEL_PATH,
torch_dtype=torch.bfloat16,
device_map="auto",
)
model.eval()
FEW_SHOT = """CASE: 2yo girl, high fever, tugging right ear, irritable, not sleeping.
DIAGNOSIS: Acute otitis media (AOM). Differentials: otitis externa, teething.
REASONING: Unilateral ear tugging with fever and irritability in a toddler is the
classic AOM presentation. Peak incidence at 6mo-2yr due to horizontal Eustachian
tube anatomy impairing drainage.
IMMEDIATE TREATMENT:
- Amoxicillin 90mg/kg/day divided BID x 10 days
- Ibuprofen/paracetamol for pain and fever
- Re-evaluate in 48-72h if no improvement
RED FLAGS: Refer immediately if mastoid swelling, facial palsy, or no improvement
after 72h of antibiotics."""
def ask(question: str) -> str:
prompt = (
f"<|begin_of_text|>"
f"<|start_header_id|>system<|end_header_id|>\n"
f"You are LlamaTron RS1 MedThinker, a clinical medical assistant. "
f"Always use the structured format shown.<|eot_id|>"
f"<|start_header_id|>user<|end_header_id|>\n"
f"Answer this case using structured format:\n\n{FEW_SHOT}<|eot_id|>"
f"<|start_header_id|>assistant<|end_header_id|>\n{FEW_SHOT}<|eot_id|>"
f"<|start_header_id|>user<|end_header_id|>\nCASE: {question}<|eot_id|>"
f"<|start_header_id|>assistant<|end_header_id|>\n"
)
inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
input_len = inputs["input_ids"].shape[1]
with torch.no_grad():
out = model.generate(
**inputs,
max_new_tokens=400,
temperature=0.35,
top_p=0.85,
do_sample=True,
repetition_penalty=1.2,
pad_token_id=tokenizer.eos_token_id,
)
raw = tokenizer.decode(out[0][input_len:], skip_special_tokens=False)
for stop in ["<|eot_id|>", "<|end_of_text|>", "<|start_header_id|>"]:
if stop in raw:
raw = raw[:raw.index(stop)]
return raw.strip()
# Run
print(ask("68yo woman, chest pain radiating to left arm, diaphoresis, nausea. BP 90/60, HR 110."))
```
<br/>
## Important Notes on Inference
This model benefits significantly from **few-shot prompting**. Because the fine-tuning dataset emphasised reasoning content over instruction-following format, providing a single worked example in the prompt before your real question enforces the structured output reliably. The quickstart code above includes this pattern — do not remove the `FEW_SHOT` block.
Recommended inference parameters:
| Parameter | Value | Reason |
|---|---|---|
| temperature | 0.35 | Confident without hallucinating |
| top_p | 0.85 | Cuts low-probability tokens |
| repetition_penalty | 1.2 | Prevents reasoning loops |
| max_new_tokens | 400-512 | Sufficient for full structured response |
<br/>
## Disclaimer
LlamaTron RS1 MedThinker is intended strictly for **research and educational purposes**. It is not a substitute for professional medical advice, clinical diagnosis, or treatment decisions. All outputs must be reviewed by a qualified medical professional before any clinical application. The authors accept no liability for decisions made on the basis of this model's outputs.
<br/>
## Citation
```bibtex
@model{llamatron_rs1_medthinker_2026,
title = {LlamaTron RS1 MedThinker},
author = {Rumiii},
year = {2026},
base_model = {meta-llama/Llama-3.2-1B-Instruct},
dataset = {OpenMed/Medical-Reasoning-SFT-Trinity-Mini},
method = {LoRA SFT via Unsloth},
url = {https://huggingface.co/Rumiii/LlamaTron-RS1-MedThinker}
}
```

93
chat_template.jinja Normal file
View File

@@ -0,0 +1,93 @@
{{- bos_token }}
{%- if custom_tools is defined %}
{%- set tools = custom_tools %}
{%- endif %}
{%- if not tools_in_user_message is defined %}
{%- set tools_in_user_message = true %}
{%- endif %}
{%- if not date_string is defined %}
{%- if strftime_now is defined %}
{%- set date_string = strftime_now("%d %b %Y") %}
{%- else %}
{%- set date_string = "26 Jul 2024" %}
{%- endif %}
{%- endif %}
{%- if not tools is defined %}
{%- set tools = none %}
{%- endif %}
{#- This block extracts the system message, so we can slot it into the right place. #}
{%- if messages[0]['role'] == 'system' %}
{%- set system_message = messages[0]['content']|trim %}
{%- set messages = messages[1:] %}
{%- else %}
{%- set system_message = "" %}
{%- endif %}
{#- System message #}
{{- "<|start_header_id|>system<|end_header_id|>\n\n" }}
{%- if tools is not none %}
{{- "Environment: ipython\n" }}
{%- endif %}
{{- "Cutting Knowledge Date: December 2023\n" }}
{{- "Today Date: " + date_string + "\n\n" }}
{%- if tools is not none and not tools_in_user_message %}
{{- "You have access to the following functions. To call a function, please respond with JSON for a function call." }}
{{- 'Respond in the format {"name": function name, "parameters": dictionary of argument name and its value}.' }}
{{- "Do not use variables.\n\n" }}
{%- for t in tools %}
{{- t | tojson(indent=4) }}
{{- "\n\n" }}
{%- endfor %}
{%- endif %}
{{- system_message }}
{{- "<|eot_id|>" }}
{#- Custom tools are passed in a user message with some extra guidance #}
{%- if tools_in_user_message and not tools is none %}
{#- Extract the first user message so we can plug it in here #}
{%- if messages | length != 0 %}
{%- set first_user_message = messages[0]['content']|trim %}
{%- set messages = messages[1:] %}
{%- else %}
{{- raise_exception("Cannot put tools in the first user message when there's no first user message!") }}
{%- endif %}
{{- '<|start_header_id|>user<|end_header_id|>\n\n' -}}
{{- "Given the following functions, please respond with a JSON for a function call " }}
{{- "with its proper arguments that best answers the given prompt.\n\n" }}
{{- 'Respond in the format {"name": function name, "parameters": dictionary of argument name and its value}.' }}
{{- "Do not use variables.\n\n" }}
{%- for t in tools %}
{{- t | tojson(indent=4) }}
{{- "\n\n" }}
{%- endfor %}
{{- first_user_message + "<|eot_id|>"}}
{%- endif %}
{%- for message in messages %}
{%- if not (message.role == 'ipython' or message.role == 'tool' or 'tool_calls' in message) %}
{{- '<|start_header_id|>' + message['role'] + '<|end_header_id|>\n\n'+ message['content'] | trim + '<|eot_id|>' }}
{%- elif 'tool_calls' in message %}
{%- if not message.tool_calls|length == 1 %}
{{- raise_exception("This model only supports single tool-calls at once!") }}
{%- endif %}
{%- set tool_call = message.tool_calls[0].function %}
{{- '<|start_header_id|>assistant<|end_header_id|>\n\n' -}}
{{- '{"name": "' + tool_call.name + '", ' }}
{{- '"parameters": ' }}
{{- tool_call.arguments | tojson }}
{{- "}" }}
{{- "<|eot_id|>" }}
{%- elif message.role == "tool" or message.role == "ipython" %}
{{- "<|start_header_id|>ipython<|end_header_id|>\n\n" }}
{%- if message.content is mapping or message.content is iterable %}
{{- message.content | tojson }}
{%- else %}
{{- message.content }}
{%- endif %}
{{- "<|eot_id|>" }}
{%- endif %}
{%- endfor %}
{%- if add_generation_prompt %}
{{- '<|start_header_id|>assistant<|end_header_id|>\n\n' }}
{%- endif %}

37
config.json Normal file
View File

@@ -0,0 +1,37 @@
{
"architectures": [
"LlamaForCausalLM"
],
"attention_bias": false,
"attention_dropout": 0.0,
"bos_token_id": 128000,
"torch_dtype": "bfloat16",
"eos_token_id": 128009,
"head_dim": 64,
"hidden_act": "silu",
"hidden_size": 2048,
"initializer_range": 0.02,
"intermediate_size": 8192,
"max_position_embeddings": 131072,
"mlp_bias": false,
"model_type": "llama",
"num_attention_heads": 32,
"num_hidden_layers": 16,
"num_key_value_heads": 8,
"pad_token_id": 128004,
"pretraining_tp": 1,
"rms_norm_eps": 1e-05,
"rope_parameters": {
"factor": 32.0,
"high_freq_factor": 4.0,
"low_freq_factor": 1.0,
"original_max_position_embeddings": 8192,
"rope_theta": 500000.0,
"rope_type": "llama3"
},
"tie_word_embeddings": true,
"unsloth_fixed": true,
"unsloth_version": "2026.3.11",
"use_cache": false,
"vocab_size": 128256
}

3
model.safetensors Normal file
View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:4bca3b1c5836b1844858ceb121a93bd814632d1b6ccb541a49682f0dffde1fe3
size 2471645608

BIN
tokenizer.json (Stored with Git LFS) Normal file

Binary file not shown.

19
tokenizer_config.json Normal file
View File

@@ -0,0 +1,19 @@
{
"backend": "tokenizers",
"bos_token": "<|begin_of_text|>",
"clean_up_tokenization_spaces": true,
"eos_token": "<|eot_id|>",
"from_slow": true,
"is_local": false,
"legacy": false,
"model_input_names": [
"input_ids",
"attention_mask"
],
"model_max_length": 131072,
"pad_token": "<|finetune_right_pad_id|>",
"padding_side": "left",
"tokenizer_class": "TokenizersBackend",
"unk_token": null,
"chat_template": "{{- bos_token }}\n{%- if custom_tools is defined %}\n {%- set tools = custom_tools %}\n{%- endif %}\n{%- if not tools_in_user_message is defined %}\n {%- set tools_in_user_message = true %}\n{%- endif %}\n{%- if not date_string is defined %}\n {%- if strftime_now is defined %}\n {%- set date_string = strftime_now(\"%d %b %Y\") %}\n {%- else %}\n {%- set date_string = \"26 Jul 2024\" %}\n {%- endif %}\n{%- endif %}\n{%- if not tools is defined %}\n {%- set tools = none %}\n{%- endif %}\n\n{#- This block extracts the system message, so we can slot it into the right place. #}\n{%- if messages[0]['role'] == 'system' %}\n {%- set system_message = messages[0]['content']|trim %}\n {%- set messages = messages[1:] %}\n{%- else %}\n {%- set system_message = \"\" %}\n{%- endif %}\n\n{#- System message #}\n{{- \"<|start_header_id|>system<|end_header_id|>\\n\\n\" }}\n{%- if tools is not none %}\n {{- \"Environment: ipython\\n\" }}\n{%- endif %}\n{{- \"Cutting Knowledge Date: December 2023\\n\" }}\n{{- \"Today Date: \" + date_string + \"\\n\\n\" }}\n{%- if tools is not none and not tools_in_user_message %}\n {{- \"You have access to the following functions. To call a function, please respond with JSON for a function call.\" }}\n {{- 'Respond in the format {\"name\": function name, \"parameters\": dictionary of argument name and its value}.' }}\n {{- \"Do not use variables.\\n\\n\" }}\n {%- for t in tools %}\n {{- t | tojson(indent=4) }}\n {{- \"\\n\\n\" }}\n {%- endfor %}\n{%- endif %}\n{{- system_message }}\n{{- \"<|eot_id|>\" }}\n\n{#- Custom tools are passed in a user message with some extra guidance #}\n{%- if tools_in_user_message and not tools is none %}\n {#- Extract the first user message so we can plug it in here #}\n {%- if messages | length != 0 %}\n {%- set first_user_message = messages[0]['content']|trim %}\n {%- set messages = messages[1:] %}\n {%- else %}\n {{- raise_exception(\"Cannot put tools in the first user message when there's no first user message!\") }}\n{%- endif %}\n {{- '<|start_header_id|>user<|end_header_id|>\\n\\n' -}}\n {{- \"Given the following functions, please respond with a JSON for a function call \" }}\n {{- \"with its proper arguments that best answers the given prompt.\\n\\n\" }}\n {{- 'Respond in the format {\"name\": function name, \"parameters\": dictionary of argument name and its value}.' }}\n {{- \"Do not use variables.\\n\\n\" }}\n {%- for t in tools %}\n {{- t | tojson(indent=4) }}\n {{- \"\\n\\n\" }}\n {%- endfor %}\n {{- first_user_message + \"<|eot_id|>\"}}\n{%- endif %}\n\n{%- for message in messages %}\n {%- if not (message.role == 'ipython' or message.role == 'tool' or 'tool_calls' in message) %}\n {{- '<|start_header_id|>' + message['role'] + '<|end_header_id|>\\n\\n'+ message['content'] | trim + '<|eot_id|>' }}\n {%- elif 'tool_calls' in message %}\n {%- if not message.tool_calls|length == 1 %}\n {{- raise_exception(\"This model only supports single tool-calls at once!\") }}\n {%- endif %}\n {%- set tool_call = message.tool_calls[0].function %}\n {{- '<|start_header_id|>assistant<|end_header_id|>\\n\\n' -}}\n {{- '{\"name\": \"' + tool_call.name + '\", ' }}\n {{- '\"parameters\": ' }}\n {{- tool_call.arguments | tojson }}\n {{- \"}\" }}\n {{- \"<|eot_id|>\" }}\n {%- elif message.role == \"tool\" or message.role == \"ipython\" %}\n {{- \"<|start_header_id|>ipython<|end_header_id|>\\n\\n\" }}\n {%- if message.content is mapping or message.content is iterable %}\n {{- message.content | tojson }}\n {%- else %}\n {{- message.content }}\n {%- endif %}\n {{- \"<|eot_id|>\" }}\n {%- endif %}\n{%- endfor %}\n{%- if add_generation_prompt %}\n {{- '<|start_header_id|>assistant<|end_header_id|>\\n\\n' }}\n{%- endif %}\n"
}