feat: mejoras de navegación y visualización en sub-páginas
- sub-nav.css: barra de navegación compartida con botones estilo home (fondos por sección, texto negro, borde negro, hover neón, fix WebGL z-index) - Móvil: panel de detalle ocupa 50% inferior, grafo permanece visible arriba - Imágenes de nodo duplicadas en tamaño (160×104), detail-img a 28vh - output_*.js: función showEgoGraph — filtra el grafo al ego-network del nodo seleccionado; botón "Ver solo conexiones" (solo si hay relaciones); botón flotante "← Volver al grafo completo" - int-sec.js: eliminado makeTextSprite, igualado al resto (nulos para no-imagen) - Eliminado footer de los 5 sub-HTML - image_analyzer.py: cuantización int4 (NF4) para Qwen3-VL-8B → 6.4 GB VRAM Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
778db90d78
commit
9b67e2915b
15 changed files with 2070 additions and 1083 deletions
|
|
@ -24,7 +24,7 @@ from pathlib import Path
|
|||
|
||||
import torch
|
||||
from PIL import Image
|
||||
from transformers import Qwen3VLForConditionalGeneration, AutoProcessor
|
||||
from transformers import Qwen3VLForConditionalGeneration, AutoProcessor, BitsAndBytesConfig
|
||||
|
||||
# ── Configuración ──────────────────────────────────────────────────────────────
|
||||
|
||||
|
|
@ -33,10 +33,9 @@ CACHE_DIR = os.getenv("HF_HOME", "/var/www/theflows.net/flujos/FLUJOS_DATOS/IMAG
|
|||
|
||||
SUPPORTED_EXTENSIONS = {".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp"}
|
||||
|
||||
# RAM por imagen en batch (aprox): ~500MB activaciones encoder
|
||||
# Modelo base bfloat16: ~16GB
|
||||
# Batch de 4: ~18GB total → seguro con 64GB
|
||||
DEFAULT_BATCH_SIZE = 4
|
||||
# int4 via bitsandbytes: modelo ocupa ~4-5GB VRAM en lugar de ~16GB bfloat16
|
||||
# RTX 3060 12GB → sobra VRAM para activaciones
|
||||
DEFAULT_BATCH_SIZE = 1 # batch 1 para seguridad con 12GB
|
||||
|
||||
KEYWORD_PROMPT = """Analiza esta imagen en detalle.
|
||||
Devuelve ÚNICAMENTE un objeto JSON válido con esta estructura exacta, sin texto adicional:
|
||||
|
|
@ -73,17 +72,35 @@ class ImageAnalyzer:
|
|||
print(f"[ImageAnalyzer] Cargando modelo {self.model_id}...")
|
||||
print(f"[ImageAnalyzer] Cache: {CACHE_DIR}")
|
||||
|
||||
self._model = Qwen3VLForConditionalGeneration.from_pretrained(
|
||||
self.model_id,
|
||||
torch_dtype=torch.bfloat16,
|
||||
device_map="cpu",
|
||||
cache_dir=CACHE_DIR,
|
||||
)
|
||||
device = "cuda" if torch.cuda.is_available() else "cpu"
|
||||
print(f"[ImageAnalyzer] Dispositivo: {device}")
|
||||
|
||||
if device == "cuda":
|
||||
bnb_config = BitsAndBytesConfig(
|
||||
load_in_4bit=True,
|
||||
bnb_4bit_compute_dtype=torch.bfloat16,
|
||||
bnb_4bit_use_double_quant=True,
|
||||
bnb_4bit_quant_type="nf4",
|
||||
)
|
||||
self._model = Qwen3VLForConditionalGeneration.from_pretrained(
|
||||
self.model_id,
|
||||
quantization_config=bnb_config,
|
||||
device_map="auto",
|
||||
cache_dir=CACHE_DIR,
|
||||
)
|
||||
else:
|
||||
self._model = Qwen3VLForConditionalGeneration.from_pretrained(
|
||||
self.model_id,
|
||||
torch_dtype=torch.bfloat16,
|
||||
device_map="cpu",
|
||||
cache_dir=CACHE_DIR,
|
||||
)
|
||||
|
||||
self._processor = AutoProcessor.from_pretrained(
|
||||
self.model_id,
|
||||
cache_dir=CACHE_DIR,
|
||||
)
|
||||
print("[ImageAnalyzer] Modelo cargado.")
|
||||
print("[ImageAnalyzer] Modelo cargado (int4 cuantizado).")
|
||||
|
||||
# ── Opción 3: Resume — obtener archivos ya analizados en MongoDB ───────────
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue