primerz commited on
Commit
8bbe1e4
·
verified ·
1 Parent(s): a70cb97

Update models.py

Browse files
Files changed (1) hide show
  1. models.py +105 -177
models.py CHANGED
@@ -1,5 +1,6 @@
1
  """
2
  Model loading and initialization for Pixagram AI Pixel Art Generator
 
3
  """
4
  import torch
5
  import time
@@ -11,14 +12,15 @@ from diffusers import (
11
  )
12
  from diffusers.models.attention_processor import AttnProcessor2_0
13
  from transformers import CLIPVisionModelWithProjection
14
- from transformers import BlipProcessor, BlipForConditionalGeneration
15
  from insightface.app import FaceAnalysis
16
  from controlnet_aux import ZoeDetector
17
  from huggingface_hub import hf_hub_download
18
  from compel import Compel, ReturnedEmbeddingsType
19
 
20
- from ip_attention_processor_compatible import IPAttnProcessorCompatible as IPAttnProcessor2_0
21
- from resampler_compatible import create_compatible_resampler as create_enhanced_resampler
 
 
22
  from config import (
23
  device, dtype, MODEL_REPO, MODEL_FILES, HUGGINGFACE_TOKEN,
24
  FACE_DETECTION_CONFIG, CLIP_SKIP, DOWNLOAD_CONFIG
@@ -26,17 +28,7 @@ from config import (
26
 
27
 
28
  def download_model_with_retry(repo_id, filename, max_retries=None):
29
- """
30
- Download model with retry logic and proper token handling.
31
-
32
- Args:
33
- repo_id: HuggingFace repository ID
34
- filename: File to download
35
- max_retries: Maximum number of retries (uses config default if None)
36
-
37
- Returns:
38
- Path to downloaded file
39
- """
40
  if max_retries is None:
41
  max_retries = DOWNLOAD_CONFIG['max_retries']
42
 
@@ -44,7 +36,6 @@ def download_model_with_retry(repo_id, filename, max_retries=None):
44
  try:
45
  print(f" Attempting to download {filename} (attempt {attempt + 1}/{max_retries})...")
46
 
47
- # Use token if available
48
  kwargs = {"repo_type": "model"}
49
  if HUGGINGFACE_TOKEN:
50
  kwargs["token"] = HUGGINGFACE_TOKEN
@@ -71,12 +62,7 @@ def download_model_with_retry(repo_id, filename, max_retries=None):
71
 
72
 
73
  def load_face_analysis():
74
- """
75
- Load face analysis model with proper error handling.
76
-
77
- Returns:
78
- Tuple of (face_app, success_bool)
79
- """
80
  print("Loading face analysis model...")
81
  try:
82
  face_app = FaceAnalysis(
@@ -96,12 +82,7 @@ def load_face_analysis():
96
 
97
 
98
  def load_depth_detector():
99
- """
100
- Load Zoe Depth detector.
101
-
102
- Returns:
103
- Tuple of (zoe_depth, success_bool)
104
- """
105
  print("Loading Zoe Depth detector...")
106
  try:
107
  zoe_depth = ZoeDetector.from_pretrained("lllyasviel/Annotators")
@@ -114,13 +95,7 @@ def load_depth_detector():
114
 
115
 
116
  def load_controlnets():
117
- """
118
- Load ControlNet models.
119
-
120
- Returns:
121
- Tuple of (controlnet_depth, controlnet_instantid, instantid_success)
122
- """
123
- # Load ControlNet for depth
124
  print("Loading ControlNet Zoe Depth model...")
125
  controlnet_depth = ControlNetModel.from_pretrained(
126
  "diffusers/controlnet-zoe-depth-sdxl-1.0",
@@ -128,7 +103,6 @@ def load_controlnets():
128
  ).to(device)
129
  print(" [OK] ControlNet Depth loaded")
130
 
131
- # Load InstantID ControlNet
132
  print("Loading InstantID ControlNet...")
133
  try:
134
  controlnet_instantid = ControlNetModel.from_pretrained(
@@ -144,12 +118,7 @@ def load_controlnets():
144
 
145
 
146
  def load_image_encoder():
147
- """
148
- Load CLIP Image Encoder for IP-Adapter.
149
-
150
- Returns:
151
- Image encoder or None
152
- """
153
  print("Loading CLIP Image Encoder for IP-Adapter...")
154
  try:
155
  image_encoder = CLIPVisionModelWithProjection.from_pretrained(
@@ -165,15 +134,7 @@ def load_image_encoder():
165
 
166
 
167
  def load_sdxl_pipeline(controlnets):
168
- """
169
- Load SDXL checkpoint from HuggingFace Hub.
170
-
171
- Args:
172
- controlnets: ControlNet model(s) to use
173
-
174
- Returns:
175
- Tuple of (pipeline, checkpoint_loaded_bool)
176
- """
177
  print("Loading SDXL checkpoint (horizon) with bundled VAE from HuggingFace Hub...")
178
  try:
179
  model_path = download_model_with_retry(MODEL_REPO, MODEL_FILES['checkpoint'])
@@ -199,15 +160,7 @@ def load_sdxl_pipeline(controlnets):
199
 
200
 
201
  def load_lora(pipe):
202
- """
203
- Load LORA from HuggingFace Hub.
204
-
205
- Args:
206
- pipe: Pipeline to load LORA into
207
-
208
- Returns:
209
- Boolean indicating success
210
- """
211
  print("Loading LORA (retroart) from HuggingFace Hub...")
212
  try:
213
  lora_path = download_model_with_retry(MODEL_REPO, MODEL_FILES['lora'])
@@ -221,66 +174,68 @@ def load_lora(pipe):
221
 
222
  def setup_ip_adapter(pipe, image_encoder):
223
  """
224
- Setup IP-Adapter for InstantID face embeddings.
225
-
226
- Args:
227
- pipe: Pipeline to setup IP-Adapter on
228
- image_encoder: CLIP image encoder
229
-
230
- Returns:
231
- Tuple of (image_proj_model, success_bool)
232
  """
233
  if image_encoder is None:
234
  return None, False
235
 
236
- print("Setting up IP-Adapter for InstantID face embeddings...")
237
  try:
238
- # Download InstantID IP-Adapter weights
239
  ip_adapter_path = download_model_with_retry(
240
  "InstantX/InstantID",
241
  "ip-adapter.bin"
242
  )
243
 
244
- # Load IP-Adapter state dict
245
- ip_adapter_state_dict = torch.load(ip_adapter_path, map_location="cpu")
246
 
247
- # Separate image projection and IP-adapter weights
248
  image_proj_state_dict = {}
249
- ip_state_dict = {}
250
- for key, value in ip_adapter_state_dict.items():
 
251
  if key.startswith("image_proj."):
252
  image_proj_state_dict[key.replace("image_proj.", "")] = value
253
  elif key.startswith("ip_adapter."):
254
- ip_state_dict[key.replace("ip_adapter.", "")] = value
255
-
256
- print("Setting up Enhanced Perceiver Resampler for face embedding refinement...")
257
 
258
- # Create enhanced resampler
259
- image_proj_model = create_enhanced_resampler(
260
- quality_mode='quality',
261
- num_queries=4,
262
- output_dim=pipe.unet.config.cross_attention_dim,
263
- device=device,
264
- dtype=dtype
 
 
 
 
265
  )
266
 
267
- # Try to load pretrained Resampler weights if available
268
- try:
269
- if 'latents' in image_proj_state_dict:
 
 
 
270
  image_proj_model.load_state_dict(image_proj_state_dict, strict=True)
271
  print(" [OK] Resampler loaded with pretrained weights")
272
- else:
273
- print(" [INFO] No pretrained Resampler weights found")
274
  print(" Using randomly initialized Resampler")
275
- print(" Expected +8-10% face similarity improvement")
276
- except Exception as e:
277
- print(f" [INFO] Resampler initialization: {e}")
278
- print(" Using randomly initialized Resampler")
279
 
280
- # Set up IP-Adapter attention processors
 
281
  attn_procs = {}
 
 
282
  for name in pipe.unet.attn_processors.keys():
283
  cross_attention_dim = None if name.endswith("attn1.processor") else pipe.unet.config.cross_attention_dim
 
284
  if name.startswith("mid_block"):
285
  hidden_size = pipe.unet.config.block_out_channels[-1]
286
  elif name.startswith("up_blocks"):
@@ -289,6 +244,8 @@ def setup_ip_adapter(pipe, image_encoder):
289
  elif name.startswith("down_blocks"):
290
  block_id = int(name[len("down_blocks.")])
291
  hidden_size = pipe.unet.config.block_out_channels[block_id]
 
 
292
 
293
  if cross_attention_dim is None:
294
  attn_procs[name] = AttnProcessor2_0()
@@ -297,39 +254,41 @@ def setup_ip_adapter(pipe, image_encoder):
297
  hidden_size=hidden_size,
298
  cross_attention_dim=cross_attention_dim,
299
  scale=1.0,
300
- num_tokens=4
301
  ).to(device, dtype=dtype)
302
 
 
303
  pipe.unet.set_attn_processor(attn_procs)
304
 
305
- # Load IP-adapter weights into attention processors
306
- ip_layers = torch.nn.ModuleList(pipe.unet.attn_processors.values())
307
- ip_layers.load_state_dict(ip_state_dict, strict=False)
308
- print(" [OK] IP-Adapter attention processors loaded")
 
 
 
 
 
 
309
 
310
- # Store the image encoder
311
  pipe.image_encoder = image_encoder
312
 
313
- print(" [OK] IP-Adapter fully loaded with InstantID weights")
 
 
 
314
  return image_proj_model, True
 
315
  except Exception as e:
316
- print(f" [ERROR] Could not load IP-Adapter: {e}")
317
- print(" InstantID will work with keypoints only (no face embeddings)")
318
  import traceback
319
  traceback.print_exc()
320
  return None, False
321
 
322
 
323
  def setup_compel(pipe):
324
- """
325
- Setup Compel for better SDXL prompt handling.
326
-
327
- Args:
328
- pipe: Pipeline to setup Compel on
329
-
330
- Returns:
331
- Tuple of (compel, success_bool)
332
- """
333
  print("Setting up Compel for enhanced prompt processing...")
334
  try:
335
  compel = Compel(
@@ -346,27 +305,14 @@ def setup_compel(pipe):
346
 
347
 
348
  def setup_scheduler(pipe):
349
- """
350
- Setup LCM scheduler.
351
-
352
- Args:
353
- pipe: Pipeline to setup scheduler on
354
- """
355
  print("Setting up LCM scheduler...")
356
  pipe.scheduler = LCMScheduler.from_config(pipe.scheduler.config)
357
  print(" [OK] LCM scheduler configured")
358
 
359
 
360
  def optimize_pipeline(pipe):
361
- """
362
- Apply optimizations to pipeline.
363
-
364
- Args:
365
- pipe: Pipeline to optimize
366
- """
367
- # Enable attention optimizations
368
- pipe.unet.set_attn_processor(AttnProcessor2_0())
369
-
370
  # Try to enable xformers
371
  if device == "cuda":
372
  try:
@@ -378,66 +324,48 @@ def optimize_pipeline(pipe):
378
 
379
  def load_caption_model():
380
  """
381
- Load BLIP-2 model for longer, more detailed caption generation.
382
- BLIP-2 produces richer descriptions compared to BLIP base.
383
-
384
- Returns:
385
- Tuple of (processor, model, success_bool)
386
  """
387
- print("Loading BLIP-2 model for detailed caption generation...")
 
 
388
  try:
389
- # Try BLIP-2 first (produces longer, more detailed captions)
 
 
 
 
 
 
 
 
 
 
 
 
 
390
  try:
391
- from transformers import Blip2Processor, Blip2ForConditionalGeneration
392
 
393
- caption_processor = Blip2Processor.from_pretrained("Salesforce/blip2-opt-2.7b")
394
- caption_model = Blip2ForConditionalGeneration.from_pretrained(
395
- "Salesforce/blip2-opt-2.7b",
 
396
  torch_dtype=dtype
397
  ).to(device)
398
- print(" [OK] BLIP-2 model loaded successfully (produces detailed captions)")
399
- return caption_processor, caption_model, True
400
- except Exception as e:
401
- print(f" [INFO] BLIP-2 not available ({e}), trying GIT-Large...")
402
-
403
- # Fallback to GIT-Large (also produces good long captions)
404
- try:
405
- from transformers import AutoProcessor, AutoModelForCausalLM
406
-
407
- caption_processor = AutoProcessor.from_pretrained("microsoft/git-large-coco")
408
- caption_model = AutoModelForCausalLM.from_pretrained(
409
- "microsoft/git-large-coco",
410
- torch_dtype=dtype
411
- ).to(device)
412
- print(" [OK] GIT-Large model loaded successfully (produces detailed captions)")
413
- return caption_processor, caption_model, True
414
- except Exception as e2:
415
- print(f" [INFO] GIT-Large not available ({e2}), falling back to BLIP base...")
416
-
417
- # Final fallback to BLIP base
418
- caption_processor = BlipProcessor.from_pretrained("Salesforce/blip-image-captioning-base")
419
- caption_model = BlipForConditionalGeneration.from_pretrained(
420
- "Salesforce/blip-image-captioning-base",
421
- torch_dtype=dtype
422
- ).to(device)
423
- print(" [OK] BLIP base model loaded (shorter captions)")
424
- return caption_processor, caption_model, True
425
-
426
- except Exception as e:
427
- print(f" [WARNING] Caption model not available: {e}")
428
- print(" Caption generation will be disabled")
429
- return None, None, False
430
 
431
 
432
  def set_clip_skip(pipe):
433
- """
434
- Set CLIP skip value.
435
-
436
- Args:
437
- pipe: Pipeline to set CLIP skip on
438
- """
439
  if hasattr(pipe, 'text_encoder'):
440
  print(f" [OK] CLIP skip set to {CLIP_SKIP}")
441
 
442
 
443
- print("[OK] Model loading functions ready")
 
1
  """
2
  Model loading and initialization for Pixagram AI Pixel Art Generator
3
+ FIXED VERSION with proper IP-Adapter and BLIP-2 support
4
  """
5
  import torch
6
  import time
 
12
  )
13
  from diffusers.models.attention_processor import AttnProcessor2_0
14
  from transformers import CLIPVisionModelWithProjection
 
15
  from insightface.app import FaceAnalysis
16
  from controlnet_aux import ZoeDetector
17
  from huggingface_hub import hf_hub_download
18
  from compel import Compel, ReturnedEmbeddingsType
19
 
20
+ # Use reference implementation's attention processor
21
+ from attention_processor import IPAttnProcessor2_0, AttnProcessor
22
+ from resampler import Resampler
23
+
24
  from config import (
25
  device, dtype, MODEL_REPO, MODEL_FILES, HUGGINGFACE_TOKEN,
26
  FACE_DETECTION_CONFIG, CLIP_SKIP, DOWNLOAD_CONFIG
 
28
 
29
 
30
  def download_model_with_retry(repo_id, filename, max_retries=None):
31
+ """Download model with retry logic and proper token handling."""
 
 
 
 
 
 
 
 
 
 
32
  if max_retries is None:
33
  max_retries = DOWNLOAD_CONFIG['max_retries']
34
 
 
36
  try:
37
  print(f" Attempting to download {filename} (attempt {attempt + 1}/{max_retries})...")
38
 
 
39
  kwargs = {"repo_type": "model"}
40
  if HUGGINGFACE_TOKEN:
41
  kwargs["token"] = HUGGINGFACE_TOKEN
 
62
 
63
 
64
  def load_face_analysis():
65
+ """Load face analysis model with proper error handling."""
 
 
 
 
 
66
  print("Loading face analysis model...")
67
  try:
68
  face_app = FaceAnalysis(
 
82
 
83
 
84
  def load_depth_detector():
85
+ """Load Zoe Depth detector."""
 
 
 
 
 
86
  print("Loading Zoe Depth detector...")
87
  try:
88
  zoe_depth = ZoeDetector.from_pretrained("lllyasviel/Annotators")
 
95
 
96
 
97
  def load_controlnets():
98
+ """Load ControlNet models."""
 
 
 
 
 
 
99
  print("Loading ControlNet Zoe Depth model...")
100
  controlnet_depth = ControlNetModel.from_pretrained(
101
  "diffusers/controlnet-zoe-depth-sdxl-1.0",
 
103
  ).to(device)
104
  print(" [OK] ControlNet Depth loaded")
105
 
 
106
  print("Loading InstantID ControlNet...")
107
  try:
108
  controlnet_instantid = ControlNetModel.from_pretrained(
 
118
 
119
 
120
  def load_image_encoder():
121
+ """Load CLIP Image Encoder for IP-Adapter."""
 
 
 
 
 
122
  print("Loading CLIP Image Encoder for IP-Adapter...")
123
  try:
124
  image_encoder = CLIPVisionModelWithProjection.from_pretrained(
 
134
 
135
 
136
  def load_sdxl_pipeline(controlnets):
137
+ """Load SDXL checkpoint from HuggingFace Hub."""
 
 
 
 
 
 
 
 
138
  print("Loading SDXL checkpoint (horizon) with bundled VAE from HuggingFace Hub...")
139
  try:
140
  model_path = download_model_with_retry(MODEL_REPO, MODEL_FILES['checkpoint'])
 
160
 
161
 
162
  def load_lora(pipe):
163
+ """Load LORA from HuggingFace Hub."""
 
 
 
 
 
 
 
 
164
  print("Loading LORA (retroart) from HuggingFace Hub...")
165
  try:
166
  lora_path = download_model_with_retry(MODEL_REPO, MODEL_FILES['lora'])
 
174
 
175
  def setup_ip_adapter(pipe, image_encoder):
176
  """
177
+ Setup IP-Adapter for InstantID face embeddings - PROPER IMPLEMENTATION.
178
+ Based on the reference InstantID pipeline.
 
 
 
 
 
 
179
  """
180
  if image_encoder is None:
181
  return None, False
182
 
183
+ print("Setting up IP-Adapter for InstantID face embeddings (proper implementation)...")
184
  try:
185
+ # Download InstantID weights
186
  ip_adapter_path = download_model_with_retry(
187
  "InstantX/InstantID",
188
  "ip-adapter.bin"
189
  )
190
 
191
+ # Load full state dict
192
+ state_dict = torch.load(ip_adapter_path, map_location="cpu")
193
 
194
+ # Extract image_proj and ip_adapter weights
195
  image_proj_state_dict = {}
196
+ ip_adapter_state_dict = {}
197
+
198
+ for key, value in state_dict.items():
199
  if key.startswith("image_proj."):
200
  image_proj_state_dict[key.replace("image_proj.", "")] = value
201
  elif key.startswith("ip_adapter."):
202
+ ip_adapter_state_dict[key.replace("ip_adapter.", "")] = value
 
 
203
 
204
+ # Create Resampler (image projection model) with CORRECT parameters from reference
205
+ print("Creating Resampler (Perceiver architecture)...")
206
+ image_proj_model = Resampler(
207
+ dim=1280, # Hidden dimension
208
+ depth=4, # IMPORTANT: 4 layers (not 8!)
209
+ dim_head=64, # Dimension per head
210
+ heads=20, # Number of heads
211
+ num_queries=16, # Number of output tokens
212
+ embedding_dim=512, # InsightFace embedding dim
213
+ output_dim=pipe.unet.config.cross_attention_dim, # SDXL cross-attention dim (2048)
214
+ ff_mult=4 # Feedforward multiplier
215
  )
216
 
217
+ image_proj_model.eval()
218
+ image_proj_model = image_proj_model.to(device, dtype=dtype)
219
+
220
+ # Load image_proj weights
221
+ if image_proj_state_dict:
222
+ try:
223
  image_proj_model.load_state_dict(image_proj_state_dict, strict=True)
224
  print(" [OK] Resampler loaded with pretrained weights")
225
+ except Exception as e:
226
+ print(f" [WARNING] Could not load Resampler weights: {e}")
227
  print(" Using randomly initialized Resampler")
228
+ else:
229
+ print(" [WARNING] No image_proj weights found, using random initialization")
 
 
230
 
231
+ # Setup IP-Adapter attention processors
232
+ print("Setting up IP-Adapter attention processors...")
233
  attn_procs = {}
234
+ num_tokens = 16 # Match Resampler num_queries
235
+
236
  for name in pipe.unet.attn_processors.keys():
237
  cross_attention_dim = None if name.endswith("attn1.processor") else pipe.unet.config.cross_attention_dim
238
+
239
  if name.startswith("mid_block"):
240
  hidden_size = pipe.unet.config.block_out_channels[-1]
241
  elif name.startswith("up_blocks"):
 
244
  elif name.startswith("down_blocks"):
245
  block_id = int(name[len("down_blocks.")])
246
  hidden_size = pipe.unet.config.block_out_channels[block_id]
247
+ else:
248
+ hidden_size = pipe.unet.config.block_out_channels[-1]
249
 
250
  if cross_attention_dim is None:
251
  attn_procs[name] = AttnProcessor2_0()
 
254
  hidden_size=hidden_size,
255
  cross_attention_dim=cross_attention_dim,
256
  scale=1.0,
257
+ num_tokens=num_tokens
258
  ).to(device, dtype=dtype)
259
 
260
+ # Set attention processors
261
  pipe.unet.set_attn_processor(attn_procs)
262
 
263
+ # Load IP-Adapter weights into attention processors
264
+ if ip_adapter_state_dict:
265
+ try:
266
+ ip_layers = torch.nn.ModuleList(pipe.unet.attn_processors.values())
267
+ ip_layers.load_state_dict(ip_adapter_state_dict, strict=False)
268
+ print(" [OK] IP-Adapter attention weights loaded")
269
+ except Exception as e:
270
+ print(f" [WARNING] Could not load IP-Adapter weights: {e}")
271
+ else:
272
+ print(" [WARNING] No ip_adapter weights found")
273
 
274
+ # Store image encoder and projection model
275
  pipe.image_encoder = image_encoder
276
 
277
+ print(" [OK] IP-Adapter fully loaded with InstantID architecture")
278
+ print(f" - Resampler: 4 layers, 20 heads, 16 output tokens")
279
+ print(f" - Face embeddings: 512D → 16x2048D")
280
+
281
  return image_proj_model, True
282
+
283
  except Exception as e:
284
+ print(f" [ERROR] Could not setup IP-Adapter: {e}")
 
285
  import traceback
286
  traceback.print_exc()
287
  return None, False
288
 
289
 
290
  def setup_compel(pipe):
291
+ """Setup Compel for better SDXL prompt handling."""
 
 
 
 
 
 
 
 
292
  print("Setting up Compel for enhanced prompt processing...")
293
  try:
294
  compel = Compel(
 
305
 
306
 
307
  def setup_scheduler(pipe):
308
+ """Setup LCM scheduler."""
 
 
 
 
 
309
  print("Setting up LCM scheduler...")
310
  pipe.scheduler = LCMScheduler.from_config(pipe.scheduler.config)
311
  print(" [OK] LCM scheduler configured")
312
 
313
 
314
  def optimize_pipeline(pipe):
315
+ """Apply optimizations to pipeline."""
 
 
 
 
 
 
 
 
316
  # Try to enable xformers
317
  if device == "cuda":
318
  try:
 
324
 
325
  def load_caption_model():
326
  """
327
+ Load caption model with proper error handling.
328
+ Tries multiple models in order of quality.
 
 
 
329
  """
330
+ print("Loading caption model...")
331
+
332
+ # Try GIT-Large first (good balance of quality and compatibility)
333
  try:
334
+ from transformers import AutoProcessor, AutoModelForCausalLM
335
+
336
+ print(" Attempting GIT-Large (recommended)...")
337
+ caption_processor = AutoProcessor.from_pretrained("microsoft/git-large-coco")
338
+ caption_model = AutoModelForCausalLM.from_pretrained(
339
+ "microsoft/git-large-coco",
340
+ torch_dtype=dtype
341
+ ).to(device)
342
+ print(" [OK] GIT-Large model loaded (produces detailed captions)")
343
+ return caption_processor, caption_model, True, 'git'
344
+ except Exception as e1:
345
+ print(f" [INFO] GIT-Large not available: {e1}")
346
+
347
+ # Try BLIP base as fallback
348
  try:
349
+ from transformers import BlipProcessor, BlipForConditionalGeneration
350
 
351
+ print(" Attempting BLIP base (fallback)...")
352
+ caption_processor = BlipProcessor.from_pretrained("Salesforce/blip-image-captioning-base")
353
+ caption_model = BlipForConditionalGeneration.from_pretrained(
354
+ "Salesforce/blip-image-captioning-base",
355
  torch_dtype=dtype
356
  ).to(device)
357
+ print(" [OK] BLIP base model loaded (standard captions)")
358
+ return caption_processor, caption_model, True, 'blip'
359
+ except Exception as e2:
360
+ print(f" [WARNING] Caption models not available: {e2}")
361
+ print(" Caption generation will be disabled")
362
+ return None, None, False, 'none'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
363
 
364
 
365
  def set_clip_skip(pipe):
366
+ """Set CLIP skip value."""
 
 
 
 
 
367
  if hasattr(pipe, 'text_encoder'):
368
  print(f" [OK] CLIP skip set to {CLIP_SKIP}")
369
 
370
 
371
+ print("[OK] Model loading functions ready")