a802f59f55
- cmd/fn/doctor.go - cmd/fn/main.go - cpp/apps/primitives_gallery/playground/tables/CMakeLists.txt - cpp/apps/primitives_gallery/playground/tables/data_table.cpp - cpp/apps/primitives_gallery/playground/tables/data_table_logic.cpp - cpp/apps/primitives_gallery/playground/tables/data_table_logic.h - cpp/apps/primitives_gallery/playground/tables/self_test.cpp - cpp/apps/primitives_gallery/playground/tables/tql.cpp - cpp/apps/primitives_gallery/playground/tables/viz.cpp - cpp/apps/primitives_gallery/playground/tables/viz.h - ... Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
99 lines
3.2 KiB
Python
99 lines
3.2 KiB
Python
"""diffusers_generate — ejecuta inferencia con un pipeline diffusers y retorna ImageGenResult."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
import os
|
|
import time
|
|
from typing import Any
|
|
|
|
sys.path.insert(0, os.path.dirname(__file__))
|
|
|
|
from generation_config import GenerationConfig
|
|
from image_gen_result import ImageGenResult
|
|
from genconfig_to_diffusers_kwargs import genconfig_to_diffusers_kwargs
|
|
|
|
|
|
def diffusers_generate(pipe: Any, cfg: GenerationConfig) -> ImageGenResult:
|
|
"""Ejecuta inferencia con un pipeline diffusers y retorna ImageGenResult.
|
|
|
|
Convierte el GenerationConfig a kwargs via genconfig_to_diffusers_kwargs,
|
|
crea un torch.Generator con la semilla configurada, mide duracion y pico
|
|
de VRAM (si CUDA disponible). El campo meta del resultado incluye backend,
|
|
modelo, sampler, seed y steps usados.
|
|
|
|
Args:
|
|
pipe: Pipeline diffusers cargado (resultado de diffusers_load_pipeline).
|
|
Debe ser callable: pipe(prompt=..., ...) -> objeto con .images[0].
|
|
cfg: Parametros de generacion. cfg.seed se usa para torch.Generator.
|
|
cfg.model.name se incluye en meta. cfg.sampler se incluye en meta
|
|
pero NO se aplica aqui — usar diffusers_set_scheduler antes si se
|
|
quiere cambiar el sampler.
|
|
|
|
Returns:
|
|
ImageGenResult con image=PIL.Image, meta con keys backend/model/sampler/
|
|
actual_steps/seed, duration_ms y vram_peak_mb (None si no hay CUDA).
|
|
|
|
Raises:
|
|
ImportError: Si torch o diffusers no estan instalados.
|
|
RuntimeError: Si la inferencia falla (OOM, modelo incompatible, etc.).
|
|
"""
|
|
try:
|
|
import torch
|
|
except ImportError as exc:
|
|
raise ImportError(
|
|
"diffusers_generate requiere torch. "
|
|
"Instalar con: pip install torch"
|
|
) from exc
|
|
|
|
# Determinar device del pipeline
|
|
device = "cpu"
|
|
if hasattr(pipe, "device"):
|
|
device = str(pipe.device)
|
|
|
|
# Medir VRAM solo en CUDA
|
|
cuda_available = torch.cuda.is_available()
|
|
if cuda_available:
|
|
torch.cuda.reset_peak_memory_stats()
|
|
|
|
# Construir kwargs desde GenerationConfig
|
|
kwargs = genconfig_to_diffusers_kwargs(cfg)
|
|
|
|
# Crear generator con semilla
|
|
seed = cfg.seed if cfg.seed >= 0 else int(time.time()) % (2**32)
|
|
generator = torch.Generator(device=device).manual_seed(seed)
|
|
kwargs["generator"] = generator
|
|
|
|
# Inferencia
|
|
t0 = time.perf_counter()
|
|
result = pipe(**kwargs)
|
|
t1 = time.perf_counter()
|
|
|
|
duration_ms = int((t1 - t0) * 1000)
|
|
|
|
# VRAM peak
|
|
vram_peak_mb: int | None = None
|
|
if cuda_available:
|
|
vram_peak_mb = torch.cuda.max_memory_allocated() // 1024 // 1024
|
|
|
|
# Nombre del modelo
|
|
model_name = cfg.model.name if cfg.model and hasattr(cfg.model, "name") else "unknown"
|
|
|
|
meta: dict[str, Any] = {
|
|
"backend": "diffusers",
|
|
"model": model_name,
|
|
"sampler": cfg.sampler,
|
|
"actual_steps": cfg.steps,
|
|
"seed": seed,
|
|
"width": cfg.width,
|
|
"height": cfg.height,
|
|
"cfg_scale": cfg.cfg_scale,
|
|
}
|
|
|
|
return ImageGenResult(
|
|
image=result.images[0],
|
|
meta=meta,
|
|
duration_ms=duration_ms,
|
|
vram_peak_mb=vram_peak_mb,
|
|
)
|