Spaces:
Runtime error
Runtime error
# AUTOGENERATED! DO NOT EDIT! File to edit: app.ipynb. | |
# %% auto 0 | |
__all__ = ['model_name', 'device', 'better_vae', 'unet_attn_slice', 'sampler_kls', 'hf_sampler', 'model_kwargs', 'num_steps', | |
'height', 'width', 'k_sampler', 'use_karras_sigmas', 'NEG_PROMPT', 'generation_kwargs', 'baseline_g', | |
'max_val', 'min_val', 'num_warmup_steps', 'warmup_init_val', 'num_cycles', 'k_decay', 'DEFAULT_COS_PARAMS', | |
'static_sched', 'k_sched', 'inv_k_sched', 'scheds', 'iface', 'load_model', 'cos_harness', | |
'compare_dynamic_guidance'] | |
# %% app.ipynb 1 | |
import gradio as gr | |
from cf_guidance import schedules, transforms | |
from min_diffusion.core import MinimalDiffusion | |
import torch | |
import nbdev | |
# %% app.ipynb 2 | |
## MODEL SETUP | |
###################################### | |
###################################### | |
model_name = 'stabilityai/stable-diffusion-2' | |
device = ('cpu','cuda')[torch.cuda.is_available()] | |
if device == 'cuda': | |
revision = 'fp16' | |
dtype = torch.float16 | |
else: | |
revision = 'fp32' | |
dtype = torch.float32 | |
# model parameters | |
better_vae = '' | |
unet_attn_slice = True | |
sampler_kls = 'dpm_multi' | |
hf_sampler = 'dpm_multi' | |
model_kwargs = { | |
'better_vae': better_vae, | |
'unet_attn_slice': unet_attn_slice, | |
'scheduler_kls': hf_sampler, | |
} | |
def load_model(): | |
pipeline = MinimalDiffusion( | |
model_name, | |
device, | |
dtype, | |
revision, | |
**model_kwargs, | |
) | |
pipeline.load() | |
return pipeline | |
###################################### | |
###################################### | |
# %% app.ipynb 3 | |
## GENERATION PARAMETERS | |
###################################### | |
###################################### | |
num_steps = 18 | |
height, width = 768, 768 | |
k_sampler = 'k_dpmpp_2m' #'k_dpmpp_sde' | |
use_karras_sigmas = True | |
# a good negative prompt | |
NEG_PROMPT = "ugly, stock photo, tiling, poorly drawn hands, poorly drawn feet, poorly drawn face, out of frame, mutation, mutated, extra limbs, extra legs, extra arms, disfigured, deformed, cross-eye, body out of frame, blurry, bad art, bad anatomy, blurred, text, watermark, grainy" | |
generation_kwargs = { | |
'num_steps': num_steps, | |
'height': height, | |
'width': width, | |
'k_sampler': k_sampler, | |
'negative_prompt': NEG_PROMPT, | |
'use_karras_sigmas': use_karras_sigmas, | |
} | |
###################################### | |
###################################### | |
# %% app.ipynb 4 | |
## dynamicCFG SETUP | |
###################################### | |
###################################### | |
# default cosine schedule parameters | |
baseline_g = 9 # default, static guidance value | |
max_val = 9 # the max scheduled guidance scaling value | |
min_val = 6 # the minimum scheduled guidance value | |
num_warmup_steps = 0 # number of warmup steps | |
warmup_init_val = 0 # the intial warmup value | |
num_cycles = 0.5 # number of cosine cycles | |
k_decay = 1 # k-decay for cosine curve scaling | |
# group the default schedule parameters | |
DEFAULT_COS_PARAMS = { | |
'max_val': max_val, | |
'num_steps': num_steps, | |
'min_val': min_val, | |
'num_cycles': num_cycles, | |
'k_decay': k_decay, | |
'num_warmup_steps': num_warmup_steps, | |
'warmup_init_val': warmup_init_val, | |
} | |
def cos_harness(new_params: dict) -> dict: | |
'''Creates cosine schedules with updated parameters in `new_params` | |
''' | |
# start from the given baseline `default_params` | |
cos_params = dict(DEFAULT_COS_PARAMS) | |
# update the with the new, given parameters | |
cos_params.update(new_params) | |
# return the new cosine schedule | |
sched = schedules.get_cos_sched(**cos_params) | |
return sched | |
# build the static schedule | |
static_sched = [baseline_g] * num_steps | |
# build the inverted kdecay schedule | |
k_sched = cos_harness({'k_decay': 0.2}) | |
inv_k_sched = [max_val - g + min_val for g in k_sched] | |
# group the schedules | |
scheds = { | |
'cosine': {'g': inv_k_sched}, | |
'static': {'g': static_sched}, | |
} | |
###################################### | |
###################################### | |
# %% app.ipynb 5 | |
def compare_dynamic_guidance(prompt): | |
''' | |
Compares the default, static Classifier-free Guidance to a dynamic schedule. | |
Model and sampling paramters: | |
Stable Diffusion 2 v-model | |
Half-precision | |
DPM++ 2M sampler, with Karras sigma schedule | |
18 sampling steps | |
(768 x 768) image | |
Using a generic negative prompt | |
Schedules: | |
Static guidance with scale of 9 | |
Inverse kDecay (cosine variant) scheduled guidance | |
''' | |
# load the model | |
pipeline = load_model() | |
# stores the output images | |
res = [] | |
# generate images with static and dynamic schedules | |
for (name,sched) in scheds.items(): | |
# make the guidance norm | |
gtfm = transforms.GuidanceTfm(sched) | |
# generate the image | |
with torch.autocast(device), torch.no_grad(): | |
img = pipeline.generate(prompt, gtfm, **generation_kwargs) | |
# add the generated image | |
res.append(name) | |
# return the generated images | |
return { | |
'values': res, | |
'label': 'Cosine vs. Static CFG' | |
} | |
# %% app.ipynb 6 | |
iface = gr.Interface( | |
compare_dynamic_guidance, | |
inputs="text", | |
outputs=gr.Gallery(), | |
title="Comparing image generations with dynamic Classifier-free Guidance", | |
) | |
iface.launch() | |