MogensR commited on
Commit
4b817e6
Β·
1 Parent(s): 20cbc35
models/matany_compat_patch.py CHANGED
@@ -1,19 +1,21 @@
1
  #!/usr/bin/env python3
2
  # MatAnyone HF-compat patch: squeeze time dim T=1 before first Conv2d
3
  # Changes (2025-09-16):
 
 
4
  # - Added isinstance(img, torch.Tensor) for non-tensor safety
5
  # - Enhanced logging with input/output shapes
6
- # - Added version check logging
7
  # - Kept monkey-patch for HF Spaces compatibility
8
 
9
  import logging
10
  import torch
 
11
 
12
  log = logging.getLogger("backgroundfx_pro")
13
 
14
  def apply_matany_t1_squeeze_guard() -> bool:
15
  """
16
- Monkey-patch MatAnyone.encode_img to squeeze [B,1,C,H,W] β†’ [B,C,H,W].
17
  Safe for multi-frame (T>1) as it only squeezes when T==1.
18
  Returns True if patch applied successfully, False otherwise.
19
  """
@@ -26,27 +28,42 @@ def apply_matany_t1_squeeze_guard() -> bool:
26
  log.warning("[MatAnyCompat] MatAnyone class not found")
27
  return False
28
  MatAnyone = M.MatAnyone
29
- if not hasattr(MatAnyone, "encode_img"):
30
- log.warning("[MatAnyCompat] encode_img not found on MatAnyone")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  return False
32
- if getattr(MatAnyone, "_encode_img_patched", False):
33
- log.info("[MatAnyCompat] encode_img already patched")
34
  return True
35
 
36
  # Store original method
37
- orig_encode_img = MatAnyone.encode_img
38
 
39
- def encode_img_compat(self, img, *args, **kwargs):
40
  # Handle inputs that MatAnyone.step turned into [B,1,C,H,W]
41
  try:
42
  if isinstance(img, torch.Tensor) and img.dim() == 5 and img.shape[1] == 1:
43
- log.info(f"[MatAnyCompat] Squeezing 5D {img.shape} to 4D {img.squeeze(1).shape}")
44
  img = img.squeeze(1) # [B,1,C,H,W] β†’ [B,C,H,W]
45
  except Exception as e:
46
- log.warning("[MatAnyCompat] Failed to process input shape: %s", e)
47
- return orig_encode_img(self, img, *args, **kwargs)
48
 
49
- MatAnyone.encode_img = encode_img_compat
50
- MatAnyone._encode_img_patched = True
51
- log.info("[MatAnyCompat] Applied T=1 squeeze guard in MatAnyone.encode_img")
52
  return True
 
1
  #!/usr/bin/env python3
2
  # MatAnyone HF-compat patch: squeeze time dim T=1 before first Conv2d
3
  # Changes (2025-09-16):
4
+ # - Added fallback patching for forward/encode if encode_img missing
5
+ # - Log dir(MatAnyone) and module version for debugging
6
  # - Added isinstance(img, torch.Tensor) for non-tensor safety
7
  # - Enhanced logging with input/output shapes
 
8
  # - Kept monkey-patch for HF Spaces compatibility
9
 
10
  import logging
11
  import torch
12
+ import importlib.metadata
13
 
14
  log = logging.getLogger("backgroundfx_pro")
15
 
16
  def apply_matany_t1_squeeze_guard() -> bool:
17
  """
18
+ Monkey-patch MatAnyone.encode_img (or forward/encode) to squeeze [B,1,C,H,W] β†’ [B,C,H,W].
19
  Safe for multi-frame (T>1) as it only squeezes when T==1.
20
  Returns True if patch applied successfully, False otherwise.
21
  """
 
28
  log.warning("[MatAnyCompat] MatAnyone class not found")
29
  return False
30
  MatAnyone = M.MatAnyone
31
+
32
+ # Log MatAnyone version and attributes for debugging
33
+ try:
34
+ version = importlib.metadata.version("matanyone")
35
+ log.info(f"[MatAnyCompat] MatAnyone version: {version}")
36
+ except Exception:
37
+ log.info("[MatAnyCompat] MatAnyone version unknown")
38
+ log.debug(f"[MatAnyCompat] MatAnyone attributes: {dir(MatAnyone)}")
39
+
40
+ # Try encode_img first, then fallback to forward or encode
41
+ method_name = None
42
+ for candidate in ["encode_img", "forward", "encode"]:
43
+ if hasattr(MatAnyone, candidate):
44
+ method_name = candidate
45
+ break
46
+ if not method_name:
47
+ log.warning("[MatAnyCompat] No patchable method (encode_img, forward, encode) found on MatAnyone")
48
  return False
49
+ if getattr(MatAnyone, f"_{method_name}_patched", False):
50
+ log.info(f"[MatAnyCompat] {method_name} already patched")
51
  return True
52
 
53
  # Store original method
54
+ orig_method = getattr(MatAnyone, method_name)
55
 
56
+ def method_compat(self, img, *args, **kwargs):
57
  # Handle inputs that MatAnyone.step turned into [B,1,C,H,W]
58
  try:
59
  if isinstance(img, torch.Tensor) and img.dim() == 5 and img.shape[1] == 1:
