
Patients worldwide face a critical challenge: symptom interpretation and medical pathway navigation. When experiencing symptoms, individuals often resort to unreliable web searches, generic symptom checkers, or costly unnecessary hospital visits. Meanwhile, medical professionals and patients struggle with:
This problem is fundamentally a semantic matching and retrieval task — precisely where large language models excel. While rule-based systems and simple keyword matching fail due to symptom variability and linguistic diversity, transformer-based models can:
┌─────────────────────────────────────────────────────────────┐
│ User-Facing Layer: Gradio Web Interface │
│ (Symptom Input, Privacy Controls, Result Visualization) │
└────────────────────┬────────────────────────────────────────┘
│
┌────────────────────▼────────────────────────────────────────┐
│ Query Engine: Vector Similarity Search │
│ (Text → Embedding → FAISS Search → Ranking) │
└────────────────────┬────────────────────────────────────────┘
│
┌────────────────────▼────────────────────────────────────────┐
│ Embedding Layer: MedGemma + Metric Learning Head │
│ (Symptom Encoding to 1024D normalized vectors) │
└────────────────────┬────────────────────────────────────────┘
│
┌────────────────────▼────────────────────────────────────────┐
│ Index Layer: FAISS (Fast Approximate Nearest Neighbor) │
│ (Pre-computed disease-symptom embeddings) │
└─────────────────────────────────────────────────────────────┘
Training Data: Disease and symptoms dataset 2023
Production and Evaluation Data: Symptom2Disease
We convert given text into prompts:
Instruct: Diagnose the disease given symptoms.
Symptoms: {text}
Diagnosis:
Rather than using MedGemma for generation, we exploit its learned medical representations as a foundation for semantic embeddings:
Input Symptoms → MedGemma Language Model → Last Hidden State
↓
Dual-Head
├─ Last Token → Head (512D) → Diagnosis Vector
└─ Mean Pooled Tokens → Head (512D) → Context Vector
↓
Concatenation + Normalization
↓
Final Embedding (1024D normalized)
Rather than standard mean pooling, we combine:
We concatenate them for inference. For training, we calculate cosine similarity between last token and mean token as an auxiliary loss. This dual-head approach captures both diagnostic intent and symptom context, improving matching accuracy and speeding up convergence.
Arc-Face Loss for Metric Learning: We implemented ArcMarginProduct loss, typically used in face recognition, adapted for medical concept clustering:
LoRA Fine-tuning:
q_proj, k_proj, v_proj (attention heads)Training Configuration:
| Parameter | Value |
|---|---|
| Base Model | google/medgemma-1.5-4b-it |
| Fine-tune Method | LoRA (r=4) |
| Loss Function | ArcFace and Self-Similarity |
| Training Epochs | 4 |
| Batch Size | 16 |
| Learning Rate | 4e-5 |
| Hardware | Single RTX 3090 |
| Total Training Time | ~20 Minutes |
All source code is provided:
How to reproduce the demo: First download the datasets described in Dataset Section and put them in data folder.
# Install dependencies
pip install -r requirements.txt
# Train model
PYTHONPATH=. python training.py
# Index mock doctors and symptoms data
PYTHONPATH=. python demo/mock_data.py
# Run web interface
PYTHONPATH=. python demo/app.py
This project is licensed under the Creative Commons Attribution 4.0 International License (CC BY 4.0).
Python
100.0%

Patients worldwide face a critical challenge: symptom interpretation and medical pathway navigation. When experiencing symptoms, individuals often resort to unreliable web searches, generic symptom checkers, or costly unnecessary hospital visits. Meanwhile, medical professionals and patients struggle with:
This problem is fundamentally a semantic matching and retrieval task — precisely where large language models excel. While rule-based systems and simple keyword matching fail due to symptom variability and linguistic diversity, transformer-based models can:
┌─────────────────────────────────────────────────────────────┐
│ User-Facing Layer: Gradio Web Interface │
│ (Symptom Input, Privacy Controls, Result Visualization) │
└────────────────────┬────────────────────────────────────────┘
│
┌────────────────────▼────────────────────────────────────────┐
│ Query Engine: Vector Similarity Search │
│ (Text → Embedding → FAISS Search → Ranking) │
└────────────────────┬────────────────────────────────────────┘
│
┌────────────────────▼────────────────────────────────────────┐
│ Embedding Layer: MedGemma + Metric Learning Head │
│ (Symptom Encoding to 1024D normalized vectors) │
└────────────────────┬────────────────────────────────────────┘
│
┌────────────────────▼────────────────────────────────────────┐
│ Index Layer: FAISS (Fast Approximate Nearest Neighbor) │
│ (Pre-computed disease-symptom embeddings) │
└─────────────────────────────────────────────────────────────┘
Training Data: Disease and symptoms dataset 2023
Production and Evaluation Data: Symptom2Disease
We convert given text into prompts:
Instruct: Diagnose the disease given symptoms.
Symptoms: {text}
Diagnosis:
Rather than using MedGemma for generation, we exploit its learned medical representations as a foundation for semantic embeddings:
Input Symptoms → MedGemma Language Model → Last Hidden State
↓
Dual-Head
├─ Last Token → Head (512D) → Diagnosis Vector
└─ Mean Pooled Tokens → Head (512D) → Context Vector
↓
Concatenation + Normalization
↓
Final Embedding (1024D normalized)
Rather than standard mean pooling, we combine:
We concatenate them for inference. For training, we calculate cosine similarity between last token and mean token as an auxiliary loss. This dual-head approach captures both diagnostic intent and symptom context, improving matching accuracy and speeding up convergence.
Arc-Face Loss for Metric Learning: We implemented ArcMarginProduct loss, typically used in face recognition, adapted for medical concept clustering:
LoRA Fine-tuning:
q_proj, k_proj, v_proj (attention heads)Training Configuration:
| Parameter | Value |
|---|---|
| Base Model | google/medgemma-1.5-4b-it |
| Fine-tune Method | LoRA (r=4) |
| Loss Function | ArcFace and Self-Similarity |
| Training Epochs | 4 |
| Batch Size | 16 |
| Learning Rate | 4e-5 |
| Hardware | Single RTX 3090 |
| Total Training Time | ~20 Minutes |
All source code is provided:
How to reproduce the demo: First download the datasets described in Dataset Section and put them in data folder.
# Install dependencies
pip install -r requirements.txt
# Train model
PYTHONPATH=. python training.py
# Index mock doctors and symptoms data
PYTHONPATH=. python demo/mock_data.py
# Run web interface
PYTHONPATH=. python demo/app.py
This project is licensed under the Creative Commons Attribution 4.0 International License (CC BY 4.0).
Python
100.0%