crash10155 commited on
Commit
ddf9937
Β·
verified Β·
1 Parent(s): 136e03e

Update SwitcherAI/processors/frame/modules/face_swapper.py

Browse files
SwitcherAI/processors/frame/modules/face_swapper.py CHANGED
@@ -13,17 +13,16 @@ from SwitcherAI.core import update_status
13
  from SwitcherAI.face_analyser import get_one_face, get_many_faces, find_similar_faces
14
  from SwitcherAI.face_reference import get_face_reference, set_face_reference
15
  from SwitcherAI.typing import Face, Frame
16
- from SwitcherAI.utilities import conditional_download, resolve_relative_path, is_image, is_video
17
 
18
  FRAME_PROCESSOR = None
19
  EMBEDDING_CONVERTER = None
20
  THREAD_LOCK = threading.Lock()
21
  NAME = 'FACEFUSION.FRAME_PROCESSOR.FACE_SWAPPER'
22
 
23
- # Model configurations with working public URLs
24
  MODEL_CONFIGS = {
25
  'inswapper_128': {
26
- 'url': 'https://huggingface.co/ezioruan/inswapper_128.onnx/resolve/main/inswapper_128.onnx',
27
  'path': '../.assets/models/inswapper_128.onnx',
28
  'type': 'inswapper',
29
  'size': (128, 128),
@@ -32,7 +31,6 @@ MODEL_CONFIGS = {
32
  'requires_converter': False
33
  },
34
  'inswapper_128_fp16': {
35
- 'url': 'https://huggingface.co/ninjawick/webui-faceswap-unlocked/resolve/main/inswapper_128_fp16.onnx',
36
  'path': '../.assets/models/inswapper_128_fp16.onnx',
37
  'type': 'inswapper',
38
  'size': (128, 128),
@@ -40,6 +38,15 @@ MODEL_CONFIGS = {
40
  'standard_deviation': [1.0, 1.0, 1.0],
41
  'requires_converter': False
42
  },
 
 
 
 
 
 
 
 
 
43
  }
44
 
45
  # Default model - can be changed via globals
@@ -80,10 +87,13 @@ def get_frame_processor() -> Any:
80
  model_priority.remove(current_model)
81
 
82
  for model_name in model_priority:
 
 
 
83
  try:
84
  print(f"πŸ”„ Trying to load face swap model: {model_name}")
85
 
86
- # Update config to current model being tested
87
  temp_config = MODEL_CONFIGS[model_name]
88
  model_path = resolve_relative_path(temp_config['path'])
89
 
@@ -93,23 +103,14 @@ def get_frame_processor() -> Any:
93
  else:
94
  model_path_obj = model_path
95
 
96
- # Check if model exists, download if needed
97
  if not model_path_obj.exists():
98
- print(f"πŸ“₯ Downloading {model_name}...")
99
- download_directory_path = resolve_relative_path('../.assets/models')
100
- if isinstance(download_directory_path, str):
101
- download_directory_path = Path(download_directory_path)
102
- download_directory_path.mkdir(parents=True, exist_ok=True)
103
-
104
- download_urls = [temp_config['url']]
105
- if temp_config.get('requires_converter', False):
106
- download_urls.append(temp_config['converter_url'])
107
-
108
- conditional_download(str(download_directory_path), download_urls)
109
 
110
  # Verify model file size
111
  if model_path_obj.stat().st_size < 1024: # Less than 1KB indicates corruption
112
- print(f"⚠️ {model_name} appears corrupted, skipping...")
113
  continue
114
 
115
  # Try to load the model
@@ -125,44 +126,10 @@ def get_frame_processor() -> Any:
125
 
126
  except Exception as e:
127
  print(f"❌ Failed to load {model_name}: {e}")
128
-
129
- # If protobuf parsing failed, delete the corrupted file and try to re-download
130
- if "INVALID_PROTOBUF" in str(e) or "Protobuf parsing failed" in str(e):
131
- print(f"πŸ—‘οΈ Deleting corrupted {model_name} file...")
132
- try:
133
- if model_path_obj.exists():
134
- model_path_obj.unlink()
135
- print(f"πŸ“₯ Re-downloading {model_name}...")
136
-
137
- download_directory_path = resolve_relative_path('../.assets/models')
138
- if isinstance(download_directory_path, str):
139
- download_directory_path = Path(download_directory_path)
140
- download_directory_path.mkdir(parents=True, exist_ok=True)
141
-
142
- download_urls = [temp_config['url']]
143
- if temp_config.get('requires_converter', False):
144
- download_urls.append(temp_config['converter_url'])
145
-
146
- conditional_download(str(download_directory_path), download_urls)
147
-
148
- # Try loading again after re-download
149
- if model_path_obj.exists() and model_path_obj.stat().st_size > 1024:
150
- print(f"πŸ”„ Retrying {model_name} after re-download...")
151
- FRAME_PROCESSOR = insightface.model_zoo.get_model(
152
- str(model_path_obj),
153
- providers=SwitcherAI.globals.execution_providers
154
- )
155
- # If successful, update the global setting and break
156
- SwitcherAI.globals.face_swapper_model = model_name
157
- print(f"βœ… Successfully loaded face swap model: {model_name}")
158
- break
159
- except Exception as retry_error:
160
- print(f"❌ Retry failed for {model_name}: {retry_error}")
161
-
162
  continue
163
 
164
  if FRAME_PROCESSOR is None:
165
- print("❌ All face swap models failed to load")
166
 
167
  return FRAME_PROCESSOR
168
 
@@ -185,12 +152,11 @@ def get_embedding_converter() -> Any:
185
  else:
186
  converter_path_obj = converter_path
187
 
188
- # Check if converter exists
189
  if not converter_path_obj.exists():
190
- print(f"⚠️ Embedding converter not found at: {converter_path_obj}")
191
- if not pre_check():
192
- print("❌ Failed to download embedding converter")
193
- return None
194
 
195
  EMBEDDING_CONVERTER = insightface.model_zoo.get_model(
196
  str(converter_path_obj),
@@ -199,7 +165,7 @@ def get_embedding_converter() -> Any:
199
  print("βœ… Embedding converter initialized")
200
 
201
  except Exception as e:
202
- print(f"⚠️ Failed to initialize embedding converter: {e}")
203
  EMBEDDING_CONVERTER = None
204
 
205
  return EMBEDDING_CONVERTER
@@ -213,24 +179,36 @@ def clear_frame_processor() -> None:
213
 
214
 
215
  def pre_check() -> bool:
 
216
  try:
217
- download_directory_path = resolve_relative_path('../.assets/models')
218
-
219
- # Ensure download directory exists
220
- if isinstance(download_directory_path, str):
221
- download_directory_path = Path(download_directory_path)
222
- download_directory_path.mkdir(parents=True, exist_ok=True)
223
-
224
  config = get_current_model_config()
225
 
226
- # Download main model
227
- download_urls = [config['url']]
 
 
 
 
 
 
 
 
 
228
 
229
- # Download converter if needed
230
  if config.get('requires_converter', False):
231
- download_urls.append(config['converter_url'])
 
 
 
 
 
 
 
 
 
232
 
233
- conditional_download(str(download_directory_path), download_urls)
234
  return True
235
 
236
  except Exception as e:
@@ -250,10 +228,15 @@ def pre_process() -> bool:
250
  update_status(wording.get('select_image_or_video_target') + wording.get('exclamation_mark'), NAME)
251
  return False
252
 
 
 
 
 
 
253
  # Check if processor is available
254
  processor = get_frame_processor()
255
  if processor is None:
256
- print("⚠️ Face swap processor not available")
257
  return False
258
 
259
  return True
 
13
  from SwitcherAI.face_analyser import get_one_face, get_many_faces, find_similar_faces
14
  from SwitcherAI.face_reference import get_face_reference, set_face_reference
15
  from SwitcherAI.typing import Face, Frame
16
+ from SwitcherAI.utilities import resolve_relative_path, is_image, is_video
17
 
18
  FRAME_PROCESSOR = None
19
  EMBEDDING_CONVERTER = None
20
  THREAD_LOCK = threading.Lock()
21
  NAME = 'FACEFUSION.FRAME_PROCESSOR.FACE_SWAPPER'
22
 
23
+ # Model configurations - local paths only
24
  MODEL_CONFIGS = {
25
  'inswapper_128': {
 
26
  'path': '../.assets/models/inswapper_128.onnx',
27
  'type': 'inswapper',
28
  'size': (128, 128),
 
31
  'requires_converter': False
32
  },
33
  'inswapper_128_fp16': {
 
34
  'path': '../.assets/models/inswapper_128_fp16.onnx',
35
  'type': 'inswapper',
36
  'size': (128, 128),
 
38
  'standard_deviation': [1.0, 1.0, 1.0],
39
  'requires_converter': False
40
  },
41
+ 'simswap_256': {
42
+ 'path': '../.assets/models/simswap_256.onnx',
43
+ 'converter_path': '../.assets/models/simswap_256_converter.onnx',
44
+ 'type': 'simswap',
45
+ 'size': (256, 256),
46
+ 'mean': [0.485, 0.456, 0.406],
47
+ 'standard_deviation': [0.229, 0.224, 0.225],
48
+ 'requires_converter': True
49
+ },
50
  }
51
 
52
  # Default model - can be changed via globals
 
87
  model_priority.remove(current_model)
88
 
89
  for model_name in model_priority:
90
+ if model_name not in MODEL_CONFIGS:
91
+ continue
92
+
93
  try:
94
  print(f"πŸ”„ Trying to load face swap model: {model_name}")
95
 
96
+ # Get model config
97
  temp_config = MODEL_CONFIGS[model_name]
98
  model_path = resolve_relative_path(temp_config['path'])
99
 
 
103
  else:
104
  model_path_obj = model_path
105
 
106
+ # Check if model exists locally
107
  if not model_path_obj.exists():
108
+ print(f"❌ Model {model_name} not found at: {model_path_obj}")
109
+ continue
 
 
 
 
 
 
 
 
 
110
 
111
  # Verify model file size
112
  if model_path_obj.stat().st_size < 1024: # Less than 1KB indicates corruption
113
+ print(f"⚠️ {model_name} appears corrupted (file too small), skipping...")
114
  continue
115
 
116
  # Try to load the model
 
126
 
127
  except Exception as e:
128
  print(f"❌ Failed to load {model_name}: {e}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  continue
130
 
131
  if FRAME_PROCESSOR is None:
132
+ print("❌ All face swap models failed to load. Please ensure models are present in .assets/models folder.")
133
 
134
  return FRAME_PROCESSOR
135
 
 
152
  else:
153
  converter_path_obj = converter_path
154
 
155
+ # Check if converter exists locally
156
  if not converter_path_obj.exists():
157
+ print(f"❌ Embedding converter not found at: {converter_path_obj}")
158
+ print("Please ensure the converter model is present in .assets/models folder.")
159
+ return None
 
160
 
161
  EMBEDDING_CONVERTER = insightface.model_zoo.get_model(
162
  str(converter_path_obj),
 
165
  print("βœ… Embedding converter initialized")
166
 
167
  except Exception as e:
168
+ print(f"❌ Failed to initialize embedding converter: {e}")
169
  EMBEDDING_CONVERTER = None
170
 
171
  return EMBEDDING_CONVERTER
 
179
 
180
 
181
  def pre_check() -> bool:
182
+ """Check if required models exist locally"""
183
  try:
 
 
 
 
 
 
 
184
  config = get_current_model_config()
185
 
186
+ # Check main model path
187
+ model_path = resolve_relative_path(config['path'])
188
+ if isinstance(model_path, str):
189
+ model_path_obj = Path(model_path)
190
+ else:
191
+ model_path_obj = model_path
192
+
193
+ if not model_path_obj.exists():
194
+ print(f"❌ Main model not found at: {model_path_obj}")
195
+ print("Please ensure the model file is present in .assets/models folder.")
196
+ return False
197
 
198
+ # Check converter if needed
199
  if config.get('requires_converter', False):
200
+ converter_path = resolve_relative_path(config['converter_path'])
201
+ if isinstance(converter_path, str):
202
+ converter_path_obj = Path(converter_path)
203
+ else:
204
+ converter_path_obj = converter_path
205
+
206
+ if not converter_path_obj.exists():
207
+ print(f"❌ Converter model not found at: {converter_path_obj}")
208
+ print("Please ensure the converter model file is present in .assets/models folder.")
209
+ return False
210
 
211
+ print("βœ… All required models found locally")
212
  return True
213
 
214
  except Exception as e:
 
228
  update_status(wording.get('select_image_or_video_target') + wording.get('exclamation_mark'), NAME)
229
  return False
230
 
231
+ # Check if required models exist locally
232
+ if not pre_check():
233
+ update_status("Required models not found in .assets/models folder", NAME)
234
+ return False
235
+
236
  # Check if processor is available
237
  processor = get_frame_processor()
238
  if processor is None:
239
+ update_status("Face swap processor not available", NAME)
240
  return False
241
 
242
  return True