emmajoanne commited on
Commit
e4b10de
1 Parent(s): ca22940

Delete sd_models.py

Browse files
Files changed (1) hide show
  1. sd_models.py +0 -489
sd_models.py DELETED
@@ -1,489 +0,0 @@
1
- import collections
2
- import os.path
3
- import sys
4
- import gc
5
- import torch
6
- import re
7
- import safetensors.torch
8
- from omegaconf import OmegaConf
9
- from os import mkdir
10
- from urllib import request
11
- import ldm.modules.midas as midas
12
-
13
- from ldm.util import instantiate_from_config
14
-
15
- from modules import paths, shared, modelloader, devices, script_callbacks, sd_vae, sd_disable_initialization, errors, hashes, sd_models_config
16
- from modules.paths import models_path
17
- from modules.sd_hijack_inpainting import do_inpainting_hijack
18
- from modules.timer import Timer
19
-
20
- model_dir = "Stable-diffusion"
21
- model_path = os.path.abspath(os.path.join(paths.models_path, model_dir))
22
-
23
- checkpoints_list = {}
24
- checkpoint_alisases = {}
25
- checkpoints_loaded = collections.OrderedDict()
26
-
27
-
28
- class CheckpointInfo:
29
- def __init__(self, filename):
30
- self.filename = filename
31
- abspath = os.path.abspath(filename)
32
-
33
- if shared.cmd_opts.ckpt_dir is not None and abspath.startswith(shared.cmd_opts.ckpt_dir):
34
- name = abspath.replace(shared.cmd_opts.ckpt_dir, '')
35
- elif abspath.startswith(model_path):
36
- name = abspath.replace(model_path, '')
37
- else:
38
- name = os.path.basename(filename)
39
-
40
- if name.startswith("\\") or name.startswith("/"):
41
- name = name[1:]
42
-
43
- self.name = name
44
- self.name_for_extra = os.path.splitext(os.path.basename(filename))[0]
45
- self.model_name = os.path.splitext(name.replace("/", "_").replace("\\", "_"))[0]
46
- self.hash = model_hash(filename)
47
-
48
- self.sha256 = hashes.sha256_from_cache(self.filename, "checkpoint/" + name)
49
- self.shorthash = self.sha256[0:10] if self.sha256 else None
50
-
51
- self.title = name if self.shorthash is None else f'{name} [{self.shorthash}]'
52
-
53
- self.ids = [self.hash, self.model_name, self.title, name, f'{name} [{self.hash}]'] + ([self.shorthash, self.sha256, f'{self.name} [{self.shorthash}]'] if self.shorthash else [])
54
-
55
- def register(self):
56
- checkpoints_list[self.title] = self
57
- for id in self.ids:
58
- checkpoint_alisases[id] = self
59
-
60
- def calculate_shorthash(self):
61
- self.sha256 = hashes.sha256(self.filename, "checkpoint/" + self.name)
62
- if self.sha256 is None:
63
- return
64
-
65
- self.shorthash = self.sha256[0:10]
66
-
67
- if self.shorthash not in self.ids:
68
- self.ids += [self.shorthash, self.sha256, f'{self.name} [{self.shorthash}]']
69
-
70
- checkpoints_list.pop(self.title)
71
- self.title = f'{self.name} [{self.shorthash}]'
72
- self.register()
73
-
74
- return self.shorthash
75
-
76
-
77
- try:
78
- # this silences the annoying "Some weights of the model checkpoint were not used when initializing..." message at start.
79
-
80
- from transformers import logging, CLIPModel
81
-
82
- logging.set_verbosity_error()
83
- except Exception:
84
- pass
85
-
86
-
87
- def setup_model():
88
- if not os.path.exists(model_path):
89
- os.makedirs(model_path)
90
-
91
- list_models()
92
- enable_midas_autodownload()
93
-
94
-
95
- def checkpoint_tiles():
96
- def convert(name):
97
- return int(name) if name.isdigit() else name.lower()
98
-
99
- def alphanumeric_key(key):
100
- return [convert(c) for c in re.split('([0-9]+)', key)]
101
-
102
- return sorted([x.title for x in checkpoints_list.values()], key=alphanumeric_key)
103
-
104
-
105
- def list_models():
106
- checkpoints_list.clear()
107
- checkpoint_alisases.clear()
108
- model_list = modelloader.load_models(model_path=model_path, command_path=shared.cmd_opts.ckpt_dir, ext_filter=[".ckpt", ".safetensors"], ext_blacklist=[".vae.safetensors"])
109
-
110
- cmd_ckpt = shared.cmd_opts.ckpt
111
- if os.path.exists(cmd_ckpt):
112
- checkpoint_info = CheckpointInfo(cmd_ckpt)
113
- checkpoint_info.register()
114
-
115
- shared.opts.data['sd_model_checkpoint'] = checkpoint_info.title
116
- elif cmd_ckpt is not None and cmd_ckpt != shared.default_sd_model_file:
117
- print(f"Checkpoint in --ckpt argument not found (Possible it was moved to {model_path}: {cmd_ckpt}", file=sys.stderr)
118
-
119
- for filename in model_list:
120
- checkpoint_info = CheckpointInfo(filename)
121
- checkpoint_info.register()
122
-
123
-
124
- def get_closet_checkpoint_match(search_string):
125
- checkpoint_info = checkpoint_alisases.get(search_string, None)
126
- if checkpoint_info is not None:
127
- return checkpoint_info
128
-
129
- found = sorted([info for info in checkpoints_list.values() if search_string in info.title], key=lambda x: len(x.title))
130
- if found:
131
- return found[0]
132
-
133
- return None
134
-
135
-
136
- def model_hash(filename):
137
- """old hash that only looks at a small part of the file and is prone to collisions"""
138
-
139
- try:
140
- with open(filename, "rb") as file:
141
- import hashlib
142
- m = hashlib.sha256()
143
-
144
- file.seek(0x100000)
145
- m.update(file.read(0x10000))
146
- return m.hexdigest()[0:8]
147
- except FileNotFoundError:
148
- return 'NOFILE'
149
-
150
-
151
- def select_checkpoint():
152
- model_checkpoint = shared.opts.sd_model_checkpoint
153
-
154
- checkpoint_info = checkpoint_alisases.get(model_checkpoint, None)
155
- if checkpoint_info is not None:
156
- return checkpoint_info
157
-
158
- if len(checkpoints_list) == 0:
159
- print("No checkpoints found. When searching for checkpoints, looked at:", file=sys.stderr)
160
- if shared.cmd_opts.ckpt is not None:
161
- print(f" - file {os.path.abspath(shared.cmd_opts.ckpt)}", file=sys.stderr)
162
- print(f" - directory {model_path}", file=sys.stderr)
163
- if shared.cmd_opts.ckpt_dir is not None:
164
- print(f" - directory {os.path.abspath(shared.cmd_opts.ckpt_dir)}", file=sys.stderr)
165
- print("Can't run without a checkpoint. Find and place a .ckpt or .safetensors file into any of those locations. The program will exit.", file=sys.stderr)
166
- exit(1)
167
-
168
- checkpoint_info = next(iter(checkpoints_list.values()))
169
- if model_checkpoint is not None:
170
- print(f"Checkpoint {model_checkpoint} not found; loading fallback {checkpoint_info.title}", file=sys.stderr)
171
-
172
- return checkpoint_info
173
-
174
-
175
- chckpoint_dict_replacements = {
176
- 'cond_stage_model.transformer.embeddings.': 'cond_stage_model.transformer.text_model.embeddings.',
177
- 'cond_stage_model.transformer.encoder.': 'cond_stage_model.transformer.text_model.encoder.',
178
- 'cond_stage_model.transformer.final_layer_norm.': 'cond_stage_model.transformer.text_model.final_layer_norm.',
179
- }
180
-
181
-
182
- def transform_checkpoint_dict_key(k):
183
- for text, replacement in chckpoint_dict_replacements.items():
184
- if k.startswith(text):
185
- k = replacement + k[len(text):]
186
-
187
- return k
188
-
189
-
190
- def get_state_dict_from_checkpoint(pl_sd):
191
- pl_sd = pl_sd.pop("state_dict", pl_sd)
192
- pl_sd.pop("state_dict", None)
193
-
194
- sd = {}
195
- for k, v in pl_sd.items():
196
- new_key = transform_checkpoint_dict_key(k)
197
-
198
- if new_key is not None:
199
- sd[new_key] = v
200
-
201
- pl_sd.clear()
202
- pl_sd.update(sd)
203
-
204
- return pl_sd
205
-
206
-
207
- def read_state_dict(checkpoint_file, print_global_state=False, map_location=None):
208
- _, extension = os.path.splitext(checkpoint_file)
209
- if extension.lower() == ".safetensors":
210
- device = map_location or shared.weight_load_location or devices.get_optimal_device_name()
211
- pl_sd = safetensors.torch.load_file(checkpoint_file, device=device)
212
- else:
213
- pl_sd = torch.load(checkpoint_file, map_location=map_location or shared.weight_load_location)
214
-
215
- if print_global_state and "global_step" in pl_sd:
216
- print(f"Global Step: {pl_sd['global_step']}")
217
-
218
- sd = get_state_dict_from_checkpoint(pl_sd)
219
- return sd
220
-
221
-
222
- def get_checkpoint_state_dict(checkpoint_info: CheckpointInfo, timer):
223
- sd_model_hash = checkpoint_info.calculate_shorthash()
224
- timer.record("calculate hash")
225
-
226
- if checkpoint_info in checkpoints_loaded:
227
- # use checkpoint cache
228
- print(f"Loading weights [{sd_model_hash}] from cache")
229
- return checkpoints_loaded[checkpoint_info]
230
-
231
- print(f"Loading weights [{sd_model_hash}] from {checkpoint_info.filename}")
232
- res = read_state_dict(checkpoint_info.filename)
233
- timer.record("load weights from disk")
234
-
235
- return res
236
-
237
-
238
- def load_model_weights(model, checkpoint_info: CheckpointInfo, state_dict, timer):
239
- sd_model_hash = checkpoint_info.calculate_shorthash()
240
- timer.record("calculate hash")
241
-
242
- shared.opts.data["sd_model_checkpoint"] = checkpoint_info.title
243
-
244
- if state_dict is None:
245
- state_dict = get_checkpoint_state_dict(checkpoint_info, timer)
246
-
247
- model.load_state_dict(state_dict, strict=False)
248
- del state_dict
249
- timer.record("apply weights to model")
250
-
251
- if shared.opts.sd_checkpoint_cache > 0:
252
- # cache newly loaded model
253
- checkpoints_loaded[checkpoint_info] = model.state_dict().copy()
254
-
255
- if shared.cmd_opts.opt_channelslast:
256
- model.to(memory_format=torch.channels_last)
257
- timer.record("apply channels_last")
258
-
259
- if not shared.cmd_opts.no_half:
260
- vae = model.first_stage_model
261
- depth_model = getattr(model, 'depth_model', None)
262
-
263
- # with --no-half-vae, remove VAE from model when doing half() to prevent its weights from being converted to float16
264
- if shared.cmd_opts.no_half_vae:
265
- model.first_stage_model = None
266
- # with --upcast-sampling, don't convert the depth model weights to float16
267
- if shared.cmd_opts.upcast_sampling and depth_model:
268
- model.depth_model = None
269
-
270
- model.half()
271
- model.first_stage_model = vae
272
- if depth_model:
273
- model.depth_model = depth_model
274
-
275
- timer.record("apply half()")
276
-
277
- devices.dtype = torch.float32 if shared.cmd_opts.no_half else torch.float16
278
- devices.dtype_vae = torch.float32 if shared.cmd_opts.no_half or shared.cmd_opts.no_half_vae else torch.float16
279
- devices.dtype_unet = model.model.diffusion_model.dtype
280
- devices.unet_needs_upcast = shared.cmd_opts.upcast_sampling and devices.dtype == torch.float16 and devices.dtype_unet == torch.float16
281
-
282
- model.first_stage_model.to(devices.dtype_vae)
283
- timer.record("apply dtype to VAE")
284
-
285
- # clean up cache if limit is reached
286
- while len(checkpoints_loaded) > shared.opts.sd_checkpoint_cache:
287
- checkpoints_loaded.popitem(last=False)
288
-
289
- model.sd_model_hash = sd_model_hash
290
- model.sd_model_checkpoint = checkpoint_info.filename
291
- model.sd_checkpoint_info = checkpoint_info
292
- shared.opts.data["sd_checkpoint_hash"] = checkpoint_info.sha256
293
-
294
- model.logvar = model.logvar.to(devices.device) # fix for training
295
-
296
- sd_vae.delete_base_vae()
297
- sd_vae.clear_loaded_vae()
298
- vae_file, vae_source = sd_vae.resolve_vae(checkpoint_info.filename)
299
- sd_vae.load_vae(model, vae_file, vae_source)
300
- timer.record("load VAE")
301
-
302
-
303
- def enable_midas_autodownload():
304
- """
305
- Gives the ldm.modules.midas.api.load_model function automatic downloading.
306
-
307
- When the 512-depth-ema model, and other future models like it, is loaded,
308
- it calls midas.api.load_model to load the associated midas depth model.
309
- This function applies a wrapper to download the model to the correct
310
- location automatically.
311
- """
312
-
313
- midas_path = os.path.join(paths.models_path, 'midas')
314
-
315
- # stable-diffusion-stability-ai hard-codes the midas model path to
316
- # a location that differs from where other scripts using this model look.
317
- # HACK: Overriding the path here.
318
- for k, v in midas.api.ISL_PATHS.items():
319
- file_name = os.path.basename(v)
320
- midas.api.ISL_PATHS[k] = os.path.join(midas_path, file_name)
321
-
322
- midas_urls = {
323
- "dpt_large": "https://github.com/intel-isl/DPT/releases/download/1_0/dpt_large-midas-2f21e586.pt",
324
- "dpt_hybrid": "https://github.com/intel-isl/DPT/releases/download/1_0/dpt_hybrid-midas-501f0c75.pt",
325
- "midas_v21": "https://github.com/AlexeyAB/MiDaS/releases/download/midas_dpt/midas_v21-f6b98070.pt",
326
- "midas_v21_small": "https://github.com/AlexeyAB/MiDaS/releases/download/midas_dpt/midas_v21_small-70d6b9c8.pt",
327
- }
328
-
329
- midas.api.load_model_inner = midas.api.load_model
330
-
331
- def load_model_wrapper(model_type):
332
- path = midas.api.ISL_PATHS[model_type]
333
- if not os.path.exists(path):
334
- if not os.path.exists(midas_path):
335
- mkdir(midas_path)
336
-
337
- print(f"Downloading midas model weights for {model_type} to {path}")
338
- request.urlretrieve(midas_urls[model_type], path)
339
- print(f"{model_type} downloaded")
340
-
341
- return midas.api.load_model_inner(model_type)
342
-
343
- midas.api.load_model = load_model_wrapper
344
-
345
-
346
- def repair_config(sd_config):
347
-
348
- if not hasattr(sd_config.model.params, "use_ema"):
349
- sd_config.model.params.use_ema = False
350
-
351
- if shared.cmd_opts.no_half:
352
- sd_config.model.params.unet_config.params.use_fp16 = False
353
- elif shared.cmd_opts.upcast_sampling:
354
- sd_config.model.params.unet_config.params.use_fp16 = True
355
-
356
-
357
- sd1_clip_weight = 'cond_stage_model.transformer.text_model.embeddings.token_embedding.weight'
358
- sd2_clip_weight = 'cond_stage_model.model.transformer.resblocks.0.attn.in_proj_weight'
359
-
360
- def load_model(checkpoint_info=None, already_loaded_state_dict=None, time_taken_to_load_state_dict=None):
361
- from modules import lowvram, sd_hijack
362
- checkpoint_info = checkpoint_info or select_checkpoint()
363
-
364
- if shared.sd_model:
365
- sd_hijack.model_hijack.undo_hijack(shared.sd_model)
366
- shared.sd_model = None
367
- gc.collect()
368
- devices.torch_gc()
369
-
370
- do_inpainting_hijack()
371
-
372
- timer = Timer()
373
-
374
- if already_loaded_state_dict is not None:
375
- state_dict = already_loaded_state_dict
376
- else:
377
- state_dict = get_checkpoint_state_dict(checkpoint_info, timer)
378
-
379
- checkpoint_config = sd_models_config.find_checkpoint_config(state_dict, checkpoint_info)
380
- clip_is_included_into_sd = sd1_clip_weight in state_dict or sd2_clip_weight in state_dict
381
-
382
- timer.record("find config")
383
-
384
- sd_config = OmegaConf.load(checkpoint_config)
385
- repair_config(sd_config)
386
-
387
- timer.record("load config")
388
-
389
- print(f"Creating model from config: {checkpoint_config}")
390
-
391
- sd_model = None
392
- try:
393
- with sd_disable_initialization.DisableInitialization(disable_clip=clip_is_included_into_sd):
394
- sd_model = instantiate_from_config(sd_config.model)
395
- except Exception as e:
396
- pass
397
-
398
- if sd_model is None:
399
- print('Failed to create model quickly; will retry using slow method.', file=sys.stderr)
400
- sd_model = instantiate_from_config(sd_config.model)
401
-
402
- sd_model.used_config = checkpoint_config
403
-
404
- timer.record("create model")
405
-
406
- load_model_weights(sd_model, checkpoint_info, state_dict, timer)
407
-
408
- if shared.cmd_opts.lowvram or shared.cmd_opts.medvram:
409
- lowvram.setup_for_low_vram(sd_model, shared.cmd_opts.medvram)
410
- else:
411
- sd_model.to(shared.device)
412
-
413
- timer.record("move model to device")
414
-
415
- sd_hijack.model_hijack.hijack(sd_model)
416
-
417
- timer.record("hijack")
418
-
419
- sd_model.eval()
420
- shared.sd_model = sd_model
421
-
422
- sd_hijack.model_hijack.embedding_db.load_textual_inversion_embeddings(force_reload=True) # Reload embeddings after model load as they may or may not fit the model
423
-
424
- timer.record("load textual inversion embeddings")
425
-
426
- script_callbacks.model_loaded_callback(sd_model)
427
-
428
- timer.record("scripts callbacks")
429
-
430
- print(f"Model loaded in {timer.summary()}.")
431
-
432
- return sd_model
433
-
434
-
435
- def reload_model_weights(sd_model=None, info=None):
436
- from modules import lowvram, devices, sd_hijack
437
- checkpoint_info = info or select_checkpoint()
438
-
439
- if not sd_model:
440
- sd_model = shared.sd_model
441
-
442
- if sd_model is None: # previous model load failed
443
- current_checkpoint_info = None
444
- else:
445
- current_checkpoint_info = sd_model.sd_checkpoint_info
446
- if sd_model.sd_model_checkpoint == checkpoint_info.filename:
447
- return
448
-
449
- if shared.cmd_opts.lowvram or shared.cmd_opts.medvram:
450
- lowvram.send_everything_to_cpu()
451
- else:
452
- sd_model.to(devices.cpu)
453
-
454
- sd_hijack.model_hijack.undo_hijack(sd_model)
455
-
456
- timer = Timer()
457
-
458
- state_dict = get_checkpoint_state_dict(checkpoint_info, timer)
459
-
460
- checkpoint_config = sd_models_config.find_checkpoint_config(state_dict, checkpoint_info)
461
-
462
- timer.record("find config")
463
-
464
- if sd_model is None or checkpoint_config != sd_model.used_config:
465
- del sd_model
466
- checkpoints_loaded.clear()
467
- load_model(checkpoint_info, already_loaded_state_dict=state_dict, time_taken_to_load_state_dict=timer.records["load weights from disk"])
468
- return shared.sd_model
469
-
470
- try:
471
- load_model_weights(sd_model, checkpoint_info, state_dict, timer)
472
- except Exception as e:
473
- print("Failed to load checkpoint, restoring previous")
474
- load_model_weights(sd_model, current_checkpoint_info, None, timer)
475
- raise
476
- finally:
477
- sd_hijack.model_hijack.hijack(sd_model)
478
- timer.record("hijack")
479
-
480
- script_callbacks.model_loaded_callback(sd_model)
481
- timer.record("script callbacks")
482
-
483
- if not shared.cmd_opts.lowvram and not shared.cmd_opts.medvram:
484
- sd_model.to(devices.device)
485
- timer.record("move model to device")
486
-
487
- print(f"Weights loaded in {timer.summary()}.")
488
-
489
- return sd_model