Executive Summary

la VRAM delle mie schede video non basta per modelli di testo, figuriamoci per modelli di generazione immagini…
Al momento utilizzo un modello linguistico abbastanza capace (come Qwen 35B MoE) e quindi caricare contemporaneamente i pesi enormi di un modello di diffusione (come Chroma1, FLUX o Stable Diffusion) porta a un crash immediato per CUDA Out of Memory (OOM).

A questo si aggiunge un limite software: le interfacce più diffuse, come Open WebUI, permettono di collegare ComfyUI ma vincolano l’utente a un solo e unico workflow statico. Se vuoi una foto realistica, un’illustrazione anime o una pixel art, devi riconfigurare a mano il sistema ogni volta.

In questa guida spiego l’architettura definitiva che ho adottato per risolvere entrambi i problemi in modo elegante, dopo lunche discussioni con un amico, con Gemini e con Claude Opus:

  1. Zero crash OOM: alternanza fluida ed esclusiva della VRAM tra LLM e ComfyUI grazie alle API native del router di llama-server (unload in 0.5s, reload in ~10s).
  2. Stili infiniti e prompt engineering automatico: un Tool Python nativo di Open WebUI che permette all’LLM di comprendere l’intento dell’utente, arricchire il prompt in inglese e indirizzare la richiesta al workflow grafico appropriato da un catalogo JSON, a costo zero di risorse.

1. La Sfida: Due Giganti su Hardware Datato

Il Vincolo Hardware (Esclusività della VRAM)

Nel mio setup ho una configurazione dual-GPU NVIDIA Pascal con 19 GB totali di VRAM a disposizione:

  • CUDA0 (GTX 1080 Ti - 11 GB): ospita i layer MoE 0–24 e la hot cache degli esperti per l’LLM, oltre alla sessione desktop.
  • CUDA1 (GTX 1070 - 8 GB): ospita i layer MoE 25–39 e la restante cache per l’LLM.

Quando avvio il modello di chat (un MoE Q4_K_M da 35B con patch personalizzata per Pascal sm_61), questo occupa circa 17 GB di VRAM totali.
Quando decido di generare un’immagine con ComfyUI, la pipeline di diffusione richiede tra gli 8 e i 14 GB.

Poiché entrambi i carichi hanno bisogno di entrambe le schede, una suddivisione statica (una GPU per il testo e una per le immagini) è impraticabile. L’unica via percorribile senza spendere migliaia di euro in schede enterprise è il Time-Sharing (Swap completo): quando serve l’LLM, le GPU appartengono all’LLM; quando si genera un’immagine, l’LLM deve cedere ordinatamente tutta la VRAM a ComfyUI.

Il Vincolo Software di Open WebUI

Open WebUI è un’interfaccia eccellente, ma nelle impostazioni permette di registrare un solo file JSON di workflow ComfyUI.
Se configuri il workflow per la fotografia realistica, ogni richiesta produrrà foto, anche quando chiedi un disegno anime, un acquerello o un logo vettoriale.


2. L’Architettura: L’Approccio con Tool Nativo

Invece di costruire complessi reverse-proxy di rete intermedi (soggetti a timeout e difficoltà con i WebSocket), l’intera orchestrazione vive all’interno di un Tool Python nativo di Open WebUI (openwebui_tool_comfy_router.py):

sequenceDiagram
    autonumber
    participant U as Utente in Chat
    participant OW as Open WebUI
    participant T as Tool Python
    participant L as llama-server (:8001)
    participant C as ComfyUI (:8188)

    U->>OW: "Genera una volpe rossa nella neve, 512x512"
    OW->>L: Invio messaggio di chat
    L-->>OW: Chiamata a funzione: generate_image(prompt="...", style="chroma_flash_v1")
    OW->>T: Esecuzione del Tool (la chat si mette in pausa)
    T->>T: Lock esclusivo su /tmp/comfy_router.lock
    T->>L: POST /models/unload (libera 17 GB di VRAM in 0.5s)
    T->>T: Misura VRAM libera con nvidia-smi
    T->>C: POST /prompt (workflow mutato con prompt e seed)
    C-->>T: prompt_id confermato (< 100ms)
    loop Polling asincrono su /history/{id}
        T->>C: Verifica completamento rendering
    end
    T->>C: GET /view (preleva immagine renderizzata)
    T->>OW: Consegna immagine alla chat (evento files / markdown)
    T->>C: POST /free (scarica modelli di diffusione)
    T->>T: Verifica rilascio VRAM
    T->>L: POST /models/load (ricarica Qwen in 10s)
    T->>T: Rilascio del lock
    T-->>OW: Conferma completamento
    OW-->>U: Immagine visibile in chat

