Plataforma IA self-hosted · roadmap futuro (gestión multi-modelo en pve-epyc-02)
Plataforma IA self-hosted · roadmap futuro
Estado: planificación documentada, NO implementación. Bloqueado por dos pre-requisitos no negociables (sección 2). Diseñado el 01-05-2026 (sesión 45).
1. Visión general
Hoy pve-epyc-02 corre llama-server con un modelo único (Gemma 4 26B-A4B Q4_K_M) sirviendo Auto-Plan en CreaRack PROD vía OpenAI-compat. La plataforma futura amplía esto a:
- Múltiples modelos coexistiendo en disco (Gemma 4 variantes, Qwen 3.6, otros) con switch operativo entre ellos.
- UI de gestión estilo ChatGPT con conversaciones persistentes, multi-usuario, RAG, y selector de modelo.
- API keys propias para que otros proyectos (no solo CreaRack PROD) puedan consumir el llama vía endpoint controlado, con auth y rate limiting.
- Dependencia cero de APIs comerciales (Gemini, OpenRouter, Anthropic) en el día a día CreaRack — todo sirviendo desde nuestro hardware.
Es la culminación natural del trabajo iniciado en sesión 41 (cuando se valoró self-host como respuesta a OpenRouter limitando calidad de visión Auto-Plan).
2. Pre-requisitos NO negociables
Esta plataforma NO se implementa hasta que ambos hitos estén cubiertos:
Pre-req 1 · Auto-Plan al 100 % con Gemma 4 self-hosted
Hoy estamos en ~70 % calidad / ~91 % recall plano 70 racks. Falta el último tramo. Vías exploradas pero no exhaustadas:
- Probar Q6_K (21 GB) y Q8_0 (25 GB) del 26B-A4B en lugar de Q4_K_M (16 GB). Cabe en LXC 100 sin problema. Esperado: 70→80 %.
- mmproj-F32 en lugar de F16 para vision encoder más preciso.
- Pivotar a otro modelo: Gemma 4 31B denso, Qwen3.6-27B, Qwen3.6-35B-A3B, MiniCPM-V 2.6, InternVL.
- Ajustes de prompting / sampling específicos para visión densa.
Sin Auto-Plan al 100 % en self-host, expandir a otros sites IA es prematuro.
Pre-req 2 · Resto de sites IA CreaRack migrados a self-host
Sites IA actuales en CreaRack-Pro (Regla 8 CLAUDE.md, 8 sites + 3 workspace):
blueprints/services/autoplan.py(visión, Gemma 4 OpenRouter — futuro pve-epyc-02)monitoring/services/ai_providers/openrouter.py(CNS Insight)monitoring/services/tutor_service.py(síntesis tutor async)network/services/mib_assistant.py(JSON crítico SNMP)core/services/ai_operations.py(ops generales)core/services/ai_providers/router.py(router default)core/management/commands/finops_report.py(informe finops)core/management/commands/perf_review.py(review performance)- Workspace:
archivo-core.ts(Help Widget bib_ask),translate.ts(traducción ES→EN),translate-wiki.mjs(batch pre-build)
Todos apuntan hoy a google/gemma-4-26b-a4b-it vía OpenRouter (Cloudflare/Parasail upstream). Para migrar a self-host:
- Cada site cambia provider de OpenRouter a
OLLAMA_BASE_URLinterno (ya tenemos el adapter Python — driver “ollama” apuntando a nuestro:8080). - Validar latencia + calidad en cada uno (algunos son crons largos = OK lentos; otros son UX = necesitan rapidez).
- Algunos sites son síncronos en request HTTP (Help Widget, tutor en chat) — comprobar que latencia self-host es aceptable.
Una vez TODOS los sites usan pve-epyc-02 + el server soporta el caudal sin saturarse, la plataforma de gestión tiene sentido.
3. Arquitectura objetivo (alto nivel)
┌────────────────────────────────────────────────────────────────────┐
│ HOST: pve-epyc-02 (Proxmox VE 9.1) │
│ EPYC 7502P · 256 GB DDR4-2933 · 4× NVMe │
├────────────────────────────────────────────────────────────────────┤
│ │
│ LXC 100 · crearack-llama-epyc-02 (PROD - actual) │
│ ├─ llama-server :8080 (modelo PROD fijo, gemma 26B Q?_K_M) │
│ ├─ Auto-Plan + CNS + Help + tutor + MIB + ops apuntan AQUÍ │
│ └─ NUNCA se interrumpe │
│ │
│ LXC 102 · crearack-llama-playground (NUEVO) │
│ ├─ llama-server :8081 (modelo intercambiable) │
│ ├─ Switch modelo via UI o CLI sin afectar PROD │
│ └─ Multi-instancia opcional :8082, :8083 para tener varios warm │
│ │
│ LXC 101 · crearack-openwebui (NUEVO) │
│ ├─ Docker container Open WebUI :3000 │
│ ├─ Auth multi-usuario, BD conversaciones persistente │
│ ├─ API keys nativas + RAG sobre documentos │
│ ├─ Endpoint OpenAI-compat agregando ambos LXC 100 + 102 │
│ └─ Posible LiteLLM proxy delante para tenant management │
│ │
│ Pool ZFS llamacpp (888 GB) │
│ ├─ Modelos GGUF (compartidos vía bind-mounts) │
│ │ ├─ gemma-4-26B-A4B-it-Q?_K_M.gguf (PROD) │
│ │ ├─ gemma-4-31B-it-Q?_K_M.gguf │
│ │ ├─ gemma-4-E4B-it-Q?_K_M.gguf │
│ │ ├─ Qwen3.6-27B-Q?_K_M.gguf │
│ │ ├─ Qwen3.6-35B-A3B-Q?_K_M.gguf │
│ │ └─ ... │
│ └─ Registry JSON con metadatos │
│ │
│ Pool ZFS backup (888 GB) │
│ └─ vzdump nightly de los 3 LXC │
└────────────────────────────────────────────────────────────────────┘
│
│ Tailscale (CreaRackSL@)
│
┌───────────────────────┼───────────────────────────┐
│ │ │
CreaRack PROD Edu / Dani devices Otros proyectos
(Auto-Plan, (UI ChatGPT-like (futuras apps con
CNS, etc.) en navegador) API keys propias)
4. Fases del plan
Fase A · Modelos en disco + CLI gestión (estimación ~3 h)
Objetivo: tener varios modelos descargados + scripts CLI para gestión sin UI.
Implementación:
-
Scripts en
/usr/local/bin/del LXC playground (no del PROD):model-download <repo> [pattern]— wget desde HuggingFace al directorio modelos. Si HF tiene varios files matching pattern, lista para elegir.model-list— lista GGUFs en/var/lib/llamacpp/models/, marca cuál está activo, muestra tamaños y last_used.model-rm <file>— borra GGUF (con confirmación interactiva o--force).model-switch <file>— cambia--modelen systemd unit + restart. Verifica que existe + valida arquitectura compatible.model-info <file>—gguf_inforápido (architecture, quant, context size, vision/no, tokenizer).model-bench <file> [<prompt>]— benchmark rápido sobre el modelo (prompt eval + decode tps).
-
Registry simple en
/var/lib/llamacpp/registry.json:{ "models": [ { "file": "gemma-4-26B-A4B-it-UD-Q4_K_M.gguf", "repo": "unsloth/gemma-4-26B-A4B-it-GGUF", "size_bytes": 16868240704, "downloaded_at": "2026-05-01T10:35:00Z", "last_used_at": "2026-05-01T11:20:00Z", "vision": true, "mmproj": "mmproj-F16.gguf", "context_max": 16384, "is_locked_for_prod": true } ] } -
Integration HF: usar API pública
https://huggingface.co/api/models/<repo>para listar files + descargas conwgetal CDN cdn-lfs.huggingface.co. Sin token (modelos públicos).
Modelos a descargar inicialmente: los 5 que pidió Edu en s45 (verificados existen):
unsloth/gemma-4-E4B-it-GGUFunsloth/gemma-4-26B-A4B-it-GGUF(ya parcialmente descargado)unsloth/gemma-4-31B-it-GGUFunsloth/Qwen3.6-27B-GGUFunsloth/Qwen3.6-35B-A3B-GGUF
Total estimado en Q4_K_M: ~77 GB. Cabe ×10 en pool de 888 GB.
Fase B · LXC 102 playground separado (estimación ~1.5 h)
Objetivo: experimentar con modelos sin interrumpir Auto-Plan PROD.
Implementación:
pct create 102 ubuntu-24.04-standardcon misma config que LXC 100 (24 cores 8-31, 64 GB RAM, bind-mount al pool ZFS llamacpp/models en modo lectura).- Wait — los cores 8-31 ya están asignados al LXC 100. Conflicto de cgroup. Solución: LXC 102 usa cores diferentes (ej: 32-55 si se libera del host) O los 2 LXC comparten cores via cgroup
cpus=8-31ambos concpu.sharesdistintos. - Mejor enfoque: LXC 100 pin estricto (cgroup
cpuset.cpus = 8-31), LXC 102 usa pool0-7,32-63(también pin estricto, los 8 cores del host + los 32 SMT siblings). Requiere validar performance (SMT siblings comparten unidades de ejecución). - llama-server en
:8081dentro del LXC 102. - Bind-mount al mismo dataset ZFS de modelos pero readonly (LXC 102 NO modifica modelos compartidos — se hace desde LXC 100 con privilegios).
- Tailscale separado:
crearack-llama-playgroundcon su IP Tailscale propia.
Beneficio clave: cualquier model-switch en LXC 102 NO afecta a LXC 100. Auto-Plan PROD nunca pierde servicio.
Fase C · Open WebUI (LXC 101, estimación ~3 h)
Objetivo: UI ChatGPT-like para uso humano + API keys nativas.
Stack:
- LXC 101
crearack-openwebui(4 cores, 8 GB RAM, 30 GB rootfs). - Docker dentro del LXC (privileged o nesting=1).
docker composecon:open-webuicontainer (ghcr.io/open-webui/open-webui:latest).postgrescontainer (BD persistente para usuarios + conversaciones + RAG).- Opcional:
redispara cache.
- Volumen Docker en pool ZFS (snapshots gratis para BD).
Configuración:
- Open WebUI configurado con MULTIPLES OpenAI endpoints:
- “PROD (LXC 100)” →
http://100.80.142.60:8080(modelo fijo gemma 26B) - “Playground (LXC 102)” →
http://<TS-LXC-102>:8081(modelo intercambiable)
- “PROD (LXC 100)” →
- Auth via email + password (pool inicial: Edu, Dani, Txell). API keys auto-generadas por usuario.
- Conversaciones persistentes en BD postgres + drag-drop archivos para RAG.
Lo que Open WebUI NO da out-of-the-box:
- Descarga de modelos GGUF directamente — esa funcionalidad está atada a Ollama (que NO usamos). Workaround: bot CLI vía nuestros scripts Fase A, o mini-página custom en Astro (workspace) que liste modelos + permita descargar de HF.
- Switch dinámico de modelo cargado en llama-server — workaround: en Open WebUI cada modelo del playground se mapea a un endpoint distinto, y el switch real lo hace
model-switchen background del LXC 102. Latencia 30-60 s aceptable para playground (no para PROD).
Fase D · LiteLLM proxy multi-tenant (opcional, estimación ~2 h)
Cuándo: si surgen apps externas a CreaRack que necesitan consumir el llama (ej: app móvil, plugin Excel, integración con Holded, etc.).
Por qué:
- Open WebUI da API keys básicas pero su modelo es “1 user = 1 API key”. Para multi-tenant real (varios proyectos, billing por proyecto, rate limiting por team) → LiteLLM proxy delante.
- LiteLLM expone OpenAI-compat estándar + dashboard + spending tracking + virtual keys + budgets.
- Backend: nuestros llama-servers en LXC 100 + 102.
Setup: container Docker en LXC 101 junto a Open WebUI. Configurado con cada llama-server como “model” con virtual keys por tenant.
Fase E · Backups + DR (estimación ~1 h)
- vzdump nightly de los 3 LXC (100, 101, 102) al pool
backup. - Snapshots ZFS antes de cada update llama.cpp / modelo nuevo / cambio config.
- Replicación off-site (pendiente desde s45 — diferida a soak): Storage Box Hetzner o cross-server CreaRack PROD.
Fase F · Observabilidad (estimación ~2 h)
- Prometheus exporter por cada llama-server (
/metricsya expuesto). - Push a VictoriaMetrics de CreaRack PROD (existente) o instancia local.
- Dashboard Grafana con: tps por modelo, latencia P50/P95/P99, requests/min, errores, RAM usage por LXC.
- Alertas: si llama-server cae, si latencia > X, si disco pool ZFS llamacpp > 80 %.
- Integration con sensor del workspace (
workspace.crearack.com/biblioteca/pulse).
Fase G · Cost tracking interno (opcional, estimación ~3 h)
Para qué: si crece a varios proyectos consumiendo el llama, conviene saber quién usa cuánto para distribuir coste interno (aunque sea coste fijo del server, da visibilidad).
- Logging por request: tenant + tokens prompt + tokens completion + modelo + duración.
- Dashboard mensual: top consumidores + total tokens + utilización del server.
- Posible cap por tenant si saturación.
5. Estimación total
| Fase | Tiempo | Bloqueante para next |
|---|---|---|
| A · Modelos + CLI | ~3 h | sí |
| B · LXC 102 playground | ~1.5 h | sí |
| C · Open WebUI LXC 101 | ~3 h | parcial |
| D · LiteLLM (opcional) | ~2 h | no |
| E · Backups + DR | ~1 h | no |
| F · Observabilidad | ~2 h | no |
| G · Cost tracking (opcional) | ~3 h | no |
Total mínimo viable (A+B+C+E+F): ~10 h trabajo efectivo. Total completo (A-G): ~15 h.
Distribución sugerida en 2-3 sesiones cuando llegue el momento.
6. Decisiones técnicas pendientes (cuando se aborde)
- Cores LXC 102: ¿usar SMT siblings (cores 32-63) o partir el host en NUMA distinto? Probar ambos, medir.
- Docker en LXC 101: ¿privileged o nesting=1 + keyctl? El segundo es más seguro pero algunos containers fallan.
- BD Open WebUI: postgres dedicado o sqlite simple? Postgres si crecemos, sqlite suficiente para inicio.
- TLS: Open WebUI tras Caddy con LetsEncrypt en algún subdomain de crearack.com? O queda solo Tailscale interno (sin TLS, ya cifrado por Wireguard)?
- Sync de modelos LXC 100 ↔ LXC 102: ¿bind-mount al mismo dataset ZFS (compartir disco) o cada LXC tiene su copia? Compartir es más eficiente pero requiere coordinación si uno escribe y otro lee.
- Naming convention: “PROD” y “Playground” claros en UI Open WebUI, o exponer cada modelo individual? Probablemente lo segundo (más explícito).
7. Riesgos identificados
- Saturación pve-epyc-02 al migrar todos los sites CreaRack: hoy solo Auto-Plan usa el server. CNS + Help + tutor + MIB pueden tener tráfico concurrente alto. Hay que medir caudal antes de migrar y validar que un único llama-server CPU aguanta. Si no → escalar (otro EPYC) o aceptar fallback a OpenRouter para sites menos críticos.
- Open WebUI lock-in: si el proyecto upstream cambia de licencia o se abandona, hay que migrar de UI. Mitigación: BD postgres exportable, conversaciones standard.
- Multi-instancia llama-server compite por bandwidth de RAM: aunque haya 256 GB, dos modelos cargados leyendo simultáneamente saturan los 8 canales DDR4. Probar bajo carga antes de prometer “varios modelos warm a la vez”.
- API keys filtradas: si una key se filtra a tercero, le da acceso ilimitado al llama. Mitigación: rate limit + rotación periódica + scope mínimo.
- Coste de mantenimiento creciente: 3 LXC + Docker + BD + observabilidad = más superficies que mantener. Validar que merece la pena vs simplicidad actual.
8. Trigger para ejecutar el plan
Las dos condiciones que destrabaán este plan:
✅ Auto-Plan al 100 % (calidad ≥ 95 % con modelo self-hosted, plano 70 racks ≤ 4 min) durante 2 semanas estables.
✅ Sites IA CreaRack restantes (CNS, Help, tutor, MIB, ops, finops, perf, workspace 3) migrados a OLLAMA_BASE_URL=http://100.80.142.60:8080 y operativos con calidad/latencia aceptables.
Cuando ambas se cumplan, abrir sesión dedicada para Fase A + B + C como mínimo viable. D-G según prioridades del momento.
9. Referencias
- Open WebUI: https://github.com/open-webui/open-webui
- LiteLLM: https://github.com/BerriAI/litellm
- HuggingFace Hub API: https://huggingface.co/docs/hub/api
- llama.cpp server docs: https://github.com/ggml-org/llama.cpp/blob/master/tools/server/README.md
- Plan IA actual del proyecto (Regla 8): [CLAUDE.md del repo CreaRack-Pro]
Véase también
- [[crearack-tech—admin—llama-server-runbook]] — runbook actual del llama-server
- [[crearack-tech—admin—proxmox-epyc-setup]] — setup host
- [[workspace—guias—llama-acceso-uso]] — guía actual usuario
- [[workspace—agentes-ia]] — comparativa agentes IA