o
    ۷i{T                     @   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	m
Z
 ddl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)
BaseOutputlogging)randn_tensor   )SchedulerMixinc                   @   s   e Zd ZU dZejed< dS )$CMStochasticIterativeSchedulerOutputa>  
    Output class for the scheduler's `step` function.

    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.
    prev_sampleN)__name__
__module____qualname____doc__torchTensor__annotations__ r   r   h/home/ubuntu/vllm_env/lib/python3.10/site-packages/diffusers/schedulers/scheduling_consistency_models.pyr      s   
 	r   c                   @   s  e Zd ZdZdZe								dAd
edededededededdfddZ	e
defddZe
defddZdBdeddfddZdejdeejB dejfdd Zd!eejB fd"d#Z			dCd$edB d%eejB d&ee dB fd'd(Zd)ejdejfd*d+Zd,ejdeejejf fd-d.Zd,ejdeejejf fd/d0Z	dDdeejB d1ejdB defd2d3ZdeejB ddfd4d5Z			dEd6ejdeejB dejd7ejdB d8edeeB fd9d:Z d;ejd<ejd&ejdejfd=d>Z!defd?d@Z"dS )FCMStochasticIterativeSchedulera  
    Multistep and onestep sampling for consistency models.

    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 40):
            The number of diffusion steps to train the model.
        sigma_min (`float`, defaults to 0.002):
            Minimum noise magnitude in the sigma schedule. Defaults to 0.002 from the original implementation.
        sigma_max (`float`, defaults to 80.0):
            Maximum noise magnitude in the sigma schedule. Defaults to 80.0 from the original implementation.
        sigma_data (`float`, defaults to 0.5):
            The standard deviation of the data distribution from the EDM
            [paper](https://huggingface.co/papers/2206.00364). Defaults to 0.5 from the original implementation.
        s_noise (`float`, defaults to 1.0):
            The amount of additional noise to counteract loss of detail during sampling. A reasonable range is [1.000,
            1.011]. Defaults to 1.0 from the original implementation.
        rho (`float`, defaults to 7.0):
            The parameter for calculating the Karras sigma schedule from the EDM
            [paper](https://huggingface.co/papers/2206.00364). Defaults to 7.0 from the original implementation.
        clip_denoised (`bool`, defaults to `True`):
            Whether to clip the denoised outputs to `(-1, 1)`.
        timesteps (`list` or `np.ndarray` or `torch.Tensor`, *optional*):
            An explicit timestep schedule that can be optionally specified. The timesteps are expected to be in
            increasing order.
    r	   (   Mb`?      T@      ?      ?      @Tnum_train_timesteps	sigma_min	sigma_max
sigma_datas_noiserhoclip_denoisedreturnNc                 C   sp   || _ tdd|}| |}	| |	}
d | _t|	| _t|
| _	d| _
d| _d | _d | _| jd| _d S )Nr   r	   Fcpu)init_noise_sigmanplinspace_convert_to_karras
sigma_to_tnum_inference_stepsr   
from_numpysigmas	timestepscustom_timestepsis_scale_input_called_step_index_begin_indexto)selfr   r   r   r    r!   r"   r#   rampr-   r.   r   r   r   __init__K   s   

z'CMStochasticIterativeScheduler.__init__c                 C      | j S )z
        The index counter for current timestep. It will increase 1 after each scheduler step.

        Returns:
            `int` or `None`:
                The current step index, or `None` if not yet initialized.
        )r1   r4   r   r   r   
step_indexg      	z)CMStochasticIterativeScheduler.step_indexc                 C   r7   )z
        The index for the first timestep. It should be set from pipeline with `set_begin_index` method.

        Returns:
            `int` or `None`:
                The begin index, or `None` if not yet set.
        r2   r8   r   r   r   begin_indexr   r:   z*CMStochasticIterativeScheduler.begin_indexr   r<   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.
        Nr;   )r4   r<   r   r   r   set_begin_index~   s   
z.CMStochasticIterativeScheduler.set_begin_indexsampletimestepc                 C   sF   | j du r
| | | j| j  }||d | jjd  d  }d| _|S )av  
        Scales the consistency model input by `(sigma**2 + sigma_data**2) ** 0.5`.

        Args:
            sample (`torch.Tensor`):
                The input sample.
            timestep (`float` or `torch.Tensor`):
                The current timestep in the diffusion chain.

        Returns:
            `torch.Tensor`:
                A scaled input sample.
        Nr   r   T)r9   _init_step_indexr-   configr    r0   )r4   r>   r?   sigmar   r   r   scale_model_input   s   

z0CMStochasticIterativeScheduler.scale_model_inputr-   c                 C   s2   t |tjstj|tjd}dt|d  }|S )a>  
        Gets scaled timesteps from the Karras sigmas for input to the consistency model.

        Args:
            sigmas (`float` or `np.ndarray`):
                A single Karras sigma or an array of Karras sigmas.

        Returns:
            `np.ndarray`:
                A scaled input timestep array.
        dtypeg     @o@ggE6)
isinstancer'   ndarrayarrayfloat64log)r4   r-   r.   r   r   r   r*      s   z)CMStochasticIterativeScheduler.sigma_to_tr+   devicer.   c           	      C   s  |du r|du rt d|dur|durt d|durRtdt|D ]}|| ||d  kr3t dq#|d | jjkrFt d| jj dtj|tjd	}d
| _n:|| jjkrjt d| d| jj d| jj d|| _	| jj| j	 }t
d||  ddd  tj}d| _| jj}|ddd  }||d  }| |}| |}t|| jjggtj}t|j|d| _t|drt|j|tjd	| _n
t|j|d| _d| _d| _| jd| _dS )a  
        Sets the timesteps used for the diffusion chain (to be run before inference).

        Args:
            num_inference_steps (`int`, *optional*):
                The number of diffusion steps used when generating samples with a pre-trained model.
            device (`str` or `torch.device`, *optional*):
                The device to which the timesteps should be moved to. If `None`, the timesteps are not moved.
            timesteps (`list[int]`, *optional*):
                Custom timesteps used to support arbitrary spacing between timesteps. If `None`, then the default
                timestep spacing strategy of equal spacing between timesteps is used. If `timesteps` is passed,
                `num_inference_steps` must be `None`.
        NzEExactly one of `num_inference_steps` or `timesteps` must be supplied.z:Can only pass one of `num_inference_steps` or `timesteps`.r	   z(`timesteps` must be in descending order.r   z=`timesteps` must start before `self.config.train_timesteps`: .rD   Tz`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.F)rK   mpsr%   )
ValueErrorrangelenrA   r   r'   rH   int64r/   r+   arangeroundcopyastyper)   r*   concatenater   float32r   r,   r3   r-   str
startswithr.   r1   r2   )	r4   r+   rK   r.   i
step_ratior   r5   r-   r   r   r   set_timesteps   sP   *

