Files
fn_registry/python/functions/ml/comfyui_compose_capabilities.md
T
egutierrez cda36408d0 feat(ml): modelos con prefijo de categoría (IMG_/VIDEO_/3D_) + refs actualizadas
Renombra los 13 checkpoints/diffusion models de ComfyUI prefijando la
categoría al inicio del nombre, para que en el dropdown de carga el usuario
distinga de inmediato imagen/vídeo/3D y no cargue un modelo en el nodo
equivocado. Misma operación que se hizo con los LoRAs (report 0197) pero
sobre los modelos.

Clasificación:
- IMG_: dreamshaper_8, juggernaut_xl_v11, v1-5-pruned-emaonly-fp16,
  flux1-dev-fp8-e4m3fn, flux1-schnell-fp8-e4m3fn
- VIDEO_: svd, ltx-video-2b-v0.9.5, wan2.1_t2v_1.3B_fp16
- 3D_: stable_zero123, sv3d_p, hunyuan3d-dit-v2-mini, hunyuan3d-dit-v2-mv,
  hy3dgen/hunyuan3d-dit-v2-0-fp16 (mantiene subcarpeta)

A diferencia de los LoRAs aquí solo se PREFIJA la categoría conservando el
nombre completo (versión/arquitectura). Archivos físicos renombrados en
~/ComfyUI/models/checkpoints, /mnt/2tb/comfyui_models/{checkpoints,
diffusion_models} y la subcarpeta hy3dgen/. Mapa de reversión en
~/ComfyUI/models/checkpoints/_ckpt_rename_map.json.

Actualiza todas las refs (ckpt_name/unet_name + defaults + prosa) en los
builders gamedev/vídeo/3D, style presets, pipelines, tests y los workflows
de ComfyUI. Arregla de paso el default roto de comfyui_text_to_3d_oneshot
(apuntaba a v1-5-pruned-emaonly.safetensors inexistente; ahora al real
IMG_v1-5-pruned-emaonly-fp16.safetensors).

No tocados (justificado): repo-paths de HuggingFace en comfyui_install_3d_model
(<repo>/model.fp16.safetensors son rutas de descarga, no nombres de dropdown)
y el mock de stable-diffusion.cpp en test_genconfig_to_sdcpp_args.

Verificado: dropdowns CheckpointLoaderSimple + UNETLoader listan los nombres
con prefijo; 1 generación real con IMG_juggernaut_xl_v11 (node_errors vacío,
pixelart_00003_.png); 327 tests comfyui verdes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 18:24:52 +02:00

5.7 KiB

name, kind, lang, domain, version, purity, signature, description, tags, uses_functions, uses_types, returns, returns_optional, error_type, imports, params, output, tested, tests, test_file_path, file_path
name kind lang domain version purity signature description tags uses_functions uses_types returns returns_optional error_type imports params output tested tests test_file_path file_path
comfyui_compose_capabilities function py ml 1.0.0 pure def comfyui_compose_capabilities(base_workflow: dict, *, loras: list[dict] | None = None, controlnet: dict | None = None, ipadapter: dict | None = None, hires: dict | None = None, facedetailer: dict | None = None) -> dict Mezclador de capacidades ComfyUI: toma un workflow base en API format (skill o txt2img) y aplica EN ORDEN las capacidades activadas (cada arg None = desactivada), componiendo los inyectores/builders encadenables del registry: loras (inject_multi_lora) -> controlnet (inject_controlnet) -> ipadapter (inject_ipadapter) -> facedetailer (build_facedetailer_workflow) -> hires (inject_hires_fix), reconectando MODEL/CLIP/positive/IMAGE. Cada capacidad es opcional e independiente; sin ninguna devuelve el base intacto. Pura: no muta el dict de entrada.
comfyui
comfyui-skill
ml
mixer
lora
controlnet
ipadapter
facedetailer
hires
workflow
comfyui_inject_multi_lora_py_ml
comfyui_inject_controlnet_py_ml
comfyui_inject_ipadapter_py_ml
comfyui_build_facedetailer_workflow_py_ml
comfyui_inject_hires_fix_py_ml
false
name desc
base_workflow dict en API format (salida de comfyui_build_skill_workflow o comfyui_build_txt2img_workflow). No se muta; se devuelve una copia.
name desc
loras Lista de dicts {name, strength_model?, strength_clip?} para inject_multi_lora. None o vacia = sin LoRAs. keyword-only.
name desc
controlnet Dict para inject_controlnet: {control_image (obligatoria), cn_name (obligatoria), strength?, positive_node?}. None = sin ControlNet. keyword-only.
name desc
ipadapter Dict para inject_ipadapter: {ref_image (obligatoria), mode ('style'|'faceid'), weight?, ...}. None = sin IPAdapter. keyword-only.
name desc
hires Dict de kwargs para inject_hires_fix (upscale_by, denoise, steps, cfg, seed, upscale_model, ...). {} = hires con defaults. None = sin hires. keyword-only.
name desc
facedetailer Dict de overrides para build_facedetailer_workflow. ckpt_name/positive/negative se detectan del workflow si faltan; resto = params del builder (denoise, steps, bbox_model, ...). {} = detect + defaults. None = sin facedetailer. keyword-only.
copia del base con las capacidades activadas encadenadas en orden (loras -> controlnet -> ipadapter -> facedetailer -> hires). Sin ninguna activada, copia del base intacta. Tras facedetailer deja un unico SaveImage (el del detailer). true
sin capacidades devuelve el base intacto (mismos nodos)
solo loras encadena los LoraLoader
loras + facedetailer: cadena de loras + FaceDetailer + un solo SaveImage
ipadapter + lora: IPAdapter toma el MODEL del ultimo LoraLoader
hires anade UltimateSDUpscale
controlnet sin control_image propaga ValueError
ipadapter sin ref_image propaga ValueError
no muta el dict de entrada (pureza)
api format valido en todas las combinaciones
activar una capacidad cambia el conjunto de class_types
python/functions/ml/tests/test_comfyui_compose_capabilities.py python/functions/ml/comfyui_compose_capabilities.py

