Nad54 commited on
Commit
633210e
·
verified ·
1 Parent(s): 3a7fbf1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +30 -29
app.py CHANGED
@@ -1,22 +1,29 @@
1
- # app.py — InstantID SDXL (Option 1: téléchargements auto des poids depuis un repo Model)
2
- # - Tu uploades localement SEULEMENT la pipeline .py (texte) dans ./instantid/
3
- # - Les poids (safetensors/bin) sont téléchargés au runtime depuis InstantX/InstantID (repo Model)
 
4
  import os, traceback, importlib.util
5
 
6
- # Eviter l'erreur libgomp
7
- os.environ.setdefault("OMP_NUM_THREADS", "4")
 
 
 
 
 
 
8
  os.environ.setdefault("HF_HUB_ENABLE_HF_TRANSFER", "1")
9
 
10
  import torch, gradio as gr
11
  from PIL import Image, ImageOps
12
- from huggingface_hub import hf_hub_download, HfHubHTTPError
13
  from diffusers.models import ControlNetModel
14
 
15
  DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
16
  DTYPE = torch.float16 if DEVICE == "cuda" else torch.float32
17
 
18
- # -------- Références Hub (repo MODEL public qui contient les poids) --------
19
- ASSETS_REPO = "InstantX/InstantID" # tu peux le remplacer par ton propre repo MODEL si besoin
20
 
21
  # -------- Chemins locaux attendus dans le Space --------
22
  PIPE_CANDIDATES = [
@@ -33,10 +40,10 @@ def import_pipeline_or_fail():
33
  if pipeline_file is None:
34
  raise RuntimeError(
35
  "Pipeline InstantID introuvable.\n"
36
- "➡️ Uploade l’un de ces fichiers (texte) dans ton Space :\n"
37
  " - instantid/pipeline_stable_diffusion_xl_instantid.py\n"
38
  " - instantid/pipeline_stable_diffusion_xl_instantid_full.py\n"
39
- "Les poids seront téléchargés automatiquement."
40
  )
41
  spec = importlib.util.spec_from_file_location("instantid_pipeline", pipeline_file)
42
  mod = importlib.util.module_from_spec(spec)
@@ -50,21 +57,14 @@ def import_pipeline_or_fail():
50
  def ensure_assets_or_download():
51
  os.makedirs(CHECKPOINTS_DIR, exist_ok=True)
52
  os.makedirs(CN_LOCAL_DIR, exist_ok=True)
53
- # Télécharge/valide ControlNet IdentityNet
54
- try:
55
- if not os.path.isfile(os.path.join(CN_LOCAL_DIR, "config.json")):
56
- hf_hub_download(ASSETS_REPO, "ControlNetModel/config.json", local_dir=CHECKPOINTS_DIR)
57
- if not os.path.isfile(os.path.join(CN_LOCAL_DIR, "diffusion_pytorch_model.safetensors")):
58
- hf_hub_download(ASSETS_REPO, "ControlNetModel/diffusion_pytorch_model.safetensors", local_dir=CHECKPOINTS_DIR)
59
- except HfHubHTTPError as e:
60
- raise RuntimeError(f"Echec téléchargement IdentityNet depuis {ASSETS_REPO} : {e}")
61
-
62
- # Télécharge/valide ip-adapter.bin
63
- try:
64
- if not os.path.isfile(IP_ADAPTER_LOCAL):
65
- hf_hub_download(ASSETS_REPO, "ip-adapter.bin", local_dir=CHECKPOINTS_DIR)
66
- except HfHubHTTPError as e:
67
- raise RuntimeError(f"Echec téléchargement ip-adapter.bin depuis {ASSETS_REPO} : {e}")
68
 
69
  # -------- Chargement pipeline --------
70
  load_logs = []
@@ -72,7 +72,7 @@ try:
72
  SDXLInstantID, draw_kps = import_pipeline_or_fail()
73
  ensure_assets_or_download()
74
 
75
- BASE_MODEL = "stabilityai/stable-diffusion-xl-base-1.0" # remplaçable par un SDXL style anime si tu en as
76
 
77
  load_logs.append("Chargement ControlNet IdentityNet…")
78
  controlnet_identitynet = ControlNetModel.from_pretrained(CN_LOCAL_DIR, torch_dtype=DTYPE)
@@ -86,6 +86,7 @@ try:
86
  feature_extractor=None,
87
  ).to(DEVICE)
88
 
 
89
  if hasattr(pipe, "load_ip_adapter_instantid"):
90
  pipe.load_ip_adapter_instantid(IP_ADAPTER_LOCAL)
91
  else:
@@ -103,7 +104,7 @@ except Exception:
103
  if pipe is None:
104
  raise RuntimeError("Échec chargement pipeline InstantID.\n" + "\n".join(load_logs))
105
 
106
- # -------- InsightFace pour landmarks --------
107
  from insightface.app import FaceAnalysis
108
  fa = FaceAnalysis(name="antelopev2", root="./", providers=["CPUExecutionProvider"])
109
  fa.prepare(ctx_id=0, det_size=(640, 640))
@@ -114,7 +115,7 @@ def extract_kps_image(pil_img: Image.Image):
114
  faces = fa.get(img_cv2)
115
  if not faces:
116
  raise ValueError("Aucun visage détecté. Utilise un portrait net (visage centré).")
117
- face = faces[-1] # visage principal
118
  return draw_kps(pil_img, face["kps"])
119
 
120
  # -------- Inference --------
