Spaces:
Runtime error
Runtime error
File size: 3,780 Bytes
a8a0eeb 51c2f44 c94d305 a8a0eeb c94d305 a8a0eeb c94d305 a8a0eeb c94d305 a8a0eeb c94d305 a8a0eeb c94d305 a8a0eeb c94d305 a8a0eeb c94d305 a8a0eeb c94d305 a8a0eeb 51c2f44 c94d305 a8a0eeb c94d305 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | import io
import torch
import numpy as np
from fastapi import FastAPI, UploadFile, File, Form
from fastapi.responses import StreamingResponse
from PIL import Image
# Importaciones de IA
from diffusers import StableDiffusionPipeline, DDIMScheduler
from huggingface_hub import hf_hub_download
from ip_adapter.ip_adapter_faceid import IPAdapterFaceID
from insightface.app import FaceAnalysis
app = FastAPI(title="IP-Adapter-FaceID API")
# Variables globales para evitar recargar los modelos en cada petición
app_insight = None
ip_model = None
@app.on_event("startup")
def load_models():
global app_insight, ip_model
device = "cuda" if torch.cuda.is_available() else "cpu"
print(f"Iniciando servidor. Hardware detectado: {device.upper()}")
# 1. Inicializar InsightFace para detectar rostros
print("Cargando InsightFace...")
app_insight = FaceAnalysis(name="buffalo_l", providers=['CUDAExecutionProvider', 'CPUExecutionProvider'])
app_insight.prepare(ctx_id=0, det_size=(640, 640))
# 2. Inicializar Stable Diffusion v1.5
print("Cargando modelo base de Stable Diffusion...")
base_model_path = "SG161222/Realistic_Vision_V4.0_noVAE"
noise_scheduler = DDIMScheduler(
num_train_timesteps=1000,
beta_start=0.00085,
beta_end=0.012,
beta_schedule="scaled_linear",
clip_sample=False,
set_alpha_to_one=False,
steps_offset=1,
)
pipe = StableDiffusionPipeline.from_pretrained(
base_model_path,
torch_dtype=torch.float16 if device == "cuda" else torch.float32,
scheduler=noise_scheduler
).to(device)
# 3. Descargar y cargar las capas de IP-Adapter FaceID
print("Descargando pesos de IP-Adapter-FaceID...")
ip_ckpt_path = hf_hub_download(
repo_id="h94/IP-Adapter-FaceID",
filename="ip-adapter-faceid_sd15.bin",
repo_type="model"
)
print("Acoplando IP-Adapter al modelo base...")
ip_model = IPAdapterFaceID(pipe, ip_ckpt_path, device, num_tokens=4)
print("¡Todos los modelos cargados exitosamente!")
@app.get("/")
def read_root():
return {"status": "running", "message": "API de IP-Adapter-FaceID lista. Realiza un POST a /predict"}
@app.post("/predict")
async def predict(
prompt: str = Form(...),
negative_prompt: str = Form("monochrome, lowres, bad anatomy, worst quality, low quality"),
num_inference_steps: int = Form(30),
face_image: UploadFile = File(...)
):
try:
# 1. Leer y preparar la imagen
face_bytes = await face_image.read()
image = Image.open(io.BytesIO(face_bytes)).convert("RGB")
cv_img = np.array(image)
# 2. Extraer el rostro (Embedding) usando InsightFace
faces = app_insight.get(cv_img)
if len(faces) == 0:
return {"error": "No se detectó ningún rostro en la imagen provista. Por favor intenta con otra foto."}
face_id_embed = torch.from_numpy(faces[0].normed_embedding).unsqueeze(0).unsqueeze(0)
# 3. Generar la imagen
images = ip_model.generate(
prompt=prompt,
negative_prompt=negative_prompt,
face_id_embed=face_id_embed,
num_samples=1,
num_inference_steps=num_inference_steps,
seed=42 # Cambia o recibe este parámetro si quieres resultados aleatorios
)
# 4. Formatear la respuesta como PNG
output_image = images[0]
img_byte_arr = io.BytesIO()
output_image.save(img_byte_arr, format='PNG')
img_byte_arr.seek(0)
return StreamingResponse(img_byte_arr, media_type="image/png")
except Exception as e:
return {"error": str(e)} |