primerz commited on
Commit
8a3467f
·
verified ·
1 Parent(s): 051c96e

Update generator.py

Browse files
Files changed (1) hide show
  1. generator.py +46 -27
generator.py CHANGED
@@ -21,7 +21,6 @@ class Generator:
21
  lineart_map_raw = self.mh.lineart_anime_detector(image)
22
 
23
  # Manually resize maps to match the exact output resolution
24
- # This ensures the aspect ratio is preserved from the processed_image
25
  depth_map = depth_map_raw.resize((width, height), Image.LANCZOS)
26
  lineart_map = lineart_map_raw.resize((width, height), Image.LANCZOS)
27
 
@@ -39,16 +38,50 @@ class Generator:
39
  lineart_strength=0.3,
40
  seed=-1
41
  ):
42
- # 1. Pre-process Inputs (Maintains Aspect Ratio)
43
  print("Processing Input...")
44
- # Keeps original aspect ratio logic
45
  processed_image = resize_image_to_1mp(input_image)
46
  target_width, target_height = processed_image.size
47
 
48
- # 2. Get Face Info
49
- # (Note: Your model.py already handles the "Max Face" sorting logic)
50
  face_info = self.mh.get_face_info(processed_image)
51
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  # 3. Generate Prompt
53
  if not user_prompt.strip():
54
  try:
@@ -61,46 +94,34 @@ class Generator:
61
  final_prompt = f"{Config.STYLE_TRIGGER}, {user_prompt}"
62
 
63
  print(f"Prompt: {final_prompt}")
64
- print(f"Negative Prompt: {negative_prompt}")
65
 
66
- # 4. Generate OTHER Control Maps (Structure)
67
  print("Generating Control Maps (Depth, LineArt)...")
68
  depth_map, lineart_map = self.prepare_control_images(processed_image, target_width, target_height)
69
 
70
  # 5. Logic for Face vs No-Face
71
- # ControlNet order: [InstantID_KPS, Zoe_Depth, LineArt]
72
  if face_info is not None:
73
  print("Face detected: Applying InstantID with keypoints.")
74
 
75
- # --- FIX APPLIED HERE ---
76
- # Changed from face_info.normed_embedding to face_info['embedding']
77
- # This fixes the "generic/Chinese face" issue by using the raw embedding magnitude.
78
  face_emb = torch.tensor(
79
  face_info['embedding'],
80
  dtype=Config.DTYPE,
81
  device=Config.DEVICE
82
  ).unsqueeze(0)
83
- # --- END FIX ---
84
 
85
- # Create keypoint image
86
  face_kps = draw_kps(processed_image, face_info['kps'])
87
 
88
- # Set strengths
89
- # Note: 0.8 is the standard effective strength for InstantID
90
  controlnet_conditioning_scale = [0.8, depth_strength, lineart_strength]
91
  self.mh.pipeline.set_ip_adapter_scale(0.8)
92
  else:
93
  print("No face detected: Disabling InstantID.")
94
- # Create dummy embedding
95
  face_emb = torch.zeros((1, 512), dtype=Config.DTYPE, device=Config.DEVICE)
96
- # Create dummy keypoint image (black)
97
  face_kps = Image.new('RGB', (target_width, target_height), (0, 0, 0))
98
 
99
- # Set strengths
100
  controlnet_conditioning_scale = [0.0, depth_strength, lineart_strength]
101
  self.mh.pipeline.set_ip_adapter_scale(0.0)
102
 
103
- # We keep the guidance_end for pose low (Standard InstantID practice)
104
  control_guidance_end = [0.3, 0.6, 0.6]
105
 
106
  # --- Seed/Generator Logic ---
@@ -108,27 +129,25 @@ class Generator:
108
  seed = torch.Generator().seed()
109
  generator = torch.Generator(device=Config.DEVICE).manual_seed(int(seed))
110
  print(f"Using seed: {seed}")
111
- # --- END ---
112
 
113
  # 6. Run Inference
114
  print("Running pipeline...")
115
  result = self.mh.pipeline(
116
  prompt=final_prompt,
117
  negative_prompt=negative_prompt,
118
- image=processed_image, # Base img2img image
119
  control_image=[face_kps, depth_map, lineart_map],
120
- image_embeds=face_emb, # Face identity embedding
121
  generator=generator,
122
 
123
- # --- Parameters from UI ---
124
- strength=img2img_strength,
 
125
  num_inference_steps=num_inference_steps,
126
- guidance_scale=guidance_scale,
127
- # --- End Parameters from UI ---
128
 
129
  controlnet_conditioning_scale=controlnet_conditioning_scale,
130
  control_guidance_end=control_guidance_end,
131
-
132
  clip_skip=2,
133
 
134
  ).images[0]
 
21
  lineart_map_raw = self.mh.lineart_anime_detector(image)
22
 
23
  # Manually resize maps to match the exact output resolution
 
24
  depth_map = depth_map_raw.resize((width, height), Image.LANCZOS)
25
  lineart_map = lineart_map_raw.resize((width, height), Image.LANCZOS)
26
 
 
38
  lineart_strength=0.3,
39
  seed=-1
40
  ):
41
+ # 1. Pre-process Inputs
42
  print("Processing Input...")
 
