Thekingbalxd commited on
Commit
868b12b
·
verified ·
1 Parent(s): c6584a3

Update inference_realesrgan_gpu.py

Browse files
Files changed (1) hide show
  1. inference_realesrgan_gpu.py +27 -53
inference_realesrgan_gpu.py CHANGED
@@ -3,9 +3,7 @@
3
 
4
  """
5
  GPU-only Real-ESRGAN + GFPGAN inference script.
6
- - Kötelezően CUDA-t követel (ha nincs GPU, hibát dob).
7
- - A modell(ek) és a GFPGAN belső hálói expliciten GPU-ra kerülnek.
8
- - Támogat fp16 (half) inference, ha nem adod meg --fp32.
9
  """
10
 
11
  import argparse
@@ -24,25 +22,20 @@ from realesrgan.archs.srvgg_arch import SRVGGNetCompact
24
 
25
 
26
  def setup_device(gpu_id: int) -> torch.device:
27
- """Ellenőrzi CUDA elérhetőségét, beállítja az eszközt és néhány gyorsítótár beállítást."""
28
  if not torch.cuda.is_available():
29
  raise RuntimeError("CUDA nem elérhető — ez a script csak GPU-n futtatható.")
30
- # biztosítsuk, hogy a megadott GPU legyen kiválasztva
31
  torch.cuda.set_device(int(gpu_id))
32
  device = torch.device(f"cuda:{int(gpu_id)}")
33
  torch.backends.cudnn.benchmark = True
34
- # kikapcsoljuk a gradet inferencia alatt
35
  torch.set_grad_enabled(False)
36
  return device
37
 
38
 
39
  def move_obj_to_device(obj: Any, device: torch.device, use_half: bool):
40
  """
41
- Rekurzívan megpróbál minden torch.nn.Module objektumot GPU-ra mozgatni,
42
- és a lehetőségek szerint half()-olni.
43
- Ez a GFPGAN különböző verzióihoz hasznos.
44
  """
45
- # Modul esetén egyszerűen .to(device) és .half() ha lehet
46
  try:
47
  import torch.nn as nn
48
  except Exception:
@@ -55,12 +48,18 @@ def move_obj_to_device(obj: Any, device: torch.device, use_half: bool):
55
  pass
56
  if use_half:
57
  try:
 
58
  obj.half()
59
  except Exception:
60
  pass
 
 
 
 
 
 
61
  return
62
 
63
- # ha dict/list/tuple, nézzük át az elemeket
64
  if isinstance(obj, dict):
65
  for v in obj.values():
66
  move_obj_to_device(v, device, use_half)
@@ -70,21 +69,16 @@ def move_obj_to_device(obj: Any, device: torch.device, use_half: bool):
70
  move_obj_to_device(v, device, use_half)
71
  return
72
 
73
- # ha egy objektumnak vannak attribútumai, próbáljuk átnézni őket (GFPGAN belsők)
74
  if hasattr(obj, "__dict__"):
75
  for _, v in vars(obj).items():
76
- # elkerüljük a végtelen rekurrenciát és az egyszerű típusokat
77
  if v is None:
78
  continue
79
- # közvetlenül modulok és konténerek kezelése
80
  try:
81
- # modulokra alapból ráhívjuk a mozgást
82
  if nn is not None and isinstance(v, nn.Module):
83
  move_obj_to_device(v, device, use_half)
84
  elif isinstance(v, (list, tuple, dict, set)):
85
  move_obj_to_device(v, device, use_half)
86
  except Exception:
87
- # tűrjük a hibákat, mert GFPGAN belsők különbözőek lehetnek
88
  pass
89
 
90
 
@@ -111,9 +105,10 @@ def main():
111
  args = parser.parse_args()
112
 
113
  device = setup_device(args.gpu_id)
 
114
  use_half = not args.fp32
115
 
116
- # model kiválasztása
117
  args.model_name = args.model_name.split('.')[0]
