finetuning embedding models for glioma tasks
Jupyter Notebook
1
29 commits
updated Oct 6, 2026
This repository contains code for our clinically aligned embedding framework. We align radiology and pathology reports to produce robust clinical embeddings tailored for glioma prognostication, using Multiple Negatives Ranking Loss (MNRL) with LoRA-adapted fine‑tuning of jinaai/jina-embeddings-v3. We benchmark across tumor type classification, MGMT methylation prediction, and 1‑year survival prediction.
Large language models exhibit strong general text understanding yet lack oncology‑specific alignment needed for clinical prognostication. We propose a clinically aligned embedding model trained on matched radiology–pathology report pairs using MNRL with LoRA on jina-embeddings-v3. Across three neuro‑oncology tasks (tumor type, MGMT status, one‑year survival), the fine‑tuned encoder achieves strong, balanced performance with modest compute.
jina-embeddings-v3 (1024‑d embeddings, long context).git clone https://github.com/benedictneo/glioma_embedding.git
cd glioma_embedding
bash setup_env.sh
uv run python glioma.py prepare-data --config configs/dataset_config.yaml
uv run python glioma.py finetune --config configs/finetune_config.yaml
Multi‑GPU (DDP):
uv run python glioma.py finetune --config configs/finetune_config.yaml --ddp --num_gpus 4 --gpus 0,1,2,3
uv run python glioma.py generate --config configs/generate_config.yaml
uv run python glioma.py evaluate --config configs/evaluation_config.yaml
uv run python glioma.py align --config configs/alignment_config.yaml
uv run python glioma.py visualize --config configs/visualize_config.yaml
To reproduce all ablations/sequential evaluation:
# Create dataset splits (10k, 40k) for ablations
python scripts/experiments/create_dataset_splits.py \
--train-path data/training/mnrl/train.csv \
--eval-path data/training/mnrl/eval.csv \
--output-dir data/training/mnrl/splits
# Launch training groups (two terminals)
bash scripts/experiments/run_group_1.sh
bash scripts/experiments/run_group_2.sh
# After training completes, evaluate all experiments
RESULTS_BASE_DIR=models/results \
EMBEDDINGS_BASE_DIR=embeddings/experiments \
bash scripts/experiments/run_evaluation_sequential.sh
# Compare results
python scripts/experiments/compare_results.py
Hardware
Software
flash-attn>=2.5.8).Install (Linux GPU server)
# Already done by setup_env.sh, but manual steps:
uv venv
uv pip install --index-url https://download.pytorch.org/whl/cu121 \
torch==2.3.1 torchvision==0.18.1 torchaudio==2.3.1
uv pip install -r requirements.txt
uv pip install 'flash-attn>=2.5.8' --no-build-isolation # Linux only, optional
uv pip install -e .
Notes
jina-embeddings-v3 to enable encode/task adapters.Reproducibility notes
To avoid dependency conflicts, we recommend three separate uv environments:
Jina fine‑tune + embeddings (this repo): uv venv .venv-jina; source .venv-jina/bin/activate
uv pip install --index-url https://download.pytorch.org/whl/cu121 torch==2.3.1 torchvision==0.18.1 torchaudio==2.3.1uv pip install -r requirements.txtuv pip install 'flash-attn>=2.5.8' --no-build-isolationuv pip install -e .data/raw/* and data/eval/* to exercise the full pipeline.configs/dataset_config.yaml and src/data/data_pipeline.py:
Run:
uv run python glioma.py prepare-data --config configs/dataset_config.yaml
Fine‑tuning uses src/models/finetune.py with MNRL and SentenceTransformers trainer over jinaai/jina-embeddings-v3.
lora_main_params_trainable: true also fine‑tunes base params (per ablations).NO_DUPLICATES for in‑batch negatives.Single‑GPU:
uv run python glioma.py finetune --config configs/finetune_config.yaml
Multi‑GPU (DDP):
uv run python glioma.py finetune --config configs/finetune_config.yaml --ddp --num_gpus 4 --gpus 0,1,2,3
Reproducing ablations (scripts/experiments/configs/*.yaml):
python scripts/experiments/create_dataset_splits.py \
--train-path data/training/mnrl/train.csv \
--eval-path data/training/mnrl/eval.csv \
--output-dir data/training/mnrl/splits
bash scripts/experiments/run_group_1.sh
bash scripts/experiments/run_group_2.sh
Generate embeddings from base or fine‑tuned models:
uv run python glioma.py generate --config configs/generate_config.yaml
Supported models (configured in configs/generate_config.yaml):
| Model | Key | Dimensionality |
|---|---|---|
| Jina Embeddings v3 (base) | jina_base | 1024 |
| NV-Embed-v2 | nvidia | 4096 |
| GatorTron | gatortron | 3584 |
| MedEmbed | medembed | 384 |
| BioClinicalBERT | bioclinicalbert | 768 |
| PubMedBERT | pubmedbert | 768 |
| ModernBERT | modernbert | 768 |
| Jina finetuned variants (MNRL, Contrastive, Triplet) | jina_finetuned_variants | 1024 |
Notes
checkpoint_path to your checkpoint. We accept either a direct file (model.safetensors) or a directory containing the SentenceTransformers layout (auto‑resolved).output.skip_existing: true to avoid regenerating existing embeddings.embeddings/{tumor_type,os,mgmt}/ as .npy files.Evaluate embeddings (10‑fold stratified CV with Random Forest):
uv run python glioma.py evaluate --config configs/evaluation_config.yaml
Notes
embedding.directory from the config and looks under tumor_type/, os/, mgmt/ subdirectories for .npy files.evaluation.models in the config to a list of filenames (without .npy). Omit to evaluate all.results/.Sequential experiment evaluation:
RESULTS_BASE_DIR=models/results \
EMBEDDINGS_BASE_DIR=embeddings/experiments \
bash scripts/experiments/run_evaluation_sequential.sh
python scripts/experiments/compare_results.py
To quantify the quality of the learned radiology–pathology alignment, we provide a cross-modal retrieval evaluation (src/models/alignment.py).
Given a held-out set of paired radiology and pathology reports, the evaluation:
Reported metrics:
Run:
uv run python glioma.py align --config configs/alignment_config.yaml
The config (configs/alignment_config.yaml) specifies which model variants to compare (e.g., base vs. MNRL vs. Contrastive vs. Triplet). Results are saved as a markdown table and JSON to results/.
uv run python glioma.py visualize --config configs/visualize_config.yaml
Produces t‑SNE projections with class overlays and confidence ellipses for all three tasks (tumor type, MGMT, survival); outputs to figures/.
glioma_embedding/
├── LICENSE
├── README.md
├── requirements.txt
├── setup.py
├── setup_env.sh
├── glioma.py # CLI entry point
├── configs/
│ ├── finetune_config.yaml # Fine-tuning configuration
│ ├── generate_config.yaml # Embedding generation (base + finetuned models)
│ ├── evaluation_config.yaml # Downstream classification evaluation
│ ├── alignment_config.yaml # Cross-modal retrieval alignment evaluation
│ ├── visualize_config.yaml # t-SNE visualization
│ ├── dataset_config.yaml # Data preparation
│ └── inference_config.yaml # LLM inference
├── data/
│ ├── eval/ # Evaluation CSVs (tumor_type, mgmt, os)
│ ├── training/ # Training pairs (MNRL anchor–positive)
│ └── raw/ # Raw synthetic reports
├── src/
│ ├── data/data_pipeline.py # Data preparation and pair generation
│ ├── models/
│ │ ├── finetune.py # MNRL fine-tuning with SentenceTransformers
│ │ ├── evaluation.py # k-fold classification evaluation
│ │ ├── alignment.py # Cross-modal retrieval evaluation
│ │ └── inference.py # LLM inference
│ ├── embeddings/
│ │ ├── generate.py # Embedding generation (Jina, NV-Embed, etc.)
│ │ └── visualize.py # t-SNE visualization
│ └── utils/ # Config, logging, metrics, seeding
├── embeddings/ # Generated embeddings (.npy)
├── figures/ # Visualization outputs
├── models/ # Model checkpoints
├── results/ # Evaluation results
└── scripts/experiments/ # Ablation experiment scripts
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
finetuning embedding models for glioma tasks
Jupyter Notebook
1
29 commits
updated Oct 6, 2026
This repository contains code for our clinically aligned embedding framework. We align radiology and pathology reports to produce robust clinical embeddings tailored for glioma prognostication, using Multiple Negatives Ranking Loss (MNRL) with LoRA-adapted fine‑tuning of jinaai/jina-embeddings-v3. We benchmark across tumor type classification, MGMT methylation prediction, and 1‑year survival prediction.
Large language models exhibit strong general text understanding yet lack oncology‑specific alignment needed for clinical prognostication. We propose a clinically aligned embedding model trained on matched radiology–pathology report pairs using MNRL with LoRA on jina-embeddings-v3. Across three neuro‑oncology tasks (tumor type, MGMT status, one‑year survival), the fine‑tuned encoder achieves strong, balanced performance with modest compute.
jina-embeddings-v3 (1024‑d embeddings, long context).git clone https://github.com/benedictneo/glioma_embedding.git
cd glioma_embedding
bash setup_env.sh
uv run python glioma.py prepare-data --config configs/dataset_config.yaml
uv run python glioma.py finetune --config configs/finetune_config.yaml
Multi‑GPU (DDP):
uv run python glioma.py finetune --config configs/finetune_config.yaml --ddp --num_gpus 4 --gpus 0,1,2,3
uv run python glioma.py generate --config configs/generate_config.yaml
uv run python glioma.py evaluate --config configs/evaluation_config.yaml
uv run python glioma.py align --config configs/alignment_config.yaml
uv run python glioma.py visualize --config configs/visualize_config.yaml
To reproduce all ablations/sequential evaluation:
# Create dataset splits (10k, 40k) for ablations
python scripts/experiments/create_dataset_splits.py \
--train-path data/training/mnrl/train.csv \
--eval-path data/training/mnrl/eval.csv \
--output-dir data/training/mnrl/splits
# Launch training groups (two terminals)
bash scripts/experiments/run_group_1.sh
bash scripts/experiments/run_group_2.sh
# After training completes, evaluate all experiments
RESULTS_BASE_DIR=models/results \
EMBEDDINGS_BASE_DIR=embeddings/experiments \
bash scripts/experiments/run_evaluation_sequential.sh
# Compare results
python scripts/experiments/compare_results.py
Hardware
Software
flash-attn>=2.5.8).Install (Linux GPU server)
# Already done by setup_env.sh, but manual steps:
uv venv
uv pip install --index-url https://download.pytorch.org/whl/cu121 \
torch==2.3.1 torchvision==0.18.1 torchaudio==2.3.1
uv pip install -r requirements.txt
uv pip install 'flash-attn>=2.5.8' --no-build-isolation # Linux only, optional
uv pip install -e .
Notes
jina-embeddings-v3 to enable encode/task adapters.Reproducibility notes
To avoid dependency conflicts, we recommend three separate uv environments:
Jina fine‑tune + embeddings (this repo): uv venv .venv-jina; source .venv-jina/bin/activate
uv pip install --index-url https://download.pytorch.org/whl/cu121 torch==2.3.1 torchvision==0.18.1 torchaudio==2.3.1uv pip install -r requirements.txtuv pip install 'flash-attn>=2.5.8' --no-build-isolationuv pip install -e .data/raw/* and data/eval/* to exercise the full pipeline.configs/dataset_config.yaml and src/data/data_pipeline.py:
Run:
uv run python glioma.py prepare-data --config configs/dataset_config.yaml
Fine‑tuning uses src/models/finetune.py with MNRL and SentenceTransformers trainer over jinaai/jina-embeddings-v3.
lora_main_params_trainable: true also fine‑tunes base params (per ablations).NO_DUPLICATES for in‑batch negatives.Single‑GPU:
uv run python glioma.py finetune --config configs/finetune_config.yaml
Multi‑GPU (DDP):
uv run python glioma.py finetune --config configs/finetune_config.yaml --ddp --num_gpus 4 --gpus 0,1,2,3
Reproducing ablations (scripts/experiments/configs/*.yaml):
python scripts/experiments/create_dataset_splits.py \
--train-path data/training/mnrl/train.csv \
--eval-path data/training/mnrl/eval.csv \
--output-dir data/training/mnrl/splits
bash scripts/experiments/run_group_1.sh
bash scripts/experiments/run_group_2.sh
Generate embeddings from base or fine‑tuned models:
uv run python glioma.py generate --config configs/generate_config.yaml
Supported models (configured in configs/generate_config.yaml):
| Model | Key | Dimensionality |
|---|---|---|
| Jina Embeddings v3 (base) | jina_base | 1024 |
| NV-Embed-v2 | nvidia | 4096 |
| GatorTron | gatortron | 3584 |
| MedEmbed | medembed | 384 |
| BioClinicalBERT | bioclinicalbert | 768 |
| PubMedBERT | pubmedbert | 768 |
| ModernBERT | modernbert | 768 |
| Jina finetuned variants (MNRL, Contrastive, Triplet) | jina_finetuned_variants | 1024 |
Notes
checkpoint_path to your checkpoint. We accept either a direct file (model.safetensors) or a directory containing the SentenceTransformers layout (auto‑resolved).output.skip_existing: true to avoid regenerating existing embeddings.embeddings/{tumor_type,os,mgmt}/ as .npy files.Evaluate embeddings (10‑fold stratified CV with Random Forest):
uv run python glioma.py evaluate --config configs/evaluation_config.yaml
Notes
embedding.directory from the config and looks under tumor_type/, os/, mgmt/ subdirectories for .npy files.evaluation.models in the config to a list of filenames (without .npy). Omit to evaluate all.results/.Sequential experiment evaluation:
RESULTS_BASE_DIR=models/results \
EMBEDDINGS_BASE_DIR=embeddings/experiments \
bash scripts/experiments/run_evaluation_sequential.sh
python scripts/experiments/compare_results.py
To quantify the quality of the learned radiology–pathology alignment, we provide a cross-modal retrieval evaluation (src/models/alignment.py).
Given a held-out set of paired radiology and pathology reports, the evaluation:
Reported metrics:
Run:
uv run python glioma.py align --config configs/alignment_config.yaml
The config (configs/alignment_config.yaml) specifies which model variants to compare (e.g., base vs. MNRL vs. Contrastive vs. Triplet). Results are saved as a markdown table and JSON to results/.
uv run python glioma.py visualize --config configs/visualize_config.yaml
Produces t‑SNE projections with class overlays and confidence ellipses for all three tasks (tumor type, MGMT, survival); outputs to figures/.
glioma_embedding/
├── LICENSE
├── README.md
├── requirements.txt
├── setup.py
├── setup_env.sh
├── glioma.py # CLI entry point
├── configs/
│ ├── finetune_config.yaml # Fine-tuning configuration
│ ├── generate_config.yaml # Embedding generation (base + finetuned models)
│ ├── evaluation_config.yaml # Downstream classification evaluation
│ ├── alignment_config.yaml # Cross-modal retrieval alignment evaluation
│ ├── visualize_config.yaml # t-SNE visualization
│ ├── dataset_config.yaml # Data preparation
│ └── inference_config.yaml # LLM inference
├── data/
│ ├── eval/ # Evaluation CSVs (tumor_type, mgmt, os)
│ ├── training/ # Training pairs (MNRL anchor–positive)
│ └── raw/ # Raw synthetic reports
├── src/
│ ├── data/data_pipeline.py # Data preparation and pair generation
│ ├── models/
│ │ ├── finetune.py # MNRL fine-tuning with SentenceTransformers
│ │ ├── evaluation.py # k-fold classification evaluation
│ │ ├── alignment.py # Cross-modal retrieval evaluation
│ │ └── inference.py # LLM inference
│ ├── embeddings/
│ │ ├── generate.py # Embedding generation (Jina, NV-Embed, etc.)
│ │ └── visualize.py # t-SNE visualization
│ └── utils/ # Config, logging, metrics, seeding
├── embeddings/ # Generated embeddings (.npy)
├── figures/ # Visualization outputs
├── models/ # Model checkpoints
├── results/ # Evaluation results
└── scripts/experiments/ # Ablation experiment scripts
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.