o
    pi#I                     @   s   d dl mZ d dlmZmZmZ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 )    )	dataclass)ListOptionalTupleUnionN   )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   p/home/ubuntu/SoloSpeech/.venv/lib/python3.10/site-packages/diffusers/schedulers/scheduling_consistency_models.pyr      s   
 	r   c                   @   s~  e Zd ZdZdZe								d>d
ededede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ejdeeejf dejfddZd eeejf fd!d"Z	#	#	#d@d$ee d%eeejf d&eee  fd'd(Zd)d* Zd+d, Zd-d. ZdAd/d0Zd1d2 Z	#		dBd3ejdeeejf dejd4eej d5edee e!f fd6d7Z"d8ejd9ejd&ejdejfd:d;Z#d<d= Z$d#S )C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_denoisedc                 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'   rampr0   r1   r   r   r   __init__L   s   

z'CMStochasticIterativeScheduler.__init__c                 C      | j S )zg
        The index counter for current timestep. It will increase 1 after each scheduler step.
        )r4   r7   r   r   r   
step_indexh      z)CMStochasticIterativeScheduler.step_indexc                 C   r:   )zq
        The index for the first timestep. It should be set from pipeline with `set_begin_index` method.
        r5   r;   r   r   r   begin_indexo   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`):
                The begin index for the scheduler.
        Nr>   )r7   r?   r   r   r   set_begin_indexw   s   
z.CMStochasticIterativeScheduler.set_begin_indexsampletimestepreturnc                 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)r<   _init_step_indexr0   configr$   r3   )r7   rA   rB   sigmar   r   r   scale_model_input   s   

z0CMStochasticIterativeScheduler.scale_model_inputr0   c                 C   s2   t |tjstj|tjd}dt|d  }|S )ab  
        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:
            `float` or `np.ndarray`:
                A scaled input timestep or scaled input timestep array.
        dtypeg     @o@ggE6)
isinstancer*   ndarrayarrayfloat64log)r7   r0   r1   r   r   r   r-      s   z)CMStochasticIterativeScheduler.sigma_to_tNr.   devicer1   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`):
                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`: .rH   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)rO   mpsr(   )
ValueErrorrangelenrE   r!   r*   rL   int64r2   r.   arangeroundcopyastyper,   r-   concatenater"   float32r   r/   r6   r0   str
startswithr1   r4   r5   )	r7   r.   rO   r1   i
step_ratior!   r8   r0   r   r   r   set_timesteps   sT   *

z,CMStochasticIterativeScheduler.set_timestepsc                 C   sH   | j j}| j j}| j j}|d|  }|d|  }||||   | }|S )z6Constructs the noise schedule of Karras et al. (2022).r   )rE   r"   r#   r&   )r7   r8   r"   r#   r&   min_inv_rhomax_inv_rhor0   r   r   r   r,      s   z1CMStochasticIterativeScheduler._convert_to_karrasc                 C   sD   | j j}|d |d |d   }|| |d |d  d  }||fS )Nr   r   )rE   r$   )r7   rF   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`.

        </Tip>

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

        Returns:
            `tuple`:
                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   )rE   r"   r$   )r7   rF   r"   r$   rd   re   r   r   r   #get_scalings_for_boundary_condition  s
    zBCMStochasticIterativeScheduler.get_scalings_for_boundary_conditionc                 C   s:   |d u r| j }||k }t|dkrdnd}||  S )Nr   r   )r1   nonzerorU   item)r7   rB   schedule_timesteps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 N)
r?   rJ   r   r   r6   r1   rO   rm   r4   r5   )r7   rB   r   r   r   rD   6  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`):
                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`, *optional*, 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   rQ   )rI   rO   rp   )minmaxr   r   )r   )rJ   intr   	IntTensor
LongTensorrS   	__class__r3   loggerwarningrE   r"   r#   r<   rD   r0   r!   rg   r'   clamprU   r1   r   shaperI   rO   
zeros_liker%   r4   r   )r7   ro   rB   rA   rp   rq   r"   r#   rF   
sigma_nextrd   re   denoisednoisez	sigma_hatr   r   r   r   step>  sD    




z#CMStochasticIterativeScheduler.steporiginal_samplesr   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 )N)rO   rI   rR   rH   c                    s   g | ]} | qS r   )rm   ).0trj   r7   r   r   
<listcomp>  s    z<CMStochasticIterativeScheduler.add_noise.<locals>.<listcomp>r   rQ   )r0   r6   rO   rI   typer   is_floating_pointr1   r\   r?   r<   r{   flattenrU   	unsqueeze)r7   r   r   r1   r0   step_indicesrF   noisy_samplesr   r   r   	add_noise  s"   


z(CMStochasticIterativeScheduler.add_noisec                 C   s   | j jS rn   )rE   r!   r;   r   r   r   __len__  s   z&CMStochasticIterativeScheduler.__len__)r   r   r   r   r   r    T)r   )NNNrn   )NT)%r   r   r   r   orderr	   rt   floatboolr9   propertyr<   r?   r@   r   r   r   rG   r*   rK   r-   r   r]   rO   r   ra   r,   rf   rg   rm   rD   	Generatorr   r   r   r   r   r   r   r   r   r   ,   s    

$


K


^
!r   )dataclassesr   typingr   r   r   r   numpyr*   r   configuration_utilsr   r	   utilsr
   r   utils.torch_utilsr   scheduling_utilsr   
get_loggerr   rx   r   r   r   r   r   r   <module>   s   