118
  if args.model_name == 'RealESRGAN_x4plus':
119
  model = RRDBNet(num_in_ch=3, num_out_ch=3, num_feat=64, num_block=23, num_grow_ch=32, scale=4)
@@ -145,7 +140,6 @@ def main():
145
  else:
146
  raise ValueError(f"Ismeretlen model_name: {args.model_name}")
147
 
148
- # model path letöltése ha szükséges
149
  if args.model_path is not None:
150
  model_path = args.model_path
151
  else:
@@ -155,24 +149,21 @@ def main():
155
  for url in file_url:
156
  model_path = load_file_from_url(url=url, model_dir=os.path.join(ROOT_DIR, 'weights'), progress=True, file_name=None)
157
 
158
- # dni weight (realesr-general esetén)
159
  dni_weight = None
160
  if args.model_name == 'realesr-general-x4v3' and args.denoise_strength != 1:
161
  wdn_model_path = model_path.replace('realesr-general-x4v3', 'realesr-general-wdn-x4v3')
162
  model_path = [model_path, wdn_model_path]
163
  dni_weight = [args.denoise_strength, 1 - args.denoise_strength]
164
 
165
- # modell GPU-ra helyezése és precision beállítása
166
  model = model.to(device)
167
  model.eval()
168
  if use_half:
169
  try:
170
  model.half()
171
  except Exception:
172
- # ha nem támogatja a half-ot, megy fp32-ben
173
  print("Figyelem: modell nem támogatta a .half() hívást -> használ fp32-t.")
174
 
175
- # RealESRGANer létrehozása (gpu_id explicit, hogy ne essen CPU fallbackbe)
176
  upsampler = RealESRGANer(
177
  scale=netscale,
178
  model_path=model_path,
@@ -182,10 +173,10 @@ def main():
182
  tile_pad=args.tile_pad,
183
  pre_pad=args.pre_pad,
184
  half=use_half,
185
- gpu_id=int(args.gpu_id) # soha ne legyen None
186
  )
187
 
188
- # GFPGAN inicializálása (ha kértük) és kényszerített GPU-ra mozgatás
189
  face_enhancer = None
190
  if args.face_enhance:
191
  try:
@@ -193,48 +184,33 @@ def main():
193
  except Exception as e:
194
  raise RuntimeError("GFPGAN kértél, de a gfpgan modul nem található: " + str(e))
195
 
196
- # Próbáljuk meg device paraméterrel létrehozni (újabb verziók ezt elfogadják)
 
 
197
  try:
198
  face_enhancer = GFPGANer(
199
- model_path='https://github.com/TencentARC/GFPGAN/releases/download/v1.3.0/GFPGANv1.3.pth',
200
  upscale=args.outscale,
201
  arch='clean',
202
  channel_multiplier=2,
203
  bg_upsampler=upsampler,
204
- device=device # ha a GFPGANer támogatja
205
  )
206
  except TypeError:
207
- # ha a konstruktor nem fogadja a device parametert, fallback a régebbi inicializációra
208
  face_enhancer = GFPGANer(
209
- model_path='https://github.com/TencentARC/GFPGAN/releases/download/v1.3.0/GFPGANv1.3.pth',
210
  upscale=args.outscale,
211
  arch='clean',
212
  channel_multiplier=2,
213
  bg_upsampler=upsampler
214
  )
215
 
216
- # most KÉZZEL mozgassuk GPU-ra az összes belső modult
217
- move_obj_to_device(face_enhancer, device, use_half)
218
-
219
- # extra ellenőrzés: írjuk ki az első paraméter device-át, ha van
220
- try:
221
- # megtaláljuk az első modulparamétert
222
- found = False
223
- import torch.nn as nn
224
- for attr in vars(face_enhancer).values():
225
- if isinstance(attr, nn.Module):
226
- for p in attr.parameters(recurse=True):
227
- print("GFPGAN első paraméter device:", p.device)
228
- found = True
229
- break
230
- if found:
231
- break
232
- except Exception:
233
- pass
234
 
