adamelliotfields commited on
Commit
0177258
1 Parent(s): 9f665e5

Fix refiner progress

Browse files
Files changed (4) hide show
  1. README.md +34 -0
  2. lib/config.py +7 -5
  3. lib/inference.py +19 -10
  4. lib/loader.py +12 -6
README.md CHANGED
@@ -48,3 +48,37 @@ preload_from_hub:
48
  # diffusion-xl
49
 
50
  Gradio app for Stable Diffusion XL.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  # diffusion-xl
49
 
50
  Gradio app for Stable Diffusion XL.
51
+
52
+ ## Usage
53
+
54
+ See [DOCS.md](https://huggingface.co/spaces/adamelliotfields/diffusion-xl/blob/main/DOCS.md).
55
+
56
+ ## Installation
57
+
58
+ ```sh
59
+ # clone
60
+ git clone https://huggingface.co/spaces/adamelliotfields/diffusion-xl.git
61
+ cd diffusion-xl
62
+ git remote set-url origin https://adamelliotfields:$HF_TOKEN@huggingface.co/spaces/adamelliotfields/diffusion-xl
63
+
64
+ # install
65
+ python -m venv .venv
66
+ source .venv/bin/activate
67
+ pip install -r requirements.txt
68
+
69
+ # gradio
70
+ python app.py --port 7860
71
+ ```
72
+
73
+ ## Development
74
+
75
+ See [pull requests and discussions](https://huggingface.co/docs/hub/en/repositories-pull-requests-discussions).
76
+
77
+ ```sh
78
+ git fetch origin refs/pr/42:pr/42
79
+ git checkout pr/42
80
+ # ...
81
+ git add .
82
+ git commit -m "Commit message"
83
+ git push origin pr/42:refs/pr/42
84
+ ```
lib/config.py CHANGED
@@ -6,7 +6,8 @@ from diffusers import (
6
  DPMSolverMultistepScheduler,
7
  EulerAncestralDiscreteScheduler,
8
  EulerDiscreteScheduler,
9
- PNDMScheduler,
 
10
  StableDiffusionXLImg2ImgPipeline,
11
  StableDiffusionXLPipeline,
12
  )
@@ -34,22 +35,23 @@ Config = SimpleNamespace(
34
  ],
35
  VAE_MODEL="madebyollin/sdxl-vae-fp16-fix",
36
  REFINER_MODEL="stabilityai/stable-diffusion-xl-refiner-1.0",
37
- SCHEDULER="DEIS 2M",
38
  SCHEDULERS={
39
  "DDIM": DDIMScheduler,
40
  "DEIS 2M": DEISMultistepScheduler,
41
  "DPM++ 2M": DPMSolverMultistepScheduler,
 
 
42
  "Euler": EulerDiscreteScheduler,
43
  "Euler a": EulerAncestralDiscreteScheduler,
44
- "PNDM": PNDMScheduler,
45
  },
46
  STYLE="sai-enhance",
47
  WIDTH=896,
48
  HEIGHT=1152,
49
  NUM_IMAGES=1,
50
  SEED=-1,
51
- GUIDANCE_SCALE=5,
52
- INFERENCE_STEPS=40,
53
  DEEPCACHE_INTERVAL=1,
54
  SCALE=1,
55
  SCALES=[1, 2, 4],
 
6
  DPMSolverMultistepScheduler,
7
  EulerAncestralDiscreteScheduler,
8
  EulerDiscreteScheduler,
9
+ KDPM2AncestralDiscreteScheduler,
10
+ KDPM2DiscreteScheduler,
11
  StableDiffusionXLImg2ImgPipeline,
12
  StableDiffusionXLPipeline,
13
  )
 
35
  ],
36
  VAE_MODEL="madebyollin/sdxl-vae-fp16-fix",
37
  REFINER_MODEL="stabilityai/stable-diffusion-xl-refiner-1.0",
38
+ SCHEDULER="Euler",
39
  SCHEDULERS={
40
  "DDIM": DDIMScheduler,
41
  "DEIS 2M": DEISMultistepScheduler,
42
  "DPM++ 2M": DPMSolverMultistepScheduler,
43
+ "DPM2": KDPM2DiscreteScheduler,
44
+ "DPM2 a": KDPM2AncestralDiscreteScheduler,
45
  "Euler": EulerDiscreteScheduler,
46
  "Euler a": EulerAncestralDiscreteScheduler,
 
47
  },
48
  STYLE="sai-enhance",
49
  WIDTH=896,
50
  HEIGHT=1152,