Perché questa soluzione è geniale:

  1. Serializzazione Naturale: Quando Open WebUI invoca un Tool, il thread di conversazione si mette automaticamente in attesa. C’è una garanzia matematica che l’utente non potrà mandare altri messaggi nella stessa chat finché la VRAM non è stata restituita all’LLM.
  2. Qwen fa da Prompt Engineer a costo zero: Qwen legge la docstring del Tool, traduce la richiesta dell’utente dall’italiano all’inglese e arricchisce autonomamente il prompt con luci, atmosfera e dettagli di composizione per massimizzare la resa del modello di diffusione.
  3. Nessun riavvio di processi: llama-server gira in router mode (--models-preset llama-models.ini --models-max 1). Quando riceve /models/unload, termina il processo figlio in 0.5 secondi azzerando la VRAM; quando riceve /models/load, lo ricarica in 10 secondi.

3. Il Catalogo dei Workflow (catalog.json)

Tutti i workflow esportati da ComfyUI (in formato Save (API Format)) vengono raccolti in una directory dedicata assieme a un file catalog.json con mappature uniformi [node_id, input_name]:

{
  "version": 2,
  "default": "chroma_flash_v1",
  "workflows": [
    {
      "id": "chroma_flash_v1",
      "file": "chroma-flash-unfiltered-v1-workflow.json",
      "description": "General purpose and photorealistic images (Chroma1-HD Flash, 8 steps)",
      "defaults": { "width": 1024, "height": 1024 },
      "nodes_mapping": {
        "positive_prompt": ["748", "text"],
        "negative_prompt": ["749", "text"],
        "seed": ["718", "noise_seed"],
        "width": ["737", "width"],
        "height": ["737", "height"],
        "steps": ["751", "steps"]
      }
    }
  ]
}

Quando aggiungo un nuovo workflow (es. uno stile Anime o Ghibli con i suoi checkpoint e LoRA dedicati):

  1. Copio il file .json nella cartella workflows/.
  2. Aggiungo la voce in catalog.json.
  3. Aggiungo il nome dello stile nella docstring del Tool.

Da quel momento in poi, se chiedo un ritratto fotografico Qwen sceglie chroma_flash_v1, se chiedo Mazinga o un castello volante sceglie lo stile anime!


4. Prestazioni Misurate sul Silicio

Ecco i tempi e le occupazioni reali registrati sulle due schede:

FaseCUDA0 (GTX 1080 Ti - 11 GB)CUDA1 (GTX 1070 - 8 GB)Durata
LLM a riposo (Qwen3.6-35B-vis)10.075 MiB7.352 MiB—
Dopo /models/unload1.284 MiB (solo desktop/Xorg)142 MiB (totalmente libera)0.5 s
Rendering ComfyUIModelli caricati in VRAMModelli caricati in VRAM~60–120 s
Dopo /free ComfyUIRitorno a baselineRitorno a baseline~2 s
Dopo /models/load (Reload LLM)10.075 MiB7.352 MiB10.2 s

5. Le Regole d’Oro per Evitare OOM

Per rendere il sistema blindato:

  1. Disattivare la generazione nativa in Open WebUI (Amministrazione → Impostazioni → Immagini).
  2. Disattivare “Autocomplete Generation” in Open WebUI (Impostazioni → Interfaccia), evitando che l’LLM venga interrogato mentre si digita durante un rendering.
  3. Creare un modello in Workspace: impostare Function Calling su Native e abilitare lo strumento in modo permanente.
  4. Non aprire seconde schede per chattare mentre ComfyUI disegna: con una sola VRAM per due giganti, la disciplina di utilizzo mono-utente garantisce stabilità granitica.

L’hardware datato non è affatto da buttare: con un’architettura software ben congegnata, due schede Pascal del 2016 possono offrire un’esperienza AI moderna, ricca e completamente integrata.