235
  os.makedirs(args.output, exist_ok=True)
236
 
237
- # beolvasási lista
238
  if os.path.isfile(args.input):
239
  paths = [args.input]
240
  else:
@@ -256,14 +232,13 @@ def main():
256
 
257
  try:
258
  if args.face_enhance and face_enhancer is not None:
259
- # GFPGANer.enhance általában (np array) bemenetet vár
260
  _, _, output = face_enhancer.enhance(img, has_aligned=False, only_center_face=False, paste_back=True)
261
  else:
262
  output, _ = upsampler.enhance(img, outscale=args.outscale)
263
  except RuntimeError as error:
264
  print('Error during enhancement:', error)
265
- print('If you encounter CUDA out of memory, try --tile with a smaller number or reduce --outscale.')
266
- # tisztítás GPU memóriából
267
  try:
268
  torch.cuda.empty_cache()
269
  gc.collect()
@@ -284,7 +259,6 @@ def main():
284
  cv2.imwrite(save_path, output)
285
  print('Saved to', save_path)
286
 
287
- # végső takarítás
288
  try:
289
  torch.cuda.empty_cache()
290
  gc.collect()
@@ -293,4 +267,4 @@ def main():
293
 
294
 
295
  if __name__ == '__main__':
296
- main()
 
3
 
4
  """
5
  GPU-only Real-ESRGAN + GFPGAN inference script.
6
+ FIXED VERSION: Safe string handling & Forced FP32 for GFPGAN.
 
 
7
  """
8
 
9
  import argparse
 
22
 
23
 
24
  def setup_device(gpu_id: int) -> torch.device:
25
+ """Ellenőrzi CUDA elérhetőségét, beállítja az eszközt."""
26
  if not torch.cuda.is_available():
27
  raise RuntimeError("CUDA nem elérhető — ez a script csak GPU-n futtatható.")
 
28
  torch.cuda.set_device(int(gpu_id))
29
  device = torch.device(f"cuda:{int(gpu_id)}")
30
  torch.backends.cudnn.benchmark = True
 
31
  torch.set_grad_enabled(False)
32
  return device
33
 
34
 
35
  def move_obj_to_device(obj: Any, device: torch.device, use_half: bool):
36
  """
37
+ Rekurzívan megpróbál minden torch.nn.Module objektumot GPU-ra mozgatni.
 
 
38
  """
 
39
  try:
40
  import torch.nn as nn
41
  except Exception:
 
48
  pass
49
  if use_half:
50
  try:
51
+ # Csak akkor konvertáljuk, ha explicit kértük
52
  obj.half()
53
  except Exception:
54
  pass
55
+ else:
56
+ # Ha NEM kérünk half-ot, biztosítjuk, hogy float legyen (GFPGAN javítás)
57
+ try:
58
+ obj.float()
59
+ except Exception:
60
+ pass
61
  return
62
 
 
63
  if isinstance(obj, dict):
64
  for v in obj.values():
65
  move_obj_to_device(v, device, use_half)
 
69
  move_obj_to_device(v, device, use_half)
70
  return
71
 
 
72
  if hasattr(obj, "__dict__"):
73
  for _, v in vars(obj).items():
 
74
  if v is None:
75
  continue
 
76
  try:
 
77
  if nn is not None and isinstance(v, nn.Module):
78
  move_obj_to_device(v, device, use_half)
79
  elif isinstance(v, (list, tuple, dict, set)):
80
  move_obj_to_device(v, device, use_half)
81
  except Exception:
 
82
  pass
83
 
84
 
 
105
  args = parser.parse_args()
106
 
107
  device = setup_device(args.gpu_id)
108
+ # Ha fp32 flag nincs megadva, akkor use_half=True
109
  use_half = not args.fp32
110
 
111
+ # --- MODEL KIVÁLASZTÁS ---
112
  args.model_name = args.model_name.split('.')[0]
