IA local

Le puse dos cerebros a mi IA (I) - Instalación

Tenía dos modelos de IA corriendo sueltos, uno por tarjeta gráfica. Quise meterlos en Docker y, por el camino, casi borro 47GB que no eran míos, cambié de modelo a mitad de partida y dos GPUs se negaron a cooperar de formas distintas y creativas.

Le puse dos cerebros a mi IA (I) - Instalación
Tenía dos modelos de IA corriendo sueltos, uno por tarjeta gráfica, sin ningún tipo de orden. Quería meterlos en Docker, ordenados, para no depender de que nada del sistema los pisara por accidente. Un día entero después, por el camino, casi borro 47GB que no eran míos, cambio de modelo a mitad de partida, y dos tarjetas gráficas se niegan a cooperar de formas distintas y creativas. Esta es la parte de "montarlo". Las dos siguientes entregas, todavía en marcha, son la de "traer a Hermes a la fiesta" (la configuración) y la de publicarlo de verdad para que mi socio también pueda usarlo sin depender de mí.
💡
En resumen, para quien tenga prisa

Un día entero: tenía un Qwen3.5 en la RTX 2060 y un Gemma4 en la RTX 4060 Ti, cada uno corriendo suelto sobre el sistema, sin ningún tipo de protección. Los metí a los dos en Docker. Por el camino: casi borro 47GB ajenos, probé a cambiar el modelo de la 2060 y tuve que dar marcha atrás, y las dos tarjetas se negaron a cooperar de formas distintas. Todo se arregló.

Aviso antes de empezar: esto se pone técnico en algunos tramos, porque lo fue de verdad. Pero te voy explicando cada palabra rara según sale, así que no hace falta saber programar para seguirlo.


🎬 El punto de partida

Tenía dos modelos de IA corriendo cada uno en su tarjeta gráfica: en la RTX 2060 un Qwen3.5 — el mismo protagonista de la comparativa de rendimiento de esta newsletter — y en la RTX 4060 Ti un Gemma4. Los dos instalados directamente sobre el sistema operativo, cada uno como un servicio suelto, sin ningún tipo de aislamiento. Y Hermes Agent, mi asistente de IA con herramientas propias (navega por internet, ejecuta comandos, busca cosas), vivía en la misma situación: instalado a pelo, en la carpeta de otro usuario del servidor.

"Instalado a pelo" significa que el programa convive directamente con el resto del sistema operativo, sin ninguna barrera entre medias. Funciona genial, hasta que una actualización cualquiera del sistema le pisa algo que necesitaba, y todo se rompe sin avisar.

La gente que sabe de esto tiene un nombre para la solución: Docker. En vez de instalar el programa directamente sobre el sistema, lo metes en una especie de caja sellada (un contenedor) que lleva dentro absolutamente todo lo que necesita para funcionar. Esa caja la puedes parar, mover o borrar sin que le afecte a nada de fuera. Es la diferencia entre tener las herramientas desperdigadas por todo el garaje y tenerlas metidas en una caja de herramientas como Dios manda.

El plan: eliminar los dos servicios sueltos, meterlos ordenados cada uno en su propia caja de Docker, y una vez con eso resuelto, acompañarlos con Hermes.


🗑️ Casi me cargo 47GB que no eran míos

Antes de tocar nada hice inventario de lo que había en el servidor, por aquello de mirar antes de romper. Encontré una carpeta de 47GB de modelos descargados y di por hecho, sin comprobarlo, que pertenecía al modelo que iba a eliminar. Tenía el comando escrito. El dedo casi en el enter.

⚠️
El susto nº1

Por pura manía de no fiarme del todo, miré dentro antes de ejecutarlo. De esos 47GB, lo que de verdad pertenecía a lo que iba a eliminar ocupaba 8KB. Ocho. El resto eran modelos de transcripción de voz y de análisis de imágenes que el propio Hermes usa para otras cosas, nada que ver con lo que estaba a punto de borrar.

