o
    ۷i/                     @   s   d dl mZ d dlZd dlZddlmZmZ ddlm	Z	 ddl
mZmZ ddlmZ eeZeG dd	 d	eZG d
d de	eZdS )    )	dataclassN   )ConfigMixinregister_to_config)SchedulerMixin)
BaseOutputlogging)randn_tensorc                   @   s.   e Zd ZU dZejed< dZejdB ed< dS )SCMSchedulerOutputaq  
    Output class for the scheduler's `step` function output.

    Args:
        prev_sample (`torch.Tensor` of shape `(batch_size, num_channels, height, width)` for images):
            Computed sample `(x_{t-1})` of previous timestep. `prev_sample` should be used as next model input in the
            denoising loop.
        pred_original_sample (`torch.Tensor` of shape `(batch_size, num_channels, height, width)` for images):
            The predicted denoised sample `(x_{0})` based on the model output from the current timestep.
            `pred_original_sample` can be used to preview progress or for guidance.
    prev_sampleNpred_original_sample)__name__
__module____qualname____doc__torchTensor__annotations__r    r   r   Y/home/ubuntu/vllm_env/lib/python3.10/site-packages/diffusers/schedulers/scheduling_scm.pyr
       s   
 
r
   c                   @   s  e Zd ZdZdZe			d-dededefd	d
Z	e
dd Ze
dd Zd.defddZ				d/dedejdeejB dedef
ddZdeejB ddfdd Z	d0deejB d!ejdB defd"d#Z		$d1d%ejded&ejd'ejd(edeeB fd)d*Zd+d, ZdS )2SCMSchedulera  
    `SCMScheduler` extends the denoising procedure introduced in denoising diffusion probabilistic models (DDPMs) with
    non-Markovian guidance. This model inherits from [`SchedulerMixin`] and [`ConfigMixin`]. Check the superclass
    documentation for the generic methods the library implements for all schedulers such as loading and saving.

    Args:
        num_train_timesteps (`int`, defaults to 1000):
            The number of diffusion steps to train the model.
        prediction_type (`str`, defaults to `trigflow`):
            Prediction type of the scheduler function. Currently only supports "trigflow".
        sigma_data (`float`, defaults to 0.5):
            The standard deviation of the noise added during multi-step inference.
         trigflow      ?num_train_timestepsprediction_type
sigma_datac                 C   sF   d| _ d| _ttd|ddd  tj| _	d| _
d| _dS )a  
        Initialize the SCM scheduler.

        Args:
            num_train_timesteps (`int`, defaults to 1000):
                The number of diffusion steps to train the model.
            prediction_type (`str`, defaults to `trigflow`):
                Prediction type of the scheduler function. Currently only supports "trigflow".
            sigma_data (`float`, defaults to 0.5):
                The standard deviation of the noise added during multi-step inference.
        g      ?Nr   )init_noise_sigmanum_inference_stepsr   
from_numpynparangecopyastypeint64	timesteps_step_index_begin_index)selfr   r   r   r   r   r   __init__E   s
   *
zSCMScheduler.__init__c                 C      | j S N)r(   r*   r   r   r   
step_indexa      zSCMScheduler.step_indexc                 C   r,   r-   r)   r.   r   r   r   begin_indexe   r0   zSCMScheduler.begin_indexr   r2   c                 C   s
   || _ dS )z
        Sets the begin index for the scheduler. This function should be run from pipeline before the inference.

        Args:
            begin_index (`int`, defaults to `0`):
                The begin index for the scheduler.
        Nr1   )r*   r2   r   r   r   set_begin_indexj   s   
zSCMScheduler.set_begin_indexNH.!??r    r'   devicemax_timestepsintermediate_timestepsc                 C   sF  || j jkrtd| d| j j d| j j d|dur(t||d kr(td|dur4|dur4td|du r@|du r@td	|durL|d
krLtd|| _|dur{t|trctj||d	 | _
n8t|tjrr||	 | _
n)tdt| |durtj||dg|d	 | _
ntj|d|d |d	 | _
d| _d| _dS )a  
        Sets the discrete timesteps used for the diffusion chain (to be run before inference).

        Args:
            num_inference_steps (`int`):
                The number of diffusion steps used when generating samples with a pre-trained model.
            timesteps (`torch.Tensor`, *optional*):
                Custom timesteps to use for the denoising process.
            max_timesteps (`float`, defaults to 1.57080):
                The maximum timestep value used in the SCM scheduler.
            intermediate_timesteps (`float`, *optional*, defaults to 1.3):
                The intermediate timestep value used in SCM scheduler (only used when num_inference_steps=2).
        z`num_inference_steps`: z6 cannot be larger than `self.config.train_timesteps`: zG as the unet model trained with this scheduler can only handle maximal z timesteps.Nr   zWIf providing custom timesteps, `timesteps` must be of length `num_inference_steps + 1`.zFIf providing custom timesteps, `max_timesteps` should not be provided.z5Should provide either `timesteps` or `max_timesteps`.r   zNIntermediate timesteps for SCM is not supported when num_inference_steps != 2.)r6   zUnsupported timesteps type: r   )configr   
