Diario
Secciones
Ajustes de lectura
Ninguna voz para este idioma en este navegador.
Más voces
Código y términos técnicos en inglés
Desactivado: la voz de la página lo lee todo, sin pausa entre dos voces.
Ninguna voz para este idioma en este navegador.
Más voces
Más voces: Microsoft Edge ofrece voces naturales en línea, y Windows (Configuración › Hora e idioma › Voz), macOS y Android instalan otras.
Progreso
Sección titulada «Progreso»- ComfyUI v0.36.0 (commit
ee71d5c), frontend 1.52.7, SDXL base 1.0 fijado por el hash del archivo -
check.sh: comprobaciones de workflows sin conexión, conversión del formato de la interfaz al de la API comparada con la exportación del frontend, los clientes C# y Java contra ComfyUI en la CPU - CI en Ubuntu, Windows y macOS, sin GPU ni modelo
- Lección 1: el grafo de nodos, la instalación y una primera imagen
- Lección 2: la difusión, y qué hace reproducible una imagen
- Lección 3: los workflows en JSON
- Lección 4: la API HTTP y WebSocket desde C# y Java
- Traducciones al francés y al español de las lecciones 1 a 4
- Lección 5: img2img, inpainting y outpainting
- Lección 6: ControlNet, bordes y profundidad
- Lección 7: LoRA
- Lección 8: modelos recientes, licencias, cuantización y VRAM
- Traducciones al francés y al español de las lecciones 5 a 8
- Lección 9: escalado, texturas sin costuras y HDR
- Lección 10: vídeo
- Lección 11: los nodos personalizados y su seguridad
- Lección 12: ComfyUI en producción
- Lección 15: audio, leído en el código fuente
- Una sección «tu turno» en cada lección escrita, y una galería de las treinta imágenes
- Lección 13: texturas para este sitio y para GuitarAlchemist
- Lección 14: el laboratorio Guitar Alchemist
Lo que este curso encontró en ComfyUI v0.36.0, en su documentación y en los archivos que carga, ejecutándolos en lugar de leer lo que se dice de ellos. Los enlaces de código apuntan a ee71d5c, el commit que el curso fija. Ninguno de estos puntos es todavía un informe de error: es lo que mostraron las mediciones.
| Esperado | Lo que pasa | Dónde | Medición | Estado |
|---|---|---|---|---|
| Una carpeta base nueva arranca el servidor | El arranque se detiene con FileNotFoundError: el servidor lista custom_nodes en la carpeta nueva antes de que nada la cree |
main.py:198-201 |
Reproducido en cada carpeta base nueva | Reproducido; server.sh crea primero la carpeta vacía |
--base-directory no toca la instalación |
Migró la base user/comfyui.db heredada de la instalación, dejó un .bak al lado y copió la base en la carpeta de prueba |
--base-directory sin --database-url |
El original se restauró desde la copia; ambos SHA-256 coincidían | Reproducido; se evita con --database-url sqlite:///:memory: (Verificación de ComfyUI para la escena orbital) |
El tutorial de inicio describe EmptyLatentImage |
Dice que el nodo crea un latente de ruido. El nodo crea ceros, y es KSampler quien hace el ruido |
nodes.py, frente al tutorial de texto a imagen |
Leído en el código del nodo en el commit fijado | Reproducido. La documentación es falsa, el comportamiento es correcto |
| El mismo grafo y la misma semilla dan los mismos píxeles | La imagen cambia cuando la indicación negativa se vuelve a codificar con la UNet ya cargada | nodes.py, CLIPTextEncode y KSampler |
698e7867… en un servidor recién arrancado, 5374ac40… en caliente: 0,92 niveles de diferencia media, 2,63 % de los píxeles por encima de 8. --deterministic no cambió nada |
Reproducido. La operación responsable sigue sin identificarse (Una semilla, dos imágenes) |
| Una imagen dentro de un lote es igual a esa semilla renderizada sola | La primera imagen del lote difiere del render suelto | nodes.py, EmptyLatentImage y KSampler |
0,74 niveles de diferencia media | Reproducido |
| La validación enumera todos los problemas de un prompt | Un enlace a un nodo que no existe lanza un KeyError fuera del bloque try, y el servidor responde con una traza que lleva su ruta de instalación |
execution.py:932-933 |
El servidor informó de 2 errores donde la comprobación sin conexión encontró 5; uno estaba archivado bajo el nodo 3 con el nombre de entrada del nodo 8, samples |
Reproducido |
| El PNG registra lo que el cliente envió | La validación convierte cada entrada FLOAT con float() y reescribe el valor en el prompt que se guarda |
execution.py:995-997 |
El frontend envió 7 para cfg; el prompt escrito en el PNG contiene "cfg": 7.0 |
Reproducido. Sin efecto en la imagen, y suficiente para romper una comparación byte a byte de dos prompts |
| Los nodos de salida se ejecutan en un orden estable | Las salidas validadas se guardan en un conjunto de Python, cuyo orden de recorrido sigue al hash de cadenas aleatorizado | execution.py:1186-1282 |
check.sh falló en su segunda ejecución: los dos SaveImage se ejecutaron en el otro orden |
Reproducido; resuelto en el curso con PYTHONHASHSEED=0 |
POST /upload/image tiene un comportamiento documentado |
Bytes idénticos conservan el nombre existente; bytes distintos reciben name (1).png |
server.py |
Ambos casos observados; ninguno está documentado | Reproducido. La documentación calla |
La página de SetUnionControlNetType enumera los tipos que el nodo tiene |
La página enumera 13 tipos, el nodo tiene 8 | nodes_controlnet.py, frente a su documentación |
Los 8 nombres se leyeron en el código del nodo | Reproducido. Tomar los nombres del código |
| Los metadatos de un LoRA describen sus tensores | Los metadatos del LCM-LoRA y su título dicen rango 1 y alfa 1 | sdxl_LCM_lora_rank1.safetensors |
Sus tensores dan rango 64 y alfa 8 | Reproducido. Los metadatos del archivo son falsos; leer los tensores (Modelos para las lecciones 5 a 8) |
| El nombre de un archivo cuantizado dice lo que contiene | qwen_3_4b_fp8_mixed contiene 12 capas nvfp4, y qwen_3_4b_fp4_mixed contiene 58 capas fp8 |
Los codificadores de texto Z-Image-Turbo de Comfy-Org | Contadas en las cabeceras | Reproducido. «mixed» es el aviso: leer la cabecera |
nvidia-smi muestra lo que un modelo necesita |
La VRAM dinámica toma lo que está libre, así que la cifra no dice nada del modelo | --disable-dynamic-vram y las líneas de puesta en escena del registro |
De 12,5 a 15,3 GB en uso en todas las configuraciones, desde 19,4 GB de pesos bf16 hasta nvfp4 | Reproducido. Los tamaños puestos en escena en el registro son las cifras útiles |
| La documentación de la API enumera las rutas que sirve el servidor | Faltan las rutas /api/jobs, el prefijo /api en todas las rutas y los mensajes binarios de vista previa |
server.py |
Leído en la tabla de rutas en el commit fijado | Reproducido. La documentación está incompleta |
execution_success significa que el render puede leerse en /history |
Se envía antes de que se escriba el historial. El mismo prompt_id enviado dos veces se ejecuta dos veces y sobrescribe su entrada, y una reconexión no reproduce nada |
execution.py, server.py |
Cada caso se provocó en un servidor de CPU y se registraron sus respuestas | Reproducido; tratado en el worker del curso (ComfyUI en producción) |
LoadImage enumera los archivos que el servidor sabe leer |
Enumera aquellos cuyo tipo MIME empieza por image, y esa tabla pertenece a la máquina, no a ComfyUI |
folder_paths.py |
.exr no tiene ningún tipo MIME en esta máquina Windows ni en el ejecutor macos-latest, y vale image/aces en ubuntu-latest, todas con Python 3.13 |
Reproducido en tres máquinas por data/mime-info.py. Un EXR escrito por SaveImageAdvanced no puede tomarse de la lista en dos de las tres |
| La licencia de un reempaquetado cubre los archivos que entrega | Comfy-Org/TRELLIS.2 está etiquetado MIT y entrega clip_vision/dino_v3_vit_l.safetensors, que está bajo la licencia DINOv3, sin una copia de esa licencia |
El árbol de archivos del repositorio | Leído en la ficha del modelo y en el árbol | Reproducido. Un reempaquetado no cambia la licencia de un archivo. Esto no es asesoramiento legal |
| La licencia de un modelo rige lo que se hace con los pesos | La licencia Hunyuan 3D 2.0 restringe además dónde pueden mostrarse sus salidas: cláusula 5.c, Territorio que excluye la Unión Europea, el Reino Unido y Corea del Sur | Cláusulas 1.l y 5.c, leídas en el commit 9cd649ba |
Dos renders ya se habían publicado en este sitio, y fueron retirados | Reproducido. El curso no publica ninguna salida de Hunyuan3D (Un modelo 3D publicado antes de leer su licencia) |
| Un nodo que prepara un latente de inpainting deja los píxeles en paz | VAEEncodeForInpaint lleva cada píxel enmascarado al gris medio antes de codificar, algo que el tutorial de inpainting no menciona |
nodes.py:443-447 |
Con denoise 0,5 la zona enmascarada volvía como una elipse gris uniforme; denoise 1 con un borde suave de 24 píxeles, o el UNet de inpainting, da un resultado utilizable |
Reproducido. El nodo está hecho para denoise 1 |
| La ficha de un LoRA describe el archivo que entrega | Pixel Art XL se publica bajo CreativeML Open RAIL-M, y no bajo la RAIL++-M del SDXL que extiende, y su ficha dice que no hace falta palabra desencadenante mientras la cabecera del archivo fija instance_prompt: pixel art |
nerijs/pixel-art-xl en 8bf4a4d9 |
Licencia leída en la ficha en el momento de la descarga, instance_prompt leído en la cabecera safetensors |
Reproducido. Leer la cabecera, no la ficha |
| Algo inspecciona un paquete de nodos personalizados antes de ejecutarlo | Nada lo hace. Cada paquete se importa con exec_module antes de leer sus NODE_CLASS_MAPPINGS, un prestartup_script.py se ejecuta aún antes, y el JavaScript del WEB_DIRECTORY de un paquete se ejecuta en el navegador |
nodes.py:2266 |
comfyui_manager 4.2.2 filtra las instalaciones por nivel de seguridad, escucha y dos indicadores, y compara con nombres de paquetes conocidos como maliciosos al arrancar; ningún paso lee el código de un paquete. Los 42 archivos de su rueda de PyPI eran idénticos a los del tag 4.2.2, commit bd4ede22 |
Reproducido. Instalar un paquete es ejecutar su código |
| Cargar un checkpoint no ejecuta código | Un pickle cuya carga llama a print se ejecutó con pickle.loads y con torch.load(weights_only=False); torch.load(weights_only=True) lo rechazó en PyTorch 2.13 |
comfyui_controlnet_aux, anclado al 16 de septiembre de 2026: un paquete, no el núcleo de ComfyUI |
72 llamadas a torch.load sin weights_only, cuyo valor por defecto solo es seguro a partir de PyTorch 2.6 |
Reproducido |
| Instalar un paquete es el único paso que toca la red | ComfyUI-Impact-Pack instala onnxruntime con pip la primera vez que se ejecuta un detector ONNX, y su install.py descarga un .pth de SAM; rgthree-comfy envía el SHA-256 de un archivo de modelo a Civitai cuando la interfaz pide la información de ese modelo |
ComfyUI-Impact-Pack/install.py y rgthree-comfy, anclados al 16 de septiembre de 2026 |
Auditoría de seis paquetes: ComfyUI-GGUF, comfyui_controlnet_aux, ComfyUI-Impact-Pack, ComfyUI-VideoHelperSuite, rgthree-comfy, ComfyUI_essentials | Reproducido. Nada de esto sugiere mala intención; es lo que un paquete puede hacer sin decirlo |
| La condición de parada del cliente de ejemplo dice que el render salió bien | websockets_api_example.py sale con un mensaje executing cuyo nodo vale null, lo que solo dice que ya no se ejecuta nada, no si el render tuvo éxito, falló o fue interrumpido |
script_examples/websockets_api_example.py:37-40 |
Ese mensaje se envía después de escribir el historial, a diferencia de execution_success, así que releer los resultados después es seguro; los clientes del curso se detienen con execution_success, execution_error o execution_interrupted |
No es un defecto, y es demasiado tosco para un worker: un render fallido debe distinguirse de uno terminado |
| Un render totalmente en caché solo informa de lo que hizo | Envía executed por cada nodo de salida, con los nombres de archivo del primer render, y no escribe ningún archivo |
comfy_execution/asset_enrichment.py:102-115 |
Con un prompt idéntico reencolado, el acierto de caché en execution.py:446-451 llama a emit_cached_output, que envía el mensaje con la salida cacheada |
Reproducido. Un cliente que cuente los mensajes executed, o que se fíe de sus nombres de archivo, creerá que se escribieron archivos |
/object_info enumera las entradas de un nodo bajo required y optional |
Una entrada COMFY_DYNAMICCOMBO_V3 lleva sus hijos dentro de sus opciones, así que el format.codec de SaveVideo no está en ninguna de las dos tablas |
/object_info para SaveVideo, v0.36.0 |
El verificador del propio curso informó de «no hay entrada format.codec» en tres flujos, y se equivocaba |
No es un defecto: la forma es deliberada y la documentación no dice nada. El fallo era nuestro (Un flujo verificado antes de la GPU) |
QUANTIZATION.md señala el código que describe |
Da MixedPrecisionOps como «lines 542-648 in comfy/ops.py»; la clase está en la línea 1347, y está anidada dentro de la fábrica mixed_precision_ops() en lugar de ser una clase de módulo |
QUANTIZATION.md:83 frente a comfy/ops.py:1346-1347 |
La línea 542 contiene self.weight_comfy_model_dtype = dtype, sin relación |
Reproducido en el commit anclado (Cuatro hallazgos que nunca salieron del informe) |
| La página del formato API describe las claves de nodo del formato UI | Su tabla da «Node titles or labels» para el formato de guardado frente a «Numeric node IDs» para el formato API; ambos identifican los nodos por id | la página del formato API de los flujos, leída el 22 de septiembre de 2026 | 01-txt2img.ui.json contiene nodes como lista de 7 objetos, cada uno con un id numérico, ninguno con title, y links remite a esos números |
Reproducido. La diferencia es un array frente a un objeto indexado por el id, no títulos frente a ids (Cuatro hallazgos que nunca salieron del informe) |
--lowvram mantiene menos modelo residente que por defecto |
Fija VRAMState.LOW_VRAM, pero el presupuesto de carga parcial toma la misma rama para LOW_VRAM y NORMAL_VRAM y calcula la misma cantidad a partir de la memoria libre |
comfy/model_management.py:1007-1011 |
Los renders del 16 de septiembre no midieron ninguna diferencia entre el indicador y el valor por defecto; --novram sí difiere, fijando el presupuesto en 0,1 |
Reproducido (Cuatro hallazgos que nunca salieron del informe) |
| Una CLI envía sus comandos adonde dice la línea de comandos | comfy-cli detecta el destino por su cuenta: cloud si hay alguna credencial de cloud configurada —clave de API o sesión OAuth activa—, y si no, local. Iniciar sesión una vez cambia el destino de los comandos siguientes | comfy_cli/where.py, leído el 22 de septiembre de 2026 en main; comfy-cli no está anclado por este curso |
La precedencia está escrita en el docstring del propio módulo, regla 5 | Reproducido. Conviene saberlo antes de que un script salga fuera de localhost (Cuatro hallazgos que nunca salieron del informe) |
Experimentos
Sección titulada «Experimentos»Una fila por experimento medido. La columna de hipótesis dice qué se predijo antes de que el número existiera; donde el curso midió primero y entendió después, lo dice, en lugar de inventar una predicción que ya conocería la respuesta.
| Pregunta | Hipótesis | Resultado medido | Veredicto | Pruebas |
|---|---|---|---|---|
¿Un denoise menor que 1 acorta el render? |
No escrita de antemano. Lo que se ponía a prueba es la lectura que invita la palabra: menos pasos para menos eliminación de ruido | Los 25 pasos se ejecutaron con todos los valores de 0,3 a 0,9, en 4,6 a 5,1 s | Refutada: denoise arranca el muestreador a mitad de un calendario de la misma longitud |
Img2img, inpainting, ControlNet y LoRA, 05-img2img.api.json |
| ¿Las dos imágenes de la semilla 42 vienen de la puesta en escena de la VRAM dinámica? | Escrita antes del render: desactivar la VRAM dinámica debería devolver los píxeles del arranque en frío | --disable-dynamic-vram dio la huella en caliente 5374ac40… ya en la primera ejecución, y los mismos píxeles que con VRAM dinámica, en 78,87 s frente a 63,93 |
No concluyente: la hipótesis falló y la operación responsable sigue siendo desconocida | Una semilla, dos imágenes, Modelos recientes y cuantización |
¿El modelo de inpainting de SD-XL exige un strength menor que 1,0, como dice su ficha? |
La instrucción de la ficha hacía las veces de predicción | 1,0 y 0,99 difieren en el 0,01 % de los píxeles en más de 8 niveles | Refutada en esta imagen; una imagen no es una respuesta general | Img2img, inpainting, ControlNet y LoRA, 05-inpaint-model.api.json |
| ¿Qué cuesta la cuantización en imagen y qué aporta en velocidad? | No escrita de antemano | int8 con el codificador fp8: del 9 al 15 % de los píxeles difieren de bf16 en más de 8, a 3,1 pasos por segundo frente a 1,5. nvfp4 con fp4: del 62 al 74 %, a 3,7-4,1 | Confirmada para int8, refutada para nvfp4: no es una imagen degradada sino otra disposición de la misma escena | Modelos recientes y cuantización, 08-z-image-turbo.api.json |
| ¿Sigue haciendo falta un ControlNet después de los primeros pasos? | Escrita en la lección antes del render: la disposición se decide pronto, así que end_percent a 0,3 debería conservar la composición |
El ControlNet guió 8 de los 25 pasos, y la imagen fue casi la misma que con él activo todo el tiempo | Confirmada | Img2img, inpainting, ControlNet y LoRA, 06-canny.api.json |
| ¿Un LoRA ralentiza el muestreo? | No escrita de antemano. La suposición que se pone a prueba es que unos pesos añadidos cuestan tiempo en cada paso | Cambiar de LoRA costó de 4 a 5 s antes del primer paso; una imagen LCM-LoRA de 4 pasos tardó después 1,16 s | Refutada: el parche se calcula una vez, al cargar el modelo | Img2img, inpainting, ControlNet y LoRA, 07-lcm.api.json |
| ¿Una cruz más ancha elimina la costura de una textura desplazada y repintada? | Escrita tras el primer fracaso y antes del segundo render: 384 píxeles de cruz, 128 de difuminado y denoise 1 deberían cerrarla | La cruz de 160 píxeles redujo la costura a la mitad, de 13,4 a 5,2 niveles en la fila central, pero dejó una línea moteada y un salto de tono. La cruz ancha eliminó la línea; el salto de tono se quedó | Confirmada, con una reserva: la costura desapareció, la diferencia de tono entre las mitades no | Escalado, texturas sin costuras y HDR, 09-seamless.api.json |
| ¿Un PNG de 16 bits o un EXR de un render son de verdad HDR? | No escrita de antemano. La expectativa que se pone a prueba es que un contenedor más amplio lleva más | 256 niveles por canal en el PNG de 16 bits de un render de 8 bits, y ningún valor por encima de 1,0 en el EXR: el VAE acota su salida entre 0 y 1 | Refutada: el contenedor es HDR, el contenido no | Escalado, texturas sin costuras y HDR, 09-exr.api.json |
| ¿El decodificado VAE por baldosas cambia la imagen? | No escrita de antemano | 0,93 niveles de diferencia media a 2048 × 2048, donde un decodificado simple también cabía en la GPU | Confirmada: pequeña, y no nula — decodificar de forma simple cuando cabe | Escalado, texturas sin costuras y HDR, 09-hires-fix.api.json |
¿La salida del nodo Canny es comparable entre máquinas? |
Escrita antes de pasar por CI: un filtro de bordes con salida de aspecto entero debería dar los mismos píxeles en todas partes | Cuatro máquinas dieron cuatro huellas de píxeles; los tres ejecutores de CI encontraron 467 píxeles de borde, la máquina del autor 464 | Refutada: es código en coma flotante. La CI imprime los números a título informativo en lugar de compararlos | Img2img, inpainting, ControlNet y LoRA, check.sh |
¿En qué paso del canny de Kornia dejan de coincidir las máquinas? |
No escrita de antemano: la lección pedía el paso sin nombrar ninguno | La entrada es idéntica en cuatro máquinas; el desenfoque gaussiano separa tres grupos, el gradiente espacial las cuatro, todas las magnitudes difieren, y los contornos umbralizados son idénticos, 1461 píxeles de 3072 | Respondida, en dos mitades: la divergencia empieza en la primera convolución y siempre está ahí; solo llega a la salida cuando hay píxeles cerca de un umbral | data/canny-steps.py, lección 6 |
¿Qué hace el indicador convrot de un checkpoint int8? |
Escrita en la lección 8 antes de leer el kernel: una rotación de grupos de pesos antes de cuantizar, para repartir los valores grandes y que una sola escala se ajuste mejor | comfy-kitchen 0.2.34 rota cada grupo de 256 canales de entrada con una matriz de Hadamard regular, simétrica y ortogonal: el peso fuera de línea, las activaciones en línea. Sobre un peso con un valor atípico por fila, el error de ida y vuelta int8 es del 5,7 % sin rotación y del 0,76 % con ella | Confirmada, con una cifra. Al ser su propia inversa, la matriz deja el producto intacto; solo cambia lo que el int8 tiene que contener | data/convrot.py, lección 8 |
| ¿Qué cuesta un arranque en frío frente a uno en caliente? | No escrita de antemano. El supuesto que se pone a prueba es que el tiempo de un render es su tiempo de muestreo | El primer render SDXL tardó 14,71 s, de los cuales unos 4 s fueron los 25 pasos a 6,4 pasos por segundo; con los modelos cargados, una nueva semilla tardó 4,6 s | Unos diez segundos de un primer render son carga, no muestreo | Primeros renders, 01-txt2img.api.json |
| ¿Qué cuestan las vistas previas de latentes? | No escrita de antemano. El supuesto que se pone a prueba es que decodificar una vista previa a la vez que se muestrea es insignificante | --preview-method taesd llevó el muestreo de 6,4 a 4,9 pasos por segundo, alrededor del 23 % |
Una vista previa no es gratis; se paga en velocidad de muestreo | Primeros renders, 01-txt2img.api.json |
| ¿El inpainting deja en paz los píxeles no enmascarados? | No escrita de antemano. El supuesto que se pone a prueba es que una máscara confina el cambio a la región enmascarada | El resultado decodificado cambió el 6,2 % de los píxeles fuera de la máscara en más de 8 niveles; volver a pegarlo con ImageCompositeMasked los dejó idénticos |
Refutada: el viaje de ida y vuelta por el VAE toca toda la imagen, y es el pegado lo que la preserva | Img2img, inpainting, ControlNet y LoRA, 05-inpaint-model.api.json |
| ¿Un prompt se transfiere a otro modelo? | No escrita de antemano. El supuesto que se pone a prueba es que un prompt ajustado en un modelo se traslada a uno más reciente | FLUX.2 klein 4B dibujó un soporte de latón, no un metrónomo, en las semillas 42, 43 y 44: 0 de 3; Z-Image-Turbo dibujó un metrónomo 3 de 3 | Refutada: las mismas palabras no son la misma instrucción para dos modelos | Modelos recientes y cuantización, 08-flux2-klein.api.json |
| ¿Cómo escala un paso de muestreo con la resolución? | No escrita de antemano. El supuesto que se pone a prueba es que el coste sigue al número de píxeles | Unos 0,3 s por paso en 1024 × 1024, y de 2,2 a 2,8 s en 2048 × 2048: de 7 a 9 veces el coste por 4 veces los píxeles | Peor que lineal en número de píxeles, y esa es la razón de ser del hires fix | Escalado, texturas sin costuras y HDR, 09-hires-fix.api.json |
| ¿Qué cuesta cargar y ejecutar un paquete de nodos bien educado? | Previa solo en una mitad: los indicadores se comprobaron contra código leído de antemano. Para los tiempos, No escrita de antemano. El supuesto que se pone a prueba es que un paquete en Python puro no cuesta nada medible | En la CPU, en una carpeta base desechable: el paquete se importó en 0,0 s y se ejecutó en 0,06 s, SaveImage escribió los mismos píxeles que el PNG esperado de la prueba, y 14 pruebas unitarias pasaron solo con NumPy y Pillow |
Confirmada en ambas mitades: los indicadores se comportan como dice la fuente, y el coste está por debajo de lo que muestra el reloj | Los nodos personalizados y su seguridad |
| ¿Se pueden validar 26 flujos sin GPU y sin modelo? | No escrita de antemano. El supuesto que se pone a prueba es que un flujo no puede comprobarse antes de que exista la memoria para ejecutarlo | Un ComfyUI sin modelo en la CPU dio su /object_info —957 clases de nodos, 1,85 MB— y los 26 flujos son válidos frente a él. La comprobación informó primero de que SaveVideo no tiene entrada format.codec en tres de ellos, y se equivocaba: el fallo estaba en el validador del propio curso |
Confirmada: la lección 10 puede lanzarse en cuanto la memoria esté | Un flujo verificado antes de la GPU, check.sh |
2026-09-16 — Versiones y configuración
Sección titulada «2026-09-16 — Versiones y configuración»- ComfyUI v0.36.0 se publicó la víspera, el 15 de septiembre de 2026, y es la última versión; su etiqueta apunta al commit
ee71d5c. La versión portable para Windows y NVIDIA ocupa 1.917.442.353 bytes e incluye Python 3.13.14 y PyTorch 2.13.0 para CUDA 13.0. - El curso reutiliza una versión portable ya instalada en la máquina, y nunca escribe en ella: el servidor arranca con
--base-directoryapuntando a otro sitio,--models-directoryapuntando a los modelos de la instalación, y--database-url sqlite:///:memory:. - Un directorio base nuevo hizo que el servidor se detuviera al arrancar con
FileNotFoundError, porque listacustom_nodesantes de crear nada.server.shcrea la carpeta vacía. sd_xl_base_1.0.safetensorstiene en la máquina el SHA-256 que indica Hugging Face,31e35c80…7e5b.- Las páginas de primeros pasos y los ejemplos de la API de la documentación usan Stable Diffusion 1.5 a 512 × 512, no SDXL. La página de instalación manual usa conda;
venvsolo aparece en la página de comfy-cli. El tutorial de texto a imagen dice queEmptyLatentImagecrea un latente de ruido; crea ceros, y esKSamplerquien crea el ruido.
2026-09-16 — Primeros renders
Sección titulada «2026-09-16 — Primeros renders»- El primer render de SDXL tardó 14,71 segundos, de los que unos 4 fueron los 25 pasos de muestreo a 6,4 pasos por segundo. Con los modelos cargados, una nueva semilla tardó 4,6 segundos.
- El prompt pedía un metrónomo de latón; la semilla 42 dibujó algo parecido a un reloj de arena. La semilla 43 se acercó más.
nvidia-smimostró unos 7 GB más en uso durante el render. El log preparó 1.560 MB para los codificadores de texto, 4.896 MB para la UNet y 159 MB para el VAE.- Las vistas previas del latente de
--preview-method taesdralentizaron el muestreo de 6,4 a 4,9 pasos por segundo.

