Estudio empírico sobre cómo el corpus de fine-tuning desplaza la orientación ideológica y psicológica de Large Language Models, medida mediante el Political Compass Test (PCT) y el Big Five Inventory (BFI-44).
- Pregunta de Investigación
- Diseño Experimental
- Resultados Principales
- Estructura del Repositorio
- Instalación
- Uso: Pipeline de Corpus
- Uso: Fine-Tuning
- Uso: Evaluación y Visualización
- Documentación
- Referencias
¿Puede el corpus de fine-tuning modificar el perfil político-psicológico de un LLM instrucción-alineado de forma sistemática y medible?
La alineación de LLMs mediante RLHF se estudia extensamente, pero la influencia del corpus de preentrenamiento y fine-tuning sobre valores, ideología y rasgos de personalidad permanece menos explorada. Este proyecto propone operacionalizar esa influencia mediante dos instrumentos psicométricos estándar aplicados antes y después de cada fine-tuning.
Grid 5 modelos × 7 corpus = 35 experimentos de fine-tuning
| Modelo | Parámetros | Hub ID |
|---|---|---|
| Llama-3.2-1B-Instruct | 1.2B | unsloth/Llama-3.2-1B-Instruct |
| Qwen2.5-1.5B-Instruct | 1.5B | unsloth/Qwen2.5-1.5B-Instruct |
| Phi-4-mini-Instruct | 3.8B | unsloth/phi-4-mini-instruct |
| SmolLM2-1.7B-Instruct | 1.7B | unsloth/SmolLM2-1.7B-Instruct |
| Gemma-3-1B-IT | 1B | unsloth/gemma-3-1b-it |
| Corpus | Orientación / Temática |
|---|---|
izquierda |
Socialismo, marxismo, anarquismo |
derecha |
Conservadurismo, liberalismo clásico, nacionalismo |
siglo_de_oro |
Literatura española del Siglo de Oro |
economia_clasica |
Smith, Ricardo, Mill — liberalismo económico |
tradicion_religiosa |
Tradición cristiana medieval (Aquino, Agustín) |
judaismo |
Talmud, Maimonides, tradición judía |
bible_kjv |
Biblia en inglés (King James Version) |
QLoRA 4-bit (NF4) + LoRA con RSLoRA, formato instruction-style.
Ver docs/INFORME_FineTuning.md para la metodología completa.
- PCT — Political Compass Test: 62 ítems, ejes economía (izquierda↔derecha) y social (autoritario↔libertario).
- BFI-44 — Big Five Inventory: 44 ítems, cinco factores (Extraversión, Amabilidad, Responsabilidad, Neuroticismo, Apertura).
Cada experimento evalúa el modelo en step 0 (baseline), cada 60 pasos, y al final del entrenamiento.
- Textos de izquierda desplazan los modelos hacia valores económicos izquierdistas de manera robusta (4/5 modelos), pero el eje social (libertario↔autoritario) muestra variabilidad.
- Textos religiosos y del Siglo de Oro incrementan Amabilidad (A) y Responsabilidad (C) en BFI, con efecto moderado en eje social-autoritario.
- Economía clásica produce el paradoja económica: fine-tuning con textos de libre mercado mueve modelos hacia el eje izquierda-económico (efecto de "contraste"), excepto en Qwen2.5 que sigue la dirección esperada.
- SmolLM2 es un caso degenerado: converge al atractor (0.00, +2.22) para cualquier corpus.
- Phi-4-mini muestra rigidez excepcional: los cambios son menores al 5% del rango en la mayoría de los experimentos.
Ver docs/INFORME_Resultados.md y docs/INFORME_Análisis.md para análisis detallado.
NLP_TP/
│
├── src/ # Pipeline de corpus (descarga, limpieza, construcción)
│ ├── downloader.py # Descarga textos desde Project Gutenberg / fuentes propias
│ ├── cleaner.py # Normalización y limpieza de texto
│ ├── builder.py # Genera dataset HuggingFace con chunks + metadatos
│ └── reporter.py # Estadísticas del corpus
│
├── src2/ # Pipeline de ML (entrenamiento, evaluación, análisis)
│ ├── train.py # Fine-tuning con Unsloth/QLoRA (entrada principal)
│ ├── take_test.py # Evaluación PCT + BFI-44 sobre cualquier modelo
│ ├── build_aggregate.py # Agrega resultados de todos los runs → all_runs.jsonl
│ ├── parse_results.py # Parsing y normalización de resultados individuales
│ ├── results_loader.py # Carga de resultados para análisis
│ ├── utils.py # Utilidades compartidas (prompting, parsers)
│ ├── visualize_grid.py # Gráficos del grid 5×7
│ ├── visualize_experiment.py # Gráficos por experimento individual
│ ├── visualize_presentation.py # Figuras para presentación (results/presentation/)
│ ├── visualize_results.py # Gráficos de resultados agregados
│ └── analyze_grid.py # ANOVA estadístico (trabajo futuro)
│
├── train_config/ # Configuraciones de fine-tuning
│ ├── template_full_corpus.yaml # Plantilla documentada con todos los parámetros
│ ├── *_fullcorpus.yaml # 35 configs de producción (5 modelos × 7 corpus)
│ └── exploratory/ # Configs de runs exploratorios / desarrollo
│
├── scripts/ # Scripts de orquestación
│ ├── setup_nvidia_cuda.sh # Setup venv NVIDIA CUDA
│ ├── setup_inference_amd_rocm.sh # Setup conda AMD ROCm
│ ├── run_fullcorpus_all.sh # Lanza los 35 fine-tunings en secuencia
│ └── run_*.sh # Scripts de runs específicos
│
├── docs/ # Documentación extendida del proyecto
│ ├── INFORME_Metodología.md # Metodología completa (PCT, BFI, QLoRA, pipeline)
│ ├── INFORME_FineTuning.md # Fine-tuning en detalle con ejemplos completos
│ ├── INFORME_Resultados.md # Resultados del grid con tablas y figuras
│ ├── INFORME_Análisis.md # Análisis e interpretación de resultados
│ ├── PROXIMOS_PASOS.md # Trabajo futuro y extensiones planificadas
│ └── CONCLUSIONES.md # CLM puro vs instruction-style (decisión metodológica)
│
├── scraper/ # Scraper del Political Compass Test
│ └── political_compass.py # Automatiza las respuestas online para validación
│
├── corpus/ # Corpus de texto (no versionado por tamaño)
│ ├── raw/ # Textos descargados
│ ├── processed/ # Textos limpios
│ └── datasets/ # Datasets HuggingFace listos para entrenamiento
│
├── results/ # Resultados de experimentos
│ ├── step_evolution/ # Resultados por run (PCT + BFI en cada step)
│ ├── aggregate/ # all_runs.jsonl con todos los runs consolidados
│ ├── presentation/ # Figuras para presentaciones
│ └── analysis/ # Análisis estadístico (pendiente)
│
├── Makefile # Targets de conveniencia (ver `make help`)
├── run_queue.sh # Ejecuta todos los fine-tunings en cola con skip inteligente
├── activate_env.sh # Activa .venv-nvidia (usar con `source`)
├── Train.ipynb # Notebook interactivo de entrenamiento
├── Inference.ipynb # Notebook interactivo de inferencia/evaluación
├── requirements.txt # Dependencias base
├── requirements-training-nvidia-cuda.txt
└── requirements-inference-amd-rocm.txt
- Python 3.11 (recomendado; Unsloth requiere ≤ 3.11 para compilación óptima)
- GPU NVIDIA con CUDA 12.x o AMD con ROCm 7.x
- ~20 GB de espacio libre (modelos + corpus + checkpoints)
# Crea el venv .venv-nvidia e instala todas las dependencias con CUDA
bash scripts/setup_nvidia_cuda.sh
# Activa el entorno (necesario antes de cualquier comando de entrenamiento)
source activate_env.sh# Crea un conda environment con soporte ROCm
bash scripts/setup_inference_amd_rocm.shsource activate_env.sh
python -c "import torch; print(torch.cuda.get_device_name(0))"El pipeline de corpus construye los datasets de entrenamiento a partir de fuentes públicas.
source activate_env.sh
# 1. Descargar textos (guarda en corpus/raw/<nombre>/)
python src/downloader.py --corpus siglo_de_oro
# 2. Limpiar y normalizar texto
python src/cleaner.py --corpus siglo_de_oro
# 3. Construir dataset HuggingFace con chunks de 512 tokens
python src/builder.py --corpus siglo_de_oro --chunk-size 512
# 4. Estadísticas del corpus generado
python src/reporter.py --corpus siglo_de_oroLos 7 corpus disponibles: izquierda, derecha, siglo_de_oro, economia_clasica,
tradicion_religiosa, judaismo, bible_kjv.
Cada run se controla mediante un archivo YAML en train_config/. La plantilla documentada
con todos los parámetros disponibles es train_config/template_full_corpus.yaml.
Ejemplo mínimo (basado en train_config/llama_siglo_de_oro_fullcorpus.yaml):
model_name: unsloth/Llama-3.2-1B-Instruct
corpus_name: siglo_de_oro
save_name: llama_siglo_de_oro_fullcorpus
lora_r: 16
lora_alpha: 16
use_rslora: true
max_steps: 320
learning_rate: 2.0e-4
per_device_train_batch_size: 2
gradient_accumulation_steps: 4
instruction_style: true # Obligatorio: preserva instruction-following
eval_at_steps: [0, 60, 120, 180, 240, 320]Importante:
instruction_style: truees obligatorio. El CLM puro sobre texto literario destruye la capacidad de instruction-following del modelo. Verdocs/CONCLUSIONES.mdpara la justificación empírica.
source activate_env.sh
python src2/train.py --config train_config/llama_siglo_de_oro_fullcorpus.yaml# Opción 1: script de cola con skip inteligente (recomendado)
# Saltea automáticamente runs que ya tienen resultados
bash run_queue.sh
# Opción 2: script directo de todos los fullcorpus
bash scripts/run_fullcorpus_all.shEl script run_queue.sh puede interrumpirse con Ctrl+C y reanudarse sin perder progreso.
Los logs se guardan en /tmp/run_queue.log.
Cada run genera un directorio en results/step_evolution/<save_name>__<timestamp>/:
results/step_evolution/llama_siglo_de_oro_fullcorpus__20260430_142300/
├── evolution_summary.json # Resumen: PCT + BFI en cada step evaluado
├── step_0/ # Evaluación baseline (antes del fine-tuning)
│ ├── political_compass_results.json
│ ├── political_compass_scores.json
│ ├── big_five_results.json
│ └── big_five_scores.json
├── step_60/ # Evaluaciones intermedias
├── ...
└── step_320/ # Evaluación final
source activate_env.sh
python src2/take_test.py \
--model unsloth/Llama-3.2-1B-Instruct \
--output results/mi_baseline/Después de completar los runs, construir el archivo agregado para análisis:
python src2/build_aggregate.py
# Genera: results/aggregate/all_runs.jsonl# Figuras del grid completo (heatmaps, compass por corpus, BFI radar)
python src2/visualize_grid.py
# Figuras de un experimento individual
python src2/visualize_experiment.py --run llama_siglo_de_oro_fullcorpus
# Figuras para presentación (44 gráficos en results/presentation/)
python src2/visualize_presentation.py
# Figuras de resultados agregados
python src2/visualize_results.pyLas figuras de presentación se organizan en subcarpetas:
results/presentation/
├── baselines/ # Political compass: baselines de los 5 modelos
├── compass/ # Compass por corpus y por modelo
├── trayectorias/ # Evolución por step del PCT
├── por_corpus/ # Delta PCT y BFI por corpus
├── bfi/ # BFI radar y distribuciones
└── resumen/ # Heatmaps, rankings, resumen global
| Documento | Descripción |
|---|---|
docs/INFORME_Metodología.md |
Metodología completa: PCT, BFI-44, QLoRA, pipeline de corpus, formato de evaluación |
docs/INFORME_FineTuning.md |
Fine-tuning en detalle: LoRA, RSLoRA, formatting_chat_func, StepEvaluationCallback, ejemplo completo con Siglo de Oro |
docs/INFORME_Resultados.md |
Resultados del grid 5×7: tablas, compass, análisis por corpus |
docs/INFORME_Análisis.md |
Interpretación de resultados: arquetipos de modelo, paradojas, patrones por dominio |
docs/PROXIMOS_PASOS.md |
Trabajo futuro: extensiones, mejoras metodológicas, análisis estadístico formal |
docs/CONCLUSIONES.md |
Justificación empírica del instruction-style fine-tuning vs CLM puro |
- Lewis et al. (2020). Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks.
- Hu et al. (2021). LoRA: Low-Rank Adaptation of Large Language Models. arXiv:2106.09685
- Dettmers et al. (2023). QLoRA: Efficient Finetuning of Quantized LLMs. arXiv:2305.14314
- Kasirzadeh & Gabriel (2023). In conversation with artificial intelligence: aligning language models with human values.
- Political Compass Test: politicalcompass.org
- Big Five Inventory (BFI-44): John & Srivastava (1999). The Big Five trait taxonomy.
- Unsloth: github.com/unslothai/unsloth