adamelliotfields commited on
Commit
ca5a1e4
1 Parent(s): 5f7707a

Move to lib

Browse files
Files changed (5) hide show
  1. app.py +1 -1
  2. cli.py +1 -1
  3. lib/__init__.py +2 -0
  4. generate.py → lib/inference.py +2 -158
  5. lib/loader.py +166 -0
app.py CHANGED
@@ -4,7 +4,7 @@ import json
4
  import gradio as gr
5
 
6
  import config as cfg
7
- from generate import generate
8
 
9
  # the CSS `content` attribute expects a string so we need to wrap the number in quotes
10
  random_seed_js = """
 
4
  import gradio as gr
5
 
6
  import config as cfg
7
+ from lib import generate
8
 
9
  # the CSS `content` attribute expects a string so we need to wrap the number in quotes
10
  random_seed_js = """
cli.py CHANGED
@@ -3,7 +3,7 @@
3
  import argparse
4
 
5
  import config as cfg
6
- from generate import generate
7
 
8
 
9
  def save_images(images, filename="image.png"):
 
3
  import argparse
4
 
5
  import config as cfg
6
+ from lib import generate
7
 
8
 
9
  def save_images(images, filename="image.png"):
lib/__init__.py ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ from .inference import generate
2
+ from .loader import Loader
generate.py → lib/inference.py RENAMED
@@ -12,19 +12,8 @@ import tomesd
12
  import torch
13
  from compel import Compel, DiffusersTextualInversionManager, ReturnedEmbeddingsType
14
  from compel.prompt_parser import PromptParser
15
- from DeepCache import DeepCacheSDHelper
16
- from diffusers import (
17
- DEISMultistepScheduler,
18
- DPMSolverMultistepScheduler,
19
- EulerAncestralDiscreteScheduler,
20
- HeunDiscreteScheduler,
21
- KDPM2AncestralDiscreteScheduler,
22
- LMSDiscreteScheduler,
23
- PNDMScheduler,
24
- StableDiffusionPipeline,
25
- )
26
- from diffusers.models import AutoencoderKL, AutoencoderTiny
27
- from torch._dynamo import OptimizedModule
28
 
29
  __import__("warnings").filterwarnings("ignore", category=FutureWarning, module="diffusers")
30
  __import__("warnings").filterwarnings("ignore", category=FutureWarning, module="transformers")
@@ -35,155 +24,10 @@ ZERO_GPU = (
35
  or os.environ.get("SPACES_ZERO_GPU", "") == "1"
36
  )
37
 
38
- EMBEDDINGS = {
39
- "./embeddings/bad_prompt_version2.pt": "<bad_prompt>",
40
- "./embeddings/BadDream.pt": "<bad_dream>",
41
- "./embeddings/FastNegativeV2.pt": "<fast_negative>",
42
- "./embeddings/negative_hand.pt": "<negative_hand>",
43
- "./embeddings/UnrealisticDream.pt": "<unrealistic_dream>",
44
- }
45
-
46
  with open("./styles/twri.json") as f:
47
  styles = json.load(f)
48
 
49
 
