code: def ddim_bit_scheduler_step(
      self,
      model_output: torch.FloatTensor,
      timestep: int,
      sample: torch.FloatTensor,
      eta: float = 0.0,
      use_clipped_model_output: bool = True,
      generator=None,
      return_dict: bool = True,
  ) -> Union[DDIMSchedulerOutput, Tuple]:
      """
      Predict the sample at the previous timestep by reversing the SDE. Core function to propagate the diffusion
      process from the learned model outputs (most often the predicted noise).
      Args:
          model_output (`torch.FloatTensor`): direct output from learned diffusion model.
          timestep (`int`): current discrete timestep in the diffusion chain.
          sample (`torch.FloatTensor`):
              current instance of sample being created by diffusion process.
          eta (`float`): weight of noise for added noise in diffusion step.
          use_clipped_model_output (`bool`): TODO
          generator: random number generator.
          return_dict (`bool`): option for returning tuple rather than DDIMSchedulerOutput class
      Returns:
          [`~schedulers.scheduling_utils.DDIMSchedulerOutput`] or `tuple`:
          [`~schedulers.scheduling_utils.DDIMSchedulerOutput`] if `return_dict` is True, otherwise a `tuple`. When
          returning a tuple, the first element is the sample tensor.
      """
      if self.num_inference_steps is None:
          raise ValueError(
              "Number of inference steps is 'None', you need to run 'set_timesteps' after creating the scheduler"
          )
  
      # See formulas (12) and (16) of DDIM paper https://arxiv.org/pdf/2010.02502.pdf
      # Ideally, read DDIM paper in-detail understanding
  
      # Notation (<variable name> -> <name in paper>
      # - pred_noise_t -> e_theta(x_t, t)
      # - pred_original_sample -> f_theta(x_t, t) or x_0
      # - std_dev_t -> sigma_t
      # - eta -> η
      # - pred_sample_direction -> "direction pointing to x_t"
      # - pred_prev_sample -> "x_t-1"
  
      # 1. get previous step value (=t-1)
      prev_timestep = (
          timestep
          - self.config.num_train_timesteps // self.num_inference_steps
      )
  
      # 2. compute alphas, betas
      alpha_prod_t = self.alphas_cumprod[timestep]
      alpha_prod_t_prev = (
          self.alphas_cumprod[prev_timestep]
          if prev_timestep >= 0
          else self.final_alpha_cumprod
      )
  
      beta_prod_t = 1 - alpha_prod_t
  
      # 3. compute predicted original sample from predicted noise also called
      # "predicted x_0" of formula (12) from https://arxiv.org/pdf/2010.02502.pdf
      pred_original_sample = (
          sample - beta_prod_t ** (0.5) * model_output
      ) / alpha_prod_t ** (0.5)
  
      # 4. Clip "predicted x_0"
      scale = self.bit_scale
      if self.config.clip_sample:
          pred_original_sample = torch.clamp(
              pred_original_sample, -scale, scale
          )
  
      # 5. compute variance: "sigma_t(η)" -> see formula (16)
      # σ_t = sqrt((1 − α_t−1)/(1 − α_t)) * sqrt(1 − α_t/α_t−1)
      variance = self._get_variance(timestep, prev_timestep)
      std_dev_t = eta * variance ** (0.5)
  
      if use_clipped_model_output:
          # the model_output is always re-derived from the clipped x_0 in Glide
          model_output = (
              sample - alpha_prod_t ** (0.5) * pred_original_sample
          ) / beta_prod_t ** (0.5)
  
      # 6. compute "direction pointing to x_t" of formula (12) from https://arxiv.org/pdf/2010.02502.pdf
      pred_sample_direction = (
          1 - alpha_prod_t_prev - std_dev_t**2
      ) ** (0.5) * model_output
  
      # 7. compute x_t without "random noise" of formula (12) from https://arxiv.org/pdf/2010.02502.pdf
      prev_sample = (
          alpha_prod_t_prev ** (0.5) * pred_original_sample
          + pred_sample_direction
      )
  
      if eta > 0:
          # randn_like does not support generator https://github.com/pytorch/pytorch/issues/27072
          device = (
              model_output.device
              if torch.is_tensor(model_output)
              else "cpu"
          )
          noise = torch.randn(
              model_output.shape,
              dtype=model_output.dtype,
              generator=generator,
          ).to(device)
          variance = (
              self._get_variance(timestep, prev_timestep) ** (0.5)
              * eta
              * noise
          )
  
          prev_sample = prev_sample + variance
  
      if not return_dict:
          return (prev_sample,)
  
      return DDIMSchedulerOutput(
          prev_sample=prev_sample,
          pred_original_sample=pred_original_sample,
      )
  
file_path: llmga/llmga/diffusers/examples/community/bit_diffusion.py
imports: from typing import Optional, Tuple, Union
  import torch
  from einops import rearrange, reduce
  from diffusers import DDIMScheduler, DDPMScheduler, DiffusionPipeline, ImagePipelineOutput, UNet2DConditionModel
  from diffusers.schedulers.scheduling_ddim import DDIMSchedulerOutput
  from diffusers.schedulers.scheduling_ddpm import DDPMSchedulerOutput
label_desc: Use image node_id 3 for calling a global function with example usage: ddim_bit_scheduler_step(model_output, timestep, sample, eta, use_clipped_model_output, generator, return_dict) and returns: DDIMSchedulerOutput, prev_sample