z,CMStochasticIterativeScheduler.set_timestepsr5   c                 C   sH   | j j}| j j}| j j}|d|  }|d|  }||||   | }|S )a  
        Construct the noise schedule as proposed in [Elucidating the Design Space of Diffusion-Based Generative
        Models](https://huggingface.co/papers/2206.00364).

        Args:
            ramp (`np.ndarray`):
                A ramp array of values between 0 and 1 used to interpolate between sigma_min and sigma_max.

        Returns:
            `np.ndarray`:
                The Karras sigma schedule array.
        r	   )rA   r   r   r"   )r4   r5   r   r   r"   min_inv_rhomax_inv_rhor-   r   r   r   r)      s   z1CMStochasticIterativeScheduler._convert_to_karrasrB   c                 C   sD   | j j}|d |d |d   }|| |d |d  d  }||fS )a|  
        Computes the scaling factors for the consistency model output.

        Args:
            sigma (`torch.Tensor`):
                The current sigma value in the noise schedule.

        Returns:
            `tuple[torch.Tensor, torch.Tensor]`:
                A tuple containing `c_skip` (scaling for the input sample) and `c_out` (scaling for the model output).
        r   r   )rA   r    )r4   rB   r    c_skipc_outr   r   r   get_scalings  s   z+CMStochasticIterativeScheduler.get_scalingsc                 C   sT   | j j}| j j}|d || d |d   }|| | |d |d  d  }||fS )a  
        Gets the scalings used in the consistency model parameterization (from Appendix C of the
        [paper](https://huggingface.co/papers/2303.01469)) to enforce boundary condition.

        > [!TIP] > `epsilon` in the equations for `c_skip` and `c_out` is set to `sigma_min`.

        Args:
            sigma (`torch.Tensor`):
                The current sigma in the Karras sigma schedule.

        Returns:
            `tuple[torch.Tensor, torch.Tensor]`:
                A two-element tuple where `c_skip` (which weights the current sample) is the first element and `c_out`
                (which weights the consistency model output) is the second element.
        r   r   )rA   r   r    )r4   rB   r   r    r`   ra   r   r   r   #get_scalings_for_boundary_condition&  s
    zBCMStochasticIterativeScheduler.get_scalings_for_boundary_condition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.   nonzerorQ   item)r4   r?   rd   indicesposr   r   r   index_for_timestep>  s
   z1CMStochasticIterativeScheduler.index_for_timestepc                 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)
r<   rF   r   r   r3   r.   rK   ri   r1   r2   )r4   r?   r   r   r   r@   ]  s
   
z/CMStochasticIterativeScheduler._init_step_indexmodel_output	generatorreturn_dictc                 C   sN  t |ttjtjfrtd| j d| jst	d | j
j}| j
j}| jdu r-| | | j| j }| jd | j
jk rE| j| jd  }	n| jd }	| |\}
}|| |
|  }| j
jrc|dd}t| jdkrvt|j|j|j|d}nt|}|| j
j }|	j||d}|||d	 |d	  d
   }|  jd7  _|s|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.Tensor`):
                The direct output from the learned diffusion model.
            timestep (`float` or `torch.Tensor`):
                The current timestep in the diffusion chain.
            sample (`torch.Tensor`):
                A current instance of a sample created by the diffusion process.
            generator (`torch.Generator`, *optional*):
                A random number generator.
            return_dict (`bool`, defaults to `True`):
                Whether or not to return a
                [`~schedulers.scheduling_consistency_models.CMStochasticIterativeSchedulerOutput`] or `tuple`.

        Returns:
            [`~schedulers.scheduling_consistency_models.CMStochasticIterativeSchedulerOutput`] or `tuple`:
                If return_dict is `True`,
                [`~schedulers.scheduling_consistency_models.CMStochasticIterativeSchedulerOutput`] is returned,
                otherwise a tuple is returned where the first element is the sample tensor.
        zLPassing integer indices (e.g. from `enumerate(timesteps)`) as timesteps to `z\.step()` is not supported. Make sure to pass one of the `scheduler.timesteps` as a timestep.zThe `scale_model_input` function should be called before `step` to ensure correct denoising. See `StableDiffusionPipeline` for a usage example.Nr	   rM   )rE   rK   rk   )minmaxr   r   )r   )rF   intr   	IntTensor
