appinitdev commited on
Commit
c94d305
·
verified ·
1 Parent(s): 3e60620

Update app.py

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