---
name: comfyui_install_3d_model
kind: function
lang: py
domain: ml
version: "1.0.0"
purity: impure
signature: "def comfyui_install_3d_model(variant: str = \"mini\", *, hf_token: str | None = None, comfyui_dir: str = \"~/ComfyUI\") -> dict"
description: "Instala un checkpoint Hunyuan3D-2 (mini/standard/mv) en la carpeta checkpoints/ de ComfyUI para los nodos nativos imagen->3D (ImageOnlyCheckpointLoader). Cascada: si el destino ya existe reutiliza; si esta en la cache de HuggingFace copia desde ahi (sin red); si no, descarga con huggingface_hub (token de pass si gated). Resuelve la ruta real de checkpoints via extra_model_paths.yaml. Impura: YAML + disco + posible red + subprocess pass."
tags: [comfyui, ml, img-to-3d, hunyuan3d, model, install]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: error_go_core
imports: []
params:
  - name: variant
    desc: "'mini' (≈5 GB VRAM, default), 'standard' (dit-v2-0, ≈6 GB) o 'mv' (multiview). Determina el repo de HF y el nombre destino del .safetensors."
  - name: hf_token
    desc: "Token de HuggingFace si la variante fuera gated. Si None y hace falta descargar, se intenta leer de 'pass show API_TOKEN_huggingFace'. keyword-only."
  - name: comfyui_dir
    desc: "Raiz de la instalacion de ComfyUI (se expande ~). La carpeta real de checkpoints se resuelve via extra_model_paths.yaml. keyword-only."
output: "dict {ok, path, bytes, reused_cache, error}. path = ruta del checkpoint en checkpoints/; reused_cache=True si ya estaba instalado o se copio de la cache de HF (sin descarga de red). Si falla, ok=False y error explica."
tested: false
tests: []
test_file_path: ""
file_path: "python/functions/ml/comfyui_install_3d_model.py"
---

## Ejemplo

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

res = comfyui_install_3d_model("mini")
# Si ya esta (cache o instalado): reused_cache=True, sin re-bajar 3.8 GB.
# res == {"ok": True, "path": "/mnt/2tb/comfyui_models/checkpoints/3D_hunyuan3d-dit-v2-mini.safetensors",
#         "bytes": 3819958234, "reused_cache": True, "error": ""}
```

Lánzalo con el python del venv (import de arriba o heredoc). Nota: `./fn run` directo no aplica porque la firma usa `*` (keyword-only), no soportado por el generador de runner de `fn run`.

## Cuando usarla

Antes de reconstruir mallas 3D con los nodos nativos de Hunyuan3D-2: asegura que
el checkpoint que pide `ImageOnlyCheckpointLoader` esta en `checkpoints/`. Llamala
una vez por PC/variante; en sucesivas devuelve `reused_cache=True` al instante. El
pipeline `comfyui_image_to_3d_oneshot` NO la llama (asume el modelo ya instalado);
ejecutala tu antes la primera vez.

## Gotchas

- Impura: lee YAML, escribe en disco (copia de GBs cuando toca), y puede hacer red
  + subprocess `pass`. La copia desde la cache de HF de un .safetensors de ~3.8 GB
  tarda unos segundos; el caso `reused_cache` ya-instalado es instantaneo.
- Resuelve la carpeta de checkpoints real via `extra_model_paths.yaml` (en este
  equipo `/mnt/2tb/comfyui_models/checkpoints/`, seccion `is_default`). Si el YAML
  falta cae a `<comfyui_dir>/models/checkpoints`.
- La descarga (rama 3) necesita `huggingface_hub` en el venv. Si no esta instalado
  y el modelo no esta en la cache, devuelve `ok=False` con instrucciones (instalar
  huggingface_hub o usar `comfyui_download_model` con la URL de resolve de HF).
- Hunyuan3D-2 mini NO es gated (no requiere token). `standard`/`mv` se asumen
  publicos tambien; si alguno fuera gated, pasa `hf_token` o ten el token en `pass`.
- Tras instalar, ComfyUI re-escanea `checkpoints/` dinamicamente (no hace falta
  reiniciar el server para checkpoints; solo los custom nodes nuevos exigen restart).
- No valida el contenido del .safetensors mas alla de un tamano minimo; confia en
  la integridad de la cache de HF o de la descarga de huggingface_hub.
