Quería chatear con Qwen en local y utilizarlo como director de arte y cine.
No quería limitarme a pedirle un prompt y copiarlo en otro sitio. Quería hablar de un plano, dejar que Qwen llamase a ComfyUI, hacer que revisase la imagen o el vídeo, comentar qué había funcionado y generar la siguiente versión. Un pequeño bucle creativo ejecutándose por completo en mi máquina.
En vez de eso, me quedaba sin VRAM.
Qwen funcionaba perfectamente en la 5090. Mis workflows de ComfyUI también funcionaban perfectamente en la 5090. El problema aparecía cuando empezaba el render y Qwen seguía cargado en Ollama. Descargaba Qwen a mano, ejecutaba el workflow, descargaba los modelos de ComfyUI y recuperaba Qwen para la siguiente respuesta.
Se suponía que tenía que estar hablando de iluminación y movimientos de cámara. Estaba haciendo limpieza manual de VRAM entre mensajes.
Después de suficientes errores de memoria, dejé de tratarlo como una molestia de configuración y metí el relevo dentro de OpenCode.

01 / Por qué se quedaba sin VRAM
Ollama y ComfyUI mantienen sus modelos cargados a propósito
Ninguna de las dos aplicaciones hacía nada mal. Ollama utiliza keep_alive porque descargar un modelo después de cada respuesta sería dolorosamente lento. ComfyUI también mantiene los modelos cargados porque volver a leer varios gigabytes de pesos para cada render suele ser una idea terrible.
Desde el punto de vista de OpenCode, mi workflow era secuencial:
Qwen → prompt → ComfyUI → recurso → Qwen → revisión
Las aplicaciones no conocían esa secuencia. Que Ollama devolviese una respuesta no significaba que Qwen hubiese abandonado la GPU, y terminar una tool call de ComfyUI tampoco significaba necesariamente que sus modelos hubiesen desaparecido.
Había una segunda trampa. Una herramienta MCP puede responder antes de que ComfyUI haya vaciado de verdad su cola. Si liberaba la GPU en el hook after normal de OpenCode, podía devolvérsela a Ollama mientras el render todavía estaba en marcha.
Entonces, ¿qué significa «terminado» aquí?
Para Ollama significa que el modelo ha desaparecido de /api/ps, no que una petición de descarga haya respondido con un 200. Para ComfyUI significa que /queue no tiene trabajo en ejecución ni pendiente y que /system_stats muestra suficiente memoria libre. Las APIs ya contaban la verdad; yo tenía que dejar de tratar una respuesta educada como si fuese una prueba.
Por eso el plugin espera a observar esos estados. No entrega la tarjeta hasta que el modelo anterior ha desaparecido de verdad y la memoria está disponible.
02 / Lo que construí
El plugin entrega la GPU en dos fases
Escribí opencode-comfy-vram-gate, un pequeño plugin de OpenCode sin dependencias de runtime. Envuelve las llamadas MCP pesadas a ComfyUI y entrega a cada una un lease exclusivo sobre la GPU.
Al entrar en un render, el plugin crea un lock de directorio atómico con heartbeat. Primero comprueba la cola de ComfyUI; si alguien ya está generando, se detiene ahí sin tocar Ollama. Si no, envía keep_alive: 0 para los modelos cargados en Ollama, consulta /api/ps hasta que desaparecen, llama al endpoint /free de ComfyUI y espera a que esté disponible la cantidad de VRAM configurada.
Solo entonces deja pasar la llamada MCP. El plugin fuerza wait: true y aumenta el timeout para que un vídeo largo no finja ser un pequeño trabajo en background.
Al volver, espera hasta que /queue queda realmente vacía, llama otra vez a /free, comprueba la memoria y libera el lease. Ollama no se reinicia a mano; Qwen vuelve a cargarse de forma normal cuando OpenCode pide la siguiente respuesta.
Ese es todo el truco. La VRAM nunca se comparte en paralelo. Qwen ocupa la silla, se levanta, ComfyUI se sienta, se levanta y Qwen vuelve.
Hay un coste, claro: cargar los pesos de un modelo lleva tiempo. Si ambos modelos caben a la vez, este plugin te ofrece una forma bastante elaborada de hacerlos más lentos. En mi máquina no cabían, así que ir más despacio era una mejora considerable frente a estrellarse.
03 / Recuperación
La primera versión podía bloquearse después de un render fallido
La primera versión podía entregar la GPU y recuperarla. Entonces falló una herramienta de ComfyUI y OpenCode no llamó al hook after normal.
El plugin tenía ahora dos malas opciones. Si borraba el lease inmediatamente, Ollama podía volver a cargarse mientras ComfyUI aún generaba. Si lo conservaba para siempre, el siguiente render de la misma sesión quedaba bloqueado contra su propio lock abandonado. También apareció una carrera más entretenida: Qwen podía regresar antes de que el evento de error llegase al plugin y ocupar otra vez la VRAM justo cuando empezaba la recuperación.
La versión 0.1.1 salió de perseguir esos fallos en vez de fingir que el ciclo de vida era más limpio. Los errores terminales de una herramienta ahora activan la recuperación inmediatamente. Los eventos de sesión inactiva, con error o eliminada cubren un hook perdido. Antes de otra llamada pesada, el plugin comprueba si esa sesión dejó un huérfano. La recuperación también descarga Ollama por segunda vez si el modelo consiguió colarse de nuevo.
El lease es un directorio atómico con información del propietario y un heartbeat. Otro proceso puede reclamarlo si el PID del propietario ha muerto en la misma máquina o si el heartbeat está obsoleto. Suena ligeramente dramático hasta que dos sesiones de OpenCode deciden que la misma GPU está libre. Entonces el lock es el componente más barato del ordenador.
El repositorio tiene 17 tests para estos casos con servidores simulados de Ollama y ComfyUI. Uno hace que la herramienta responda antes de terminar el render. Otro recarga Ollama durante la recuperación. Otro intenta robar el lease desde una segunda llamada. Ejecutar npm test recorre los caminos feos sin expulsar al Qwen real de tu workstation, que me parece la cortesía mínima exigible a un plugin de VRAM.
04 / Alcance
Gestiona VRAM, no el proceso creativo
No elige Krea, LTX, MiniMax ni ningún otro modelo de ComfyUI. No selecciona el workflow, escribe el prompt, escoge una LoRA, revisa el resultado ni decide si vale la pena iterar. Las instrucciones, skills y herramientas MCP de OpenCode ya tienen opiniones suficientes sobre todo eso.
El gate solo tiene una pregunta aburrida: ¿de quién es el turno?
La versión 0.1 es estrecha a propósito: Linux, OpenCode 1.x, Ollama, una tarjeta NVIDIA y un servidor ComfyUI local. No he validado Windows nativo y la memoria unificada de un Mac es otro problema. Prefiero escribir esa frase a poner «cross-platform» en el README y externalizar la sorpresa.
Tampoco utilizaría unloadPolicy: all en un servidor Ollama compartido, salvo que hacer desaparecer los modelos de todo el mundo forme parte del plan. El plugin permite definir una lista explícita. Ni Ollama ni ComfyUI ganan autenticación gracias a este código, así que ambos endpoints siguen perteneciendo a una red de confianza.
Y no, 17 tests contra servicios simulados no convierten esto en un laboratorio de compatibilidad de hardware. Me dan confianza en la máquina de estados y en los fallos que ya conozco. Más tarjetas, drivers e implementaciones MCP encontrarán otros nuevos. Para eso existen los números de versión.
Volver al experimento
Ahora puedo continuar la conversación después del render
El plugin nunca fue el experimento que quería hacer. Quería sentarme con Qwen, hablar de una imagen o una escena, dejar que generase algo y continuar la conversación a partir del resultado.
Antes del gate, cada llamada a ComfyUI podía terminar esa conversación con un OOM o una ronda de descargas manuales. Ahora Qwen escribe el prompt, abandona la GPU, ComfyUI genera, abandona la GPU y Qwen vuelve para revisar lo que ha creado.
Eso era lo que faltaba. Generar la primera imagen es una demo sencilla. Un director de arte o cine solo resulta útil si sigue ahí para hablar de la siguiente.
Sin descargas manuales. Sin interrumpir la conversación para mirar nvidia-smi.
Ver el trabajo