---
name: image_gen_result
lang: py
domain: ml
version: "1.0.0"
algebraic: product
definition: |
  class ImageGenResult(BaseModel):
      image: Any              # PIL.Image.Image en runtime; no serializable
      meta: dict[str, Any]    # config, model, seed_used, sampler, ...
      duration_ms: int
      vram_peak_mb: int | None = None
description: "Resultado de una operacion de generacion de imagen con modelo de difusion. Contiene la imagen PIL, metadata de la generacion, duracion y pico de VRAM."
tags: [ml, diffusion, result, image, pil, vram, latency, stable-diffusion, flux]
uses_types: [generation_config_py_ml]
file_path: "python/functions/ml/image_gen_result.py"
---

## Notas

El campo `image` es `PIL.Image.Image` en runtime pero se declara como `Any` para evitar un import duro de Pillow en este modulo. Esto permite importar `ImageGenResult` en contextos sin Pillow instalado (orquestadores, tests de tipos, servicios Go que parsean solo el JSON de `meta`).

**Como guardar la imagen:**
```python
result: ImageGenResult = generator.generate(config)
result.image.save("output.png")  # PIL API directa
```

**Como serializar para logging/Go:**
```python
# model_dump() excluye el campo image automaticamente
payload = result.model_dump()
# payload = {"meta": {...}, "duration_ms": 1234, "vram_peak_mb": 4096}
```

**Contenido esperado de `meta`:**

| Clave          | Tipo   | Descripcion                                        |
|----------------|--------|----------------------------------------------------|
| `config`       | dict   | `GenerationConfig.model_dump()` con params usados  |
| `model`        | str    | Nombre del modelo (model_ref.name)                 |
| `seed_used`    | int    | Semilla real usada (importante cuando seed=-1)     |
| `sampler`      | str    | Nombre del sampler ejecutado                       |
| `backend`      | str    | "diffusers", "sd_cpp", "comfy", etc.               |

El campo `vram_peak_mb` es `None` en inferencia CPU o cuando el backend no expone estadisticas de memoria GPU. En backends con soporte (diffusers + torch.cuda.max_memory_allocated) se rellena automaticamente.