Ejemplo

import sys, os
sys.path.insert(0, os.path.join(os.environ["HOME"], "fn_registry", "python", "functions"))
from ml.comfyui_build_txt2img_workflow import comfyui_build_txt2img_workflow
from ml.comfyui_compose_capabilities import comfyui_compose_capabilities

base = comfyui_build_txt2img_workflow("IMG_dreamshaper_8.safetensors", "a hero, 3d render style")

# 3 capacidades a la vez: 2 LoRAs + FaceDetailer (activar/desactivar = cambiar args)
mixed = comfyui_compose_capabilities(
    base,
    loras=[
        {"name": "SD15_3d_render_redmond.safetensors", "strength_model": 0.9},
        {"name": "SD15_detail_tweaker.safetensors", "strength_model": 0.5},
    ],
    facedetailer={"denoise": 0.45},
    # controlnet=..., ipadapter=..., hires=...  -> None = desactivadas
)

Cuando usarla

Cuando quieras mezclar varias capacidades de generacion (LoRAs + ControlNet + IPAdapter + FaceDetailer + hires) sobre un mismo workflow base y poder activar/desactivar cada una para iterar y mejorar. Es el "mixer" del grupo comfyui-skill: una sola funcion en vez de encadenar los inyectores a mano. La salida va directa a comfyui_submit_workflow (o usa el one-shot comfyui_generate_mixed_oneshot para submit + juicio).

Gotchas

  • Pura: no muta el base_workflow y NO valida que checkpoints/loras/modelos existan en el servidor. Las imagenes de control/referencia (ControlNet, IPAdapter) deben estar en el input/ del servidor antes de submit.
  • Orden fijo: loras -> controlnet -> ipadapter -> facedetailer -> hires. El IPAdapter se aplica sobre el MODEL ya modificado por los LoRAs (orden correcto).
  • hires + facedetailer NO encadenan con las piezas actuales: ambos toman su imagen del VAEDecode del render base, asi que combinarlos deja a uno sin efecto sobre la salida final (con los dos activos, hires "gana" y facedetailer queda sin consumidor). Usa uno U otro por workflow. Es la limitacion documentada del mixer; el resto de combinaciones (loras+controlnet+ipadapter+uno de los dos post-procesos) encadenan limpio.
  • Cada capacidad apila coste de VRAM. En 8GB lowvram con SD1.5 entran ~2-3 capacidades modestas (p.ej. 2 LoRAs + FaceDetailer a 512px). Apilar IPAdapter FaceID + ControlNet + hires + facedetailer a la vez puede dar OOM: baja resolucion o desactiva capacidades.
  • Errores de incompatibilidad (controlnet sin control_image, ipadapter sin ref_image, mode invalido) se propagan como ValueError del inyector, no petan en silencio.