Me quedé un rato mirando la pantalla pensando en lo cerca que había estado de cargarme 47GB de trabajo ajeno por no comprobar de quién era la carpeta. Y eso que todavía no había empezado lo difícil.


🎮 Dos tarjetas gráficas, dos infiernos distintos

Antes de seguir, una explicación rápida porque si no lo que viene no se entiende:

📝
Lo mínimo que hay que saber

Las tarjetas gráficas tienen su propia memoria, separada de la memoria normal del ordenador, llamada VRAM. Un modelo de IA puede funcionar usando la memoria y el procesador normales del ordenador — es posible, y mucha gente empieza así — pero es muchísimo más lento: la tarjeta gráfica está diseñada para mover datos en paralelo a lo bestia, justo lo que un modelo necesita para responder rápido. Para lo que yo quería (respuestas ágiles, varias personas hablando a la vez) necesitaba que el modelo cupiera entero en la VRAM. Y cuanto más "recuerda" de la conversación (el contexto, medido en trocitos de texto llamados tokens) y cuanta más gente le habla a la vez, más VRAM necesita.

La 2060: el infierno de la memoria

La 2060 tiene poca VRAM, 6GB, frente a los 12-24GB de una tarjeta moderna de gama alta. Antes de organizar el Qwen3.5 que ya tenía ahí, se me ocurrió probar algo distinto: en vez de un modelo por tarjeta, meter dos versiones del mismo modelo (Gemma), una pequeña de 2 mil millones de parámetros para la 2060 y la grande para la 4060 Ti.

No cupo. Ni de lejos. Descarté la idea, volví al Qwen3.5 que ya tenía funcionando ahí antes, y me puse a organizarlo bien dentro de Docker — con bastante contexto (65.536 tokens, unas 45.000 palabras de conversación) y 5 personas hablándole a la vez.

Primer intento, con el modelo en su formato normal: no cabía ni él solo en los 6GB. Ni para arrancar.

Hay una técnica que se llama cuantización: comprimir el modelo reduciendo la precisión de sus números internos para que ocupe menos — como guardar una foto en menor calidad para que quepan más en el móvil. Encontré una versión comprimida a 4 bits en vez de los 16 habituales, la probé, y el programa que sirve el modelo (vLLM) me lo rechazó porque el formato declarado no coincidía con el real. Un ajuste de una línea y arrancó. Ya, pensé. Ya está.

No estaba. El programa calculó que ni siquiera una sola conversación completa entraba en la memoria libre que quedaba tras cargar el modelo — la "libreta de apuntes" donde el modelo va anotando la conversación mientras responde (la caché) no tenía ni un hueco.

Probé a usar memoria normal del ordenador como colchón extra para esa caché. No sirvió: la tarjeta exige que al menos una conversación completa quepa en SU memoria antes siquiera de arrancar, daba igual cuánta memoria normal tuviera de reserva. Probé a comprimir también esa libreta de apuntes. Rechazado otra vez: la 2060 es demasiado vieja para ese tipo concreto de compresión.

A la cuarta combinación —otro tipo de compresión para la libreta, que esta tarjeta sí soporta, más apurar al máximo cuánta memoria se le permitía usar— cupo. Por fin.

La 4060 Ti: casi lo mismo, con propina

La otra tarjeta, la 4060 Ti, tiene más memoria (16GB) y ahí quería organizar en Docker el Gemma4 (12 mil millones de parámetros) que ya tenía corriendo, esta vez acelerado con un truco llamado speculative decoding — un modelo diminuto "adivina" varias palabras seguidas y el grande solo tiene que confirmarlas, en vez de escribirlas una a una. Como un ayudante que redacta un borrador rápido y el jefe solo lo revisa, en vez de escribirlo él desde cero.

Configuré mal qué tarjeta gráfica debía ver el contenedor —dupliqué sin darme cuenta la misma instrucción de dos formas distintas— y el programa se quedó sin ver ninguna tarjeta válida. Arreglado en dos minutos.

