Spaces:
Running on Zero
Running on Zero
1lch2 commited on
Commit ·
79595b4
1
Parent(s): e2e4ca3
fix fp16 precision bug
Browse files- model_loader.py +19 -9
model_loader.py
CHANGED
|
@@ -6,9 +6,13 @@ from PIL import Image
|
|
| 6 |
|
| 7 |
|
| 8 |
def detect_device():
|
| 9 |
-
"""Auto-detect device. Returns CPU on ZeroGPU (GPU not available at startup).
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
if torch.cuda.is_available():
|
| 11 |
-
return "cuda", torch.
|
| 12 |
return "cpu", torch.float32
|
| 13 |
|
| 14 |
|
|
@@ -78,7 +82,7 @@ class UltraSharpV2:
|
|
| 78 |
|
| 79 |
if device is not None:
|
| 80 |
self.device = device
|
| 81 |
-
self.dtype = torch.
|
| 82 |
else:
|
| 83 |
self.device, self.dtype = detect_device()
|
| 84 |
|
|
@@ -97,13 +101,15 @@ class UltraSharpV2:
|
|
| 97 |
return model
|
| 98 |
|
| 99 |
def to_cuda(self):
|
| 100 |
-
"""Move model to CUDA (called inside @spaces.GPU decorated function).
|
|
|
|
|
|
|
|
|
|
| 101 |
if self.device == "cuda":
|
| 102 |
return
|
| 103 |
print("[UltraSharpV2] 正在将模型移至 GPU ...")
|
| 104 |
self.device = "cuda"
|
| 105 |
-
self.
|
| 106 |
-
self.model.model.to(self.device).to(self.dtype)
|
| 107 |
torch.cuda.empty_cache()
|
| 108 |
|
| 109 |
def to_cpu(self):
|
|
@@ -111,9 +117,8 @@ class UltraSharpV2:
|
|
| 111 |
if self.device == "cpu":
|
| 112 |
return
|
| 113 |
print("[UltraSharpV2] 正在将模型移回 CPU ...")
|
| 114 |
-
self.model.model.to("cpu")
|
| 115 |
self.device = "cpu"
|
| 116 |
-
self.dtype = torch.float32
|
| 117 |
torch.cuda.empty_cache()
|
| 118 |
|
| 119 |
def upscale(
|
|
@@ -155,7 +160,12 @@ class UltraSharpV2:
|
|
| 155 |
return tensor.to(self.device)
|
| 156 |
|
| 157 |
def _tensor_to_pil(self, tensor: torch.Tensor) -> Image.Image:
|
| 158 |
-
tensor = tensor.squeeze(0).float()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 159 |
arr = (tensor.permute(1, 2, 0).cpu().numpy() * 255).round().astype(np.uint8)
|
| 160 |
return Image.fromarray(arr)
|
| 161 |
|
|
|
|
| 6 |
|
| 7 |
|
| 8 |
def detect_device():
|
| 9 |
+
"""Auto-detect device. Returns CPU on ZeroGPU (GPU not available at startup).
|
| 10 |
+
|
| 11 |
+
Always uses fp32 — DAT2 architecture produces NaN in fp16 (attention softmax
|
| 12 |
+
+ LayerNorm overflow). 48GB VRAM is more than sufficient for fp32.
|
| 13 |
+
"""
|
| 14 |
if torch.cuda.is_available():
|
| 15 |
+
return "cuda", torch.float32
|
| 16 |
return "cpu", torch.float32
|
| 17 |
|
| 18 |
|
|
|
|
| 82 |
|
| 83 |
if device is not None:
|
| 84 |
self.device = device
|
| 85 |
+
self.dtype = torch.float32
|
| 86 |
else:
|
| 87 |
self.device, self.dtype = detect_device()
|
| 88 |
|
|
|
|
| 101 |
return model
|
| 102 |
|
| 103 |
def to_cuda(self):
|
| 104 |
+
"""Move model to CUDA (called inside @spaces.GPU decorated function).
|
| 105 |
+
|
| 106 |
+
Keeps fp32 — DAT2 architecture produces NaN in fp16.
|
| 107 |
+
"""
|
| 108 |
if self.device == "cuda":
|
| 109 |
return
|
| 110 |
print("[UltraSharpV2] 正在将模型移至 GPU ...")
|
| 111 |
self.device = "cuda"
|
| 112 |
+
self.model.model.to(self.device)
|
|
|
|
| 113 |
torch.cuda.empty_cache()
|
| 114 |
|
| 115 |
def to_cpu(self):
|
|
|
|
| 117 |
if self.device == "cpu":
|
| 118 |
return
|
| 119 |
print("[UltraSharpV2] 正在将模型移回 CPU ...")
|
| 120 |
+
self.model.model.to("cpu")
|
| 121 |
self.device = "cpu"
|
|
|
|
| 122 |
torch.cuda.empty_cache()
|
| 123 |
|
| 124 |
def upscale(
|
|
|
|
| 160 |
return tensor.to(self.device)
|
| 161 |
|
| 162 |
def _tensor_to_pil(self, tensor: torch.Tensor) -> Image.Image:
|
| 163 |
+
tensor = tensor.squeeze(0).float()
|
| 164 |
+
if torch.isnan(tensor).any() or torch.isinf(tensor).any():
|
| 165 |
+
raise RuntimeError(
|
| 166 |
+
"模型输出包含 NaN/Inf — 请检查是否使用了 fp16(DAT2 架构不支持 fp16)"
|
| 167 |
+
)
|
| 168 |
+
tensor = tensor.clamp(0, 1)
|
| 169 |
arr = (tensor.permute(1, 2, 0).cpu().numpy() * 255).round().astype(np.uint8)
|
| 170 |
return Image.fromarray(arr)
|
| 171 |
|