TensorTonic
Study Plans
Study Plan
DDPM Ancestral Step
Diffusion ModelsSamplingGenerative Models
Medium

Perform one ancestral sampling step of a DDPM, moving the whole batch from timestep ttt to timestep t−1t - 1t−1.

μ=1αt(xt−βt1−αˉt ϵ^),xt−1=μ+σtz\mu = \frac{1}{\sqrt{\alpha_t}} \left( x_t - \frac{\beta_t}{\sqrt{1 - \bar\alpha_t}}\, \hat\epsilon \right), \qquad x_{t-1} = \mu + \sigma_t zμ=αt​​1​(xt​−1−αˉt​​βt​​ϵ^),xt−1​=μ+σt​z

Here xtx_txt​ is the current batch x_t, ϵ^\hat\epsilonϵ^ is predicted_noise, zzz is noise, and βt\beta_tβt​ is betas at index ttt. The per-step signal fraction is αt=1−βt\alpha_t = 1 - \beta_tαt​=1−βt​, and αˉt\bar\alpha_tαˉt​ is the product of α0\alpha_0α0​ through αt\alpha_tαt​. Write αˉt−1\bar\alpha_{t-1}αˉt−1​ for the product up to t−1t - 1t−1, with αˉ−1=1\bar\alpha_{-1} = 1αˉ−1​=1.

The variance σt2\sigma_t^2σt2​ depends on variance_type. For "fixed_large" it is βt\beta_tβt​. For "fixed_small" it is the posterior variance

β~t=βt 1−αˉt−11−αˉt.\tilde\beta_t = \beta_t \, \frac{1 - \bar\alpha_{t-1}}{1 - \bar\alpha_t}.β~​t​=βt​1−αˉt​1−αˉt−1​​.

At t=0t = 0t=0 the step returns μ\muμ alone and the noise is ignored, whatever the variance_type.

Return a PyTorch tensor with the same shape, dtype and device as x_t.

Examples

Input: x_t = [[[[0.8,-0.4],[1.2,0.1]]]], t = 2, predicted_noise = [[[[0.5,-1.0],[0.3,0.9]]]], betas = [0.1,0.2,0.3,0.4], noise = [[[[1.0,0.2],[-0.6,0.4]]]], variance_type = "fixed_small"

Output: [[[[1.113144,0.113347],[1.034618,-0.174086]]]]

Explanation: At t = 2 the cumulative products are 0.72 before and 0.504 at the step, so the noise coefficient is about 0.426, the mean is divided by about 0.837, and the posterior variance is about 0.169.

Input: x_t = [[[[0.8,-0.4],[1.2,0.1]]]], t = 2, predicted_noise = [[[[0.5,-1.0],[0.3,0.9]]]], betas = [0.1,0.2,0.3,0.4], noise = [[[[1.0,0.2],[-0.6,0.4]]]], variance_type = "fixed_large"

Output: [[[[1.249339,0.140586],[0.952901,-0.119608]]]]

Input: x_t = [[0.5,-0.5,1.0],[0.0,2.0,-1.5]], t = 0, predicted_noise = [[0.2,-0.1,0.4],[1.0,0.0,-0.3]], betas = [0.05,0.1,0.2], noise = [[1.0,-1.0,0.5],[0.3,0.8,-0.2]], variance_type = "fixed_large"

Output: [[0.467106,-0.490048,0.934212],[-0.229416,2.051957,-1.470143]]

Hint 1

torch.cumprod(1 - betas, dim=0) gives every alpha_bar at once.

Hint 2

Guard alpha_bars[t - 1] with a t > 0 check so index -1 does not wrap to the last entry.

Hint 3

Build the result with + rather than += or add_ so x_t stays unchanged.

Requirements

  • Use PyTorch tensor operations.
  • Build alphas and alpha_bars from betas yourself.
  • Use one integer t for every sample in the batch.
  • Leave all input tensors unchanged.

Constraints

  • x_t, predicted_noise and noise are floating-point PyTorch tensors of the same shape (B, ...) with B at least 1 and at least one non-batch dimension.
  • betas is a 1-D tensor of length T between 2 and 30 with the same dtype as x_t and every value strictly between 0 and 1.
  • t is a Python int with 0 <= t <= T - 1.
  • variance_type is exactly "fixed_small" or "fixed_large".
  • Supported dtypes are float32 and float64. All values are finite.
Try Similar Problems
DDIM StepHardClassifier-Free GuidanceMediumToy DDPM SamplerHardKarras Euler SamplerHardPosterior Mean and VarianceMediumPrediction ParameterizationMediumAnnealed Langevin DynamicsMediumReparameterized Gaussian SampleEasyDiagonal Gaussian KL DivergenceEasyAutoencoder Forward PassMediumVariational Autoencoder Forward PassMediumGAN Training StepHard

Accepts: array

Accepts: integer

Accepts: array

Accepts: array

Accepts: array

Accepts: string