60
+ log.info(f"[MatAnyCompat] Squeezing 5D {img.shape} to 4D {img.squeeze(1).shape} in {method_name}")
61
  img = img.squeeze(1) # [B,1,C,H,W] β†’ [B,C,H,W]
62
  except Exception as e:
63
+ log.warning(f"[MatAnyCompat] Failed to process input shape in {method_name}: %s", e)
64
+ return orig_method(self, img, *args, **kwargs)
65
 
66
+ setattr(MatAnyone, method_name, method_compat)
67
+ setattr(MatAnyone, f"_{method_name}_patched", True)
68
+ log.info(f"[MatAnyCompat] Applied T=1 squeeze guard in MatAnyone.{method_name}")
69
  return True
models/matanyone_loader.py CHANGED
@@ -5,15 +5,16 @@
5
 
6
  - SAM2 defines the subject (seed mask) on frame 0.
7
  - MatAnyone does frame-by-frame alpha matting.
8
- - Prefers step([B,C,H,W]) with T=1 squeeze patch for conv2d compatibility.
9
- - Falls back to process_frame([H,W,3]) if supported by the wheel.
10
 
11
  Changes (2025-09-16):
12
- - Added T=1 squeeze patch status logging in __init__
13
- - Set MATANY_FORCE_FORMAT=4d as default since patch ensures 4D compatibility
14
- - Added optional VRAM logging in process_stream (MATANY_LOG_VRAM=1)
15
- - Enhanced _safe_empty_cache with memory_summary
16
- - Updated comments to prioritize step() post-patch
 
17
  """
18
 
19
  from __future__ import annotations
@@ -76,16 +77,33 @@ def _cuda_snapshot(device: Optional[torch.device]) -> str:
76
  return f"CUDA snapshot error: {e!r}"
77
 
78
  def _safe_empty_cache():
79
- if not torch.cuda.is_available():
80
- return
81
  try:
82
- log.info(f"[MATANY] CUDA memory before empty_cache: {_cuda_snapshot(None)}")
 
 
 
 
 
 
 
 
 
83
  torch.cuda.empty_cache()
84
- log.info(f"[MATANY] CUDA memory after empty_cache: {_cuda_snapshot(None)}")
85
- if os.getenv("MATANY_LOG_VRAM", "0") == "1":
86
- log.debug(f"[MATANY] VRAM summary:\n{torch.cuda.memory_summary()}")
87
- except Exception:
88
- pass
 
 
 
 
 
 
 
 
 
89
 
90
  # ---------- SAM2 β†’ seed mask prep ----------
91
  def _prepare_seed_mask(sam2_mask: np.ndarray, H: int, W: int) -> np.ndarray:
 
5
 
6
  - SAM2 defines the subject (seed mask) on frame 0.
7
  - MatAnyone does frame-by-frame alpha matting.
8
+ - Uses T=1 squeeze patch for conv2d compatibility.
9
+ - Falls back to process_frame([H,W,3]) if step() is unavailable.
10
 
11
  Changes (2025-09-16):
12
+ - Added comprehensive error handling for MatAnyone import and initialization
13
+ - Enhanced VRAM management with auto-cleanup
14
+ - Added support for multiple MatAnyone method patching (encode_img/forward/encode)
15
+ - Improved logging with timestamps and memory usage
16
+ - Added environment variable controls for debugging
17
+ - Fixed potential memory leaks in tensor handling
18
  """
19
 
20
  from __future__ import annotations
 
77
  return f"CUDA snapshot error: {e!r}"
78
 
79
  def _safe_empty_cache():
80
+ """Safely clear PyTorch cache with detailed memory reporting."""
 
81
  try:
82
+ if not torch.cuda.is_available():
83
+ return
84
+
85
+ # Log memory stats before cleanup
86
+ if _env_flag("MATANY_LOG_VRAM"):
87
+ log.info("[MATANY] VRAM before cleanup:")
88
+ log.info(f" Allocated: {torch.cuda.memory_allocated()/1024**2:.1f} MB")
89
+ log.info(f" Reserved: {torch.cuda.memory_reserved()/1024**2:.1f} MB")
90
+
91
+ # Clear cache and sync
92
  torch.cuda.empty_cache()
93
+ torch.cuda.synchronize()
94
+
95
+ # Log memory stats after cleanup
96
+ if _env_flag("MATANY_LOG_VRAM"):
97
+ log.info("[MATANY] VRAM after cleanup:")
98
+ log.info(f" Allocated: {torch.cuda.memory_allocated()/1024**2:.1f} MB")
99
+ log.info(f" Reserved: {torch.cuda.memory_reserved()/1024**2:.1f} MB")
100
+
101
+ except Exception as e:
102
+ log.warning(f"[MATANY] Error in cache cleanup: {e}", exc_info=True)
103
+ try:
104
+ torch.cuda.empty_cache()
105
+ except Exception as e2:
106
+ log.warning(f"[MATANY] Secondary cache cleanup failed: {e2}")
107
 
108
  # ---------- SAM2 β†’ seed mask prep ----------
109
  def _prepare_seed_mask(sam2_mask: np.ndarray, H: int, W: int) -> np.ndarray: