DPM-Solver++(3M) SDE.
(model, x, sigmas, extra_args=None, callback=None, disable=None, eta=1., s_noise=1., noise_sampler=None)
| 723 | |
| 724 | @torch.no_grad() |
| 725 | def sample_dpmpp_3m_sde(model, x, sigmas, extra_args=None, callback=None, disable=None, eta=1., s_noise=1., noise_sampler=None): |
| 726 | """DPM-Solver++(3M) SDE.""" |
| 727 | |
| 728 | sigma_min, sigma_max = sigmas[sigmas > 0].min(), sigmas.max() |
| 729 | noise_sampler = BrownianTreeNoiseSampler(x, sigma_min, sigma_max) if noise_sampler is None else noise_sampler |
| 730 | extra_args = {} if extra_args is None else extra_args |
| 731 | s_in = x.new_ones([x.shape[0]]) |
| 732 | |
| 733 | denoised_1, denoised_2 = None, None |
| 734 | h_1, h_2 = None, None |
| 735 | |
| 736 | for i in trange(len(sigmas) - 1, disable=disable): |
| 737 | denoised = model(x, sigmas[i] * s_in, **extra_args) |
| 738 | if callback is not None: |
| 739 | callback({'x': x, 'i': i, 'sigma': sigmas[i], 'sigma_hat': sigmas[i], 'denoised': denoised}) |
| 740 | if sigmas[i + 1] == 0: |
| 741 | # Denoising step |
| 742 | x = denoised |
| 743 | else: |
| 744 | t, s = -sigmas[i].log(), -sigmas[i + 1].log() |
| 745 | h = s - t |
| 746 | h_eta = h * (eta + 1) |
| 747 | |
| 748 | x = torch.exp(-h_eta) * x + (-h_eta).expm1().neg() * denoised |
| 749 | |
| 750 | if h_2 is not None: |
| 751 | r0 = h_1 / h |
| 752 | r1 = h_2 / h |
| 753 | d1_0 = (denoised - denoised_1) / r0 |
| 754 | d1_1 = (denoised_1 - denoised_2) / r1 |
| 755 | d1 = d1_0 + (d1_0 - d1_1) * r0 / (r0 + r1) |
| 756 | d2 = (d1_0 - d1_1) / (r0 + r1) |
| 757 | phi_2 = h_eta.neg().expm1() / h_eta + 1 |
| 758 | phi_3 = phi_2 / h_eta - 0.5 |
| 759 | x = x + phi_2 * d1 - phi_3 * d2 |
| 760 | elif h_1 is not None: |
| 761 | r = h_1 / h |
| 762 | d = (denoised - denoised_1) / r |
| 763 | phi_2 = h_eta.neg().expm1() / h_eta + 1 |
| 764 | x = x + phi_2 * d |
| 765 | |
| 766 | if eta: |
| 767 | x = x + noise_sampler(sigmas[i], sigmas[i + 1]) * sigmas[i + 1] * (-2 * h * eta).expm1().neg().sqrt() * s_noise |
| 768 | |
| 769 | denoised_1, denoised_2 = denoised, denoised_1 |
| 770 | h_1, h_2 = h, h_1 |
| 771 | return x |
nothing calls this directly
no test coverage detected