LongTensorrO   	__class__r0   loggerwarningrA   r   r   r9   r@   r-   r   rc   r#   clamprQ   r.   r   shaperE   rK   
zeros_liker!   r1   r   )r4   rj   r?   r>   rk   rl   r   r   rB   
sigma_nextr`   ra   denoisednoisez	sigma_hatr   r   r   r   stepl  sJ    




z#CMStochasticIterativeScheduler.steporiginal_samplesrz   c                    s
  j j|j|jd}|jjdkr)t|r)jj|jtjd |j|jtjd}nj|j ||j}j	du rF fdd|D }nj
durUj
g|jd  }n	j	g|jd  }||  }t|jt|jk r}|d}t|jt|jk sn|||  }|S )	am  
        Add noise to the original samples according to the noise schedule at the specified timesteps.

        Args:
            original_samples (`torch.Tensor`):
                The original samples to which noise will be added.
            noise (`torch.Tensor`):
                The noise tensor to add to the original samples.
            timesteps (`torch.Tensor`):
                The timesteps at which to add noise, determining the noise level from the schedule.

        Returns:
            `torch.Tensor`:
                The noisy samples with added noise scaled according to the timestep schedule.
        )rK   rE   rN   rD   Nc                    s   g | ]} | qS r   )ri   ).0trd   r4   r   r   
<listcomp>  s    z<CMStochasticIterativeScheduler.add_noise.<locals>.<listcomp>r   rM   )r-   r3   rK   rE   typer   is_floating_pointr.   rX   r<   r9   rv   flattenrQ   	unsqueeze)r4   r~   rz   r.   r-   step_indicesrB   noisy_samplesr   r   r   	add_noise  s"   


z(CMStochasticIterativeScheduler.add_noisec                 C   s   | j jS )z
        Returns the number of training timesteps.

        Returns:
            `int`:
                The number of training timesteps configured for the scheduler.
        )rA   r   r8   r   r   r   __len__  s   z&CMStochasticIterativeScheduler.__len__)r   r   r   r   r   r   T)r   )NNN)N)NT)#r   r   r   r   orderr   ro   floatboolr6   propertyr9   r<   r=   r   r   rC   r'   rG   r*   rY   rK   listr]   r)   tuplerb   rc   ri   r@   	Generatorr   r}   r   r   r   r   r   r   r   +   s    	
 


J  

a
0r   )dataclassesr   numpyr'   r   configuration_utilsr   r   utilsr   r   utils.torch_utilsr   scheduling_utilsr
   
get_loggerr   rs   r   r   r   r   r   r   <module>   s   