50
- # inspired by ComfyUI
51
- # https://github.com/comfyanonymous/ComfyUI/blob/master/comfy/model_management.py
52
- class Loader:
53
- _instance = None
54
-
55
- def __new__(cls):
56
- if cls._instance is None:
57
- cls._instance = super(Loader, cls).__new__(cls)
58
- cls._instance.pipe = None
59
- return cls._instance
60
-
61
- def _load_deepcache(self, interval=1):
62
- has_deepcache = hasattr(self.pipe, "deepcache")
63
-
64
- if has_deepcache and self.pipe.deepcache.params["cache_interval"] == interval:
65
- return
66
- if has_deepcache:
67
- self.pipe.deepcache.disable()
68
- else:
69
- self.pipe.deepcache = DeepCacheSDHelper(pipe=self.pipe)
70
-
71
- self.pipe.deepcache.set_params(cache_interval=interval)
72
- self.pipe.deepcache.enable()
73
-
74
- def _load_vae(self, model_name=None, taesd=False, variant=None):
75
- vae_type = type(self.pipe.vae)
76
- is_kl = issubclass(vae_type, (AutoencoderKL, OptimizedModule))
77
- is_tiny = issubclass(vae_type, AutoencoderTiny)
78
-
79
- # by default all models use KL
80
- if is_kl and taesd:
81
- # can't compile tiny VAE
82
- print("Switching to Tiny VAE...")
83
- self.pipe.vae = AutoencoderTiny.from_pretrained(
84
- pretrained_model_name_or_path="madebyollin/taesd",
85
- use_safetensors=True,
86
- ).to(device=self.pipe.device)
87
- return
88
-
89
- if is_tiny and not taesd:
90
- print("Switching to KL VAE...")
91
- model = AutoencoderKL.from_pretrained(
92
- pretrained_model_name_or_path=model_name,
93
- use_safetensors=True,
94
- subfolder="vae",
95
- variant=variant,
96
- ).to(device=self.pipe.device)
97
- self.pipe.vae = torch.compile(
98
- mode="reduce-overhead",
99
- fullgraph=True,
100
- model=model,
101
- )
102
-
103
- def load(self, model, scheduler, karras, taesd, deepcache_interval, dtype, device):
104
- model_lower = model.lower()
105
-
106
- schedulers = {
107
- "DEIS 2M": DEISMultistepScheduler,
108
- "DPM++ 2M": DPMSolverMultistepScheduler,
109
- "DPM2 a": KDPM2AncestralDiscreteScheduler,
110
- "Euler a": EulerAncestralDiscreteScheduler,
111
- "Heun": HeunDiscreteScheduler,
112
- "LMS": LMSDiscreteScheduler,
113
- "PNDM": PNDMScheduler,
114
- }
115
-
116
- scheduler_kwargs = {
117
- "beta_schedule": "scaled_linear",
118
- "timestep_spacing": "leading",
119
- "use_karras_sigmas": karras,
120
- "beta_start": 0.00085,
121
- "beta_end": 0.012,
122
- "steps_offset": 1,
123
- }
124
-
125
- if scheduler in ["Euler a", "PNDM"]:
126
- del scheduler_kwargs["use_karras_sigmas"]
127
-
128
- # no fp16 variant
129
- if not ZERO_GPU and model_lower not in [
130
- "sg161222/realistic_vision_v5.1_novae",
131
- "prompthero/openjourney-v4",
132
- "linaqruf/anything-v3-1",
133
- ]:
134
- variant = "fp16"
135
- else:
136
- variant = None
137
-
138
- pipe_kwargs = {
139
- "scheduler": schedulers[scheduler](**scheduler_kwargs),
140
- "pretrained_model_name_or_path": model_lower,
141
- "requires_safety_checker": False,
142
- "use_safetensors": True,
143
- "safety_checker": None,
144
- "variant": variant,
145
- }
146
-
147
- # already loaded
148
- if self.pipe is not None:
149
- model_name = self.pipe.config._name_or_path
150
- same_model = model_name.lower() == model_lower
151
- same_scheduler = isinstance(self.pipe.scheduler, schedulers[scheduler])
152
- same_karras = (
153
- not hasattr(self.pipe.scheduler.config, "use_karras_sigmas")
154
- or self.pipe.scheduler.config.use_karras_sigmas == karras
155
- )
156
-
157
- if same_model:
158
- if not same_scheduler:
159
- print(f"Switching to {scheduler}...")
160
- if not same_karras:
161
- print(f"{'Enabling' if karras else 'Disabling'} Karras sigmas...")
162
- if not same_scheduler or not same_karras:
163
- self.pipe.scheduler = schedulers[scheduler](**scheduler_kwargs)
164
- self._load_vae(model_lower, taesd, variant)
165
- self._load_deepcache(interval=deepcache_interval)
166
- return self.pipe
167
- else:
168
- print(f"Unloading {model_name.lower()}...")
169
- self.pipe = None
170
-
171
- print(f"Loading {model_lower} with {'Tiny' if taesd else 'KL'} VAE...")
172
- self.pipe = StableDiffusionPipeline.from_pretrained(**pipe_kwargs).to(
173
- device=device,
174
- dtype=dtype,
175
- )
176
- self.pipe.load_textual_inversion(
177
- pretrained_model_name_or_path=list(EMBEDDINGS.keys()),
178
- tokens=list(EMBEDDINGS.values()),
179
- )
180
- self._load_vae(model_lower, taesd, variant)
181
- self._load_deepcache(interval=deepcache_interval)
182
-
183
- torch.cuda.empty_cache()
184
- return self.pipe
185
-
186
-
187
  # applies tome to the pipeline