You must run your code first.

DDPM Ancestral Step

Diffusion ModelsSamplingGenerative Models
Medium

Perform one ancestral sampling step of a DDPM, moving the whole batch from timestep ttt to timestep t−1t - 1t−1.

μ=1αt(xt−βt1−αˉt ϵ^),xt−1=μ+σtz\mu = \frac{1}{\sqrt{\alpha_t}} \left( x_t - \frac{\beta_t}{\sqrt{1 - \bar\alpha_t}}\, \hat\epsilon \right), \qquad x_{t-1} = \mu + \sigma_t zμ=αt​​1​(xt​−1−αˉt​​βt​​ϵ^),xt−1​=μ+σt​z

Here xtx_txt​ is the current batch x_t, ϵ^\hat\epsilonϵ^ is predicted_noise, zzz is noise, and βt\beta_tβt​ is betas at index ttt. The per-step signal fraction is αt=1−βt\alpha_t = 1 - \beta_tαt​=1−βt​, and αˉt\bar\alpha_tαˉt​ is the product of α0\alpha_0α0​ through αt\alpha_tαt​. Write αˉt−1\bar\alpha_{t-1}αˉt−1​ for the product up to t−1t - 1t−1, with αˉ−1=1\bar\alpha_{-1} = 1αˉ−1​=1.

The variance σt2\sigma_t^2σt2​ depends on variance_type. For "fixed_large" it is βt\beta_tβt​. For "fixed_small" it is the posterior variance

β~t=βt 1−αˉt−11−αˉt.\tilde\beta_t = \beta_t \, \frac{1 - \bar\alpha_{t-1}}{1 - \bar\alpha_t}.β~​t​=βt​1−αˉt​1−αˉt−1​​.

At t=0t = 0t=0 the step returns μ\muμ alone and the noise is ignored, whatever the variance_type.

Return a PyTorch tensor with the same shape, dtype and device as x_t.

Examples

Input: x_t = [[[[0.8,-0.4],[1.2,0.1]]]], t = 2, predicted_noise = [[[[0.5,-1.0],[0.3,0.9]]]], betas = [0.1,0.2,0.3,0.4], noise = [[[[1.0,0.2],[-0.6,0.4]]]], variance_type = "fixed_small"

Output: [[[[1.113144,0.113347],[1.034618,-0.174086]]]]

Explanation: At t = 2 the cumulative products are 0.72 before and 0.504 at the step, so the noise coefficient is about 0.426, the mean is divided by about 0.837, and the posterior variance is about 0.169.

Input: x_t = [[[[0.8,-0.4],[1.2,0.1]]]], t = 2, predicted_noise = [[[[0.5,-1.0],[0.3,0.9]]]], betas = [0.1,0.2,0.3,0.4], noise = [[[[1.0,0.2],[-0.6,0.4]]]], variance_type = "fixed_large"

Output: [[[[1.249339,0.140586],[0.952901,-0.119608]]]]

Input: x_t = [[0.5,-0.5,1.0],[0.0,2.0,-1.5]], t = 0, predicted_noise = [[0.2,-0.1,0.4],[1.0,0.0,-0.3]], betas = [0.05,0.1,0.2], noise = [[1.0,-1.0,0.5],[0.3,0.8,-0.2]], variance_type = "fixed_large"

Output: [[0.467106,-0.490048,0.934212],[-0.229416,2.051957,-1.470143]]

Hint 1

torch.cumprod(1 - betas, dim=0) gives every alpha_bar at once.

Hint 2

Guard alpha_bars[t - 1] with a t > 0 check so index -1 does not wrap to the last entry.

Hint 3

Build the result with + rather than += or add_ so x_t stays unchanged.

Requirements

  • Use PyTorch tensor operations.
  • Build alphas and alpha_bars from betas yourself.
  • Use one integer t for every sample in the batch.
  • Leave all input tensors unchanged.

Constraints

  • x_t, predicted_noise and noise are floating-point PyTorch tensors of the same shape (B, ...) with B at least 1 and at least one non-batch dimension.
  • betas is a 1-D tensor of length T between 2 and 30 with the same dtype as x_t and every value strictly between 0 and 1.
  • t is a Python int with 0 <= t <= T - 1.
  • variance_type is exactly "fixed_small" or "fixed_large".
  • Supported dtypes are float32 and float64. All values are finite.
Try Similar Problems
DDIM StepHardClassifier-Free GuidanceMediumToy DDPM SamplerHardKarras Euler SamplerHardPosterior Mean and VarianceMediumPrediction ParameterizationMediumAnnealed Langevin DynamicsMediumReparameterized Gaussian SampleEasyDiagonal Gaussian KL DivergenceEasyAutoencoder Forward PassMediumVariational Autoencoder Forward PassMediumGAN Training StepHard

Accepts: array

Accepts: integer

Accepts: array

Accepts: array

Accepts: array

Accepts: string

You must run your code first.