@@ -148,7 +149,7 @@ def generate(face_image, prompt, negative_prompt, identity_strength, adapter_str
148
 
149
  return images[0], "", "\n".join(load_logs)
150
  except torch.cuda.OutOfMemoryError as oom:
151
- msg = "CUDA OOM: baisse la résolution (ex: 640×768 → 576×704), steps 24–28, CFG 5–6."
152
  return None, f"{msg}\n{oom}", "\n".join(load_logs)
153
  except Exception:
154
  return None, "Erreur:\n"+traceback.format_exc(), "\n".join(load_logs)
 
1
+ # app.py — InstantID SDXL (Option 1, robuste aux erreurs OMP + hub)
2
+ # - Tu uploades SEULEMENT la pipeline .py (texte) dans ./instantid/
3
+ # - Les poids sont téléchargés auto depuis InstantX/InstantID (repo Model)
4
+
5
  import os, traceback, importlib.util
6
 
7
+ # --- Sécuriser OMP_NUM_THREADS (éviter libgomp error) ---
8
+ val = os.environ.get("OMP_NUM_THREADS", "")
9
+ try:
10
+ if val == "" or int(val) <= 0:
11
+ os.environ["OMP_NUM_THREADS"] = "1"
12
+ except Exception:
13
+ os.environ["OMP_NUM_THREADS"] = "1"
14
+
15
  os.environ.setdefault("HF_HUB_ENABLE_HF_TRANSFER", "1")
16
 
17
  import torch, gradio as gr
18
  from PIL import Image, ImageOps
19
+ from huggingface_hub import hf_hub_download # <- pas de HfHubHTTPError (compat large)
20
  from diffusers.models import ControlNetModel
21
 
22
  DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
23
  DTYPE = torch.float16 if DEVICE == "cuda" else torch.float32
24
 
25
+ # -------- Repo Model qui contient les poids (public) --------
26
+ ASSETS_REPO = "InstantX/InstantID"
27
 
28
  # -------- Chemins locaux attendus dans le Space --------
29
  PIPE_CANDIDATES = [
 
40
  if pipeline_file is None:
41
  raise RuntimeError(
42
  "Pipeline InstantID introuvable.\n"
43
+ "➡️ Uploade l’un de ces fichiers (TEXTE uniquement) dans ton Space :\n"
44
  " - instantid/pipeline_stable_diffusion_xl_instantid.py\n"
45
  " - instantid/pipeline_stable_diffusion_xl_instantid_full.py\n"
46
+ "(Ne mets PAS de .safetensors dans le Space — ils seront téléchargés automatiquement)."
47
  )
48
  spec = importlib.util.spec_from_file_location("instantid_pipeline", pipeline_file)
49
  mod = importlib.util.module_from_spec(spec)
 
57
  def ensure_assets_or_download():
58
  os.makedirs(CHECKPOINTS_DIR, exist_ok=True)
59
  os.makedirs(CN_LOCAL_DIR, exist_ok=True)
60
+ # ControlNet IdentityNet
61
+ if not os.path.isfile(os.path.join(CN_LOCAL_DIR, "config.json")):
62
+ hf_hub_download(ASSETS_REPO, "ControlNetModel/config.json", local_dir=CHECKPOINTS_DIR)
63
+ if not os.path.isfile(os.path.join(CN_LOCAL_DIR, "diffusion_pytorch_model.safetensors")):
64
+ hf_hub_download(ASSETS_REPO, "ControlNetModel/diffusion_pytorch_model.safetensors", local_dir=CHECKPOINTS_DIR)
65
+ # ip-adapter
66
+ if not os.path.isfile(IP_ADAPTER_LOCAL):
67
+ hf_hub_download(ASSETS_REPO, "ip-adapter.bin", local_dir=CHECKPOINTS_DIR)
 
 
 
 
 
 
 
68
 
69
  # -------- Chargement pipeline --------
70
  load_logs = []
 
72
  SDXLInstantID, draw_kps = import_pipeline_or_fail()
73
  ensure_assets_or_download()
74
 
75
+ BASE_MODEL = "stabilityai/stable-diffusion-xl-base-1.0" # tu peux remplacer par un SDXL plus anime
76
 
77
  load_logs.append("Chargement ControlNet IdentityNet…")
78
  controlnet_identitynet = ControlNetModel.from_pretrained(CN_LOCAL_DIR, torch_dtype=DTYPE)
 
86
  feature_extractor=None,
87
  ).to(DEVICE)
88
 
89
+ # ip-adapter d’InstantID
90
  if hasattr(pipe, "load_ip_adapter_instantid"):
91
  pipe.load_ip_adapter_instantid(IP_ADAPTER_LOCAL)
92
  else:
 
104
  if pipe is None:
105
  raise RuntimeError("Échec chargement pipeline InstantID.\n" + "\n".join(load_logs))
106
 
107
+ # -------- InsightFace (landmarks) --------
108
  from insightface.app import FaceAnalysis
109
  fa = FaceAnalysis(name="antelopev2", root="./", providers=["CPUExecutionProvider"])
110
  fa.prepare(ctx_id=0, det_size=(640, 640))
 
115
  faces = fa.get(img_cv2)
116
  if not faces:
117
  raise ValueError("Aucun visage détecté. Utilise un portrait net (visage centré).")
118
+ face = faces[-1]
119
  return draw_kps(pil_img, face["kps"])
120
 
121
  # -------- Inference --------
 
149
 
150
  return images[0], "", "\n".join(load_logs)
151
  except torch.cuda.OutOfMemoryError as oom:
152
+ msg = "CUDA OOM: baisse résolution (ex: 640×768 → 576×704), steps 24–28, CFG 5–6."
153
  return None, f"{msg}\n{oom}", "\n".join(load_logs)
154
  except Exception:
155
  return None, "Erreur:\n"+traceback.format_exc(), "\n".join(load_logs)