feat(ml): auto-commit con 11 cambios

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-24 01:39:30 +02:00
parent d7245efa59
commit d3f05a19a5
11 changed files with 1148 additions and 12 deletions
+31 -12
View File
@@ -42,6 +42,8 @@ El **API format** (dict de nodos numerados que produce `build_txt2img_workflow`
| [comfyui_submit_workflow_py_ml](../../python/functions/ml/comfyui_submit_workflow.md) | `submit_workflow(workflow, server, client_id, timeout) -> dict` | Encola un workflow API format vía POST /prompt; devuelve `prompt_id` + posición en cola. HTTP 400 propaga la validación por nodo. Impura. |
| [comfyui_wait_result_py_ml](../../python/functions/ml/comfyui_wait_result.md) | `wait_result(prompt_id, server, timeout, poll_interval) -> dict` | Sondea GET /history/{prompt_id} hasta que termina; devuelve los outputs (PNGs con filename/subfolder/type). Impura. |
| [comfyui_download_model_py_ml](../../python/functions/ml/comfyui_download_model.md) | `download_model(url, dest_subdir='checkpoints', *, comfyui_dir, filename, token, overwrite, timeout_s) -> dict` | Descarga un checkpoint/LoRA/VAE a `models/<dest_subdir>/`. Soporta Civitai (token) y HuggingFace. Valida que no sea HTML de error ni `.safetensors` corrupto. Impura. |
| [comfyui_interrupt_queue_py_ml](../../python/functions/ml/comfyui_interrupt_queue.md) | `interrupt_queue(server='127.0.0.1:8188') -> dict` | Corta la generación en curso (POST `/interrupt`) y lee la cola (GET `/queue`) → `{ok, interrupted, queue_running, queue_pending, error}`. Freno de mano; degrada limpio en fallo de red. Impura. |
| [comfyui_batch_generate_py_ml](../../python/functions/ml/comfyui_batch_generate.md) | `batch_generate(workflow, *, seeds=None, server='127.0.0.1:8188') -> dict` | Encola N variantes (una por seed), parcheando el campo de semilla de los nodos sampler sin mutar el original → `{ok, prompt_ids, count, error}`. Re-roll en una llamada. Compone `submit_workflow`. Impura. |
### Builders, validación e import — dominio `ml` (P0, issue 0064)
@@ -69,6 +71,18 @@ El **API format** (dict de nodos numerados que produce `build_txt2img_workflow`
| [comfyui_resolve_workflow_deps_py_ml](../../python/functions/ml/comfyui_resolve_workflow_deps.md) | `resolve_workflow_deps(workflow, server='127.0.0.1:8188') -> dict` | Para un workflow ajeno: valida y traduce lo que falta en acciones (`{missing_nodes, missing_models, suggestions}`). Compone `validate_workflow`. Impura. |
| [comfyui_list_installed_models_py_ml](../../python/functions/ml/comfyui_list_installed_models.md) | `list_installed_models(folder=None, comfyui_dir='~/ComfyUI') -> dict` | Lista modelos por carpeta resolviendo la ruta real de `extra_model_paths.yaml` (`/mnt/2tb/comfyui_models/`) + la nativa. Escaneo de FS, no depende del server. Impura. |
### Vídeo (txt2video) — dominio `ml` (tag `video-generation`)
ComfyUI ≥ 0.26.0 trae soporte nativo para **vídeo por difusión**. `build_video_workflow` cubre
los dos modelos que caben en 8 GB: **LTX-Video 2B v0.9.5** (`model='ltx'`, checkpoint todo-en-uno +
VAE temporal + scheduler propio — validado end-to-end en `reports/0084`, clip real de 65 frames,
pico ~7.7 GB) y **Wan2.1 T2V 1.3B** (`model='wan'`, diffusion + umt5 + vae aparte — plantilla nativa
canónica). El resultado es un `.mp4` vía `CreateVideo → SaveVideo`.
| ID | Firma corta | Qué hace |
|---|---|---|
| [comfyui_build_video_workflow_py_ml](../../python/functions/ml/comfyui_build_video_workflow.md) | `build_video_workflow(prompt, *, model='ltx', negative='', width=512, height=320, num_frames=65, steps=20, seed=0, fps=24) -> dict` | Builder txt2video para LTX-Video 2B (`model='ltx'`, 12 nodos LTXV*) o Wan2.1 1.3B (`model='wan'`, UNETLoader+VAELoader+ModelSamplingSD3). Nombres de modelo reales, defaults conservadores 8 GB. **Pura**. |
### Imagen → 3D (Hunyuan3D-2 nativo) — dominio `ml` + `pipelines` (tag `img-to-3d`)
ComfyUI ≥ 0.26.0 trae **soporte nativo de Hunyuan3D-2** (sin custom node): una imagen se
@@ -89,6 +103,7 @@ report `0079`).
| [comfyui_fetch_output_mesh_py_ml](../../python/functions/ml/comfyui_fetch_output_mesh.md) | `fetch_output_mesh(prompt_id, *, server, dest=None, timeout) -> dict` | Localiza la malla en `/history/{prompt_id}` (el SaveGLB la expone bajo la clave `"3d"`, no `"images"`) y la baja via GET `/view` a disco. Hermana de `fetch_output_image`. Impura. |
| [comfyui_install_3d_model_py_ml](../../python/functions/ml/comfyui_install_3d_model.md) | `install_3d_model(variant='mini', *, hf_token=None, comfyui_dir) -> dict` | Instala el checkpoint Hunyuan3D-2 (mini/standard/mv) en `checkpoints/`. Cascada: ya-instalado → cache de HF → descarga. Resuelve la ruta real via `extra_model_paths.yaml`. Impura. |
| [comfyui_image_to_3d_oneshot_py_pipelines](../../python/functions/pipelines/comfyui_image_to_3d_oneshot.md) | `image_to_3d_oneshot(image_path, *, server, variant='mini', dest=None, wait_timeout, **gen) -> dict` | **Pipeline** imagen en disco → malla GLB en una llamada: upload + build + submit + wait + fetch. Promoción de la secuencia (issue 0087). Impuro. |
| [comfyui_build_textured_3d_multiview_workflow_py_ml](../../python/functions/ml/comfyui_build_textured_3d_multiview_workflow.md) | `build_textured_3d_multiview_workflow(image_name, *, ckpt='hunyuan3d-dit-v2-mv.safetensors', views=6, octree=384, max_faces=50000, upscale_model='4x_foolhardy_Remacri.pth') -> dict` | Builder imagen→malla 3D **con textura PBR** vía el wrapper Hunyuan3DWrapper (kijai): 4/6 vistas + delight + sample multi-vista + upscale Remacri + bake sobre UV (19 nodos). Cobertura de atlas 32.93% (report 0082). **Pura**. En 8 GB ejecutar en 2 fases (shape→`/free`→paint). |
### Por la UI web (CDP) — dominio `browser`
@@ -175,30 +190,34 @@ Para tunear nodo a nodo en vez del oneshot: `build_image_to_3d_workflow(image_na
- **No es un grupo de generación genérica de imágenes**: cubre ComfyUI concretamente (su API
y su frontend litegraph). Para otros backends (Automatic1111, diffusers) harían falta otras
funciones.
- **Los builders cubren txt2img, img2img, upscale, LoRA stacks, inpaint, ControlNet y SDXL
refiner** (`build_txt2img_workflow`, `build_img2img_workflow`, `build_upscale_workflow`,
`inject_lora`, `build_inpaint_workflow`, `build_controlnet_workflow`, `build_sdxl_refiner_workflow`).
Workflows aún más complejos (multi-ControlNet avanzado, IPAdapter, vídeo) se montan en la UI a mano
y se capturan con `export_workflow_ui`, o se importan de internet con
`import_workflow_json`/`import_workflow_png`, se resuelven sus dependencias con
- **Los builders cubren txt2img, img2img, upscale, LoRA stacks, inpaint, ControlNet, SDXL
refiner, vídeo (LTX/Wan) y 3D texturizado multi-vista** (`build_txt2img_workflow`,
`build_img2img_workflow`, `build_upscale_workflow`, `inject_lora`, `build_inpaint_workflow`,
`build_controlnet_workflow`, `build_sdxl_refiner_workflow`, `build_video_workflow`,
`build_textured_3d_multiview_workflow`). Workflows aún más complejos (multi-ControlNet avanzado,
IPAdapter) se montan en la UI a mano y se capturan con `export_workflow_ui`, o se importan de
internet con `import_workflow_json`/`import_workflow_png`, se resuelven sus dependencias con
`resolve_workflow_deps` (instala nodos con `install_custom_node`, descubre modelos con
`search_civitai_models`) y se validan con `validate_workflow` antes de encolar.
- **Los 9 builders puros tienen tests de estructura** (`python/functions/ml/tests/test_comfyui_build_*.py`
- **Los 11 builders puros tienen tests de estructura** (`python/functions/ml/tests/test_comfyui_build_*.py`
+ `test_comfyui_inject_lora.py`): verifican los `class_type` esperados, que los parámetros se reflejan
en los nodos, la validez de las conexiones `[node_id, output_index]` y la pureza de `inject_lora`. Son
tests offline (no tocan GPU ni server); las funciones impuras del grupo (todo lo que habla con el server,
el navegador o Civitai/HuggingFace) no se cubren con unit tests por diseño — se validan con el server vivo.
- **Control de cola**: `interrupt_queue` corta la generación en curso + lee `/queue`; `batch_generate`
encola N variantes por seed (re-roll). No vacían la cola entera (eso es `POST /queue {"clear": true}`).
- **Las funciones `*_ui` requieren la pestaña abierta y el navegador con CDP** (puerto 9222 por
defecto). Sin target que matchee `server_url_substr`, devuelven `ok=False`. Para automatización
desatendida sin navegador, usa el camino API (`submit_workflow` + `wait_result`).
- **`download_model` no gestiona el catálogo del server**: tras bajar un modelo, llama
`refresh_nodes_ui` (o recarga la página) para que ComfyUI lo vea en los combos.
- **El camino imagen→3D es shape-only**: los nodos nativos de Hunyuan3D-2
- **El camino imagen→3D nativo es shape-only**: los nodos nativos de Hunyuan3D-2
(`build_image_to_3d_workflow`, `fetch_output_mesh`, `install_3d_model`, `image_to_3d_oneshot`)
reconstruyen la FORMA, sin color ni textura horneada. Para color/textura haría falta el wrapper
de kijai (compila `custom_rasterizer`) — fuera del grupo. Tampoco hay decimación: las mallas son
densas (decenas de MB de GLB). Decisión y comparación vs la app local en
`reports/0069-2026-06-23-comfyui-img-to-3d.md`.
reconstruyen la FORMA, sin color ni textura horneada. Para **textura PBR** está
`build_textured_3d_multiview_workflow`, que usa el wrapper de kijai (requiere `custom_rasterizer`
CUDA + `ComfyUI_essentials` + el upscaler Remacri) y debe ejecutarse en 2 fases en 8 GB
(shape→`/free`→paint). Detalle y cobertura medida en `reports/0082`; shape-only y comparación vs la
app local en `reports/0069-2026-06-23-comfyui-img-to-3d.md`.
- La primitiva de transport CDP es [`cdp_eval`](../../python/functions/browser/cdp_eval.md) (grupo
navegador): si necesitas leer/escribir algo del grafo que estas funciones no cubren, compón
`cdp_eval` directamente antes de inventar nada.