188
  @contextmanager
189
  def token_merging(pipe, tome_ratio=0):
 
12
  import torch
13
  from compel import Compel, DiffusersTextualInversionManager, ReturnedEmbeddingsType
14
  from compel.prompt_parser import PromptParser
15
+
16
+ from .loader import Loader
 
 
 
 
 
 
 
 
 
 
 
17
 
18
  __import__("warnings").filterwarnings("ignore", category=FutureWarning, module="diffusers")
19
  __import__("warnings").filterwarnings("ignore", category=FutureWarning, module="transformers")
 
24
  or os.environ.get("SPACES_ZERO_GPU", "") == "1"
25
  )
26
 
 
 
 
 
 
 
 
 
27
  with open("./styles/twri.json") as f:
28
  styles = json.load(f)
29
 
30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  # applies tome to the pipeline
32
  @contextmanager
33
  def token_merging(pipe, tome_ratio=0):
lib/loader.py ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+
3
+ import torch
4
+ from DeepCache import DeepCacheSDHelper
5
+ from diffusers import (
6
+ DEISMultistepScheduler,
7
+ DPMSolverMultistepScheduler,
8
+ EulerAncestralDiscreteScheduler,
9
+ HeunDiscreteScheduler,
10
+ KDPM2AncestralDiscreteScheduler,
11
+ LMSDiscreteScheduler,
12
+ PNDMScheduler,
13
+ StableDiffusionPipeline,
14
+ )
15
+ from diffusers.models import AutoencoderKL, AutoencoderTiny
16
+ from torch._dynamo import OptimizedModule
17
+
18
+ ZERO_GPU = (
19
+ os.environ.get("SPACES_ZERO_GPU", "").lower() == "true"
20
+ or os.environ.get("SPACES_ZERO_GPU", "") == "1"
21
+ )
22
+
23
+ EMBEDDINGS = {
24
+ "./embeddings/bad_prompt_version2.pt": "<bad_prompt>",
25
+ "./embeddings/BadDream.pt": "<bad_dream>",
26
+ "./embeddings/FastNegativeV2.pt": "<fast_negative>",
27
+ "./embeddings/negative_hand.pt": "<negative_hand>",
28
+ "./embeddings/UnrealisticDream.pt": "<unrealistic_dream>",
29
+ }
30
+
31
+
32
+ # inspired by ComfyUI
33
+ # https://github.com/comfyanonymous/ComfyUI/blob/master/comfy/model_management.py
34
+ class Loader:
35
+ _instance = None
36
+
37
+ def __new__(cls):
38
+ if cls._instance is None:
39
+ cls._instance = super(Loader, cls).__new__(cls)
40
+ cls._instance.pipe = None
41
+ return cls._instance
42
+
43
+ def _load_deepcache(self, interval=1):
44
+ has_deepcache = hasattr(self.pipe, "deepcache")
45
+
46
+ if has_deepcache and self.pipe.deepcache.params["cache_interval"] == interval:
47
+ return
48
+ if has_deepcache:
49
+ self.pipe.deepcache.disable()
50
+ else:
51
+ self.pipe.deepcache = DeepCacheSDHelper(pipe=self.pipe)
52
+
53
+ self.pipe.deepcache.set_params(cache_interval=interval)
54
+ self.pipe.deepcache.enable()
55
+
56
+ def _load_vae(self, model_name=None, taesd=False, variant=None):
57
+ vae_type = type(self.pipe.vae)
58
+ is_kl = issubclass(vae_type, (AutoencoderKL, OptimizedModule))
59
+ is_tiny = issubclass(vae_type, AutoencoderTiny)
60
+
61
+ # by default all models use KL
62
+ if is_kl and taesd:
63
+ # can't compile tiny VAE
64
+ print("Switching to Tiny VAE...")
65
+ self.pipe.vae = AutoencoderTiny.from_pretrained(
66
+ pretrained_model_name_or_path="madebyollin/taesd",
67
+ use_safetensors=True,
68
+ ).to(device=self.pipe.device)
69
+ return
70
+
71
+ if is_tiny and not taesd:
72
+ print("Switching to KL VAE...")
73
+ model = AutoencoderKL.from_pretrained(
74
+ pretrained_model_name_or_path=model_name,
75
+ use_safetensors=True,
76
+ subfolder="vae",
77
+ variant=variant,
78
+ ).to(device=self.pipe.device)
79
+ self.pipe.vae = torch.compile(
80
+ mode="reduce-overhead",
81
+ fullgraph=True,
82
+ model=model,
83
+ )
84
+
85
+ def load(self, model, scheduler, karras, taesd, deepcache_interval, dtype, device):
86
+ model_lower = model.lower()
87
+
88
+ schedulers = {
89
+ "DEIS 2M": DEISMultistepScheduler,
90
+ "DPM++ 2M": DPMSolverMultistepScheduler,
91
+ "DPM2 a": KDPM2AncestralDiscreteScheduler,
92
+ "Euler a": EulerAncestralDiscreteScheduler,
93
+ "Heun": HeunDiscreteScheduler,
94
+ "LMS": LMSDiscreteScheduler,
95
+ "PNDM": PNDMScheduler,
96
+ }
97
+
98
+ scheduler_kwargs = {
99
+ "beta_schedule": "scaled_linear",
100
+ "timestep_spacing": "leading",
101
+ "use_karras_sigmas": karras,
102
+ "beta_start": 0.00085,
103
+ "beta_end": 0.012,
104
+ "steps_offset": 1,
105
+ }
106
+
107
+ if scheduler in ["Euler a", "PNDM"]:
108
+ del scheduler_kwargs["use_karras_sigmas"]
109
+
110
+ # no fp16 variant
111
+ if not ZERO_GPU and model_lower not in [
112
+ "sg161222/realistic_vision_v5.1_novae",
113
+ "prompthero/openjourney-v4",
114
+ "linaqruf/anything-v3-1",
115
+ ]:
116
+ variant = "fp16"
117
+ else:
118
+ variant = None
119
+
120
+ pipe_kwargs = {
121
+ "scheduler": schedulers[scheduler](**scheduler_kwargs),
122
+ "pretrained_model_name_or_path": model_lower,
123
+ "requires_safety_checker": False,
124
+ "use_safetensors": True,
125
+ "safety_checker": None,
126
+ "variant": variant,
127
+ }
128
+
129
+ # already loaded
130
+ if self.pipe is not None:
131
+ model_name = self.pipe.config._name_or_path
132
+ same_model = model_name.lower() == model_lower
133
+ same_scheduler = isinstance(self.pipe.scheduler, schedulers[scheduler])
134
+ same_karras = (
135
+ not hasattr(self.pipe.scheduler.config, "use_karras_sigmas")
136
+ or self.pipe.scheduler.config.use_karras_sigmas == karras
137
+ )
138
+
139
+ if same_model:
140
+ if not same_scheduler:
141
+ print(f"Switching to {scheduler}...")
142
+ if not same_karras:
143
+ print(f"{'Enabling' if karras else 'Disabling'} Karras sigmas...")
144
+ if not same_scheduler or not same_karras:
145
+ self.pipe.scheduler = schedulers[scheduler](**scheduler_kwargs)
146
+ self._load_vae(model_lower, taesd, variant)
147
+ self._load_deepcache(interval=deepcache_interval)
148
+ return self.pipe
149
+ else:
150
+ print(f"Unloading {model_name.lower()}...")
151
+ self.pipe = None
152
+
153
+ print(f"Loading {model_lower} with {'Tiny' if taesd else 'KL'} VAE...")
154
+ self.pipe = StableDiffusionPipeline.from_pretrained(**pipe_kwargs).to(
155
+ device=device,
156
+ dtype=dtype,
157
+ )
158
+ self.pipe.load_textual_inversion(
159
+ pretrained_model_name_or_path=list(EMBEDDINGS.keys()),
160
+ tokens=list(EMBEDDINGS.values()),
161
+ )
162
+ self._load_vae(model_lower, taesd, variant)
163
+ self._load_deepcache(interval=deepcache_interval)
164
+
165
+ torch.cuda.empty_cache()
166
+ return self.pipe