diff options
author | Zac Liu <liuguang@baai.ac.cn> | 2022-11-30 03:14:04 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-30 03:14:04 +0000 |
commit | a39a57cb1f5964d9af2b541f7b352576adeeac0f (patch) | |
tree | ebae98ea40ecc5b34497424bee19310e9fac4068 /ldm/models/diffusion/dpm_solver/sampler.py | |
parent | 4b3c5bc24bffdf429c463a465763b3077fe55eb8 (diff) | |
parent | 0831ab476c626eb796b609acf8771177692bfab7 (diff) | |
download | stable-diffusion-webui-gfx803-a39a57cb1f5964d9af2b541f7b352576adeeac0f.tar.gz stable-diffusion-webui-gfx803-a39a57cb1f5964d9af2b541f7b352576adeeac0f.tar.bz2 stable-diffusion-webui-gfx803-a39a57cb1f5964d9af2b541f7b352576adeeac0f.zip |
Merge pull request #1 from 920232796/master
Add AltDiffusion
Diffstat (limited to 'ldm/models/diffusion/dpm_solver/sampler.py')
-rw-r--r-- | ldm/models/diffusion/dpm_solver/sampler.py | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/ldm/models/diffusion/dpm_solver/sampler.py b/ldm/models/diffusion/dpm_solver/sampler.py new file mode 100644 index 00000000..2c42d6f9 --- /dev/null +++ b/ldm/models/diffusion/dpm_solver/sampler.py @@ -0,0 +1,82 @@ +"""SAMPLING ONLY.""" + +import torch + +from .dpm_solver import NoiseScheduleVP, model_wrapper, DPM_Solver + + +class DPMSolverSampler(object): + def __init__(self, model, **kwargs): + super().__init__() + self.model = model + to_torch = lambda x: x.clone().detach().to(torch.float32).to(model.device) + self.register_buffer('alphas_cumprod', to_torch(model.alphas_cumprod)) + + def register_buffer(self, name, attr): + if type(attr) == torch.Tensor: + if attr.device != torch.device("cuda"): + attr = attr.to(torch.device("cuda")) + setattr(self, name, attr) + + @torch.no_grad() + def sample(self, + S, + batch_size, + shape, + conditioning=None, + callback=None, + normals_sequence=None, + img_callback=None, + quantize_x0=False, + eta=0., + mask=None, + x0=None, + temperature=1., + noise_dropout=0., + score_corrector=None, + corrector_kwargs=None, + verbose=True, + x_T=None, + log_every_t=100, + unconditional_guidance_scale=1., + unconditional_conditioning=None, + # this has to come in the same format as the conditioning, # e.g. as encoded tokens, ... + **kwargs + ): + if conditioning is not None: + if isinstance(conditioning, dict): + cbs = conditioning[list(conditioning.keys())[0]].shape[0] + if cbs != batch_size: + print(f"Warning: Got {cbs} conditionings but batch-size is {batch_size}") + else: + if conditioning.shape[0] != batch_size: + print(f"Warning: Got {conditioning.shape[0]} conditionings but batch-size is {batch_size}") + + # sampling + C, H, W = shape + size = (batch_size, C, H, W) + + # print(f'Data shape for DPM-Solver sampling is {size}, sampling steps {S}') + + device = self.model.betas.device + if x_T is None: + img = torch.randn(size, device=device) + else: + img = x_T + + ns = NoiseScheduleVP('discrete', alphas_cumprod=self.alphas_cumprod) + + model_fn = model_wrapper( + lambda x, t, c: self.model.apply_model(x, t, c), + ns, + model_type="noise", + guidance_type="classifier-free", + condition=conditioning, + unconditional_condition=unconditional_conditioning, + guidance_scale=unconditional_guidance_scale, + ) + + dpm_solver = DPM_Solver(model_fn, ns, predict_x0=True, thresholding=False) + x = dpm_solver.sample(img, steps=S, skip_type="time_uniform", method="multistep", order=2, lower_order_final=True) + + return x.to(device), None |