LLaMA 3.2-1B Medical Abbreviation Detector (Spanish)

Descripción del Modelo

Este modelo es una versión especializada de LLaMA 3.2-1B Instruct ajustada mediante fine-tuning para la detección automática de abreviaciones médicas en textos clínicos en español. Forma parte del sistema SimpliMed desarrollado para la simplificación de informes de alta hospitalaria en el ámbito de la cardiología.

El modelo ha sido entrenado específicamente para identificar:

  • Abreviaturas: formas truncadas (ej: "a.c." = antes de comida)
  • Siglas: iniciales de palabras (ej: "EPOC" = enfermedad pulmonar obstructiva crónica)
  • Acrnimos: siglas lexicalizadas (ej: "DIU" = dispositivo intrauterino)
  • Símbolos médicos: notación clínica (ej: "mmHg", "mg", "cm")

Formato de Salida

{
  "formas_abreviadas": ["HTA", "IAM", "FEVI", "EPOC"],
  "simbolos_medicos": ["mmHg", "mg/dl", "cm", "ml"]
}

Rendimiento

El modelo supera significativamente a los métodos basados en expresiones regulares:

Sistema Precisión Recall F1 Score
SLM (este modelo) 0.8902 0.9283 0.9024
Expresiones regulares 0.6271 0.7675 0.6704

Entrenamiento

Corpus de Entrenamiento

  • Fuente: Informes de alta hospitalaria del Hospital Universitario de Jaén (especialidad de cardiología)
  • Anotación: Automática con GPT-4o
  • Diccionario de referencia: 7,054 abreviaciones médicas del diccionario SEDOM (Sociedad Española de Documentación Médica)
  • Tamaño del corpus: 70% del total de informes disponibles

Hiperparámetros

{
  "per_device_train_batch_size": 2,
  "per_device_eval_batch_size": 1,
  "num_train_epochs": 3,
  "eval_steps": 10,
  "save_steps": 500,
  "gradient_accumulation_steps": 4,
  "learning_rate": 1e-4,
  "seed": 42,
  "max_seq_length": 2048
}

Frameworks

  • PyTorch
  • Hugging Face Transformers
  • vLLM (para inferencia eficiente)

Uso

import json
import re
from openai import OpenAI

class ExtractorAbreviaciones:
    def __init__(self, ruta_modelo, ruta_prompt, base_url="http://localhost:8000/v1"):
        self.model_path = ruta_modelo
        self.prompt = self._cargar_prompt(ruta_prompt)
        self.client = OpenAI(base_url=base_url, api_key="token-abc123")
    
    def _cargar_prompt(self, ruta_prompt):
        with open(ruta_prompt, "r", encoding="utf-8") as file:
            return file.read()
    
    def _extraer_listas(self, texto):
        """Fallback para extraer listas si el JSON no parsea correctamente"""
        patrones = {
            "formas_abreviadas": re.compile(r'"formas_abreviadas": \[([^\]]+)\]'),
            "simbolos_medicos": re.compile(r'"simbolos_medicos": \[([^\]]+)\]')
        }
        datos = {"formas_abreviadas": [], "simbolos_medicos": []}
        
        for clave, patron in patrones.items():
            coincidencia = patron.search(texto)
            if coincidencia:
                elementos = [x.strip().strip('"') for x in coincidencia.group(1).split(',')]
                datos[clave] = elementos
        
        return datos
    
    def extraer_abreviaciones(self, texto):
        """Extrae todas las abreviaciones (combinando ambas categorías)"""
        datos = self.extraer_abreviaciones_simbolos(texto)
        return list(set(datos["formas_abreviadas"]) | set(datos["simbolos_medicos"]))
    
    def extraer_abreviaciones_simbolos(self, text, temperature=0.0, max_new_tokens=128):
        """
        Extrae abreviaciones y símbolos médicos de un texto.
        
        Args:
            text (str): El texto clínico a analizar
            temperature (float): Temperatura para la generación (0.0 = determinista)
            max_new_tokens (int): Número máximo de tokens a generar
            
        Returns:
            dict: {"formas_abreviadas": [...], "simbolos_medicos": [...]}
        """
        try:
            messages = [
                {"role": "system", "content": self.prompt},
                {"role": "user", "content": text}
            ]
            
            response = self.client.chat.completions.create(
                model=self.model_path,
                messages=messages,
                max_tokens=max_new_tokens,
                temperature=temperature
            )
            
            resp = response.choices.message.content
            
            # Intentar parsear como JSON
            try:
                return json.loads(resp)
            except json.JSONDecodeError:
                # Buscar inicio del JSON
                inicio_json = resp.find("{")
                if inicio_json != -1:
                    json_str = resp[inicio_json:]
                    try:
                        return json.loads(json_str)
                    except json.JSONDecodeError:
                        return self._extraer_listas(resp)
                else:
                    return self._extraer_listas(resp)
                    
        except Exception as e:
            print(f"Error en la solicitud: {str(e)}")
            return {"formas_abreviadas": [], "simbolos_medicos": []}

# Ejemplo de uso
extractor = ExtractorAbreviaciones(
    ruta_modelo="lmolino/extractor_abreviaciones",
    ruta_prompt="prompt_abreviaciones.txt"
)

texto = "Paciente con HTA e IAM previo. TA: 140/90 mmHg."
resultado = extractor.extraer_abreviaciones_simbolos(texto)
print(resultado)
# {"formas_abreviadas": ["HTA", "IAM", "TA"], "simbolos_medicos": ["mmHg"]}

Limitaciones y Consideraciones

  1. Dominio específico: El modelo ha sido entrenado principalmente con informes de cardiología, por lo que su rendimiento puede variar en otras especialidades médicas, aunque su diseño es generalista.

  2. Sensibilidad al formato: El modelo puede tener dificultades con textos completamente en mayúsculas, donde pierde pistas tipográficas distintivas.

  3. Desambiguación contextual: Para abreviaciones con múltiples significados (ej: "HTP" = hipertensin portal vs. hipertensión pulmonar), se requiere un módulo adicional de desambiguación basado en contexto clínico.

  4. Dependencia del diccionario SEDOM: Las abreviaciones detectadas se validan contra el diccionario de 7,054 entradas del SEDOM.

Casos de Uso

  • Preprocesamiento de informes médicos
  • Sistemas de simplificación de textos clínicos
  • Normalización de terminología médica
  • Asistencia en la comunicación médico-paciente
  • Análisis de calidad de documentación clínica

Licencia

Apache 2.0

Downloads last month
11
Safetensors
Model size
1B params
Tensor type
BF16
·
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support