o
    piP                     @   s   d dl Z d dlZ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 ddlmZmZ ddlmZ dd	lmZmZ eG d
d deZ		dddZG dd deeZdS )    N)	dataclass)ListOptionalTupleUnion)	integrate   )ConfigMixinregister_to_config)
BaseOutput   )KarrasDiffusionSchedulersSchedulerMixinc                   @   s.   e Zd ZU dZejed< dZeej ed< dS )LMSDiscreteSchedulerOutputaq  
    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   r   j/home/ubuntu/SoloSpeech/.venv/lib/python3.10/site-packages/diffusers/schedulers/scheduling_lms_discrete.pyr      s   
 
r   +?cosinec                 C   s   |dkr	dd }n|dkrdd }nt d| g }t| D ]}||  }|d |  }|td||||  | qtj|tjdS )	a  
    Create a beta schedule that discretizes the given alpha_t_bar function, which defines the cumulative product of
    (1-beta) over time from t = [0,1].

    Contains a function alpha_bar that takes an argument t and transforms it to the cumulative product of (1-beta) up
    to that part of the diffusion process.


    Args:
        num_diffusion_timesteps (`int`): the number of betas to produce.
        max_beta (`float`): the maximum beta to use; use values lower than 1 to
                     prevent singularities.
        alpha_transform_type (`str`, *optional*, default to `cosine`): the type of noise schedule for alpha_bar.
                     Choose from `cosine` or `exp`

    Returns:
        betas (`np.ndarray`): the betas used by the scheduler to step the model outputs
    r   c                 S   s    t | d d t j d d S )NgMb?gT㥛 ?r   )mathcospitr   r   r   alpha_bar_fnI   s    z)betas_for_alpha_bar.<locals>.alpha_bar_fnexpc                 S   s   t | d S )Ng      ()r   r#   r    r   r   r   r"   N   s   z"Unsupported alpha_transform_type: r   dtype)
ValueErrorrangeappendminr   tensorfloat32)num_diffusion_timestepsmax_betaalpha_transform_typer"   betasit1t2r   r   r   betas_for_alpha_bar0   s   

"r3   c                   @   s  e Zd ZdZdd eD ZdZe							
			dDdede	de	de
deeejee	 f  dee de
de
defddZedd Zedd Zedd ZdEdefd d!Zd"ejd#ee	ejf d$ejfd%d&Zd'd( ZdFd)ed*ee
ejf fd+d,ZdFd-d.Zd/d0 Zd1d2 Zd3ejd$ejfd4d5Z 	6	7dGd8ejd#ee	ejf d"ejd9ed:ed$ee!e"f fd;d<Z#d=ejd>ejd?ejd$ejfd@dAZ$dBdC Z%d	S )HLMSDiscreteScheduleru  
    A linear multistep scheduler for discrete beta schedules.

    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.
        beta_start (`float`, defaults to 0.0001):
            The starting `beta` value of inference.
        beta_end (`float`, defaults to 0.02):
            The final `beta` value.
        beta_schedule (`str`, defaults to `"linear"`):
            The beta schedule, a mapping from a beta range to a sequence of betas for stepping the model. Choose from
            `linear` or `scaled_linear`.
        trained_betas (`np.ndarray`, *optional*):
            Pass an array of betas directly to the constructor to bypass `beta_start` and `beta_end`.
        use_karras_sigmas (`bool`, *optional*, defaults to `False`):
            Whether to use Karras sigmas for step sizes in the noise schedule during the sampling process. If `True`,
            the sigmas are determined according to a sequence of noise levels {σi}.
        prediction_type (`str`, defaults to `epsilon`, *optional*):
            Prediction type of the scheduler function; can be `epsilon` (predicts the noise of the diffusion process),
            `sample` (directly predicts the noisy sample`) or `v_prediction` (see section 2.4 of [Imagen
            Video](https://imagen.research.google/video/paper.pdf) paper).
        timestep_spacing (`str`, defaults to `"linspace"`):
            The way the timesteps should be scaled. Refer to Table 2 of the [Common Diffusion Noise Schedules and
            Sample Steps are Flawed](https://huggingface.co/papers/2305.08891) for more information.
        steps_offset (`int`, defaults to 0):
            An offset added to the inference steps, as required by some model families.
    c                 C   s   g | ]}|j qS r   )name).0er   r   r   
<listcomp>}   s    zLMSDiscreteScheduler.<listcomp>r     -C6?{Gz?linearNFepsilonlinspacer   num_train_timesteps
beta_startbeta_endbeta_scheduletrained_betasuse_karras_sigmasprediction_typetimestep_spacingsteps_offsetc
                 C   s8  |d urt j|t jd| _n:|dkrt j|||t jd| _n*|dkr4t j|d |d |t jdd | _n|dkr>t|| _n
t| d| j d| j | _t j	| jd	d
| _
td| j
 | j
 d }
t|
d d d dggtj}
t |
| _d | _|| _| |d  g | _d| _d | _d | _| jd| _d S )Nr$   r<   scaled_linear      ?r   squaredcos_cap_v2z is not implemented for       ?r   )dimr           Fcpu)r   r*   r+   r/   r>   r3   NotImplementedError	__class__alphascumprodalphas_cumprodnparrayconcatenateastype
from_numpysigmasnum_inference_stepsrD   set_timestepsderivativesis_scale_input_called_step_index_begin_indexto)selfr?   r@   rA   rB   rC   rD   rE   rF   rG   rZ   r   r   r   __init__   s,   $"zLMSDiscreteScheduler.__init__c                 C   s,   | j jdv r| j S | j d d d S )N)r>   trailingr   r   rI   )configrF   rZ   maxrb   r   r   r   init_noise_sigma   s   
z%LMSDiscreteScheduler.init_noise_sigmac                 C      | j S )zg
        The index counter for current timestep. It will increase 1 after each scheduler step.
        )r_   rg   r   r   r   
step_index      zLMSDiscreteScheduler.step_indexc                 C   ri   )zq
        The index for the first timestep. It should be set from pipeline with `set_begin_index` method.
        r`   rg   r   r   r   begin_index   rk   z LMSDiscreteScheduler.begin_indexrm   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.
        Nrl   )rb   rm   r   r   r   set_begin_index   s   