El primer render. ComfyUI v0.36.0: Stable Diffusion XL base 1.0, semilla 42, 25 pasos, euler, normal, CFG 7, 1024 × 1024, workflow 01-txt2img.api.json.
2026-09-16 — Una semilla, dos imágenes
Sección titulada «2026-09-16 — Una semilla, dos imágenes»- El mismo workflow y la misma semilla dieron
698e7867…en un servidor recién arrancado, y otra vez tras los reinicios, y5374ac40…cada vez que el prompt negativo se volvía a codificar con la UNet ya cargada. Las dos imágenes difieren en una media de 0,92 niveles, y un 2,63 % de los píxeles difieren en más de 8. --disable-dynamic-vramdio5374ac40…también en la primera ejecución.--deterministicno cambió ninguno de los dos resultados. No he encontrado qué operación difiere.- La primera imagen de un lote de dos difería de la imagen única con la misma semilla (media de 0,74), y la segunda imagen del lote no es la de la semilla 43.
- Un render con la semilla 43 hecho por el cliente Java, en otro arranque del servidor 20 minutos después, tenía los mismos píxeles que el primer render con la semilla 43.

Las dos imágenes con la semilla 42. ComfyUI v0.36.0: Stable Diffusion XL base 1.0, semilla 42, 25 pasos, euler, normal, CFG 7, workflow 01-txt2img.api.json. Izquierda: primera ejecución tras arrancar el servidor. Centro: el mismo grafo después de volver a codificar el prompt negativo. Derecha: dónde difieren, amplificado ocho veces.
2026-09-16 — Los formatos JSON y la API
Sección titulada «2026-09-16 — Los formatos JSON y la API»- Cargar el archivo de la API en el frontend y llamar a
app.graphToPrompt()dio un archivo de la interfaz y una exportación de la API. El conversor en C#, que lee los nombres de los widgets delinput_orderde/object_infoy se salta el widget de control de la semilla, produce la exportación byte a byte. - Un PNG encolado desde el navegador registró la semilla 42 en su chunk
workflow, y el frontend cambió la semilla a 140956311522585 justo después de encolar, porque su widgetcontrol_after_generateestaba enrandomize. - El servidor escribió
"cfg": 7.0en el prompt del PNG para un frontend que envió7: la validación convierte las entradasFLOATconfloat()y las reescribe. - Un enlace a un nodo inexistente hizo que la validación del servidor lanzara un
KeyErrorfuera de su bloquetry. El servidor informó de dos errores donde la comprobación sin conexión encontró cinco; uno estaba archivado bajo el nodo 3 con el nombre de entrada del nodo 8,samples, y una traza que incluye la ruta de instalación del servidor. check.shfalló en su segunda ejecución: los dos nodosSaveImagese ejecutaron en el orden inverso. El servidor guarda las salidas validadas en un conjunto de Python, y los hashes de las cadenas se aleatorizan en cada arranque.server.shfija ahoraPYTHONHASHSEED=0.- Una ejecución totalmente en caché sigue enviando
executedpor cada nodo de salida, con los nombres de archivo de la primera ejecución, y no escribe nada. - La primera ejecución de la CI falló solo en Ubuntu: el mismo PNG de 64 × 48 se comprimió en 84 bytes allí y en 88 en Windows y macOS.
png-infoimprime ahora el tamaño descomprimido. - El ejemplo de la API en Python del repositorio de ComfyUI espera
executingcon un nodonull. El servidor lo envía después de escribir el historial; los clientes se detienen en cambio conexecution_success,execution_erroroexecution_interrupted. - La documentación no enumera las rutas
/api/jobs, el prefijo/apide todas las rutas ni los mensajes binarios de vista previa.
2026-09-16 — Modelos para las lecciones 5 a 8
Sección titulada «2026-09-16 — Modelos para las lecciones 5 a 8»- El disco de la máquina del curso estaba casi lleno, así que los nuevos archivos de modelos fueron a otra unidad, declarada a ComfyUI con
--extra-model-paths-config. Cada archivo se descargó de una revisión fijada de Hugging Face y se comprobó con el SHA-256 que indica Hugging Face, y su licencia se leyó en la ficha del modelo en ese momento. - Pixel Art XL está bajo CreativeML Open RAIL-M, no bajo la RAIL++-M de SDXL. Su ficha dice que no hace falta ninguna palabra de activación, y sus metadatos fijan
instance_prompt: pixel art. - Los metadatos del LCM-LoRA dicen rango 1 y alfa 1, y su título
sdxl_LCM_lora_rank1; sus tensores tienen rango 64 y alfa 8. - El codificador de texto Qwen3 4B tiene el mismo SHA-256 en los repositorios de Z-Image-Turbo y de FLUX.2 klein de Comfy-Org.
2026-09-16 — Img2img, inpainting, ControlNet y LoRA
Sección titulada «2026-09-16 — Img2img, inpainting, ControlNet y LoRA»denoiseno cambió el número de pasos: se ejecutaron 25 pasos para cada valor de 0,3 a 0,9, en 4,6 a 5,1 segundos.- Subir bytes idénticos con un nombre ya usado devolvió el nombre existente; unos bytes distintos recibieron
name (1).png. Ninguno de los dos comportamientos está documentado. VAEEncodeForInpaintpone en gris los píxeles enmascarados, cosa que el tutorial no dice. Condenoisea 0,5, el resultado fue una elipse gris plana.