Después arrancaba bien, cargaba el modelo, el propio programa me confirmaba que sobraba memoria de sobra... y explotaba en el último segundo, compilando una pieza interna de bajo nivel, con un error de memoria que no tenía ningún sentido dado el margen que decía tener.

🐛
El fallo más tonto del día

El último paso del arranque necesitaba un poquito de memoria "de trabajo" aparte de la ya reservada, y no le estaba dejando ni un hueco. Bajar el porcentaje de memoria reservada del 90% al 80% lo arregló — sobraba memoria de sobra, y aun así hacía falta dejar más margen libre. Contraintuitivo hasta el final.

🖥️ El escritorio invisible

El icono de verdad, en mi propia barra — el mismo que se quedó mudo al hacer clic. El robotito en verde significa que hay al menos un contenedor levantado; en rojo, que están todos parados.

Con la 4060 Ti ya sirviendo el modelo grande a tope, un botón de mi propio escritorio —el que enciende y apaga los modelos, con su iconito monísimo en la barra de arriba— dejó de funcionar. Clic. Nada. El programa se lanzaba, el sistema decía que estaba ahí funcionando... y en pantalla, silencio absoluto.

Le di vueltas un buen rato hasta encontrar la causa: la 4060 Ti, con el modelo grande cargado, se había quedado con apenas 600MB libres de sus 16GB. Y resulta que esa misma tarjeta es la que uso para dibujar las ventanas de mi propio escritorio — no solo sirve modelos de IA, también pinta lo que veo en pantalla. Sin memoria libre, mi escritorio no podía dibujar ni una ventana nueva.

Me reí solo delante del monitor: el botón funcionaba perfectamente, era la misma tarjeta que le daba cerebro a mi IA la que le estaba quitando la vista a mi propio escritorio.


📋 El resumen de daños (parte 1)

Problema Causa real Arreglo
Casi borro 47GB ajenos Di por hecho de quién era la carpeta Mirar dentro antes de borrar (revolucionario, lo sé)
Quise meter una Gemma de 2B en la 2060 No cabía ni de lejos Descartada, vuelta al Qwen3.5 de siempre
Qwen3.5 no cabía en la 2060 Formato del modelo demasiado "pesado" para la VRAM Comprimir el modelo (cuantización a 4 bits)
Seguía sin caber La "libreta de apuntes" de la conversación tampoco cabía Comprimir también esa libreta, al tipo que la tarjeta sí soporta
La 4060 Ti no veía la GPU Instrucción duplicada por error Quitar la instrucción repetida
La 4060 Ti explotaba al final del arranque Sin margen de memoria "de trabajo" Bajar el límite de memoria reservada
Escritorio invisible La GPU sin memoria libre ni para dibujar ventanas Se resuelve apagando el modelo grande cuando no se usa

Con las dos tarjetas ya ordenadas y sirviendo sus modelos desde Docker, tocaba la parte que le da sentido a todo: traer a Hermes a la fiesta y hacer que funcionara bien de verdad, con personalidad, con buscador propio, y sin que ningún modelo se quedara pensando para siempre. Esa es la segunda parte.

Y después vendrá próximamente una tercera, sobre publicarlo de verdad para que mi socio —el otro admin de la app— también pueda usarlo sin depender de mí.

Docker, por cierto, salió tantas veces en esta historia (contenedores, permisos, redes, un sudo mal escrito que me dio un susto de los buenos) que se ganó su propia entrega aparte, centrada solo en él: Del odio al amor con Docker.

Jose Maria Gomez Lobato
Escrito por

Jose Maria Gomez Lobato

Desarrollador web y cofundador de Nebula Systems. Trabajo creando soluciones donde la inteligencia artificial se convierte en herramientas reales, combinando desarrollo, automatización y curiosidad por entender cómo funciona todo por dentro.