ValueErrorlenr    
isinstancelistr   tensorfloatr'   r   totypelinspacer(   r)   )r*   r    r'   r6   r7   r8   r   r   r   set_timestepst   s8   

zSCMScheduler.set_timestepstimestepreturnc                 C   s@   | j du rt|tjr|| jj}| || _dS | j	| _dS )z
        Initialize the step index for the scheduler based on the given timestep.

        Args:
            timestep (`float` or `torch.Tensor`):
                The current timestep to initialize the step index from.
        N)
r2   r<   r   r   r@   r'   r6   index_for_timestepr(   r)   )r*   rD   r   r   r   _init_step_index   s
   
zSCMScheduler._init_step_indexschedule_timestepsc                 C   s:   |du r| j }||k }t|dkrdnd}||  S )ak  
        Find the index of a given timestep in the timestep schedule.

        Args:
            timestep (`float` or `torch.Tensor`):
                The timestep value to find in the schedule.
            schedule_timesteps (`torch.Tensor`, *optional*):
                The timestep schedule to search in. If `None`, uses `self.timesteps`.

        Returns:
            `int`:
                The index of the timestep in the schedule. For the very first step, returns the second index if
                multiple matches exist to avoid skipping a sigma when starting mid-schedule (e.g., for image-to-image).
        Nr   r   )r'   nonzeror;   item)r*   rD   rH   indicesposr   r   r   rF      s
   zSCMScheduler.index_for_timestepTmodel_outputsample	generatorreturn_dictc                 C   s   | j du r	td| jdu r| | | j| jd  }| j| j }| jj}|dkr8t|| t	||  }	ntd| t
| jdkrbt|j|j|d| jj }
t||	 t	||
  }n|	}|  jd7  _|sq||	fS t||	dS )a  
        Predict the sample from the previous timestep by reversing the SDE. This function propagates the diffusion
        process from the learned model outputs (most often the predicted noise).

        Args:
            model_output (`torch.FloatTensor`):
                The direct output from learned diffusion model.
            timestep (`float`):
                The current discrete timestep in the diffusion chain.
            sample (`torch.FloatTensor`):
                A current instance of a sample created by the diffusion process.
            return_dict (`bool`, *optional*, defaults to `True`):
                Whether or not to return a [`~schedulers.scheduling_scm.SCMSchedulerOutput`] or `tuple`.
        Returns:
            [`~schedulers.scheduling_utils.SCMSchedulerOutput`] or `tuple`:
                If return_dict is `True`, [`~schedulers.scheduling_scm.SCMSchedulerOutput`] is returned, otherwise a
                tuple is returned where the first element is the sample tensor.
        NzaNumber of inference steps is 'None', you need to run 'set_timesteps' after creating the schedulerr   r   zUnsupported parameterization: )r6   rO   )r   r   )r    r:   r/   rG   r'   r9   r   r   cossinr;   r	   shaper6   r   r(   r
   )r*   rM   rD   rN   rO   rP   tsparameterizationpred_x0noiser   r   r   r   step   s.   


zSCMScheduler.stepc                 C   s   | j jS r-   )r9   r   r.   r   r   r   __len__  s   zSCMScheduler.__len__)r   r   r   )r   )NNr4   r5   r-   )NT)r   r   r   r   orderr   intstrr?   r+   propertyr/   r2   r3   r   r   r6   rC   rG   rF   FloatTensor	Generatorboolr
   tuplerY   rZ   r   r   r   r   r   3   sv    


;
#
@r   )dataclassesr   numpyr"   r   configuration_utilsr   r   schedulers.scheduling_utilsr   utilsr   r   utils.torch_utilsr	   
get_loggerr   loggerr
   r   r   r   r   r   <module>   s   