Dos fallos de inpainting y la solución, antes de volver a pegar el resultado. ComfyUI v0.36.0: Stable Diffusion XL base 1.0, semilla 42, 25 pasos, CFG 7, euler, normal. De izquierda a derecha: 05-inpaint-vaeencode.api.json con denoise 0,5; el mismo workflow con denoise 1 y una máscara con un borde suavizado de 24 píxeles; 05-inpaint-model.api.json, la UNet SD-XL inpainting 0.1 con denoise 0,99, sobre la misma máscara suavizada.
- La ficha de SD-XL inpainting dice que se mantenga
strengthpor debajo de 1,0; 1,0 y 0,99 dieron aquí casi la misma imagen (un 0,01 % de los píxeles difieren en más de 8). - El resultado de inpainting decodificado cambió en más de 8 niveles un 6,2 % de los píxeles fuera de la máscara; volver a pegarlo con
ImageCompositeMaskedlos dejó idénticos. - La página de documentación de
SetUnionControlNetTypeenumera 13 tipos; el nodo tiene 8. - La primera ejecución en la CI del nodo
Cannyfalló en los tres sistemas operativos: cuatro máquinas dieron cuatro hashes de píxeles. Los tres runners encontraron 467 píxeles de borde, y la máquina del autor 464. La CI ahora los imprime a título informativo.