z$LMSDiscreteScheduler.set_begin_indexsampletimestepreturnc                 C   s>   | j du r
| | | j| j  }||d d d  }d| _|S )a  
        Ensures interchangeability with schedulers that need to scale the denoising model input depending on the
        current timestep.

        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   rI   T)rj   _init_step_indexrZ   r^   )rb   ro   rp   sigmar   r   r   scale_model_input   s   

z&LMSDiscreteScheduler.scale_model_inputc                    s<    fdd}t j|j jd  ddd }|S )z
        Compute the linear multistep coefficient.

        Args:
            order ():
            t ():
            current_order ():
        c                    sR   d}t D ] } |krq|| j|   j   j|    9 }q|S )NrK   )r'   rZ   )tauprodkcurrent_orderorderrb   r!   r   r   lms_derivative   s   4z@LMSDiscreteScheduler.get_lms_coefficient.<locals>.lms_derivativer   r:   )epsrelr   )r   quadrZ   )rb   rz   r!   ry   r{   integrated_coeffr   rx   r   get_lms_coefficient   s   
&z(LMSDiscreteScheduler.get_lms_coefficientr[   devicec                    s  |_ jjdkrtjdjjd |tjdddd  }nVjjdkrHjjj  }td|| 	 ddd  
tj}|jj7 }n-jjdkrljjj  }tjjd| 	  
tj}|d8 }n	tjj d	tdj j d
 }t| t|tdt||}jjrj|d}t fdd|D }t|dgg
tj}t|j|d_t|j|d_d_d_jd_g _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.
            device (`str` or `torch.device`, *optional*):
                The device to which the timesteps should be moved to. If `None`, the timesteps are not moved.
        r>   r   r   r$   NrM   leadingrd   zY is not supported. Please make sure to choose one of 'linspace', 'leading' or 'trailing'.rI   )	in_sigmasc                       g | ]} | qS r   )_sigma_to_t)r6   rs   
log_sigmasrb   r   r   r8   #      z6LMSDiscreteScheduler.set_timesteps.<locals>.<listcomp>rN   )r   rO   )r[   re   rF   rU   r>   r?   r+   copyarangeroundrX   rG   r&   rV   rT   loginterplenrD   _convert_to_karrasrW   r   rY   ra   rZ   	timestepsr_   r`   r]   )rb   r[   r   r   
step_ratiorZ   r   r   r   r\      s>   
*$


z"LMSDiscreteScheduler.set_timestepsc                 C   s:   |d u r| j }||k }t|dkrdnd}||  S )Nr   r   )r   nonzeror   item)rb   rp   schedule_timestepsindicesposr   r   r   index_for_timestep0  s
   z'LMSDiscreteScheduler.index_for_timestepc                 C   s@   | j d u rt|tjr|| jj}| || _d S | j	| _d S N)
