AI Hub

Plataforma de modelos especializados

Una API por capacidades,
no por modelos

Tus aplicaciones llaman a /v1/ocr, /v1/embeddings, /v1/transcribe o /v1/tts. Nunca saben qué modelo hay detrás.

Cambiar el modelo por otro mejor es reasignar un alias en el panel. Ninguna aplicación se entera, y ninguna se despliega otra vez.

  • 4 capacidades
  • 7 modelos
  • Python · FastAPI
  • Sin GPU
POST /v1/embeddings
# La app pide la capacidad, no el modelo
Authorization: Bearer ah_a1b2c3...

{ "texts": ["hola mundo"], "task": "passage" }

# El Hub responde con el esquema del Hub
{
  "model":      "default",
  "dimensions": 384,
  "vectors":    [[0.021, -0.118, ...]]
}

Detrás está multilingual-e5-small. Mañana puede estar otro, y la respuesta seguirá teniendo esta forma.

Qué sabe hacer

Cuatro capacidades, cuatro rutas

Cada capacidad es un contenedor propio, porque las dependencias de aprendizaje automático se llevan mal entre ellas. Cada una decide en su contrato si responde al momento o encola el trabajo.

Reconocimiento de texto

POST /v1/ocr

Saca el texto de una imagen o de un PDF. Devuelve bloques, líneas y palabras con su confianza y su recuadro, venga del motor que venga.

Modo
Imagen al momento, PDF en cola
Por defecto
ppocr-v4

Embeddings de texto

POST /v1/embeddings

Convierte texto en vectores para buscar por significado. El modelo por defecto es multilingüe, así que sirve para español, catalán e inglés sin cambiar nada.

Modo
Al momento
Por defecto
e5-small

Transcripción de voz

POST /v1/transcribe

Pasa un audio a texto. En un servidor sin tarjeta gráfica una transcripción tarda minutos, así que siempre va a la cola y devuelve un identificador de trabajo.

Modo
En cola, siempre
Por defecto
whisper-small

Texto a voz

POST /v1/tts

Convierte texto en audio. La voz rápida responde al momento; la que clona una voz a partir de una muestra es lenta sin tarjeta gráfica y conviene mandarla a la cola.

Modo
Al momento o en cola
Por defecto
piper-es

Añadir la quinta capacidad es una carpeta con un adaptador, un manifiesto y un contrato. Si algún día hiciera falta tocar el gateway, el controller o el panel para conseguirlo, la arquitectura se habría estropeado.

Lo único estable

Las aplicaciones piden default

Cada capacidad puede tener varios modelos instalados a la vez, y cada modelo tiene alias. Solo default tiene garantía de estabilidad. Promocionar un experimento es reasignarlo en el panel, sin tocar ni desplegar ninguna aplicación.

Los modelos instalados hoy. La memoria estimada es la que declara el manifiesto de cada uno.
Alias Capacidad Modelo Motor RAM
e5-small default Embeddings multilingual-e5-small sentence-transformers 700 MB
minilm-l6 Embeddings all-MiniLM-L6-v2 sentence-transformers 350 MB
ppocr-v4 default OCR PP-OCRv4 RapidOCR · onnxruntime 900 MB
whisper-small default Voz a texto faster-whisper-small ctranslate2 · int8 1.200 MB
whisper-base Voz a texto faster-whisper-base ctranslate2 · int8 600 MB
piper-es default Texto a voz es_ES-davefx-medium piper · onnxruntime 300 MB
xtts-v2 no comercial Texto a voz XTTS-v2 coqui-tts · torch 3.200 MB

Banco de pruebas y producción a la vez

Puedes instalar un modelo que todavía no usa nadie y probarlo con tranquilidad. El panel trae un banco de pruebas por capacidad: lanzas la misma petición contra varios modelos y comparas la salida, el tiempo y la memoria uno al lado del otro.

Las pruebas no ensucian las cifras

Cada petición queda registrada indicando si vino de una aplicación o del banco de pruebas. Así las estadísticas de uso siguen contando lo que hacen tus aplicaciones de verdad.

La restricción que manda

16 GB compartidos y ninguna tarjeta gráfica