La salida del nodo Canny en la máquina del autor, hash de píxeles 77af5cb1b7e93a5c, 464 píxeles de borde, ampliada cuatro veces sin suavizado. ComfyUI v0.36.0 en la CPU, sin modelo, umbrales 0,05 y 0,15, workflow 05-masks.api.json. Los tres runners de la CI dibujaron cada uno 467 píxeles de borde, con otros tres hashes.
- Con
end_percenta 0,3, el ControlNet guió 8 de los 25 pasos, y la imagen fue casi la misma que con él activo en todos los pasos. - Un LoRA cuesta tiempo antes del primer paso, no durante el muestreo: cambiar de LoRA tardó de 4 a 5 segundos más, y una imagen de 4 pasos con el LCM-LoRA tardó después 1,16 segundos.
2026-09-16 — Modelos recientes y cuantización
Sección titulada «2026-09-16 — Modelos recientes y cuantización»- Z-Image-Turbo en bf16 con su codificador de texto bf16, 19,4 GB de pesos, se ejecutó en la GPU de 16 GB con la VRAM dinámica: 63,93 segundos el primer render, y luego 5,93 segundos a 1,5 pasos por segundo. int8 con el codificador de texto fp8 fue a 3,1 pasos por segundo, y nvfp4 a entre 3,7 y 4,1.
nvidia-smimostró de 12,5 a 15,3 GB en uso en todas las configuraciones: la VRAM dinámica usa lo que está libre. Los tamaños preparados en el log son las cifras útiles.- Las imágenes int8 se mantuvieron cerca de las de bf16 (entre un 9 y un 15 % de los píxeles difieren en más de 8); las imágenes nvfp4 mostraron la misma escena dispuesta de otra forma (entre un 62 y un 74 %).

