Spaces:
mikitona
/
Running on Zero

mikitona commited on
Commit
595ed80
·
verified ·
1 Parent(s): 1230d92

Update SUPIR/util.py

Browse files
Files changed (1) hide show
  1. SUPIR/util.py +224 -179
SUPIR/util.py CHANGED
@@ -1,179 +1,224 @@
1
- import os
2
- import torch
3
- import numpy as np
4
- import cv2
5
- from PIL import Image
6
- from torch.nn.functional import interpolate
7
- from omegaconf import OmegaConf
8
- from sgm.util import instantiate_from_config
9
-
10
-
11
- def get_state_dict(d):
12
- return d.get('state_dict', d)
13
-
14
-
15
- def load_state_dict(ckpt_path, location='cpu'):
16
- _, extension = os.path.splitext(ckpt_path)
17
- if extension.lower() == ".safetensors":
18
- import safetensors.torch
19
- state_dict = safetensors.torch.load_file(ckpt_path, device=location)
20
- else:
21
- state_dict = get_state_dict(torch.load(ckpt_path, map_location=torch.device(location)))
22
- state_dict = get_state_dict(state_dict)
23
- print(f'Loaded state_dict from [{ckpt_path}]')
24
- return state_dict
25
-
26
-
27
- def create_model(config_path):
28
- config = OmegaConf.load(config_path)
29
- model = instantiate_from_config(config.model).cpu()
30
- print(f'Loaded model config from [{config_path}]')
31
- return model
32
-
33
-
34
- def create_SUPIR_model(config_path, SUPIR_sign=None, load_default_setting=False):
35
- config = OmegaConf.load(config_path)
36
- model = instantiate_from_config(config.model).cpu()
37
- print(f'Loaded model config from [{config_path}]')
38
- if config.SDXL_CKPT is not None:
39
- model.load_state_dict(load_state_dict(config.SDXL_CKPT), strict=False)
40
- if config.SUPIR_CKPT is not None:
41
- model.load_state_dict(load_state_dict(config.SUPIR_CKPT), strict=False)
42
- if SUPIR_sign is not None:
43
- assert SUPIR_sign in ['F', 'Q']
44
- if SUPIR_sign == 'F':
45
- model.load_state_dict(load_state_dict(config.SUPIR_CKPT_F), strict=False)
46
- elif SUPIR_sign == 'Q':
47
- model.load_state_dict(load_state_dict(config.SUPIR_CKPT_Q), strict=False)
48
- if load_default_setting:
49
- default_setting = config.default_setting
50
- return model, default_setting
51
- return model
52
-
53
- def load_QF_ckpt(config_path):
54
- config = OmegaConf.load(config_path)
55
- ckpt_F = torch.load(config.SUPIR_CKPT_F, map_location='cpu')
56
- ckpt_Q = torch.load(config.SUPIR_CKPT_Q, map_location='cpu')
57
- return ckpt_Q, ckpt_F
58
-
59
-
60
- def PIL2Tensor(img, upsacle=1, min_size=1024, fix_resize=None):
61
- '''
62
- PIL.Image -> Tensor[C, H, W], RGB, [-1, 1]
63
- '''
64
- # size
65
- w, h = img.size
66
- w *= upsacle
67
- h *= upsacle
68
- w0, h0 = round(w), round(h)
69
- if min(w, h) < min_size:
70
- _upsacle = min_size / min(w, h)
71
- w *= _upsacle
72
- h *= _upsacle
73
- if fix_resize is not None:
74
- _upsacle = fix_resize / min(w, h)
75
- w *= _upsacle
76
- h *= _upsacle
77
- w0, h0 = round(w), round(h)
78
- w = int(np.round(w / 64.0)) * 64
79
- h = int(np.round(h / 64.0)) * 64
80
- x = img.resize((w, h), Image.BICUBIC)
81
- x = np.array(x).round().clip(0, 255).astype(np.uint8)
82
- x = x / 255 * 2 - 1
83
- x = torch.tensor(x, dtype=torch.float32).permute(2, 0, 1)
84
- return x, h0, w0
85
-
86
-
87
- def Tensor2PIL(x, h0, w0):
88
- '''
89
- Tensor[C, H, W], RGB, [-1, 1] -> PIL.Image
90
- '''
91
- x = x.unsqueeze(0)
92
- x = interpolate(x, size=(h0, w0), mode='bicubic')
93
- x = (x.squeeze(0).permute(1, 2, 0) * 127.5 + 127.5).cpu().numpy().clip(0, 255).astype(np.uint8)
94
- return Image.fromarray(x)
95
-
96
-
97
- def HWC3(x):
98
- assert x.dtype == np.uint8
99
- if x.ndim == 2:
100
- x = x[:, :, None]
101
- assert x.ndim == 3
102
- H, W, C = x.shape
103
- assert C == 1 or C == 3 or C == 4
104
- if C == 3:
105
- return x
106
- if C == 1:
107
- return np.concatenate([x, x, x], axis=2)
108
- if C == 4:
109
- color = x[:, :, 0:3].astype(np.float32)
110
- alpha = x[:, :, 3:4].astype(np.float32) / 255.0
111
- y = color * alpha + 255.0 * (1.0 - alpha)
112
- y = y.clip(0, 255).astype(np.uint8)
113
- return y
114
-
115
-
116
- def upscale_image(input_image, upscale, min_size=None, unit_resolution=64):
117
- H, W, C = input_image.shape
118
- H = float(H)
119
- W = float(W)
120
- H *= upscale
121
- W *= upscale
122
- if min_size is not None:
123
- if min(H, W) < min_size:
124
- _upsacle = min_size / min(W, H)
125
- W *= _upsacle
126
- H *= _upsacle
127
- H = int(np.round(H / unit_resolution)) * unit_resolution
128
- W = int(np.round(W / unit_resolution)) * unit_resolution
129
- img = cv2.resize(input_image, (W, H), interpolation=cv2.INTER_LANCZOS4 if upscale > 1 else cv2.INTER_AREA)
130
- img = img.round().clip(0, 255).astype(np.uint8)
131
- return img
132
-
133
-
134
- def fix_resize(input_image, size=512, unit_resolution=64):
135
- H, W, C = input_image.shape
136
- H = float(H)
137
- W = float(W)
138
- upscale = size / min(H, W)
139
- H *= upscale
140
- W *= upscale
141
- H = int(np.round(H / unit_resolution)) * unit_resolution
142
- W = int(np.round(W / unit_resolution)) * unit_resolution
143
- img = cv2.resize(input_image, (W, H), interpolation=cv2.INTER_LANCZOS4 if upscale > 1 else cv2.INTER_AREA)
144
- img = img.round().clip(0, 255).astype(np.uint8)
145
- return img
146
-
147
-
148
-
149
- def Numpy2Tensor(img):
150
- '''
151
- np.array[H, w, C] [0, 255] -> Tensor[C, H, W], RGB, [-1, 1]
152
- '''
153
- # size
154
- img = np.array(img) / 255 * 2 - 1
155
- img = torch.tensor(img, dtype=torch.float32).permute(2, 0, 1)
156
- return img
157
-
158
-
159
- def Tensor2Numpy(x, h0=None, w0=None):
160
- '''
161
- Tensor[C, H, W], RGB, [-1, 1] -> PIL.Image
162
- '''
163
- if h0 is not None and w0 is not None:
164
- x = x.unsqueeze(0)
165
- x = interpolate(x, size=(h0, w0), mode='bicubic')
166
- x = x.squeeze(0)
167
- x = (x.permute(1, 2, 0) * 127.5 + 127.5).cpu().numpy().clip(0, 255).astype(np.uint8)
168
- return x
169
-
170
-
171
- def convert_dtype(dtype_str):
172
- if dtype_str == 'fp32':
173
- return torch.float32
174
- elif dtype_str == 'fp16':
175
- return torch.float16
176
- elif dtype_str == 'bf16':
177
- return torch.bfloat16
178
- else:
179
- raise NotImplementedError
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import torch
3
+ import numpy as np
4
+ import cv2
5
+ from PIL import Image
6
+ from torch.nn.functional import interpolate
7
+ from omegaconf import OmegaConf
8
+ from sgm.util import instantiate_from_config
9
+ from huggingface_hub import hf_hub_download
10
+
11
+ def get_state_dict(d):
12
+ return d.get('state_dict', d)
13
+
14
+ def load_state_dict(ckpt_path, location='cpu'):
15
+ _, extension = os.path.splitext(ckpt_path)
16
+
17
+ # Hugging Faceのリポジトリからロードするかチェック
18
+ if '/' in ckpt_path: # リポジトリ形式のパスと判断
19
+ parts = ckpt_path.split('/')
20
+ if len(parts) == 3:
21
+ repo_id = f"{parts[0]}/{parts[1]}"
22
+ filename = parts[2]
23
+ # ダウンロードの前にログを出力
24
+ print(f"Attempting to download from Hugging Face Hub with repo_id: {repo_id} and filename: {filename}")
25
+ ckpt_path = hf_hub_download(repo_id=repo_id, filename=filename)
26
+ # ダウンロード後に実際のファイルパスを確認するためのログを出力
27
+ print(f"Downloaded file path for {filename}: {ckpt_path}")
28
+ else:
29
+ raise ValueError("Invalid format for Hugging Face path. Expected format 'username/repo/filename'.")
30
+
31
+ # safetensors形式でのロード
32
+ if extension.lower() == ".safetensors":
33
+ import safetensors.torch
34
+ state_dict = safetensors.torch.load_file(ckpt_path, device=location)
35
+ else:
36
+ state_dict = get_state_dict(torch.load(ckpt_path, map_location=torch.device(location)))
37
+
38
+ print(f'Loaded state_dict from [{ckpt_path}]')
39
+ return state_dict
40
+
41
+
42
+ def create_model(config_path):
43
+ config = OmegaConf.load(config_path)
44
+ model = instantiate_from_config(config.model).cpu()
45
+ print(f'Loaded model config from [{config_path}]')
46
+ return model
47
+
48
+
49
+ def create_SUPIR_model(config_path, SUPIR_sign=None, load_default_setting=False):
50
+ config = OmegaConf.load(config_path)
51
+ model = instantiate_from_config(config.model).cpu()
52
+ print(f'Loaded model config from [{config_path}]')
53
+ if config.SDXL_CKPT is not None:
54
+ model.load_state_dict(load_state_dict(config.SDXL_CKPT), strict=False)
55
+ if config.SUPIR_CKPT is not None:
56
+ model.load_state_dict(load_state_dict(config.SUPIR_CKPT), strict=False)
57
+ if SUPIR_sign is not None:
58
+ assert SUPIR_sign in ['F', 'Q']
59
+ if SUPIR_sign == 'F':
60
+ model.load_state_dict(load_state_dict(config.SUPIR_CKPT_F), strict=False)
61
+ elif SUPIR_sign == 'Q':
62
+ model.load_state_dict(load_state_dict(config.SUPIR_CKPT_Q), strict=False)
63
+ if load_default_setting:
64
+ default_setting = config.default_setting
65
+ return model, default_setting
66
+ return model
67
+
68
+ def load_QF_ckpt(config_path):
69
+ config = OmegaConf.load(config_path)
70
+
71
+ # SUPIR_CKPT_F のダウンロード
72
+ if '/' in config.SUPIR_CKPT_F:
73
+ parts = config.SUPIR_CKPT_F.split('/')
74
+ if len(parts) == 3:
75
+ repo_id = f"{parts[0]}/{parts[1]}"
76
+ filename = parts[2]
77
+ print(f"Attempting to download SUPIR_CKPT_F from repo_id: {repo_id} and filename: {filename}")
78
+ ckpt_F_path = hf_hub_download(repo_id=repo_id, filename=filename)
79
+ print(f"Downloaded SUPIR_CKPT_F to: {ckpt_F_path}")
80
+ else:
81
+ raise ValueError("Invalid format for SUPIR_CKPT_F. Expected format 'username/repo/filename'.")
82
+ else:
83
+ ckpt_F_path = config.SUPIR_CKPT_F # ローカルパスの場合
84
+
85
+ # SUPIR_CKPT_Q のダウンロード
86
+ if '/' in config.SUPIR_CKPT_Q:
87
+ parts = config.SUPIR_CKPT_Q.split('/')
88
+ if len(parts) == 3:
89
+ repo_id = f"{parts[0]}/{parts[1]}"
90
+ filename = parts[2]
91
+ print(f"Attempting to download SUPIR_CKPT_Q from repo_id: {repo_id} and filename: {filename}")
92
+ ckpt_Q_path = hf_hub_download(repo_id=repo_id, filename=filename)
93
+ print(f"Downloaded SUPIR_CKPT_Q to: {ckpt_Q_path}")
94
+ else:
95
+ raise ValueError("Invalid format for SUPIR_CKPT_Q. Expected format 'username/repo/filename'.")
96
+ else:
97
+ ckpt_Q_path = config.SUPIR_CKPT_Q # ローカルパスの場合
98
+
99
+ # ダウンロードしたパスからロード
100
+ ckpt_F = torch.load(ckpt_F_path, map_location='cpu')
101
+ ckpt_Q = torch.load(ckpt_Q_path, map_location='cpu')
102
+ return ckpt_Q, ckpt_F
103
+
104
+
105
+ def PIL2Tensor(img, upsacle=1, min_size=1024, fix_resize=None):
106
+ '''
107
+ PIL.Image -> Tensor[C, H, W], RGB, [-1, 1]
108
+ '''
109
+ # size
110
+ w, h = img.size
111
+ w *= upsacle
112
+ h *= upsacle
113
+ w0, h0 = round(w), round(h)
114
+ if min(w, h) < min_size:
115
+ _upsacle = min_size / min(w, h)
116
+ w *= _upsacle
117
+ h *= _upsacle
118
+ if fix_resize is not None:
119
+ _upsacle = fix_resize / min(w, h)
120
+ w *= _upsacle
121
+ h *= _upsacle
122
+ w0, h0 = round(w), round(h)
123
+ w = int(np.round(w / 64.0)) * 64
124
+ h = int(np.round(h / 64.0)) * 64
125
+ x = img.resize((w, h), Image.BICUBIC)
126
+ x = np.array(x).round().clip(0, 255).astype(np.uint8)
127
+ x = x / 255 * 2 - 1
128
+ x = torch.tensor(x, dtype=torch.float32).permute(2, 0, 1)
129
+ return x, h0, w0
130
+
131
+
132
+ def Tensor2PIL(x, h0, w0):
133
+ '''
134
+ Tensor[C, H, W], RGB, [-1, 1] -> PIL.Image
135
+ '''
136
+ x = x.unsqueeze(0)
137
+ x = interpolate(x, size=(h0, w0), mode='bicubic')
138
+ x = (x.squeeze(0).permute(1, 2, 0) * 127.5 + 127.5).cpu().numpy().clip(0, 255).astype(np.uint8)
139
+ return Image.fromarray(x)
140
+
141
+
142
+ def HWC3(x):
143
+ assert x.dtype == np.uint8
144
+ if x.ndim == 2:
145
+ x = x[:, :, None]
146
+ assert x.ndim == 3
147
+ H, W, C = x.shape
148
+ assert C == 1 or C == 3 or C == 4
149
+ if C == 3:
150
+ return x
151
+ if C == 1:
152
+ return np.concatenate([x, x, x], axis=2)
153
+ if C == 4:
154
+ color = x[:, :, 0:3].astype(np.float32)
155
+ alpha = x[:, :, 3:4].astype(np.float32) / 255.0
156
+ y = color * alpha + 255.0 * (1.0 - alpha)
157
+ y = y.clip(0, 255).astype(np.uint8)
158
+ return y
159
+
160
+
161
+ def upscale_image(input_image, upscale, min_size=None, unit_resolution=64):
162
+ H, W, C = input_image.shape
163
+ H = float(H)
164
+ W = float(W)
165
+ H *= upscale
166
+ W *= upscale
167
+ if min_size is not None:
168
+ if min(H, W) < min_size:
169
+ _upsacle = min_size / min(W, H)
170
+ W *= _upsacle
171
+ H *= _upsacle
172
+ H = int(np.round(H / unit_resolution)) * unit_resolution
173
+ W = int(np.round(W / unit_resolution)) * unit_resolution
174
+ img = cv2.resize(input_image, (W, H), interpolation=cv2.INTER_LANCZOS4 if upscale > 1 else cv2.INTER_AREA)
175
+ img = img.round().clip(0, 255).astype(np.uint8)
176
+ return img
177
+
178
+
179
+ def fix_resize(input_image, size=512, unit_resolution=64):
180
+ H, W, C = input_image.shape
181
+ H = float(H)
182
+ W = float(W)
183
+ upscale = size / min(H, W)
184
+ H *= upscale
185
+ W *= upscale
186
+ H = int(np.round(H / unit_resolution)) * unit_resolution
187
+ W = int(np.round(W / unit_resolution)) * unit_resolution
188
+ img = cv2.resize(input_image, (W, H), interpolation=cv2.INTER_LANCZOS4 if upscale > 1 else cv2.INTER_AREA)
189
+ img = img.round().clip(0, 255).astype(np.uint8)
190
+ return img
191
+
192
+
193
+
194
+ def Numpy2Tensor(img):
195
+ '''
196
+ np.array[H, w, C] [0, 255] -> Tensor[C, H, W], RGB, [-1, 1]
197
+ '''
198
+ # size
199
+ img = np.array(img) / 255 * 2 - 1
200
+ img = torch.tensor(img, dtype=torch.float32).permute(2, 0, 1)
201
+ return img
202
+
203
+
204
+ def Tensor2Numpy(x, h0=None, w0=None):
205
+ '''
206
+ Tensor[C, H, W], RGB, [-1, 1] -> PIL.Image
207
+ '''
208
+ if h0 is not None and w0 is not None:
209
+ x = x.unsqueeze(0)
210
+ x = interpolate(x, size=(h0, w0), mode='bicubic')
211
+ x = x.squeeze(0)
212
+ x = (x.permute(1, 2, 0) * 127.5 + 127.5).cpu().numpy().clip(0, 255).astype(np.uint8)
213
+ return x
214
+
215
+
216
+ def convert_dtype(dtype_str):
217
+ if dtype_str == 'fp32':
218
+ return torch.float32
219
+ elif dtype_str == 'fp16':
220
+ return torch.float16
221
+ elif dtype_str == 'bf16':
222
+ return torch.bfloat16
223
+ else:
224
+ raise NotImplementedError