Build the Karras noise schedule and integrate the probability flow ODE from sigma_max down to 0 with Euler or Heun steps.
With N = num_steps and ρ = rho, the noise levels for i=0,…,N−1 are
σi=(σmax1/ρ+N−1i(σmin1/ρ−σmax1/ρ))ρ,followed by an appended σN=0. The data is Gaussian with mean μ (data_mean) and standard deviation s (data_std) in every coordinate, so the exact denoiser is D(x,σ)=(s2x+σ2μ)/(s2+σ2).
Start from x=σmax times initial_noise. For each i from 0 to N−1, compute the slope d=(x−D(x,σi))/σi and the Euler proposal x′=x+(σi+1−σi)d. For method "euler" the new x is x′. For method "heun", when σi+1>0, compute d′=(x′−D(x′,σi+1))/σi+1 and set the new x to x+(σi+1−σi)(d+d′)/2. When σi+1=0, both methods set the new x to the Euler proposal.
Return a dict with "sigmas", a PyTorch tensor of shape (num_steps + 1,), and "samples", a PyTorch tensor with the shape of initial_noise, both with the dtype and device of initial_noise.
Input: initial_noise = [[1.2,-0.5,0.3],[-0.8,0.1,2.0]], num_steps = 5, sigma_min = 0.02, sigma_max = 10.0, rho = 7.0, data_mean = 0.5, data_std = 0.5, method = "euler"
Output: {"sigmas":[10.0,3.282849,0.872338,0.169858,0.02,0.0],"samples":[[0.882868,0.316889,0.583232],[0.217011,0.516646,1.149211]]}
Explanation: The five Karras noise levels from 10 down to 0.02 are about 10, 3.283, 0.872, 0.170 and 0.02, followed by the appended 0. The samples start at 10 times the noise, and the last Euler step to sigma 0 returns the denoiser output at sigma 0.02, so the first noise value 1.2 ends at about 0.883.
Input: initial_noise = [[1.2,-0.5,0.3],[-0.8,0.1,2.0]], num_steps = 5, sigma_min = 0.02, sigma_max = 10.0, rho = 7.0, data_mean = 0.5, data_std = 0.5, method = "heun"
Output: {"sigmas":[10.0,3.282849,0.872338,0.169858,0.02,0.0],"samples":[[1.277256,0.128269,0.668969],[-0.074493,0.533794,1.817955]]}
Input: initial_noise = [[[[0.5,-1.0],[1.5,0.0]]]], num_steps = 2, sigma_min = 1.0, sigma_max = 4.0, rho = 1.0, data_mean = -1.0, data_std = 2.0, method = "heun"
Output: {"sigmas":[4.0,1.0,0.0],"samples":[[[[0.392,-2.392],[2.248,-0.536]]]]}
torch.linspace from 0 to 1 gives the ramp i / (N - 1) for every noise level at once.
torch.cat([sigmas, sigmas.new_zeros(1)]) appends an exact 0 with the same dtype.
A small inner function D(x, sigma) lets you call the denoiser twice in the Heun branch.
Accepts: array
Accepts: integer
Accepts: number
Accepts: number
Accepts: number
Accepts: number
Accepts: number
Accepts: string
Build the Karras noise schedule and integrate the probability flow ODE from sigma_max down to 0 with Euler or Heun steps.
With N = num_steps and ρ = rho, the noise levels for i=0,…,N−1 are
σi=(σmax1/ρ+N−1i(σmin1/ρ−σmax1/ρ))ρ,followed by an appended σN=0. The data is Gaussian with mean μ (data_mean) and standard deviation s (data_std) in every coordinate, so the exact denoiser is D(x,σ)=(s2x+σ2μ)/(s2+σ2).
Start from x=σmax times initial_noise. For each i from 0 to N−1, compute the slope d=(x−D(x,σi))/σi and the Euler proposal x′=x+(σi+1−σi)d. For method "euler" the new x is x′. For method "heun", when σi+1>0, compute d′=(x′−D(x′,σi+1))/σi+1 and set the new x to x+(σi+1−σi)(d+d′)/2. When σi+1=0, both methods set the new x to the Euler proposal.
Return a dict with "sigmas", a PyTorch tensor of shape (num_steps + 1,), and "samples", a PyTorch tensor with the shape of initial_noise, both with the dtype and device of initial_noise.
Input: initial_noise = [[1.2,-0.5,0.3],[-0.8,0.1,2.0]], num_steps = 5, sigma_min = 0.02, sigma_max = 10.0, rho = 7.0, data_mean = 0.5, data_std = 0.5, method = "euler"
Output: {"sigmas":[10.0,3.282849,0.872338,0.169858,0.02,0.0],"samples":[[0.882868,0.316889,0.583232],[0.217011,0.516646,1.149211]]}
Explanation: The five Karras noise levels from 10 down to 0.02 are about 10, 3.283, 0.872, 0.170 and 0.02, followed by the appended 0. The samples start at 10 times the noise, and the last Euler step to sigma 0 returns the denoiser output at sigma 0.02, so the first noise value 1.2 ends at about 0.883.
Input: initial_noise = [[1.2,-0.5,0.3],[-0.8,0.1,2.0]], num_steps = 5, sigma_min = 0.02, sigma_max = 10.0, rho = 7.0, data_mean = 0.5, data_std = 0.5, method = "heun"
Output: {"sigmas":[10.0,3.282849,0.872338,0.169858,0.02,0.0],"samples":[[1.277256,0.128269,0.668969],[-0.074493,0.533794,1.817955]]}
Input: initial_noise = [[[[0.5,-1.0],[1.5,0.0]]]], num_steps = 2, sigma_min = 1.0, sigma_max = 4.0, rho = 1.0, data_mean = -1.0, data_std = 2.0, method = "heun"
Output: {"sigmas":[4.0,1.0,0.0],"samples":[[[[0.392,-2.392],[2.248,-0.536]]]]}
torch.linspace from 0 to 1 gives the ramp i / (N - 1) for every noise level at once.
torch.cat([sigmas, sigmas.new_zeros(1)]) appends an exact 0 with the same dtype.
A small inner function D(x, sigma) lets you call the denoiser twice in the Heun branch.
Accepts: array
Accepts: integer
Accepts: number
Accepts: number
Accepts: number
Accepts: number
Accepts: number
Accepts: string