ComfyUI v0.36.0: Z-Image-Turbo, semilla 42, 8 pasos, CFG 1, res_multistep, simple, workflow 08-z-image-turbo.api.json. De izquierda a derecha: bf16 con el codificador de texto bf16, int8 con fp8, nvfp4 con fp4, nvfp4 con bf16.
qwen_3_4b_fp8_mixedtiene 12 capas nvfp4, yqwen_3_4b_fp4_mixedtiene 58 capas fp8. El archivo nvfp4 de Z-Image mantiene sus cuatro bloques de refinado en bf16.- Con
--disable-dynamic-vram, el primer render en bf16 tardó 78,87 segundos y dio los mismos píxeles que con la VRAM dinámica. El segundo render se detuvo cuando la máquina, compartida con otros trabajos, se quedó sin RAM. Un lote bf16 anterior se había detenido del mismo modo: el servidor ocupaba 14,5 GB de RAM. Ahora cada servidor solo arranca cuando los pesos de la configuración, más un margen, caben en la RAM libre. - FLUX.2 klein 4B dibujó un soporte de latón, no un metrónomo, con las semillas 42, 43 y 44; Z-Image-Turbo dibujó un metrónomo cada vez.

ComfyUI v0.36.0. Primero: Z-Image-Turbo bf16, semilla 43, workflow 08-z-image-turbo.api.json. Después: FLUX.2 klein 4B, semillas 42, 43 y 44, 4 pasos, CFG 1, euler, workflow 08-flux2-klein.api.json.
2026-09-16 — Los nodos personalizados y su seguridad
Sección titulada «2026-09-16 — Los nodos personalizados y su seguridad»- ComfyUI v0.36.0 importa cada paquete con
exec_moduleantes de leerNODE_CLASS_MAPPINGS;prestartup_script.pyse ejecuta antes, y el JavaScript deWEB_DIRECTORYse ejecuta en el navegador.hook_breaker_ac10a0.pyrestaura una función después de cargar los paquetes; nada más separa un paquete del proceso. - ComfyUI-Manager es ahora el paquete pip
comfyui_manager==4.2.2, fijado enmanager_requirements.txt. Los 42 archivos.py,.jsony.mdde su wheel en PyPI son idénticos a la etiqueta4.2.2, commitbd4ede22. Filtra las instalaciones según el nivel de seguridad, la dirección de escucha y dos nuevas opciones, y busca al arrancar nombres de paquetes maliciosos conocidos; nada lee el código de un paquete. - El paquete de Guitar Alchemist (GA Chord Diagram, GA Fretboard Control Map, GA Scale Prompt) calcula a partir de las tablas de afinación y de escalas de GA en el commit
a826864f, dibuja con Pillow sin fuentes, y pasa 14 pruebas unitarias solo con NumPy y Pillow. Cargado en un directorio base desechable, con el Python de la versión portable, en la CPU, se importó en 0,0 s, se ejecutó en 0,06 s, ySaveImageescribió los mismos píxeles que el PNG esperado de la prueba.--disable-all-custom-nodes,--whitelist-custom-nodes gay una carpeta.disabledse comportaron como dice el código fuente. - El script de auditoría se ejecutó sobre seis paquetes fijados el 16 de septiembre de 2026: ComfyUI-GGUF, comfyui_controlnet_aux, ComfyUI-Impact-Pack, ComfyUI-VideoHelperSuite, rgthree-comfy y ComfyUI_essentials. Ningún hallazgo sugiere mala intención. Impact-Pack instala
onnxruntimecon pip la primera vez que se ejecuta un detector ONNX, y suinstall.pydescarga un.pthde SAM. rgthree-comfy envía el SHA-256 de un archivo de modelo a Civitai cuando la interfaz pide su información. comfyui_controlnet_aux tiene 72 llamadas atorch.loadsinweights_only, seguras por defecto solo con PyTorch 2.6 o posterior. - Un pickle cuya carga llama a
printse ejecutó conpickle.loadsy contorch.load(weights_only=False);torch.load(weights_only=True)lo rechazó con PyTorch 2.13.
2026-09-16 — ComfyUI en producción
Sección titulada «2026-09-16 — ComfyUI en producción»- Leído en ComfyUI v0.36.0: un único hilo
prompt_workerejecuta un prompt a la vez; un cliente puede elegir unprompt_id, que debe ser un UUID en minúsculas; el mismo identificador enviado dos veces se ejecuta dos veces y sobrescribe su entrada de historial;execution_successse envía antes de escribir el historial;execution_interruptedse difunde a todos; una reconexión no reproduce nada. Un script de grabación provocó estos casos en un servidor CPU y guardó las respuestas. - Un worker en C# y en Java con las mismas líneas de log: una cola en memoria (un
Channelen C#, unaLinkedBlockingQueuee hilos virtuales en Java) o RabbitMQ, el identificador del job comoprompt_id, un archivo de reserva ydone.jsonpara la idempotencia, backoff exponencial con full jitter, los 400 y los errores de ejecución normales a las cartas muertas, las faltas de memoria y los 5xx reintentados, una interrupción al vencer el plazo, un pool de GPU que elige el servidor con menos prompts delante, y la gestión de SIGTERM con un periodo de gracia. - Un ComfyUI falso en ASP.NET Core reproduce las respuestas grabadas según un guion de fallos. Pasan 11 pruebas de xUnit y 9 de JUnit, y los dos workers imprimen las mismas transcripciones en Windows, Linux y macOS en la CI. Contra un ComfyUI real en CPU, el worker de C# ejecutó cuatro jobs (un duplicado, una carta muerta), y el de Java, en el mismo servidor, encontró los prompts terminados en el historial sin volver a ejecutarlos.
- La primera ejecución de la CI se bloqueó en Linux y macOS: los servidores falsos sobrevivían a
kill. Ahora esperan SIGTERM conPosixSignalRegistration. - El experimento «del acorde al mástil» del laboratorio GA se ejecuta como veinte jobs con un CSV de resultados contra el servidor falso. Los adaptadores de RabbitMQ, las notas de despliegue y una ejecución en GPU siguen por verificar.
2026-09-16 — Modelos para las lecciones 9 y 10
Sección titulada «2026-09-16 — Modelos para las lecciones 9 y 10»- Descargados en el disco de modelos y comprobados con el SHA-256 de la API de árbol de Hugging Face:
RealESRGAN_x4plus.safetensors(66.857.836 bytes, BSD-3-Clause),film_net_fp16.safetensors(68.882.302 bytes), y para Wan 2.2 TI2V 5B, bajo Apache 2.0,wan2.2_ti2v_5B_fp16.safetensors(9.999.658.848 bytes),umt5_xxl_fp8_e4m3fn_scaled.safetensors(6.735.906.897 bytes) ywan2.2_vae.safetensors(1.409.400.960 bytes). Los 18,1 GB de Wan tardaron 10 minutos. - El reempaquetado de Comfy-Org no tiene ningún archivo fp8 de TI2V 5B, solo fp16.
2026-09-16 — Escalado, texturas sin costuras y HDR
Sección titulada «2026-09-16 — Escalado, texturas sin costuras y HDR»- La regla de la RAM eligió el modelo en cada arranque del servidor: Z-Image-Turbo nvfp4 con 22 GB de RAM libre, int8 con 24 GB. La RAM libre bajó a 9 GB durante los renders int8.
- Un paso de muestreo tardó unos 0,3 segundos a 1024 × 1024 y de 2,2 a 2,8 segundos a 2048 × 2048.
- Un
VAEDecodenormal del latente de 2048 × 2048 cupo en la GPU; su imagen difiere de la deVAEDecodeTileden 0,93 niveles de media. - El escalado en el espacio latente dejó un grano ruidoso y cuerdas duplicadas con un denoise de 0,3.
- El PNG de 16 bits de
SaveImageAdvancedhecho a partir de un render de 8 bits tiene 256 niveles por canal, y su EXR no tiene ningún valor por encima de 1,0. El cliente de C# se detenía en el primer PNG de 16 bits: ahora los decodifica, y lista los archivos EXR y AVIF por tamaño. - El primer intento de textura sin costuras, con una cruz de 160 píxeles, 64 píxeles de difuminado y un denoise de 0,7, redujo las costuras a la mitad (de 13,4 a 5,2 niveles en la fila central) pero dejó una línea moteada y un escalón de tono. Un denoise de 0,9 no ayudó; una cruz de 384 píxeles con 128 píxeles de difuminado, sí.
- “Pale maple” (arce claro) dibujó hojas de arce talladas en la madera. “Pale maple wood, a planed board” (madera de arce clara, una tabla cepillada) dibujó una tabla.