113
  if args.model_name == 'RealESRGAN_x4plus':
114
  model = RRDBNet(num_in_ch=3, num_out_ch=3, num_feat=64, num_block=23, num_grow_ch=32, scale=4)
 
140
  else:
141
  raise ValueError(f"Ismeretlen model_name: {args.model_name}")
142
 
 
143
  if args.model_path is not None:
144
  model_path = args.model_path
145
  else:
 
149
  for url in file_url:
150
  model_path = load_file_from_url(url=url, model_dir=os.path.join(ROOT_DIR, 'weights'), progress=True, file_name=None)
151
 
 
152
  dni_weight = None
153
  if args.model_name == 'realesr-general-x4v3' and args.denoise_strength != 1:
154
  wdn_model_path = model_path.replace('realesr-general-x4v3', 'realesr-general-wdn-x4v3')
155
  model_path = [model_path, wdn_model_path]
156
  dni_weight = [args.denoise_strength, 1 - args.denoise_strength]
157
 
158
+ # --- RealESRGAN (Háttér) Modell betöltése ---
159
  model = model.to(device)
160
  model.eval()
161
  if use_half:
162
  try:
163
  model.half()
164
  except Exception:
 
165
  print("Figyelem: modell nem támogatta a .half() hívást -> használ fp32-t.")
166
 
 
167
  upsampler = RealESRGANer(
168
  scale=netscale,
169
  model_path=model_path,
 
173
  tile_pad=args.tile_pad,
174
  pre_pad=args.pre_pad,
175
  half=use_half,
176
+ gpu_id=int(args.gpu_id)
177
  )
178
 
179
+ # --- GFPGAN (Arc) Inicializálása ---
180
  face_enhancer = None
181
  if args.face_enhance:
182
  try:
 
184
  except Exception as e:
185
  raise RuntimeError("GFPGAN kértél, de a gfpgan modul nem található: " + str(e))
186
 
187
+ # A linket változóba tesszük, hogy ne csússzon szét a sor másolásnál
188
+ gfpgan_url = 'https://github.com/TencentARC/GFPGAN/releases/download/v1.3.0/GFPGANv1.3.pth'
189
+
190
  try:
191
  face_enhancer = GFPGANer(
192
+ model_path=gfpgan_url,
193
  upscale=args.outscale,
194
  arch='clean',
195
  channel_multiplier=2,
196
  bg_upsampler=upsampler,
197
+ device=device
198
  )
199
  except TypeError:
 
200
  face_enhancer = GFPGANer(
201
+ model_path=gfpgan_url,
202
  upscale=args.outscale,
203
  arch='clean',
204
  channel_multiplier=2,
205
  bg_upsampler=upsampler
206
  )
207
 
208
+ # !!! JAVÍTÁS !!!
209
+ # Kényszerítjük a GFPGAN-t, hogy maradjon FP32-ben (False)
210
+ move_obj_to_device(face_enhancer, device, use_half=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
211
 
212
  os.makedirs(args.output, exist_ok=True)
213
 
 
214
  if os.path.isfile(args.input):
215
  paths = [args.input]
216
  else:
 
232
 
233
  try:
234
  if args.face_enhance and face_enhancer is not None:
235
+ # GFPGANer futtatása
236
  _, _, output = face_enhancer.enhance(img, has_aligned=False, only_center_face=False, paste_back=True)
237
  else:
238
  output, _ = upsampler.enhance(img, outscale=args.outscale)
239
  except RuntimeError as error:
240
  print('Error during enhancement:', error)
241
+ print('Trying to recover GPU memory...')
 
242
  try:
243
  torch.cuda.empty_cache()
244
  gc.collect()
 
259
  cv2.imwrite(save_path, output)
260
  print('Saved to', save_path)
261
 
 
262
  try:
263
  torch.cuda.empty_cache()
264
  gc.collect()
 
267
 
268
 
269
  if __name__ == '__main__':
270
+ main()