La memoria es el recurso escaso, y el diseño entero está montado alrededor de ese hecho en lugar de ignorarlo hasta que revienta.

01

Servicio parado, contenedor parado

Una capacidad que nadie usa no ocupa memoria. El controller arranca y para los contenedores según hagan falta.

02

Modelo inactivo, modelo descargado

Tras un tiempo sin peticiones, el modelo sale de memoria. El tiempo se configura por modelo desde el panel.

03

Nunca se queda sin memoria

Antes de cargar un modelo se compara la memoria que declara su manifiesto con la que hay libre. Si no cabe, responde que vuelvas más tarde o encola el trabajo. No revienta el servidor.

04

Lo pesado va de uno en uno

La cola serializa los trabajos largos, con uno o dos a la vez por servicio, para no tumbar el resto de aplicaciones del servidor.

Cómo está montado

Lo que toca internet y lo que manda están separados

El controller necesita hablar con Docker para arrancar y parar contenedores. Por eso jamás está expuesto a internet, y por eso el plano público es otra pieza distinta.

Público

Gateway

Claves, límite de peticiones, validación del contrato, enrutado y registro

Panel

Aplicación web de administración, servida como ficheros estáticos

Red interna, sin salida

Controller

Registro de capacidades y modelos, ciclo de vida de contenedores, métricas

svc-ocr

Un contenedor por capacidad

svc-embeddings

Un contenedor por capacidad

svc-speech

Un contenedor por capacidad

svc-tts

Un contenedor por capacidad

Estado

PostgreSQL

Registro, claves, historial de peticiones, cola de trabajos y configuración. La única pieza con estado

Volumen de modelos

Los pesos descargados, compartidos entre el controller y los servicios

La cola vive en la base de datos

No hay Redis ni RabbitMQ. Los trabajos se reparten con un bloqueo de PostgreSQL que salta las filas ya cogidas, y aguanta este volumen durante años. Menos piezas que mantener encendidas.

Los contratos mandan sobre el código

La forma de cada respuesta está escrita y versionada aparte, y el adaptador traduce la salida del modelo a esa forma. Es exactamente lo que permite cambiar de modelo sin romper apps.

Desde un asistente

Las mismas capacidades, como herramientas

Hay un servidor MCP que expone las capacidades del Hub como herramientas. Un asistente de IA puede leer un PDF, transcribir un audio o generar voz sin que le escribas ninguna integración.

Herramientas disponibles
aihub_ocr          # saca el texto de una imagen o un PDF
aihub_speech       # transcribe un audio
aihub_tts          # convierte texto en audio
aihub_embeddings   # vectores para buscar por significado
aihub_job          # consulta un trabajo de la cola

Las operaciones que van a la cola mantienen la respuesta abierta hasta que terminan, así que el asistente recibe el resultado y no un identificador que luego tendría que ir a buscar.

Quién puede entrar

Una clave por aplicación

  • Claves guardadas como resumen De la clave no se guarda el valor, solo su hash. Se enseña una vez al crearla.
  • Permisos por capacidad Una clave que solo tiene que leer facturas no puede lanzar transcripciones.
  • Límite de peticiones por clave Una aplicación con un fallo en un bucle no se lleva por delante a las demás.
  • Los servicios no salen a internet Los contenedores de capacidad viven solo en la red interna y no se publican nunca.
  • El acceso a Docker está aislado Solo el controller habla con Docker, y solo el panel habla con el controller.
  • Los ficheros subidos caducan Van a un volumen temporal con caducidad, y hay tope de tamaño en la entrada.

Ficha técnica

Datos del proyecto

Qué es
Plataforma que centraliza modelos de IA especializados tras una API común por capacidades
Capacidades
OCR, embeddings, transcripción de voz y texto a voz
Servicios y API
Python 3.12 con FastAPI y Pydantic
Panel
React con Vite, TypeScript y Tailwind
Base de datos
PostgreSQL 16, también como cola de trabajos
Despliegue
Docker Compose y Traefik, en un solo nodo
Servidor
8 vCPU y 16 GB de memoria compartidos con otros proyectos, sin tarjeta gráfica
Estado
En desarrollo. Las cuatro capacidades funcionan de principio a fin

Cambiar de modelo debería ser
una decisión, no una migración.

AI Hub