Astridkraft commited on
Commit
f0735ee
·
verified ·
1 Parent(s): 1b18b73

Create controlnet_facefix.py

Browse files
Files changed (1) hide show
  1. controlnet_facefix.py +68 -0
controlnet_facefix.py ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from diffusers import StableDiffusionControlNetInpaintPipeline, ControlNetModel
3
+ from controlnet_aux import OpenposeDetector, ZoeDetector
4
+ from PIL import Image
5
+
6
+ # ───── Globale Modelle (einmal laden, bleibt im VRAM) ─────
7
+ print("Lade OpenPose_faceonly + Depth für perfekte Gesichter/Hände...")
8
+
9
+ # OpenPose Face-Only Preprocessor + ControlNet
10
+ openpose_face = OpenposeDetector.from_pretrained(
11
+ "lllyasviel/ControlNet", model_name="openpose_face"
12
+ )
13
+
14
+ # Depth Preprocessor + ControlNet
15
+ depth_processor = ZoeDetector.from_pretrained("lllyasviel/ControlNet")
16
+
17
+ controlnet_face = ControlNetModel.from_pretrained(
18
+ "lllyasviel/control_v11p_sd15_openpose",
19
+ subfolder="faceonly",
20
+ torch_dtype=torch.float16
21
+ ).to("cuda")
22
+
23
+ controlnet_depth = ControlNetModel.from_pretrained(
24
+ "lllyasviel/control_v11f1e_sd15_depth",
25
+ torch_dtype=torch.float16
26
+ ).to("cuda")
27
+
28
+ # Pipeline-Cache (wird erst beim ersten Aufruf erstellt)
29
+ _facefix_pipe = None
30
+
31
+ def _get_facefix_pipeline(model_id: str):
32
+ global _facefix_pipe
33
+ if _facefix_pipe is None:
34
+ print(f"Lade Face-Fix-Pipeline mit Modell: {model_id}")
35
+ _facefix_pipe = StableDiffusionControlNetInpaintPipeline.from_pretrained(
36
+ model_id,
37
+ controlnet=[controlnet_face, controlnet_depth],
38
+ torch_dtype=torch.float16,
39
+ safety_checker=None,
40
+ requires_safety_checker=False,
41
+ ).to("cuda")
42
+ _facefix_pipe.enable_xformers_memory_efficient_attention()
43
+ _facefix_pipe.enable_model_cpu_offload() # spart ~2 GB bei 16 GB Karten
44
+ return _facefix_pipe
45
+
46
+ def apply_facefix(image: Image.Image, prompt: str, negative_prompt: str, seed: int, base_model_path: str):
47
+ """
48
+ Automatischer 20-Sekunden-Fix für perfekte Gesichter & Hände
49
+ """
50
+ pipe = _get_facefix_pipeline(base_model_path)
51
+
52
+ # Control-Images aus dem generierten Bild erzeugen
53
+ pose_img = openpose_face(image)
54
+ depth_img = depth_processor(image)
55
+
56
+ fixed_image = pipe(
57
+ prompt=prompt,
58
+ negative_prompt=negative_prompt,
59
+ image=image,
60
+ control_image=[pose_img, depth_img],
61
+ controlnet_conditioning_scale=[0.85, 0.60], # Face stark, Depth mittel
62
+ strength=0.42,
63
+ num_inference_steps=20,
64
+ guidance_scale=7.0,
65
+ generator=torch.Generator("cuda").manual_seed(seed),
66
+ ).images[0]
67
+
68
+ return fixed_image