using sfast go brrrr
Browse files- app_init.py +1 -1
- config.py +7 -0
- pipelines/controlnelSD21Turbo.py +29 -11
- pipelines/controlnetSDXLTurbo.py +42 -15
- pipelines/img2imgSD21Turbo.py +16 -4
- requirements.txt +2 -1
app_init.py
CHANGED
@@ -110,11 +110,11 @@ def init_app(app: FastAPI, user_data: UserData, args: Args, pipeline):
|
|
110 |
params = await user_data.get_latest_data(user_id)
|
111 |
if not vars(params) or params.__dict__ == last_params.__dict__:
|
112 |
await websocket.send_json({"status": "send_frame"})
|
113 |
-
await asyncio.sleep(0.1)
|
114 |
continue
|
115 |
|
116 |
last_params = params
|
117 |
image = pipeline.predict(params)
|
|
|
118 |
if image is None:
|
119 |
await websocket.send_json({"status": "send_frame"})
|
120 |
continue
|
|
|
110 |
params = await user_data.get_latest_data(user_id)
|
111 |
if not vars(params) or params.__dict__ == last_params.__dict__:
|
112 |
await websocket.send_json({"status": "send_frame"})
|
|
|
113 |
continue
|
114 |
|
115 |
last_params = params
|
116 |
image = pipeline.predict(params)
|
117 |
+
|
118 |
if image is None:
|
119 |
await websocket.send_json({"status": "send_frame"})
|
120 |
continue
|
config.py
CHANGED
@@ -16,6 +16,7 @@ class Args(NamedTuple):
|
|
16 |
pipeline: str
|
17 |
ssl_certfile: str
|
18 |
ssl_keyfile: str
|
|
|
19 |
compel: bool = False
|
20 |
debug: bool = False
|
21 |
|
@@ -102,6 +103,12 @@ parser.add_argument(
|
|
102 |
default=False,
|
103 |
help="Compel",
|
104 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
105 |
parser.set_defaults(taesd=USE_TAESD)
|
106 |
|
107 |
args = Args(**vars(parser.parse_args()))
|
|
|
16 |
pipeline: str
|
17 |
ssl_certfile: str
|
18 |
ssl_keyfile: str
|
19 |
+
sfast: bool
|
20 |
compel: bool = False
|
21 |
debug: bool = False
|
22 |
|
|
|
103 |
default=False,
|
104 |
help="Compel",
|
105 |
)
|
106 |
+
parser.add_argument(
|
107 |
+
"--sfast",
|
108 |
+
action="store_true",
|
109 |
+
default=False,
|
110 |
+
help="Enable Stable Fast",
|
111 |
+
)
|
112 |
parser.set_defaults(taesd=USE_TAESD)
|
113 |
|
114 |
args = Args(**vars(parser.parse_args()))
|
pipelines/controlnelSD21Turbo.py
CHANGED
@@ -180,6 +180,19 @@ class Pipeline:
|
|
180 |
self.pipe.vae = AutoencoderTiny.from_pretrained(
|
181 |
taesd_model, torch_dtype=torch_dtype, use_safetensors=True
|
182 |
).to(device)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
183 |
self.canny_torch = SobelOperator(device=device)
|
184 |
|
185 |
self.pipe.scheduler = LCMScheduler.from_config(self.pipe.scheduler.config)
|
@@ -188,14 +201,15 @@ class Pipeline:
|
|
188 |
if device.type != "mps":
|
189 |
self.pipe.unet.to(memory_format=torch.channels_last)
|
190 |
|
191 |
-
if
|
192 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
193 |
|
194 |
-
self.pipe.compel_proc = Compel(
|
195 |
-
tokenizer=self.pipe.tokenizer,
|
196 |
-
text_encoder=self.pipe.text_encoder,
|
197 |
-
truncate_long_prompts=True,
|
198 |
-
)
|
199 |
if args.taesd:
|
200 |
self.pipe.vae = AutoencoderTiny.from_pretrained(
|
201 |
taesd_model, torch_dtype=torch_dtype, use_safetensors=True
|
@@ -216,7 +230,13 @@ class Pipeline:
|
|
216 |
|
217 |
def predict(self, params: "Pipeline.InputParams") -> Image.Image:
|
218 |
generator = torch.manual_seed(params.seed)
|
219 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
220 |
control_image = self.canny_torch(
|
221 |
params.image, params.canny_low_threshold, params.canny_high_threshold
|
222 |
)
|
@@ -224,10 +244,10 @@ class Pipeline:
|
|
224 |
strength = params.strength
|
225 |
if int(steps * strength) < 1:
|
226 |
steps = math.ceil(1 / max(0.10, strength))
|
227 |
-
last_time = time.time()
|
228 |
results = self.pipe(
|
229 |
image=params.image,
|
230 |
control_image=control_image,
|
|
|
231 |
prompt_embeds=prompt_embeds,
|
232 |
generator=generator,
|
233 |
strength=strength,
|
@@ -240,8 +260,6 @@ class Pipeline:
|
|
240 |
control_guidance_start=params.controlnet_start,
|
241 |
control_guidance_end=params.controlnet_end,
|
242 |
)
|
243 |
-
print(f"Time taken: {time.time() - last_time}")
|
244 |
-
|
245 |
nsfw_content_detected = (
|
246 |
results.nsfw_content_detected[0]
|
247 |
if "nsfw_content_detected" in results
|
|
|
180 |
self.pipe.vae = AutoencoderTiny.from_pretrained(
|
181 |
taesd_model, torch_dtype=torch_dtype, use_safetensors=True
|
182 |
).to(device)
|
183 |
+
|
184 |
+
if args.sfast:
|
185 |
+
from sfast.compilers.stable_diffusion_pipeline_compiler import (
|
186 |
+
compile,
|
187 |
+
CompilationConfig,
|
188 |
+
)
|
189 |
+
|
190 |
+
config = CompilationConfig.Default()
|
191 |
+
config.enable_xformers = True
|
192 |
+
config.enable_triton = True
|
193 |
+
config.enable_cuda_graph = True
|
194 |
+
self.pipe = compile(self.pipe, config=config)
|
195 |
+
|
196 |
self.canny_torch = SobelOperator(device=device)
|
197 |
|
198 |
self.pipe.scheduler = LCMScheduler.from_config(self.pipe.scheduler.config)
|
|
|
201 |
if device.type != "mps":
|
202 |
self.pipe.unet.to(memory_format=torch.channels_last)
|
203 |
|
204 |
+
if args.compel:
|
205 |
+
from compel import Compel
|
206 |
+
|
207 |
+
self.pipe.compel_proc = Compel(
|
208 |
+
tokenizer=self.pipe.tokenizer,
|
209 |
+
text_encoder=self.pipe.text_encoder,
|
210 |
+
truncate_long_prompts=True,
|
211 |
+
)
|
212 |
|
|
|
|
|
|
|
|
|
|
|
213 |
if args.taesd:
|
214 |
self.pipe.vae = AutoencoderTiny.from_pretrained(
|
215 |
taesd_model, torch_dtype=torch_dtype, use_safetensors=True
|
|
|
230 |
|
231 |
def predict(self, params: "Pipeline.InputParams") -> Image.Image:
|
232 |
generator = torch.manual_seed(params.seed)
|
233 |
+
prompt = params.prompt
|
234 |
+
prompt_embeds = None
|
235 |
+
if hasattr(self.pipe, "compel_proc"):
|
236 |
+
prompt_embeds = self.pipe.compel_proc(
|
237 |
+
[params.prompt, params.negative_prompt]
|
238 |
+
)
|
239 |
+
prompt = None
|
240 |
control_image = self.canny_torch(
|
241 |
params.image, params.canny_low_threshold, params.canny_high_threshold
|
242 |
)
|
|
|
244 |
strength = params.strength
|
245 |
if int(steps * strength) < 1:
|
246 |
steps = math.ceil(1 / max(0.10, strength))
|
|
|
247 |
results = self.pipe(
|
248 |
image=params.image,
|
249 |
control_image=control_image,
|
250 |
+
prompt=prompt,
|
251 |
prompt_embeds=prompt_embeds,
|
252 |
generator=generator,
|
253 |
strength=strength,
|
|
|
260 |
control_guidance_start=params.controlnet_start,
|
261 |
control_guidance_end=params.controlnet_end,
|
262 |
)
|
|
|
|
|
263 |
nsfw_content_detected = (
|
264 |
results.nsfw_content_detected[0]
|
265 |
if "nsfw_content_detected" in results
|
pipelines/controlnetSDXLTurbo.py
CHANGED
@@ -185,20 +185,31 @@ class Pipeline:
|
|
185 |
)
|
186 |
self.canny_torch = SobelOperator(device=device)
|
187 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
188 |
self.pipe.set_progress_bar_config(disable=True)
|
189 |
self.pipe.to(device=device, dtype=torch_dtype).to(device)
|
190 |
if device.type != "mps":
|
191 |
self.pipe.unet.to(memory_format=torch.channels_last)
|
192 |
|
193 |
-
if
|
194 |
-
self.pipe.
|
|
|
|
|
|
|
|
|
|
|
195 |
|
196 |
-
self.pipe.compel_proc = Compel(
|
197 |
-
tokenizer=[self.pipe.tokenizer, self.pipe.tokenizer_2],
|
198 |
-
text_encoder=[self.pipe.text_encoder, self.pipe.text_encoder_2],
|
199 |
-
returned_embeddings_type=ReturnedEmbeddingsType.PENULTIMATE_HIDDEN_STATES_NON_NORMALIZED,
|
200 |
-
requires_pooled=[False, True],
|
201 |
-
)
|
202 |
if args.taesd:
|
203 |
self.pipe.vae = AutoencoderTiny.from_pretrained(
|
204 |
taesd_model, torch_dtype=torch_dtype, use_safetensors=True
|
@@ -220,9 +231,23 @@ class Pipeline:
|
|
220 |
def predict(self, params: "Pipeline.InputParams") -> Image.Image:
|
221 |
generator = torch.manual_seed(params.seed)
|
222 |
|
223 |
-
|
224 |
-
|
225 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
226 |
control_image = self.canny_torch(
|
227 |
params.image, params.canny_low_threshold, params.canny_high_threshold
|
228 |
)
|
@@ -234,10 +259,12 @@ class Pipeline:
|
|
234 |
results = self.pipe(
|
235 |
image=params.image,
|
236 |
control_image=control_image,
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
|
|
|
|
241 |
generator=generator,
|
242 |
strength=strength,
|
243 |
num_inference_steps=steps,
|
|
|
185 |
)
|
186 |
self.canny_torch = SobelOperator(device=device)
|
187 |
|
188 |
+
if args.sfast:
|
189 |
+
from sfast.compilers.stable_diffusion_pipeline_compiler import (
|
190 |
+
compile,
|
191 |
+
CompilationConfig,
|
192 |
+
)
|
193 |
+
|
194 |
+
config = CompilationConfig.Default()
|
195 |
+
config.enable_xformers = True
|
196 |
+
config.enable_triton = True
|
197 |
+
config.enable_cuda_graph = True
|
198 |
+
self.pipe = compile(self.pipe, config=config)
|
199 |
+
|
200 |
self.pipe.set_progress_bar_config(disable=True)
|
201 |
self.pipe.to(device=device, dtype=torch_dtype).to(device)
|
202 |
if device.type != "mps":
|
203 |
self.pipe.unet.to(memory_format=torch.channels_last)
|
204 |
|
205 |
+
if args.compel:
|
206 |
+
self.pipe.compel_proc = Compel(
|
207 |
+
tokenizer=[self.pipe.tokenizer, self.pipe.tokenizer_2],
|
208 |
+
text_encoder=[self.pipe.text_encoder, self.pipe.text_encoder_2],
|
209 |
+
returned_embeddings_type=ReturnedEmbeddingsType.PENULTIMATE_HIDDEN_STATES_NON_NORMALIZED,
|
210 |
+
requires_pooled=[False, True],
|
211 |
+
)
|
212 |
|
|
|
|
|
|
|
|
|
|
|
|
|
213 |
if args.taesd:
|
214 |
self.pipe.vae = AutoencoderTiny.from_pretrained(
|
215 |
taesd_model, torch_dtype=torch_dtype, use_safetensors=True
|
|
|
231 |
def predict(self, params: "Pipeline.InputParams") -> Image.Image:
|
232 |
generator = torch.manual_seed(params.seed)
|
233 |
|
234 |
+
prompt = params.prompt
|
235 |
+
negative_prompt = params.negative_prompt
|
236 |
+
prompt_embeds = None
|
237 |
+
pooled_prompt_embeds = None
|
238 |
+
negative_prompt_embeds = None
|
239 |
+
negative_pooled_prompt_embeds = None
|
240 |
+
if hasattr(self.pipe, "compel_proc"):
|
241 |
+
_prompt_embeds, pooled_prompt_embeds = self.pipe.compel_proc(
|
242 |
+
[params.prompt, params.negative_prompt]
|
243 |
+
)
|
244 |
+
prompt = None
|
245 |
+
negative_prompt = None
|
246 |
+
prompt_embeds = _prompt_embeds[0:1]
|
247 |
+
pooled_prompt_embeds = pooled_prompt_embeds[0:1]
|
248 |
+
negative_prompt_embeds = _prompt_embeds[1:2]
|
249 |
+
negative_pooled_prompt_embeds = pooled_prompt_embeds[1:2]
|
250 |
+
|
251 |
control_image = self.canny_torch(
|
252 |
params.image, params.canny_low_threshold, params.canny_high_threshold
|
253 |
)
|
|
|
259 |
results = self.pipe(
|
260 |
image=params.image,
|
261 |
control_image=control_image,
|
262 |
+
prompt=prompt,
|
263 |
+
negative_prompt=negative_prompt,
|
264 |
+
prompt_embeds=prompt_embeds,
|
265 |
+
pooled_prompt_embeds=pooled_prompt_embeds,
|
266 |
+
negative_prompt_embeds=negative_prompt_embeds,
|
267 |
+
negative_pooled_prompt_embeds=negative_pooled_prompt_embeds,
|
268 |
generator=generator,
|
269 |
strength=strength,
|
270 |
num_inference_steps=steps,
|
pipelines/img2imgSD21Turbo.py
CHANGED
@@ -14,6 +14,10 @@ from config import Args
|
|
14 |
from pydantic import BaseModel, Field
|
15 |
from PIL import Image
|
16 |
import math
|
|
|
|
|
|
|
|
|
17 |
|
18 |
base_model = "stabilityai/sd-turbo"
|
19 |
taesd_model = "madebyollin/taesd"
|
@@ -104,15 +108,23 @@ class Pipeline:
|
|
104 |
taesd_model, torch_dtype=torch_dtype, use_safetensors=True
|
105 |
).to(device)
|
106 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
107 |
self.pipe.set_progress_bar_config(disable=True)
|
108 |
self.pipe.to(device=device, dtype=torch_dtype)
|
109 |
if device.type != "mps":
|
110 |
self.pipe.unet.to(memory_format=torch.channels_last)
|
111 |
|
112 |
-
# check if computer has less than 64GB of RAM using sys or os
|
113 |
-
if psutil.virtual_memory().total < 64 * 1024**3:
|
114 |
-
self.pipe.enable_attention_slicing()
|
115 |
-
|
116 |
if args.torch_compile:
|
117 |
print("Running torch compile")
|
118 |
self.pipe.unet = torch.compile(
|
|
|
14 |
from pydantic import BaseModel, Field
|
15 |
from PIL import Image
|
16 |
import math
|
17 |
+
from sfast.compilers.stable_diffusion_pipeline_compiler import (
|
18 |
+
compile,
|
19 |
+
CompilationConfig,
|
20 |
+
)
|
21 |
|
22 |
base_model = "stabilityai/sd-turbo"
|
23 |
taesd_model = "madebyollin/taesd"
|
|
|
108 |
taesd_model, torch_dtype=torch_dtype, use_safetensors=True
|
109 |
).to(device)
|
110 |
|
111 |
+
if args.sfast:
|
112 |
+
from sfast.compilers.stable_diffusion_pipeline_compiler import (
|
113 |
+
compile,
|
114 |
+
CompilationConfig,
|
115 |
+
)
|
116 |
+
|
117 |
+
config = CompilationConfig.Default()
|
118 |
+
config.enable_xformers = True
|
119 |
+
config.enable_triton = True
|
120 |
+
config.enable_cuda_graph = True
|
121 |
+
self.pipe = compile(self.pipe, config=config)
|
122 |
+
|
123 |
self.pipe.set_progress_bar_config(disable=True)
|
124 |
self.pipe.to(device=device, dtype=torch_dtype)
|
125 |
if device.type != "mps":
|
126 |
self.pipe.unet.to(memory_format=torch.channels_last)
|
127 |
|
|
|
|
|
|
|
|
|
128 |
if args.torch_compile:
|
129 |
print("Running torch compile")
|
130 |
self.pipe.unet = torch.compile(
|
requirements.txt
CHANGED
@@ -10,4 +10,5 @@ compel==2.0.2
|
|
10 |
controlnet-aux==0.0.7
|
11 |
peft==0.6.0
|
12 |
xformers; sys_platform != 'darwin' or platform_machine != 'arm64'
|
13 |
-
markdown2
|
|
|
|
10 |
controlnet-aux==0.0.7
|
11 |
peft==0.6.0
|
12 |
xformers; sys_platform != 'darwin' or platform_machine != 'arm64'
|
13 |
+
markdown2
|
14 |
+
stable_fast @ https://github.com/chengzeyi/stable-fast/releases/download/v0.0.15.post1/stable_fast-0.0.15.post1+torch211cu121-cp310-cp310-manylinux2014_x86_64.whl
|