joeygambino commited on
Commit
971b15c
·
verified ·
1 Parent(s): 2ec166a

per-device capability probe: pre-Ada GPUs auto-fall back to upcast path

Browse files
libs/ltx_core/quantization/fp8_torch_mm.py CHANGED
@@ -17,6 +17,22 @@ from ltx_core.quantization.fp8_cast import _replace_fwd_with_upcast
17
 
18
  _F8_MAX = 448.0 # float8_e4m3fn finite max
19
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
 
21
  def _replace_fwd_with_scaled_mm(layer: torch.nn.Linear) -> None:
22
  """Swap layer.forward for a runtime-branching fp8 path.
@@ -41,8 +57,9 @@ def _replace_fwd_with_scaled_mm(layer: torch.nn.Linear) -> None:
41
  return layer.original_forward(*args, **_kwargs)
42
  if layer.bias is not None and layer.bias.dtype == torch.float8_e4m3fn:
43
  layer.bias.data = layer.bias.data.to(torch.bfloat16) # one-time restore
44
- if (not (x.is_cuda and w.is_cuda)) or w.shape[0] % 16 or w.shape[1] % 16:
45
- # CPU pass or non-16-aligned dims: per-layer upcast math.
 
46
  w_up = w.to(x.dtype)
47
  b = layer.bias.to(x.dtype) if layer.bias is not None else None
48
  return torch.nn.functional.linear(x, w_up, b)
 
17
 
18
  _F8_MAX = 448.0 # float8_e4m3fn finite max
19
 
20
+ _SM_OK: dict = {} # device -> bool: native fp8 mm available (sm_89+)
21
+
22
+
23
+ def _scaled_mm_supported(device) -> bool:
24
+ ok = _SM_OK.get(device)
25
+ if ok is None:
26
+ try:
27
+ ok = torch.cuda.get_device_capability(device) >= (8, 9)
28
+ except Exception:
29
+ ok = False
30
+ _SM_OK[device] = ok
31
+ if not ok:
32
+ print(f"[ltx_core] fp8 scaled-mm: {device} lacks sm_89+ fp8 cores; "
33
+ "falling back to per-layer upcast on this device.", flush=True)
34
+ return ok
35
+
36
 
37
  def _replace_fwd_with_scaled_mm(layer: torch.nn.Linear) -> None:
38
  """Swap layer.forward for a runtime-branching fp8 path.
 
57
  return layer.original_forward(*args, **_kwargs)
58
  if layer.bias is not None and layer.bias.dtype == torch.float8_e4m3fn:
59
  layer.bias.data = layer.bias.data.to(torch.bfloat16) # one-time restore
60
+ if (not (x.is_cuda and w.is_cuda)) or w.shape[0] % 16 or w.shape[1] % 16 \
61
+ or not _scaled_mm_supported(x.device):
62
+ # CPU pass, non-16-aligned dims, or pre-Ada GPU: per-layer upcast math.
63
  w_up = w.to(x.dtype)
64
  b = layer.bias.to(x.dtype) if layer.bias is not None else None
65
  return torch.nn.functional.linear(x, w_up, b)