refactor: reorganizar docs y pocs bajo INFO/

- docs/ → INFO/DOCS/CONTEXT/ (documentación técnica en markdown)
- FLUJOS/DOCS/ + FLUJOS_DATOS/DOCS/ → INFO/DOCS/ (txts de arquitectura)
- POCS/ → INFO/POCS/ (pruebas de concepto)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
CAPITANSITO 2026-04-21 23:49:33 +02:00
parent 83f67b76b4
commit 954f47996f
33 changed files with 0 additions and 0 deletions

View file

@ -0,0 +1,271 @@
# Scraper de Imágenes + Analizador Qwen3-VL — Contexto técnico FLUJOS
**Fecha:** 2026-04-21
**Directorio:** `FLUJOS_DATOS/IMAGENES/`
**Entorno:** `FLUJOS_DATOS/myenv/` (Python 3.11, venv)
---
## Componentes del módulo
```
FLUJOS_DATOS/IMAGENES/
├── wikipedia_image_scraper.py # Descarga imágenes de Wikipedia por tema
├── image_analyzer.py # Analiza imágenes con Qwen3-VL-8B
├── image_comparator.py # Compara imágenes (similaridad visual)
├── mongo_helper.py # Utilidades MongoDB para este módulo
├── pipeline_imagenes.py # Orquestador del módulo (flags CLI)
├── requirements_imagenes.txt # Dependencias del módulo
├── model_cache/ # Modelo Qwen descargado (~16 GB) — en .gitignore
└── output/
└── wiki_images/ # Imágenes descargadas — en .gitignore
├── cambio_climático/
├── geopolítica_conflictos/
├── seguridad_internacional_espionaje/
└── ...
```
---
## Parte 1: wikipedia_image_scraper.py
### Qué hace
Descarga imágenes de Wikipedia por tema usando la **Wikimedia REST API**. Para cada tema de FLUJOS busca artículos relacionados, extrae las imágenes de cada artículo y las descarga filtrando iconos/logos pequeños.
### Temas de FLUJOS que se scrapean (`TEMAS_FLUJOS`)
```python
TEMAS_FLUJOS = [
"cambio climático",
"geopolítica conflictos",
"seguridad internacional espionaje",
"libertad de prensa periodismo",
"corporaciones poder económico",
"populismo extremismo",
"desinformación redes sociales",
"privacidad vigilancia masiva",
"biodiversidad medioambiente",
"inteligencia artificial tecnología",
]
```
### Filtros de calidad (imágenes que se descartan)
```python
MIN_WIDTH = 200 # pixels
MIN_HEIGHT = 200 # pixels
MIN_BYTES = 20_000 # 20 KB mínimo
SKIP_PATTERNS = [
"flag_", "Flag_", "icon", "Icon", "logo", "Logo",
"symbol", "Symbol", "coat_of_arms", "commons-logo",
"wiki", "Wiki", "question_mark", "edit-", "nuvola",
"Nuvola", "pictogram", "OOjs", "Ambox", "Portal-", "Disambig",
]
VALID_EXTENSIONS = {".jpg", ".jpeg", ".png", ".webp"}
```
### Flujo interno
```
buscar_articulos(tema, lang='es')
└── GET https://es.wikipedia.org/w/api.php?action=query&list=search&srsearch={tema}
└── para cada artículo:
get_article_images(titulo)
└── GET https://es.wikipedia.org/w/api.php?action=query&prop=images
└── para cada imagen:
get_image_info(filename) → Wikimedia API
└── descarga si pasa filtros
└── guarda en output/wiki_images/{tema_slug}/
└── upsert en MongoDB imagenes_wiki
```
### Deduplicación
Upsert por `archivo` (nombre del fichero) en MongoDB `imagenes_wiki`. Si el fichero ya existe en disco, se salta la descarga.
### Uso CLI
```bash
# Scrape de todos los temas FLUJOS, max 20 imgs/tema, con MongoDB
python wikipedia_image_scraper.py --flujos --max 20 --mongo
# Scrape de un tema concreto
python wikipedia_image_scraper.py --tema "cambio climático" --max 30 --mongo
# Con idioma inglés
python wikipedia_image_scraper.py --tema "climate change" --lang en --max 40
```
### Documento MongoDB generado (colección `imagenes_wiki`)
```json
{
"archivo": "cambio_climático_003.jpg",
"image_path": "/var/www/theflows.net/flujos/FLUJOS_DATOS/IMAGENES/output/wiki_images/cambio_climático/cambio_climático_003.jpg",
"image_url": "https://upload.wikimedia.org/wikipedia/commons/...",
"tema": "cambio climático",
"subtema": "derretimiento glaciar ártico",
"descripcion_wiki": "Glaciar en retroceso en el Ártico, 2019",
"articulo_titulo": "Cambio climático en el Ártico",
"fecha": ISODate("2026-04-21")
}
```
---
## Parte 2: image_analyzer.py (Qwen3-VL-8B)
### Modelo usado
**Qwen/Qwen2.5-VL-7B-Instruct** (HuggingFace)
- Tamaño: ~16 GB en disco (bfloat16)
- Inferencia: CPU (sin GPU disponible actualmente)
- RAM necesaria: ~1618 GB para el modelo + ~2 GB por batch de 4 imágenes
- Cache local: `IMAGENES/model_cache/`
> El servidor tiene 64 GB RAM, por lo que cabe sin problema. En GPU (A100/RTX 3090+) sería 1050x más rápido.
### Carga del modelo
```python
from transformers import Qwen2_5_VLForConditionalGeneration, AutoProcessor
import torch
model = Qwen2_5_VLForConditionalGeneration.from_pretrained(
"Qwen/Qwen2.5-VL-7B-Instruct",
torch_dtype=torch.bfloat16, # mitad de RAM vs float32
device_map="cpu",
cache_dir=str(IMAGENES_DIR / "model_cache"),
)
processor = AutoProcessor.from_pretrained(
"Qwen/Qwen2.5-VL-7B-Instruct",
cache_dir=str(IMAGENES_DIR / "model_cache"),
)
```
### Prompt de análisis
```python
PROMPT = """Analiza esta imagen y proporciona:
1. Una descripción concisa del contenido principal (máx. 2 frases).
2. El tema principal (elige uno): cambio climático, conflicto armado, economía, política, tecnología, sociedad, otro.
3. Lista de 3-5 palabras clave relevantes.
Formato de respuesta:
DESCRIPCIÓN: [descripción]
TEMA: [tema]
PALABRAS CLAVE: [kw1, kw2, kw3]"""
```
### Procesamiento por batch
```python
def analyze_batch(image_paths: list[Path]) -> list[dict]:
"""Procesa hasta 4 imágenes por llamada al modelo."""
```
`batch_size=4` por defecto. Cada batch ocupa ~2 GB RAM adicionales.
### Resume automático
Antes de analizar, verifica qué imágenes ya están en MongoDB `imagenes`:
```python
def get_already_analyzed() -> set[str]:
"""Devuelve set de nombres de archivo ya en la colección imagenes."""
return {doc['archivo'] for doc in db['imagenes'].find({}, {'archivo': 1})}
```
Solo procesa imágenes no presentes en la BD.
### Priorización de imágenes
```python
def get_known_article_titles() -> set[str]:
"""Títulos de artículos presentes en wikipedia/noticias."""
# Prioriza imágenes cuyo tema coincide con artículos existentes
```
Las imágenes de temas con más documentos de texto en la BD se procesan primero, para maximizar la probabilidad de que los nodos imagen queden conectados por comparaciones.
### Documento MongoDB generado (colección `imagenes`)
```json
{
"archivo": "cambio_climático_003.jpg",
"image_path": "/var/www/.../output/wiki_images/cambio_climático/cambio_climático_003.jpg",
"tema": "cambio climático",
"subtema": "calentamiento global",
"texto": "Imagen satelital del retroceso del glaciar ártico entre 1990 y 2023. Se observa una reducción significativa de la capa de hielo.",
"keywords": ["glaciar", "ártico", "deshielo", "calentamiento", "satélite"],
"fecha": ISODate("2026-04-21")
}
```
---
## Parte 3: pipeline_imagenes.py (orquestador)
### Flags CLI
```bash
python pipeline_imagenes.py --scrape # solo scraping de imágenes
python pipeline_imagenes.py --analizar # solo análisis Qwen
python pipeline_imagenes.py --mongo # escribe resultados en MongoDB
python pipeline_imagenes.py --solo-json # escribe JSON local en vez de Mongo
python pipeline_imagenes.py --analizar --carpeta /ruta/custom --mongo
```
### Integración en el pipeline maestro
El `pipeline_maestro.py` lo llama así:
**Fase 1 (scraping):**
```bash
python wikipedia_image_scraper.py --flujos --max 20 --mongo
```
**Fase 2 (análisis):**
```bash
python pipeline_imagenes.py --analizar \
--carpeta FLUJOS_DATOS/IMAGENES/output/wiki_images \
--mongo
```
---
## Dependencias Python (requirements_imagenes.txt)
```
transformers>=4.45
torch>=2.1
qwen-vl-utils
Pillow
requests
pymongo
scikit-learn
python-dotenv
```
Instalación en el venv:
```bash
/var/www/theflows.net/flujos/FLUJOS_DATOS/myenv/bin/python3 -m pip install -r requirements_imagenes.txt
```
---
## Estado actual (2026-04-21)
- Imágenes en disco: ~155 imágenes en `output/wiki_images/` (10 temas × ~15 imgs)
- Imágenes en `imagenes_wiki` (MongoDB): ~150 docs
- Imágenes analizadas con Qwen en `imagenes` (MongoDB): proceso en curso / pendiente de primera ejecución completa
- El modelo Qwen se descarga automáticamente la primera vez que se llama (~16 GB, puede tardar 3060 min)
## Pendiente / mejoras futuras
- Conectar nodos imagen a la colección `comparaciones` (requiere embeddings de imagen o comparación texto-descripción)
- Activar GPU cuando esté disponible (cambiar `device_map="cpu"``"cuda"`)
- Aumentar `--max` a 50+ imágenes por tema una vez el análisis esté validado
- Añadir soporte para imágenes de noticias (no solo Wikipedia)