rm   
isinstancer   r   ra   r   r   r   r_   r`   )rb   rp   r   r   r   rr   ?  s
   
z%LMSDiscreteScheduler._init_step_indexc                 C   s   t t |d}||d d t jf  }t j|dkddjddj|jd d d}|d }|| }|| }|| ||  }	t |	dd}	d|	 | |	|  }
|
|j}
|
S )Ng|=r   )axisr   )rf   r   )	rU   r   maximumnewaxiscumsumargmaxclipshapereshape)rb   rs   r   	log_sigmadistslow_idxhigh_idxlowhighwr!   r   r   r   r   H  s   ,z LMSDiscreteScheduler._sigma_to_tr   c           	      C   s\   |d   }|d   }d}tdd| j}|d|  }|d|  }||||   | }|S )z6Constructs the noise schedule of Karras et al. (2022).rM   r   g      @r   )r   rU   r>   r[   )	rb   r   	sigma_min	sigma_maxrhorampmin_inv_rhomax_inv_rhorZ   r   r   r   r   `  s   z'LMSDiscreteScheduler._convert_to_karras   Tmodel_outputrz   return_dictc                    sH  j std jdu r| jj }jjdkr%|||  }n/jjdkrA|| |d d d   ||d d   }njjdkrJ|}n
td	jj d
|| | }j	
| tj	 krmj	d tjd    fddt D }	|tdd t|	tj	D  }
 jd7  _|s|
fS t|
|dS )aa  
        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 learned diffusion model.
            timestep (`float` or `torch.Tensor`):
                The current discrete timestep in the diffusion chain.
            sample (`torch.Tensor`):
                A current instance of a sample created by the diffusion process.
            order (`int`, defaults to 4):
                The order of the linear multistep method.
            return_dict (`bool`, *optional*, defaults to `True`):
                Whether or not to return a [`~schedulers.scheduling_utils.SchedulerOutput`] or tuple.

        Returns:
            [`~schedulers.scheduling_utils.SchedulerOutput`] or `tuple`:
                If return_dict is `True`, [`~schedulers.scheduling_utils.SchedulerOutput`] is returned, otherwise a
                tuple is returned where the first element is the sample tensor.

        zThe `scale_model_input` function should be called before `step` to ensure correct denoising. See `StableDiffusionPipeline` for a usage example.Nr=   v_predictionr   r   rI   ro   zprediction_type given as z, must be one of `epsilon`, or `v_prediction`r   c                    s   g | ]
}  j|qS r   )r   rj   )r6   
curr_orderrz   rb   r   r   r8     s    z-LMSDiscreteScheduler.step.<locals>.<listcomp>c                 s   s    | ]	\}}|| V  qd S r   r   )r6   coeff
derivativer   r   r   	<genexpr>  s    
z,LMSDiscreteScheduler.step.<locals>.<genexpr>)r   r   )r^   warningswarnrj   rr   rZ   re   rE   r&   r]   r(   r   popr)   r'   sumzipreversedr_   r   )rb   r   rp   ro   rz   r   rs   r   r   
lms_coeffsr   r   r   r   stepm  s:   

,

zLMSDiscreteScheduler.steporiginal_samplesnoiser   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)r   r%   mpsr$   c                    r   r   )r   )r6   r!   r   rb   r   r   r8     r   z2LMSDiscreteScheduler.add_noise.<locals>.<listcomp>r   rM   )rZ   ra   r   r%   typer   is_floating_pointr   r+   rm   rj   r   flattenr   	unsqueeze)rb   r   r   r   rZ   step_indicesrs   noisy_samplesr   r   r   	add_noise  s"   


zLMSDiscreteScheduler.add_noisec                 C   s   | j jS r   )re   r?   rg   r   r   r   __len__  s   zLMSDiscreteScheduler.__len__)	r9   r:   r;   r<   NFr=   r>   r   )r   r   )r   T)&r   r   r   r   r   _compatiblesrz   r
   intfloatstrr   r   rU   ndarrayr   boolrc   propertyrh   rj   rm   rn   r   r   rt   r   r   r\   r   rr   r   r   r   r   r   r   r   r   r   r   r   r4   \   s     	
+


$

5	

N
!r4   )r   r   )r   r   dataclassesr   typingr   r   r   r   numpyrU   r   scipyr   configuration_utilsr	   r
   utilsr   scheduling_utilsr   r   r   r3   r4   r   r   r   r   <module>   s    
,