Los fallos, antes de la corrección. ComfyUI v0.36.0: Z-Image-Turbo nvfp4 con Qwen3 4B fp4 mixed, semilla 42, 8 pasos, CFG 1, res_multistep, simple, workflow 09-seamless.api.json con su cruz ajustada a 160 píxeles, 64 de difuminado y un denoise de 0,7. De izquierda a derecha: el palisandro repetido 2 × 2; los 512 × 512 píxeles centrales del palisandro; el prompt “flat top-down photograph of pale maple, subtle straight grain, even soft lighting, no shadows, wood texture” (foto cenital de arce claro, con veta fina y recta, luz suave y uniforme, sin sombras, textura de madera), repetido 2 × 2.
2026-09-17 — Un modelo 3D publicado antes de leer su licencia
Sección titulada «2026-09-17 — Un modelo 3D publicado antes de leer su licencia»- El 16 de septiembre, la sesión Atlas generó un metrónomo y un gramófono como mallas 3D, a partir de imágenes de SDXL, con Hunyuan3D 2.0 y los nodos del núcleo de ComfyUI. El diario del curso de Blender publicó sus renders a las 00:23 del 17 de septiembre, en el commit
a165915. - Al leer la licencia para el experimento de imagen a 3D del laboratorio GA, la sesión learn-33 encontró la cláusula 5.c de la Tencent Hunyuan 3D 2.0 Community License: «You must not use, reproduce, modify, distribute, or display the Tencent Hunyuan 3D 2.0 Works, Output or results of the Tencent Hunyuan 3D 2.0 Works outside the Territory. Any such use outside the Territory is unlicensed and unauthorized under this Agreement.» El Territorio excluye la Unión Europea, el Reino Unido y Corea del Sur, y este sitio es público. Nuestro error: los renders se publicaron antes de que nadie leyera la cláusula 5.c.
- A las 00:44, el usuario decidió: Hunyuan3D se queda en la máquina local, y todo lo que se publique usa TRELLIS.2 (MIT, con DINOv3 bajo su propia licencia) o modelos construidos con código. El curso de Blender retiró los dos renders en el commit
c8a5a33y describe con palabras lo que mostraban. - TRELLIS.2 pide aquí unos 23 GB de RAM libre, y el proyecto original pide 24 GB de VRAM; no se ha ejecutado. Los dos objetos se están remodelando con
bpyen su lugar: el diario de Blender cuenta ese lado de la historia, antes y después. - La lección 8 tiene ahora una sección sobre leer la licencia antes de publicar una salida, con las cláusulas y la comparación de las tres rutas. Ninguna imagen de Hunyuan3D aparece en este curso.
2026-09-19 — Verificación de ComfyUI para la escena orbital
Sección titulada «2026-09-19 — Verificación de ComfyUI para la escena orbital»Un servidor CPU separado (0.36.0, localhost:8193) confirmó las clases de nodos del workflow Canny del curso, el checkpoint SDXL y el ControlNet union instalados. No se envió ningún prompt; inferencia GPU: 0 s. Después se detuvo el servidor. Efecto inesperado: --base-directory por sí solo movió el antiguo user/comfyui.db de la instalación a un .bak y lo copió al directorio de prueba. Se restauró el archivo original desde esa copia sin sobrescribir otro archivo; ambos SHA-256 coinciden. Se conservó la copia. Las próximas pruebas aisladas deben indicar --database-url sqlite:///:memory: o una URL de base exclusiva de la prueba. La inferencia y la calidad de imagen siguen por verificar.
2026-09-19 — Preprocesamiento real de Blender a ComfyUI
Sección titulada «2026-09-19 — Preprocesamiento real de Blender a ComfyUI»El render Blender v2 se copió al directorio de entrada ComfyUI aislado. LoadImage → Canny → SaveImage terminó correctamente en CPU en 3.731 s (marcas del historial); se inspeccionó la imagen. Se conservan los bordes de anillos, pilares y pasillo. Es una imagen de control, no una escena generada por SDXL ni geometría 3D nueva. ID: 7f26de5e-5d83-455c-97be-1e3401e9ba5f. Salida: C:/tmp/blender-comfy-scenes-20260919/comfy-base/output/orbital-study/canny-edges_00001_.png. La base explícita en memoria evitó la migración anterior; el hash de la base de la instalación no cambió. Tiempo GPU y llamadas API de pago: 0. Se aplazó la inferencia SDXL para no cargar ambos modelos con solo unos 10 GiB de RAM disponibles.
2026-09-22 — Un flujo verificado antes de la GPU, y un fallo en nuestro propio verificador
Sección titulada «2026-09-22 — Un flujo verificado antes de la GPU, y un fallo en nuestro propio verificador»- Los flujos de la lección 10 estaban escritos pero nunca ejecutados: la máquina no ha tenido la memoria libre para Wan 2.2. En lugar de esperar, se arrancó un servidor de ComfyUI sin ningún modelo, en CPU, solo para guardar su
/object_info: 957 clases de nodos, 1,85 MB. El servidor se detuvo enseguida. - Frente a ese archivo, los 26 flujos del curso están bien.
Wan22ImageToVideoLatent,CreateVideo,SaveVideo,FrameInterpolationModelLoaderyFrameInterpolateestán en el núcleo en la v0.36.0,film_net_fp16aparece en la lista del cargador, y los nombres de los archivos de Wan 2.2 son los que ve el servidor: las rutas de modelos adicionales son correctas. La lección 10 puede lanzarse en cuanto haya memoria. - La verificación anunció primero que
SaveVideono tenía una entradaformat.codec, en los tres flujos. Se equivocaba, y el fallo era nuestro:Workflow.cssolo leía las entradasrequiredyoptionalde primer nivel, mientras que unCOMFY_DYNAMICCOMBO_V3lleva sus hijos dentro de sus opciones. Ahora las recorre, y comprueba también las claves de opción. La lección 3 tiene la sección, ycheck.shun juego de pruebas con los tres errores posibles de una entrada con punto. - Un verificador que nunca ha fallado no demuestra nada. Este tiene ya un archivo que debe fallar, y las cuatro líneas nuevas de
expected/03-validate.txtson lo que debe imprimir. - El mismo día, cada lección escrita recibió una sección «tu turno» — la 9 era la única que terminaba con algo que hacer en la propia máquina — y las treinta imágenes del curso se reunieron en una galería, cada una con el flujo que la hizo, en la revisión que la hizo.
2026-09-22 — Dónde deja Canny de coincidir, y qué rota convrot
Sección titulada «2026-09-22 — Dónde deja Canny de coincidir, y qué rota convrot»- La pregunta abierta de la lección 6 tiene respuesta.
data/canny-steps.pycalcula un hash por paso del filtro de Kornia sobre un patrón de 64 por 48 construido con aritmética entera, ycheck.shlo ejecuta en las tres máquinas de la CI. La entrada son los mismos bytes en todas partes. El desenfoque gaussiano ya separa la máquina del autor de los runners, y el runner Apple Silicon de los dos x86; el gradiente espacial difiere en las cuatro, aunque Windows y Linux coincidían un paso antes: la misma convolución toma un camino distinto según la compilación. Todas las magnitudes difieren, y su suma sigue imprimiendo 2729.489258. - Los contornos, en cambio, son idénticos en las cuatro máquinas: 1461 píxeles de 3072, un solo hash. Este patrón son áreas planas y bordes duros, así que nada queda cerca de un umbral. Esa es la otra mitad de la respuesta: la divergencia siempre está ahí, desde la primera convolución; es la imagen la que decide si se ve. La lección 6 tiene la tabla.
convrotera una suposición escrita en la lección 8, «una rotación de grupos de pesos antes de cuantizar». comfy-kitchen 0.2.34 la confirma y dice cuál: una matriz de Hadamard regular, simétrica y ortogonal, sobre grupos de 256 canales de entrada; el peso fuera de línea, las activaciones en línea, fusionado en el cuantizador por filas. Al ser su propia inversa, deja el producto intacto y solo cambia lo que el int8 tiene que contener.data/convrot.pyla reconstruye, idéntica a la de la biblioteca con tamaños 16, 64 y 256, y mide el error de ida y vuelta sobre un peso con un valor atípico por fila: 5,7 % sin rotación, 0,76 % con ella.- El punto sobre EXR de la lección 9 ganó la consecuencia que importa al compartir: un flujo construido donde
.exrtiene un tipo MIME designa una imagen que la lista de la máquina siguiente no ofrecerá. El archivo sigue siendo válido; el render deja de ser reproducible.
2026-09-22 — Cuatro hallazgos que nunca salieron del informe, y uno que caducó
Sección titulada «2026-09-22 — Cuatro hallazgos que nunca salieron del informe, y uno que caducó»Cinco hallazgos de los primeros días vivían solo en el informe de la vía, nunca en este diario, así que no podían convertirse en filas. Cada uno se volvió a comprobar hoy antes de escribirlo. Cuatro se sostienen; uno no.
QUANTIZATION.mdseñala las líneas equivocadas, y la forma equivocada. Dice «TheMixedPrecisionOpsclass (lines 542-648 incomfy/ops.py)». En el commit anclado la clase se declara en la línea 1347, la línea 542 esself.weight_comfy_model_dtype = dtype, yMixedPrecisionOpsno es en absoluto una clase de módulo: se define dentro de la fábricamixed_precision_ops(), en la línea 1346, así que no puede importarse con ese nombre.- La página del formato API se equivoca con las claves de nodo del formato UI. Su tabla comparativa da «Node keys: Node titles or labels» para el formato de guardado, frente a «Numeric node IDs» para el formato API. El archivo exportado del propio curso dice lo contrario:
01-txt2img.ui.jsoncontienenodescomo una lista de 7 objetos, cada uno con unidnumérico, ninguno contitle, y cada entrada delinksremite a esos números. Ambos formatos identifican los nodos por id; lo que cambia es que uno es un array y el otro un objeto indexado por el id. --lowvramno cambia nada frente al estado normal. El indicador fijaVRAMState.LOW_VRAM, pero el presupuesto de carga parcial toma la misma rama paraLOW_VRAMy paraNORMAL_VRAM, y calcula la misma cantidad a partir de la memoria libre en ambos casos. Los renders del 16 de septiembre no midieron ninguna diferencia; el código dice por qué.--novrames otra cosa: fija el presupuesto en 0,1.- comfy-cli envía los comandos a Comfy Cloud en cuanto existe una credencial. Su propio
where.pyexpone el orden de precedencia, y la última regla es una detección automática: cloud si hay alguna credencial de cloud configurada, clave de API o sesión OAuth activa, y si no, local. Iniciar sesión una vez cambia el destino de los comandos siguientes, sin que la línea de comandos lo diga. Leído hoy enmain; comfy-cli no está anclado por este curso. - El que caducó. Una nota del 16 de septiembre decía que la página de instalación portable solo anuncia NVIDIA o CPU, mientras que la v0.36.0 publica builds de AMD e Intel. La versión sí publica cuatro archivos de Windows —amd, intel, nvidia y nvidia_cu126— pero la página leída hoy documenta los tres fabricantes, con un archivo de comandos para cada uno. Dijera lo que dijera entonces, ya no lo dice, y no hay ninguna captura que pruebe el estado anterior. La nota se retira en vez de publicarse: un reproche a una documentación, sin prueba del texto reprochado, no es un hallazgo.
Por verificar
Sección titulada «Por verificar»- SDXL en Linux con CUDA, y en Apple Silicon con MPS: la máquina con GPU del curso usa Windows; la CI solo instala las builds para CPU.
- Qué operación hace que los codificadores de texto den resultados distintos según la UNet esté cargada o no, y si ocurre con otras GPU u otros drivers.
- Si un sampler ancestral da la misma imagen en la CPU y en la GPU para una semilla: el ruido de sus pasos se genera en el dispositivo.
- Si un hash perceptual sería estable en los casos de la lección 2.
- Las cadenas de ControlNet,
start_percent, y el paso exacto en que cae el nivel de ruido de un porcentaje, que la lección calculó pero no renderizó. - Entrenar un LoRA con los nodos experimentales de ComfyUI, y cuánto de los 16 GB necesita para SDXL.
- Varios LoRA apilados en el otro orden: la misma imagen, y el mismo hash de píxeles o no.
- La ruta emulada de nvfp4 y fp8 en una GPU sin sus kernels; la máquina del curso solo tiene una GPU de la serie RTX 50.
- Por qué la red nvfp4 de Z-Image muestreaba más rápido con el codificador de texto bf16 que con el fp4.
- Muestrear los mosaicos de
SplitImageToTileListy unirlas conImageMergeTileList: si se ven costuras con un denoise bajo. - Si el
EXRLoaderde three.js lee en un navegador el EXR sin comprimir de ComfyUI. - Cómo muestran los navegadores el AVIF HLG de
SaveImageAdvanced. - Los tiempos de render en caliente con
--disable-dynamic-vram, en una máquina con suficiente RAM libre. execution_interruptedtal como lo imprimen los clientes, yPOST /interruptcon un id de prompt: hace falta una ejecución lo bastante larga que interrumpir, y por tanto un modelo.
Preguntas abiertas
Sección titulada «Preguntas abiertas»No son mediciones pendientes —esas están arriba— sino decisiones que este curso no ha tomado.
- ¿Merece una issue en ComfyUI que
LoadImagedependa de la tabla MIME de la máquina, o es el comportamiento deseado? Una llamada amimetypes.add_typepara los formatos que el propio ComfyUI escribe lo arreglaría en una línea, y cambiaría lo que una instalación existente enumera. - ¿Qué parte de dos compilaciones x86 de la misma versión de PyTorch hace que sus convoluciones difieran: la vectorización, el paralelismo o la biblioteca de álgebra lineal? La sonda por pasos muestra que difieren desde la primera, no por qué.
- ¿Cuándo mover el anclaje? Todas las mediciones de aquí están atadas a ComfyUI v0.36.0 en un commit concreto, y eso es lo que les da sentido; nada dice qué será de ellas en la v0.37.