dikdimon commited on
Commit
d751685
·
verified ·
1 Parent(s): 43647ee

Update !1-custom-hires-fix-mod-for-automatic1111-2.9.5/scripts/!!custom_hires_fix.py

Browse files
!1-custom-hires-fix-mod-for-automatic1111-2.9.5/scripts/!!custom_hires_fix.py CHANGED
@@ -1928,6 +1928,64 @@ class CustomHiresFix(scripts.Script):
1928
  pass
1929
  self._orig_opt_vae_tiling = None
1930
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1931
 
1932
  # --- safe upscaler wrapper (PIL fallback) ---
1933
  def _resize_with_upscaler(self, img: Image.Image, w: int, h: int, upscaler_name: str) -> Image.Image:
@@ -2558,11 +2616,7 @@ class CustomHiresFix(scripts.Script):
2558
  ).to(devices.dtype_vae)
2559
 
2560
  devices.torch_gc()
2561
- decoded_sample = processing.decode_first_stage(shared.sd_model, samples)
2562
- if torch.isnan(decoded_sample).any().item():
2563
- devices.torch_gc()
2564
- samples = torch.clamp(samples, -3, 3)
2565
- decoded_sample = processing.decode_first_stage(shared.sd_model, samples)
2566
 
2567
  decoded_sample = torch.clamp((decoded_sample + 1.0) / 2.0, min=0.0, max=1.0).squeeze()
2568
  x_np = 255.0 * np.moveaxis(decoded_sample.to(torch.float32).cpu().numpy(), 0, 2)
@@ -2790,11 +2844,7 @@ class CustomHiresFix(scripts.Script):
2790
  ).to(devices.dtype_vae)
2791
 
2792
  devices.torch_gc()
2793
- decoded_sample = processing.decode_first_stage(shared.sd_model, samples)
2794
- if torch.isnan(decoded_sample).any().item():
2795
- devices.torch_gc()
2796
- samples = torch.clamp(samples, -3, 3)
2797
- decoded_sample = processing.decode_first_stage(shared.sd_model, samples)
2798
 
2799
  decoded_sample = torch.clamp((decoded_sample + 1.0) / 2.0, min=0.0, max=1.0).squeeze()
2800
  x_np = 255.0 * np.moveaxis(decoded_sample.to(torch.float32).cpu().numpy(), 0, 2)
 
1928
  pass
1929
  self._orig_opt_vae_tiling = None
1930
 
1931
+ def _decode_first_stage_safe(self, samples: torch.Tensor) -> torch.Tensor:
1932
+ """
1933
+ Обёртка над processing.decode_first_stage с защитой от OOM:
1934
+ 1) Агрессивная очистка VRAM перед декодом (torch_gc + empty_cache).
1935
+ 2) Авто-включение VAE tiling при первом OOM и повтор с теми же данными.
1936
+ 3) Второй OOM: повтор с clamp(-3,3) — ВНИМАНИЕ: незначительно меняет
1937
+ результат, используется только как последний аварийный шанс.
1938
+ 4) NaN guard: если декод вернул NaN — clamp + повтор.
1939
+ Перевод результата на CPU выполняется в вызывающем коде, не здесь.
1940
+ """
1941
+ # Шаг 1: максимально освободить VRAM перед тяжёлым декодом
1942
+ devices.torch_gc()
1943
+ try:
1944
+ torch.cuda.empty_cache()
1945
+ except Exception:
1946
+ pass
1947
+
1948
+ def _do_decode(s: torch.Tensor) -> torch.Tensor:
1949
+ return processing.decode_first_stage(shared.sd_model, s)
1950
+
1951
+ # Шаг 2: попытка декода; при OOM — включаем VAE tiling и повторяем
1952
+ # с теми же данными (результат не меняется)
1953
+ try:
1954
+ decoded = _do_decode(samples)
1955
+ except torch.cuda.OutOfMemoryError:
1956
+ logger.warning(
1957
+ "OOM during decode_first_stage — enabling VAE tiling and retrying "
1958
+ "(same data, result unchanged). Consider enabling 'VAE tiling (low VRAM)' "
1959
+ "in extension settings to avoid this overhead."
1960
+ )
1961
+ devices.torch_gc()
1962
+ try:
1963
+ torch.cuda.empty_cache()
1964
+ except Exception:
1965
+ pass
1966
+ self._set_vae_tiling(True)
1967
+ try:
1968
+ decoded = _do_decode(samples)
1969
+ except torch.cuda.OutOfMemoryError:
1970
+ # Шаг 3: последний аварийный шанс — clamp(-3,3) + повтор.
1971
+ # ВНИМАНИЕ: clamp незначительно изменяет экстремальные значения латента,
1972
+ # что может чуть повлиять на детали картинки. Применяется только при
1973
+ # втором подряд OOM, когда даже VAE tiling не помог.
1974
+ logger.warning(
1975
+ "OOM again after VAE tiling — clamping latents to [-3, 3] and retrying. "
1976
+ "This is a last-resort fallback and may slightly alter the output image."
1977
+ )
1978
+ devices.torch_gc()
1979
+ decoded = _do_decode(torch.clamp(samples, -3, 3))
1980
+
1981
+ # Шаг 4: NaN guard (отдельно от OOM — может возникнуть без нехватки памяти)
1982
+ if torch.isnan(decoded).any().item():
1983
+ logger.warning("NaN detected in decoded sample — clamping latents and retrying.")
1984
+ devices.torch_gc()
1985
+ decoded = _do_decode(torch.clamp(samples, -3, 3))
1986
+
1987
+ return decoded
1988
+
1989
 
1990
  # --- safe upscaler wrapper (PIL fallback) ---
1991
  def _resize_with_upscaler(self, img: Image.Image, w: int, h: int, upscaler_name: str) -> Image.Image:
 
2616
  ).to(devices.dtype_vae)
2617
 
2618
  devices.torch_gc()
2619
+ decoded_sample = self._decode_first_stage_safe(samples)
 
 
 
 
2620
 
2621
  decoded_sample = torch.clamp((decoded_sample + 1.0) / 2.0, min=0.0, max=1.0).squeeze()
2622
  x_np = 255.0 * np.moveaxis(decoded_sample.to(torch.float32).cpu().numpy(), 0, 2)
 
2844
  ).to(devices.dtype_vae)
2845
 
2846
  devices.torch_gc()
2847
+ decoded_sample = self._decode_first_stage_safe(samples)
 
 
 
 
2848
 
2849
  decoded_sample = torch.clamp((decoded_sample + 1.0) / 2.0, min=0.0, max=1.0).squeeze()
2850
  x_np = 255.0 * np.moveaxis(decoded_sample.to(torch.float32).cpu().numpy(), 0, 2)