This project explores a fully generative alternative to traditional retrieval and re-ranking pipelines by leveraging encoder–decoder and decoder-only language models
Python
0
4 commits
updated Mar 31, 2026
This repository contains the code and data for reproducing the experiments described in the paper:
Generative Models for Clinical Entity Linking in Spanish
Elena Zotova, Montse Cuadros and German Rigau
Array, Elsevier, 2026
We address the task of clinical entity linking — mapping medical terms in clinical Spanish text to ICD-10 codes — by generating natural language definitions that are then linked to the ICD-10 terminology. We evaluate and compare:
All approaches are evaluated on the CodiEsp shared task corpus.
| Path | Description |
|---|---|
.env | Environment variables (copy from .env.example) |
requirements.txt | Python dependencies |
evaluate_hf.py | Evaluate the published HF model on the test set |
hf_example.py | Minimal single-example inference script |
corpus/ | CodiEsp corpus + mapped corpora |
codiesp/ | Train/dev/test splits with sentence-level annotations |
cross_encoder_corpus_codiesp/ | Cross-encoder training/dev corpus |
mapped_corpora/ | Spanish Mantra, E3C, MedTerm mapped to ICD-10 |
icd_10_es/ | ICD-10 ontology files (Spanish, 2020) |
baselines/ | Baseline experiments |
string_match/ | Exact string matching baseline |
bi-encoder/ | SapBERT + FAISS retrieval |
cross-encoder/ | Cross-encoder re-ranking |
encoder-decoder/ | mT5 and mBART fine-tuning & evaluation |
decoder-only/ | Llama 3.1-8B fine-tuning & evaluation |
eval/ | Shared evaluation utilities |
utils/ | Shared transformer/FAISS utilities |
analysis/ | Performance aggregation scripts |
link_generated/ | Semantic similarity linking for generated outputs |
The best model (Medical-mT5-large fine-tuned on CodiEsp + mapped corpora) is published on HuggingFace:
ezotova/medical-mt5-clinical-el-spanish
from transformers import AutoConfig, AutoTokenizer, MT5ForConditionalGeneration
model_id = "ezotova/medical-mt5-clinical-el-spanish"
config = AutoConfig.from_pretrained(model_id)
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = MT5ForConditionalGeneration.from_pretrained(model_id, config=config)
def make_prompt(term, sentence):
return f"Genera una definición para el término: {term} - en la frase: {sentence}"
term = "inestabilidad a la marcha"
sentence = "El paciente refiere sensación de inestabilidad a la marcha y temblores en las manos."
inputs = tokenizer(make_prompt(term, sentence), return_tensors="pt")
outputs = model.generate(**inputs, max_new_tokens=64, num_beams=5, early_stopping=True)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
Note:
AutoConfigmust be loaded first and passed tofrom_pretrained. The model was fine-tuned with independentlm_headweights, so passingconfigprevents the defaulttie_word_embeddingsbehaviour from overwriting them.
evaluate_hf.py downloads the model automatically and evaluates it on the CodiEsp test set. No training artefacts are required.
# with default settings (batch_size=8, output saved to hf_eval/)
python evaluate_hf.py
# all options
python evaluate_hf.py \
--model ezotova/medical-mt5-clinical-el-spanish \
--corpus codiesp \
--batch_size 8 \
--output_dir hf_eval
| Argument | Default | Description |
|---|---|---|
--model | ezotova/medical-mt5-clinical-el-spanish | HuggingFace model ID or local path |
--corpus | codiesp | Corpus name (folder inside corpus/) |
--batch_size | 8 | Generation batch size (lower if OOM on GPU) |
--output_dir | hf_eval | Directory for predictions and score files |
Output files written to --output_dir:
<model>_test_predictions.tsv — test rows with pred, semscore, bertscore columns<model>_test_scores.tsv — aggregate ROUGE / BLEU / METEOR / BERTScore / SemScoreIf predictions already exist the script skips generation and recomputes scores only.
git clone https://github.com/<your-username>/<repo-name>.git
cd <repo-name>
# Create virtual environment
python -m venv venv
source venv/bin/activate
# Install dependencies
pip install -r requirements.txt
# Download NLTK data (for BLEU/METEOR evaluation)
python -c "import nltk; nltk.download('punkt'); nltk.download('wordnet')"
HuggingFace token: Required for downloading gated models (e.g., Llama 3.1).
Edit .env at the repo root and fill in HF_TOKEN:
HF_TOKEN=hf_your_token_here
Cache location: Set CACHE_FOLDER in .env to your HuggingFace model cache directory.
GPU selection: CUDA_VISIBLE_DEVICES is also controlled via .env. Adjust to match your hardware.
The model was fine-tuned on three Spanish clinical NLP datasets:
| Dataset | Description |
|---|---|
| Biomedical-TeMU/CodiEsp_corpus | CodiEsp shared task corpus — Spanish clinical cases annotated with ICD-10 codes (diagnoses and procedures) |
| DrBenchmark/E3C | European clinical corpus with entity annotations across multiple languages, including Spanish |
| IIC/CT-EBM-SP | Spanish clinical trial corpus annotated for biomedical entities |
| Mantra GSC | Medline abstract titles, drug labels, biomedical patent claims in Spanish |
If you use this code or data, please cite:
@article{zotova2026generative,
title={Generative Models for Clinical Entity Linking in Spanish},
author={Zotova, Elena and Cuadros, Montse and Rigau, German},
journal={Preprint submitted to Elsevier: Available at SSRN 5976036},
year={2026},
url={https://github.com/Vicomtech/generative-clinical-entity-linking}
}
This work is licensed under the Creative Commons Attribution-NonCommercial 4.0 International License (CC BY-NC 4.0).
You are free to share and adapt the material for non-commercial purposes, provided appropriate credit is given. See the LICENSE file for the full terms.
This project explores a fully generative alternative to traditional retrieval and re-ranking pipelines by leveraging encoder–decoder and decoder-only language models
Python
0
4 commits
updated Mar 31, 2026
This repository contains the code and data for reproducing the experiments described in the paper:
Generative Models for Clinical Entity Linking in Spanish
Elena Zotova, Montse Cuadros and German Rigau
Array, Elsevier, 2026
We address the task of clinical entity linking — mapping medical terms in clinical Spanish text to ICD-10 codes — by generating natural language definitions that are then linked to the ICD-10 terminology. We evaluate and compare:
All approaches are evaluated on the CodiEsp shared task corpus.
| Path | Description |
|---|---|
.env | Environment variables (copy from .env.example) |
requirements.txt | Python dependencies |
evaluate_hf.py | Evaluate the published HF model on the test set |
hf_example.py | Minimal single-example inference script |
corpus/ | CodiEsp corpus + mapped corpora |
codiesp/ | Train/dev/test splits with sentence-level annotations |
cross_encoder_corpus_codiesp/ | Cross-encoder training/dev corpus |
mapped_corpora/ | Spanish Mantra, E3C, MedTerm mapped to ICD-10 |
icd_10_es/ | ICD-10 ontology files (Spanish, 2020) |
baselines/ | Baseline experiments |
string_match/ | Exact string matching baseline |
bi-encoder/ | SapBERT + FAISS retrieval |
cross-encoder/ | Cross-encoder re-ranking |
encoder-decoder/ | mT5 and mBART fine-tuning & evaluation |
decoder-only/ | Llama 3.1-8B fine-tuning & evaluation |
eval/ | Shared evaluation utilities |
utils/ | Shared transformer/FAISS utilities |
analysis/ | Performance aggregation scripts |
link_generated/ | Semantic similarity linking for generated outputs |
The best model (Medical-mT5-large fine-tuned on CodiEsp + mapped corpora) is published on HuggingFace:
ezotova/medical-mt5-clinical-el-spanish
from transformers import AutoConfig, AutoTokenizer, MT5ForConditionalGeneration
model_id = "ezotova/medical-mt5-clinical-el-spanish"
config = AutoConfig.from_pretrained(model_id)
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = MT5ForConditionalGeneration.from_pretrained(model_id, config=config)
def make_prompt(term, sentence):
return f"Genera una definición para el término: {term} - en la frase: {sentence}"
term = "inestabilidad a la marcha"
sentence = "El paciente refiere sensación de inestabilidad a la marcha y temblores en las manos."
inputs = tokenizer(make_prompt(term, sentence), return_tensors="pt")
outputs = model.generate(**inputs, max_new_tokens=64, num_beams=5, early_stopping=True)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
Note:
AutoConfigmust be loaded first and passed tofrom_pretrained. The model was fine-tuned with independentlm_headweights, so passingconfigprevents the defaulttie_word_embeddingsbehaviour from overwriting them.
evaluate_hf.py downloads the model automatically and evaluates it on the CodiEsp test set. No training artefacts are required.
# with default settings (batch_size=8, output saved to hf_eval/)
python evaluate_hf.py
# all options
python evaluate_hf.py \
--model ezotova/medical-mt5-clinical-el-spanish \
--corpus codiesp \
--batch_size 8 \
--output_dir hf_eval
| Argument | Default | Description |
|---|---|---|
--model | ezotova/medical-mt5-clinical-el-spanish | HuggingFace model ID or local path |
--corpus | codiesp | Corpus name (folder inside corpus/) |
--batch_size | 8 | Generation batch size (lower if OOM on GPU) |
--output_dir | hf_eval | Directory for predictions and score files |
Output files written to --output_dir:
<model>_test_predictions.tsv — test rows with pred, semscore, bertscore columns<model>_test_scores.tsv — aggregate ROUGE / BLEU / METEOR / BERTScore / SemScoreIf predictions already exist the script skips generation and recomputes scores only.
git clone https://github.com/<your-username>/<repo-name>.git
cd <repo-name>
# Create virtual environment
python -m venv venv
source venv/bin/activate
# Install dependencies
pip install -r requirements.txt
# Download NLTK data (for BLEU/METEOR evaluation)
python -c "import nltk; nltk.download('punkt'); nltk.download('wordnet')"
HuggingFace token: Required for downloading gated models (e.g., Llama 3.1).
Edit .env at the repo root and fill in HF_TOKEN:
HF_TOKEN=hf_your_token_here
Cache location: Set CACHE_FOLDER in .env to your HuggingFace model cache directory.
GPU selection: CUDA_VISIBLE_DEVICES is also controlled via .env. Adjust to match your hardware.
The model was fine-tuned on three Spanish clinical NLP datasets:
| Dataset | Description |
|---|---|
| Biomedical-TeMU/CodiEsp_corpus | CodiEsp shared task corpus — Spanish clinical cases annotated with ICD-10 codes (diagnoses and procedures) |
| DrBenchmark/E3C | European clinical corpus with entity annotations across multiple languages, including Spanish |
| IIC/CT-EBM-SP | Spanish clinical trial corpus annotated for biomedical entities |
| Mantra GSC | Medline abstract titles, drug labels, biomedical patent claims in Spanish |
If you use this code or data, please cite:
@article{zotova2026generative,
title={Generative Models for Clinical Entity Linking in Spanish},
author={Zotova, Elena and Cuadros, Montse and Rigau, German},
journal={Preprint submitted to Elsevier: Available at SSRN 5976036},
year={2026},
url={https://github.com/Vicomtech/generative-clinical-entity-linking}
}
This work is licensed under the Creative Commons Attribution-NonCommercial 4.0 International License (CC BY-NC 4.0).
You are free to share and adapt the material for non-commercial purposes, provided appropriate credit is given. See the LICENSE file for the full terms.