51
  NUM_IMAGES=1,
52
  SEED=-1,
53
+ GUIDANCE_SCALE=6,
54
+ INFERENCE_STEPS=35,
55
  DEEPCACHE_INTERVAL=1,
56
  SCALE=1,
57
  SCALES=[1, 2, 4],
lib/inference.py CHANGED
@@ -91,7 +91,7 @@ def generate(
91
  style=None,
92
  seed=None,
93
  model="stabilityai/stable-diffusion-xl-base-1.0",
94
- scheduler="DEIS 2M",
95
  width=1024,
96
  height=1024,
97
  guidance_scale=7.5,
@@ -100,7 +100,7 @@ def generate(
100
  scale=1,
101
  num_images=1,
102
  use_karras=False,
103
- use_refiner=True,
104
  Info: Callable[[str], None] = None,
105
  Error=Exception,
106
  progress=None,
@@ -112,30 +112,39 @@ def generate(
112
  if seed is None or seed < 0:
113
  seed = int(datetime.now().timestamp() * 1_000_000) % (2**64)
114
 
115
- EMBEDDINGS_TYPE = ReturnedEmbeddingsType.PENULTIMATE_HIDDEN_STATES_NON_NORMALIZED
116
-
117
  KIND = "txt2img"
118
-
119
- CURRENT_IMAGE = 1
120
  CURRENT_STEP = 0
 
 
121
 
122
  if progress is not None:
123
  TQDM = False
124
- progress((0, inference_steps), desc=f"Generating image {CURRENT_IMAGE}/{num_images}")
125
  else:
126
  TQDM = True
127
 
128
  def callback_on_step_end(pipeline, step, timestep, latents):
129
  nonlocal CURRENT_IMAGE, CURRENT_STEP
 
130
  if progress is None:
131
  return latents
 
132
  strength = 1
133
  total_steps = min(int(inference_steps * strength), inference_steps)
134
- CURRENT_STEP += step + 1
 
 
 
 
 
 
 
 
135
  progress(
136
  (CURRENT_STEP, total_steps),
137
- desc=f"Generating image {CURRENT_IMAGE}/{num_images}",
138
  )
 
139
  return latents
140
 
141
  start = time.perf_counter()
@@ -150,6 +159,7 @@ def generate(
150
  use_refiner,
151
  TQDM,
152
  )
 
153
  # prompt embeds for base and refiner
154
  compel_1 = Compel(
155
  text_encoder=[pipe.text_encoder, pipe.text_encoder_2],
@@ -232,7 +242,6 @@ def generate(
232
 
233
  if progress is not None:
234
  refiner_kwargs["callback_on_step_end"] = callback_on_step_end
235
-
236
  if use_refiner:
237
  image = refiner(**refiner_kwargs).images[0]
238
  if scale > 1:
 
91
  style=None,
92
  seed=None,
93
  model="stabilityai/stable-diffusion-xl-base-1.0",
94
+ scheduler="DDIM",
95
  width=1024,
96
  height=1024,
97
  guidance_scale=7.5,
 
100
  scale=1,
101
  num_images=1,
102
  use_karras=False,
103
+ use_refiner=False,
104
  Info: Callable[[str], None] = None,
105
  Error=Exception,
106
  progress=None,
 
112
  if seed is None or seed < 0:
113
  seed = int(datetime.now().timestamp() * 1_000_000) % (2**64)
114
 
 
 
115
  KIND = "txt2img"
 
 
116
  CURRENT_STEP = 0
117
+ CURRENT_IMAGE = 1
118
+ EMBEDDINGS_TYPE = ReturnedEmbeddingsType.PENULTIMATE_HIDDEN_STATES_NON_NORMALIZED
119
 
120
  if progress is not None:
121
  TQDM = False
122
+ progress((0, inference_steps), desc=f"Generating image 1/{num_images}")
123
  else:
124
  TQDM = True
125
 
126
  def callback_on_step_end(pipeline, step, timestep, latents):
127
  nonlocal CURRENT_IMAGE, CURRENT_STEP
128
+
129
  if progress is None:
130
  return latents
131
+
132
  strength = 1
133
  total_steps = min(int(inference_steps * strength), inference_steps)
134
+
135
+ # if steps are different we're in the refiner
136
+ refining = False
137
+ if CURRENT_STEP == step:
138
+ CURRENT_STEP = step + 1
139
+ else:
140
+ refining = True
141
+ CURRENT_STEP += 1
142
+
143
  progress(
144
  (CURRENT_STEP, total_steps),
145
+ desc=f"{'Refining' if refining else 'Generating'} image {CURRENT_IMAGE}/{num_images}",
146
  )
147
+
148
  return latents
149
 
150
  start = time.perf_counter()
 
159
  use_refiner,
160
  TQDM,
161
  )
162
+
163
  # prompt embeds for base and refiner
164
  compel_1 = Compel(
165
  text_encoder=[pipe.text_encoder, pipe.text_encoder_2],
 
242
 
243
  if progress is not None:
244
  refiner_kwargs["callback_on_step_end"] = callback_on_step_end
 
245
  if use_refiner:
246
  image = refiner(**refiner_kwargs).images[0]
247
  if scale > 1:
lib/loader.py CHANGED
@@ -53,13 +53,13 @@ class Loader:
53
 
54
  def _unload(self, model, refiner, scale):
55
  to_unload = []
56
- if self._should_unload_upscaler(scale):
57
- to_unload.append("upscaler")
58
- if self._should_unload_refiner(refiner):
59
- to_unload.append("refiner")
60
  if self._should_unload_pipeline(model):
61
  to_unload.append("model")
62
  to_unload.append("pipe")
 
 
 
 
63
  for component in to_unload:
64
  delattr(self, component)
65
  self._flush()
@@ -71,8 +71,13 @@ class Loader:
71
  if self.pipe is None:
72
  try:
73
  print(f"Loading {model}...")
74
- self.pipe = pipeline.from_pretrained(model, **kwargs).to("cuda")
75
  self.model = model
 
 
 
 
 
 
76
  except Exception as e:
77
  print(f"Error loading {model}: {e}")
78
  self.model = None
@@ -125,7 +130,7 @@ class Loader:
125
  "steps_offset": 1,
126
  }
127
 
128
- if scheduler not in ["DDIM", "Euler a", "PNDM"]:
129
  scheduler_kwargs["use_karras_sigmas"] = karras
130
 
131
  # https://github.com/huggingface/diffusers/blob/8a3f0c1/scripts/convert_original_stable_diffusion_to_diffusers.py#L939
@@ -169,6 +174,7 @@ class Loader:
169
  print(f"{'Enabling' if karras else 'Disabling'} Karras sigmas...")
170
  if not same_scheduler or not same_karras:
171
  self.pipe.scheduler = Config.SCHEDULERS[scheduler](**scheduler_kwargs)
 
172
 
173
  # https://huggingface.co/stabilityai/stable-diffusion-xl-refiner-1.0/blob/main/model_index.json
174
  refiner_kwargs = {
 
53
 
54
  def _unload(self, model, refiner, scale):
55
  to_unload = []
 
 
 
 
56
  if self._should_unload_pipeline(model):
57
  to_unload.append("model")
58
  to_unload.append("pipe")
59
+ if self._should_unload_refiner(refiner):
60
+ to_unload.append("refiner")
61
+ if self._should_unload_upscaler(scale):
62
+ to_unload.append("upscaler")
63
  for component in to_unload:
64
  delattr(self, component)
65
  self._flush()
 
71
  if self.pipe is None:
72
  try:
73
  print(f"Loading {model}...")
 
74
  self.model = model
75
+ self.pipe = pipeline.from_pretrained(model, **kwargs).to("cuda")
76
+ if self.refiner is not None:
77
+ self.refiner.vae = self.pipe.vae
78
+ self.refiner.scheduler = self.pipe.scheduler
79
+ self.refiner.tokenizer_2 = self.pipe.tokenizer_2
80
+ self.refiner.text_encoder_2 = self.pipe.text_encoder_2
81
  except Exception as e:
82
  print(f"Error loading {model}: {e}")
83
  self.model = None
 
130
  "steps_offset": 1,
131
  }
132
 
133
+ if scheduler not in ["DDIM", "Euler a"]:
134
  scheduler_kwargs["use_karras_sigmas"] = karras
135
 
136
  # https://github.com/huggingface/diffusers/blob/8a3f0c1/scripts/convert_original_stable_diffusion_to_diffusers.py#L939
 
174
  print(f"{'Enabling' if karras else 'Disabling'} Karras sigmas...")
175
  if not same_scheduler or not same_karras:
176
  self.pipe.scheduler = Config.SCHEDULERS[scheduler](**scheduler_kwargs)
177
+ self.refiner.scheduler = self.pipe.scheduler
178
 
179
  # https://huggingface.co/stabilityai/stable-diffusion-xl-refiner-1.0/blob/main/model_index.json
180
  refiner_kwargs = {