43
  processed_image = resize_image_to_1mp(input_image)
44
  target_width, target_height = processed_image.size
45
 
46
+ # 2. Get Face Info
 
47
  face_info = self.mh.get_face_info(processed_image)
48
 
49
+ # --- START ADAPTIVE PARAMETER LOGIC ---
50
+ adaptive_cfg = guidance_scale
51
+ adaptive_strength = img2img_strength
52
+
53
+ if face_info is not None:
54
+ # Calculate Face Coverage Ratio
55
+ bbox = face_info['bbox']
56
+ face_area = (bbox[2] - bbox[0]) * (bbox[3] - bbox[1])
57
+ total_area = target_width * target_height
58
+ coverage_ratio = face_area / total_area
59
+
60
+ print(f"Face Coverage: {coverage_ratio:.2f} ({int(coverage_ratio * 12)}/12)")
61
+
62
+ # Apply variance logic based on your requested thresholds
63
+ if coverage_ratio >= (8/12): # > 0.66 (High Coverage)
64
+ # Lower CFG by 5-15% (avg 10%), keep strength same
65
+ adaptive_cfg = guidance_scale * 0.90
66
+ adaptive_strength = img2img_strength * 1.0
67
+ print("-> High Coverage: Applying slight CFG reduction (-10%)")
68
+
69
+ elif coverage_ratio >= (4/12): # 0.33 to 0.66 (Medium Coverage)
70
+ # CFG lower 20-30% (avg 25%), strength lower 5-10% (avg 7.5%)
71
+ adaptive_cfg = guidance_scale * 0.75
72
+ adaptive_strength = img2img_strength * 0.925
73
+ print("-> Medium Coverage: Lowering CFG (-25%) and Strength (-7.5%)")
74
+
75
+ else: # < 0.33 (Low Coverage)
76
+ # CFG lower 30-40% (avg 35%), strength lower 10-15% (avg 12.5%)
77
+ adaptive_cfg = guidance_scale * 0.65
78
+ adaptive_strength = img2img_strength * 0.875
79
+ print("-> Low Coverage: Significantly lowering CFG (-35%) and Strength (-12.5%)")
80
+
81
+ print(f"Adaptive CFG: {guidance_scale} -> {adaptive_cfg:.2f}")
82
+ print(f"Adaptive Strength: {img2img_strength} -> {adaptive_strength:.2f}")
83
+ # --- END ADAPTIVE PARAMETER LOGIC ---
84
+
85
  # 3. Generate Prompt
86
  if not user_prompt.strip():
87
  try:
 
94
  final_prompt = f"{Config.STYLE_TRIGGER}, {user_prompt}"
95
 
96
  print(f"Prompt: {final_prompt}")
 
97
 
98
+ # 4. Generate OTHER Control Maps
99
  print("Generating Control Maps (Depth, LineArt)...")
100
  depth_map, lineart_map = self.prepare_control_images(processed_image, target_width, target_height)
101
 
102
  # 5. Logic for Face vs No-Face
 
103
  if face_info is not None:
104
  print("Face detected: Applying InstantID with keypoints.")
105
 
106
+ # Corrected Raw Embedding Usage
 
 
107
  face_emb = torch.tensor(
108
  face_info['embedding'],
109
  dtype=Config.DTYPE,
110
  device=Config.DEVICE
111
  ).unsqueeze(0)
 
112
 
 
113
  face_kps = draw_kps(processed_image, face_info['kps'])
114
 
 
 
115
  controlnet_conditioning_scale = [0.8, depth_strength, lineart_strength]
116
  self.mh.pipeline.set_ip_adapter_scale(0.8)
117
  else:
118
  print("No face detected: Disabling InstantID.")
 
119
  face_emb = torch.zeros((1, 512), dtype=Config.DTYPE, device=Config.DEVICE)
 
120
  face_kps = Image.new('RGB', (target_width, target_height), (0, 0, 0))
121
 
 
122
  controlnet_conditioning_scale = [0.0, depth_strength, lineart_strength]
123
  self.mh.pipeline.set_ip_adapter_scale(0.0)
124
 
 
125
  control_guidance_end = [0.3, 0.6, 0.6]
126
 
127
  # --- Seed/Generator Logic ---
 
129
  seed = torch.Generator().seed()
130
  generator = torch.Generator(device=Config.DEVICE).manual_seed(int(seed))
131
  print(f"Using seed: {seed}")
 
132
 
133
  # 6. Run Inference
134
  print("Running pipeline...")
135
  result = self.mh.pipeline(
136
  prompt=final_prompt,
137
  negative_prompt=negative_prompt,
138
+ image=processed_image,
139
  control_image=[face_kps, depth_map, lineart_map],
140
+ image_embeds=face_emb,
141
  generator=generator,
142
 
143
+ # --- UPDATED: Use Adaptive Parameters ---
144
+ strength=adaptive_strength, # <-- Uses calculated strength
145
+ guidance_scale=adaptive_cfg, # <-- Uses calculated CFG
146
  num_inference_steps=num_inference_steps,
147
+ # --------------------------------------
 
148
 
149
  controlnet_conditioning_scale=controlnet_conditioning_scale,
150
  control_guidance_end=control_guidance_end,
 
151
  clip_skip=2,
152
 
153
  ).images[0]