Conditioning en ComfyUI: Prompt, Referencia y Máscara — Qué Funciona de Verdad (Krea 2, RTX 3090)
“Solo hace falta un buen prompt” dejó de ser cierto hace tiempo. Los workflows modernos de ComfyUI combinan texto con imágenes de referencia, máscaras, poses y otras señales para controlar exactamente qué cambia y qué se mantiene en una generación. El problema es que no todas las técnicas de conditioning funcionan con todos los modelos, y la única forma de saberlo es probarlas. Así que probamos tres técnicas reales con Krea 2 Turbo en una RTX 3090 — prompt puro, imagen de referencia y máscara de inpainting — y una de las tres no hizo absolutamente nada.
De un vistazo: qué probamos y qué pasó
| Técnica | Nodo clave | Resultado |
|---|---|---|
| Prompt de texto | CLIPTextEncode | Funciona como referencia base |
| Imagen de referencia | ReferenceLatent | ❌ Sin efecto — imagen idéntica al baseline (diff=0) |
| Máscara / inpainting | VAEEncodeForInpaint + ImageToMask | ✅ Funcionó perfecto, cambio limpio solo en la zona enmascarada |
| Pose / ControlNet | — | No probado en esta sesión (ver limitaciones) |
Metodología: mismo prompt, mismo seed, un solo cambio por prueba
Igual que en nuestra comparativa de LoRAs de estilo de Krea 2, aislamos una sola variable por prueba:
- Mismo checkpoint: Krea 2 Turbo fp8_scaled, mismo text encoder (
qwen3vl_4b_fp8_scaled.safetensors) y VAE (qwen_image_vae.safetensors) en las tres pruebas. - Mismo seed:
918273645. - Mismos parámetros de KSampler: 8 pasos, cfg 1,
euler/simple. - Único cambio: la técnica de conditioning aplicada sobre el mismo prompt base.
Prueba 1: prompt de texto puro (referencia)
Prompt: “cinematic photograph of a red vintage bicycle leaning against a brick wall covered in ivy, golden hour light, shallow depth of field, sharp focus, 35mm photography, high detail”.
Resultado con solo CLIPTextEncode, sin ninguna otra conditioning. Este es el punto de partida contra el que comparamos las otras dos técnicas.
Sin sorpresas: el modelo interpreta el prompt razonablemente bien. Esta imagen es la referencia contra la que comparamos la prueba 2.
Prueba 2: imagen de referencia con ReferenceLatent — el hallazgo negativo
ReferenceLatent es un nodo que permite inyectar una imagen de referencia (codificada a latente) dentro del conditioning, para que el modelo se apoye en ella al generar. En teoría, debería influir en el resultado — estilo, composición o contenido, dependiendo de cómo el modelo haya sido entrenado para usar esa señal.
Cogimos una imagen de referencia completamente distinta al prompt (la escena de GPU con ARGB morado/cian del artículo de transferencia de cámara), la conectamos vía VAEEncode → ReferenceLatent, y generamos con el mismo prompt de la bicicleta y el mismo seed.
La imagen de referencia conectada vía ReferenceLatent — completamente distinta al prompt de la bicicleta, para que cualquier influencia real fuera fácil de detectar a simple vista.
Resultado: la imagen generada fue pixel a pixel idéntica a la de la prueba 1. Lo comprobamos con un diff numérico directo entre ambos ficheros PNG:
diff = abs(imagen_prompt_only - imagen_con_referencia)
# max diff: 0, mean diff: 0.0, identical: True
Cero diferencia. El nodo se ejecutó sin ningún error, pero Krea 2 Turbo no llegó a usar la latente de referencia en ningún momento.
Por qué, exactamente: revisamos el código fuente de ComfyUI (comfy/model_base.py) para no quedarnos en la especulación. La clase Krea2 implementa su propio método extra_conds(), y ese método solo lee la clave cross_attn del conditioning — nunca llama a kwargs.get('reference_latents', ...). En cambio, la clase Flux (de la que Krea 2 no hereda, aunque comparte la arquitectura SingleStreamDiT y su model_type es ModelType.FLUX) sí lee esa clave y la convierte en una señal real (ref_latents) que llega a la red. El nodo ReferenceLatent escribe correctamente la clave reference_latents en el conditioning, pero la implementación concreta de Krea 2 nunca la recoge — por eso el diff da exactamente cero, no una diferencia pequeña. No es que “el modelo aprenda a ignorarla”; es que el código nunca la mira.
⚠️ Lo que esto significa: que un nodo de conditioning exista y se conecte sin error no garantiza que el modelo lo use — depende de si la clase Python de ese modelo concreto implementa la lectura de esa clave. Si conectas un nodo de conditioning y el resultado no cambia nada, antes de asumir que tu grafo está mal, comprueba con un diff de píxeles si realmente no hay ningún efecto — un cambio muy sutil puede pasar desapercibido a simple vista, pero un diff en cero es inequívoco.
👉 Lo que aprendimos: ejecutar sin error no es lo mismo que funcionar. Verificar con datos (aquí, un diff de píxeles) es la única forma de estar seguro de que una conditioning está teniendo efecto real.
Prueba 3: máscara e inpainting — esta sí funcionó
Para la tercera prueba reutilizamos la imagen de la máquina de escribir del artículo de bf16 vs GGUF como base, y construimos una máscara rectangular sobre la zona de la ventana (blanco = zona a regenerar, negro = mantener intacto).
Grafo: LoadImage (imagen base) + LoadImage (máscara) → ImageToMask (canal rojo) → VAEEncodeForInpaint (con la imagen, la máscara y grow_mask_by: 6) → KSampler con denoise 0.85 sobre esa latente → nuevo prompt describiendo un cielo nocturno estrellado con skyline en vez de la lluvia original.
Izquierda: imagen original (ventana con lluvia). Derecha: tras el inpainting, solo la ventana cambió — máquina de escribir, mesa y teclas permanecen visualmente idénticas.
Resultado: limpio. La ventana pasó de un día lluvioso a un cielo nocturno con rascacielos iluminados, y el resto de la composición — la máquina de escribir, la mesa de madera, el papel cargado — se mantuvo sin cambios perceptibles. Sin costuras visibles en el borde de la máscara.
👉 Lo que aprendimos: a diferencia de ReferenceLatent, el inpainting por máscara es una técnica robusta que funcionó a la primera con un checkpoint estándar, sin necesitar un modelo especializado en edición.
Por qué una funcionó y la otra no
La diferencia no es casualidad: inpainting por máscara actúa de forma mecánica sobre el espacio latente (la máscara le dice a KSampler qué región puede modificar; grow_mask_by simplemente dilata unos píxeles ese límite para evitar bordes duros, no añade ruido ni altera el resto de la imagen más allá del propio round-trip de codificación/decodificación VAE que sufre toda la imagen), y funciona igual con cualquier checkpoint compatible con inpainting, sin que el modelo necesite “entender” nada especial. ReferenceLatent, en cambio, depende de que la clase de ese modelo concreto en el código de ComfyUI implemente la lectura de esa clave de conditioning — como vimos arriba, Krea 2 no lo hace. Lo primero es una propiedad del proceso de sampling. Lo segundo es una propiedad del código de cada modelo, presente en unos y ausente en otros.
Limitaciones de esta prueba
- No probamos ControlNet de pose/canny/depth en esta sesión. Requiere instalar el paquete de nodos
comfyui_controlnet_aux(con su propio modelo preprocesador, ej. DWPose) más un checkpoint de ControlNet — no los teníamos instalados y decidimos no improvisar esa parte solo para completar la lista. Queda como prueba de seguimiento. - No probamos
ReferenceLatentcon un modelo entrenado para edición (Flux Kontext, Qwen-Image-Edit) — no los teníamos descargados en el momento de esta prueba. No podemos confirmar con datos propios que esa conditioning funcione en algún modelo; solo confirmamos que en Krea 2 Turbo no tiene efecto. - Probamos inpainting con una máscara rectangular simple. No probamos máscaras con formas irregulares ni
grow_mask_byen valores distintos de 6.
Preguntas frecuentes
¿Por qué ReferenceLatent no cambió nada en mi generación con Krea 2?
Porque la clase Krea2 en el código de ComfyUI nunca lee la clave reference_latents del conditioning — solo procesa cross_attn. La clase Flux, de la que Krea 2 no hereda pese a compartir arquitectura, sí la lee. El nodo ReferenceLatent escribe la clave correctamente, pero la implementación de Krea 2 nunca la recoge. Confirmamos esto generando la misma imagen con y sin ReferenceLatent, mismo prompt y seed: el resultado fue pixel a pixel idéntico.
¿Qué modelos sí soportan ReferenceLatent de verdad en ComfyUI?
Los que su clase de modelo en comfy/model_base.py implementa la lectura de la clave reference_latents dentro de extra_conds() — confirmamos leyendo el código que la clase base Flux lo hace. No generamos con un modelo de este tipo en esta prueba concreta (no lo teníamos descargado), así que no tenemos una imagen propia que lo demuestre visualmente; lo que sí confirmamos, con el código y con el diff de píxeles, es que Krea 2 Turbo no lee esa clave.
¿Cómo edito solo una parte de una imagen en ComfyUI sin tocar el resto?
Con inpainting por máscara: carga la imagen base con LoadImage, crea o carga una máscara (blanco = zona a regenerar, negro = zona a mantener) con ImageToMask, pásala junto a la imagen por VAEEncodeForInpaint, y usa esa latente como entrada de KSampler con un denoise entre 0.7 y 0.9. En nuestra prueba, esto cambió solo la ventana de una escena de escritorio, dejando la máquina de escribir en primer plano sin ninguna alteración visible.
¿Qué denoise se usa para inpainting en ComfyUI?
Usamos 0.85 en esta prueba. Denoise 1.0 regenera la zona enmascarada desde ruido puro, ignorando el contenido original. Valores más bajos (0.5-0.7) conservan más estructura original, útil para retoques sutiles.
Sigue leyendo
Si quieres ver otra forma de conditioning por referencia que sí funciona de verdad (porque actúa sobre el vídeo, no dentro del propio modelo), nuestra transferencia de movimiento de cámara con IC-LoRA usa un vídeo de referencia externo para guiar el movimiento sin depender de que el checkpoint “entienda” la referencia internamente. Y si te interesa la cuantización del modelo que usamos aquí, la comparativa bf16 vs GGUF mide VRAM y velocidad reales sobre Z-Image Turbo.
Conclusión: prueba antes de confiar en un nodo
🏆 Nuestra recomendación
Si necesitas editar una zona concreta sin tocar el resto → inpainting por máscara funciona de forma fiable con cualquier checkpoint estándar compatible, sin necesitar un modelo especializado. Si quieres condicionar por imagen de referencia → verifica primero si tu checkpoint fue entrenado para ello (busca si es un modelo “edit” o “Kontext”); con un checkpoint de generación estándar como Krea 2 Turbo, es posible que el nodo se ejecute sin errores pero no haga absolutamente nada.
La lección de fondo: en ComfyUI, un grafo que se ejecuta sin errores no es garantía de que la conditioning esté funcionando. Cuando el resultado visual parezca sospechosamente similar al baseline, un diff de píxeles tarda segundos y te da una respuesta inequívoca.
Fuentes
Siguientes pasos en ComfyUI
Primeros pasos
Preguntas frecuentes
- ¿Por qué ReferenceLatent no cambió nada en mi generación con Krea 2?
- Porque la clase Krea2 en el código de ComfyUI (comfy/model_base.py) nunca lee la clave reference_latents del conditioning -- revisamos el código fuente y su método extra_conds() solo procesa cross_attn, a diferencia de la clase Flux (de la que Krea 2 no hereda, aunque comparte arquitectura), que sí la lee y la convierte en una señal real para la red. El nodo ReferenceLatent escribe la clave correctamente, pero la implementación de Krea 2 nunca la recoge: no llega a influir en la generación. Confirmamos el efecto (o su ausencia) generando la misma imagen con y sin ReferenceLatent, mismo prompt y seed: el resultado fue pixel a pixel idéntico (diff de píxeles = 0).
- ¿Qué modelos sí soportan ReferenceLatent de verdad en ComfyUI?
- Los que su clase de modelo en comfy/model_base.py implementa la lectura de la clave reference_latents dentro de extra_conds() -- la clase base Flux es un ejemplo confirmado leyendo el propio código fuente. No probamos generar con un modelo de este tipo en esta prueba concreta (no lo teníamos descargado en el momento de escribir esto), así que no podemos confirmar con datos propios de generación real que funcione visualmente; lo que sí confirmamos, con el propio código y con el diff de píxeles, es que Krea 2 Turbo no lee esa clave y por tanto no responde a esta conditioning.
- ¿Cómo edito solo una parte de una imagen en ComfyUI sin tocar el resto?
- Con inpainting por máscara: carga la imagen base con LoadImage, crea o carga una máscara (blanco = zona a regenerar, negro = zona a mantener) con ImageToMask, pásala junto a la imagen por VAEEncodeForInpaint, y usa esa latente como entrada de KSampler con un denoise entre 0.7 y 0.9 (no 1.0, o perderías también el contexto de la zona no enmascarada). En nuestra prueba, esto cambió solo la ventana de una escena de escritorio, dejando la máquina de escribir en primer plano sin ninguna alteración visible.
- ¿Qué denoise se usa para inpainting en ComfyUI?
- Usamos 0.85 en esta prueba. Denoise 1.0 regenera la zona enmascarada desde ruido puro, ignorando por completo el contenido original de esa zona (útil si quieres un cambio total). Valores más bajos (0.5-0.7) conservan más de la estructura original de la zona enmascarada, útil para retoques sutiles en vez de reemplazos completos.