o
    pi^                     @   s   d dl Z d dlmZmZmZmZ d dlZd dlZd dl	Z	ddl
mZmZ ddlmZmZmZ G dd dZG d	d
 d
Z		dddZG dd deeZdS )    N)ListOptionalTupleUnion   )ConfigMixinregister_to_config   )KarrasDiffusionSchedulersSchedulerMixinSchedulerOutputc                   @   s.   e Zd ZdZd	ddZedd Zdd ZdS )
BatchedBrownianTreezGA wrapper around torchsde.BrownianTree that enables batches of entropy.Nc                    s   |  \| _ dt||d u r tddg  }d| _zt||j	d ks/J d W n t
yC   |g}d| _Y nw  fdd|D | _d S )Nw0r   l    TFc                    s&   g | ]}t jfd |i qS )entropy)torchsdeBrownianTree).0skwargst0t1r    k/home/ubuntu/SoloSpeech/.venv/lib/python3.10/site-packages/diffusers/schedulers/scheduling_dpmsolver_sde.py
<listcomp>)   s   & z0BatchedBrownianTree.__init__.<locals>.<listcomp>)sortsigngettorch
zeros_likerandintitembatchedlenshape	TypeErrortrees)selfxr   r   seedr   r   r   r   __init__   s   
zBatchedBrownianTree.__init__c                 C   s   | |k r	| |dfS || dfS )Nr	   r   )abr   r   r   r   +   s   zBatchedBrownianTree.sortc                    sJ   |   \ }t fdd| jD | j|  }| jr!|S |d S )Nc                    s   g | ]}| qS r   r   )r   treer   r   r   r   r   1   s    z0BatchedBrownianTree.__call__.<locals>.<listcomp>r   )r   r   stackr&   r   r"   )r'   r   r   r   wr   r/   r   __call__/   s   &zBatchedBrownianTree.__call__N)__name__
__module____qualname____doc__r*   staticmethodr   r2   r   r   r   r   r      s    

r   c                   @   s*   e Zd ZdZddd fddZdd ZdS )	BrownianTreeNoiseSampleras  A noise sampler backed by a torchsde.BrownianTree.

    Args:
        x (Tensor): The tensor whose shape, device and dtype to use to generate
            random samples.
        sigma_min (float): The low end of the valid interval.
        sigma_max (float): The high end of the valid interval.
        seed (int or List[int]): The random seed. If a list of seeds is
            supplied instead of a single integer, then the noise sampler will use one BrownianTree per batch item, each
            with its own seed.
        transform (callable): A function that maps sigma to the sampler's
            internal timestep.
    Nc                 C   s   | S r3   r   )r(   r   r   r   <lambda>D   s    z!BrownianTreeNoiseSampler.<lambda>c                 C   s<   || _ |  t||  t|}}t||||| _d S r3   )	transformr   	as_tensorr   r.   )r'   r(   	sigma_min	sigma_maxr)   r;   r   r   r   r   r   r*   D   s   "z!BrownianTreeNoiseSampler.__init__c                 C   s>   |  t||  t|}}| ||||    S r3   )r;   r   r<   r.   abssqrt)r'   sigma
sigma_nextr   r   r   r   r   r2   I   s   "z!BrownianTreeNoiseSampler.__call__)r4   r5   r6   r7   r*   r2   r   r   r   r   r9   5   s    r9   +?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
    rD   c                 S   s    t | d d t j d d S )NgMb?gT㥛 ?r   )mathcospitr   r   r   alpha_bar_fnh   s    z)betas_for_alpha_bar.<locals>.alpha_bar_fnexpc                 S   s   t | d S )Ng      ()rE   rK   rH   r   r   r   rJ   m   s   z"Unsupported alpha_transform_type: r	   dtype)
ValueErrorrangeappendminr   tensorfloat32)num_diffusion_timestepsmax_betaalpha_transform_typerJ   betasir   t2r   r   r   betas_for_alpha_barO   s   

"rZ   c                   @   s  e Zd ZdZdd eD ZdZe							
					dGdede	de	de
deeejee	 f  de
dee dee de
defddZdHddZdd Zedd Zed d! Zed"d# ZdId$efd%d&Zd'ejd(ee	ejf d)ejfd*d+Z				dJd,ed-ee
ejf dee fd.d/Zd0d1 Zd2d3 Zd4ejd)ejfd5d6Z ed7d8 Z!	9	:dKd;eejejf d(ee	ejf d'eejejf d<ed=e	d)ee"e#f fd>d?Z$d@ejdAejdBejd)ejfdCdDZ%dEdF Z&d	S )LDPMSolverSDEScheduleru  
    DPMSolverSDEScheduler implements the stochastic sampler from the [Elucidating the Design Space of Diffusion-Based
    Generative Models](https://huggingface.co/papers/2206.00364) paper.

    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.00085):
            The starting `beta` value of inference.
        beta_end (`float`, defaults to 0.012):
            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`.
        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).
        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}.
        noise_sampler_seed (`int`, *optional*, defaults to `None`):
            The random seed to use for the noise sampler. If `None`, a random seed is generated.
        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)r   er   r   r   r      s    z DPMSolverSDEScheduler.<listcomp>r     _QK?~jt?linearNepsilonFlinspacer   num_train_timesteps
beta_startbeta_endbeta_scheduletrained_betasprediction_typeuse_karras_sigmasnoise_sampler_seedtimestep_spacingsteps_offsetc                 C   s   |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
| _
| |d | || _d | _|| _d | _d | _| jd| _d S )NrL   ra   scaled_linear      ?r   squaredcos_cap_v2z is not implemented for       ?r   )dimcpu)r   rR   rS   rW   rc   rZ   NotImplementedError	__class__alphascumprodalphas_cumprodset_timestepsrj   noise_samplerrk   _step_index_begin_indexsigmasto)r'   rd   re   rf   rg   rh   ri   rj   rk   rl   rm   r   r   r   r*      s$   $zDPMSolverSDEScheduler.__init__c                 C   s:   |d u r| j }||k }t|dkrdnd}||  S )Nr	   r   )	timestepsnonzeror#   r!   )r'   timestepschedule_timestepsindicesposr   r   r   index_for_timestep   s
   z(DPMSolverSDEScheduler.index_for_timestepc                 C   s@   | j d u rt|tjr|| jj}| || _d S | j	| _d S r3   )
begin_index
isinstancer   Tensorr~   r   devicer   r{   r|   )r'   r   r   r   r   _init_step_index   s
   
z&DPMSolverSDEScheduler._init_step_indexc                 C   s,   | j jdv r| j S | j d d d S )N)rc   trailingr   r	   ro   )configrl   r}   maxr'   r   r   r   init_noise_sigma   s   
z&DPMSolverSDEScheduler.init_noise_sigmac                 C      | j S )zg
        The index counter for current timestep. It will increase 1 after each scheduler step.
        )r{   r   r   r   r   
step_index      z DPMSolverSDEScheduler.step_indexc                 C   r   )zq
        The index for the first timestep. It should be set from pipeline with `set_begin_index` method.
        r|   r   r   r   r   r      r   z!DPMSolverSDEScheduler.begin_indexr   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   )r'   r   r   r   r   set_begin_index   s   
z%DPMSolverSDEScheduler.set_begin_indexsampler   returnc                 C   sH   | j du r
| | | j| j  }| jr|n| j}||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 (`int`, *optional*):
                The current timestep in the diffusion chain.

        Returns:
            `torch.Tensor`:
                A scaled input sample.
        Nr   r	   ro   )r   r   r}   state_in_first_ordermid_point_sigma)r'   r   r   rA   sigma_inputr   r   r   scale_model_input  s   

z'DPMSolverSDEScheduler.scale_model_inputnum_inference_stepsr   c                    sZ  |_ |pjj}jjdkr"tjd|d |tdddd  }nNjjdkrH|j  }td|| 	 ddd  
t}|jj7 }n(jjdkrg|j  }t|d| 	  
t}|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|dd |dd d|dd g_t|}t|}t|dd |dd dg}||ddd< t|dr|j|tjd_n|j|d_d_ d_!d_"d_#j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.
            device (`str` or `torch.device`, *optional*):
                The device to which the timesteps should be moved to. If `None`, the timesteps are not moved.
        rc   r   r	   rL   Nr+   leadingr   zY is not supported. Please make sure to choose one of 'linspace', 'leading' or 'trailing'.ro   )	in_sigmasc                       g | ]} | qS r   _sigma_to_tr   rA   
log_sigmasr'   r   r   r   J      z7DPMSolverSDEScheduler.set_timesteps.<locals>.<listcomp>g        )r   r   mpsrs   )%r   r   rd   rl   nprc   floatcopyarangeroundastyperm   rN   arrayrx   loginterpr#   rj   _convert_to_karras_second_order_timestepsconcatenaterS   r   
from_numpyr~   catrepeat_interleaver}   str
startswithr   r   r   r{   r|   rz   )r'   r   r   rd   r   
step_ratior}   second_order_timestepsr   r   r   ry     sL   &
(


0

$
z#DPMSolverSDEScheduler.set_timestepsc                    s`   dd }dd }d}||}t |}|d d ||  }||}	t  fdd|	D }
|
S )	Nc                 S   s   t |  S r3   )r   rK   _tr   r   r   sigma_fng     z?DPMSolverSDEScheduler._second_order_timesteps.<locals>.sigma_fnc                 S   s   t |  S r3   )r   r   _sigmar   r   r   t_fnj  r   z;DPMSolverSDEScheduler._second_order_timesteps.<locals>.t_fnro   r+   c                    r   r   r   r   r   r   r   r   r  r   zADPMSolverSDEScheduler._second_order_timesteps.<locals>.<listcomp>)r   diffr   )r'   r}   r   r   r   midpoint_ratiorI   
delta_time
t_proposedsig_proposedr   r   r   r   r   f  s   
z-DPMSolverSDEScheduler._second_order_timestepsc                 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   )r   r	   )	r   r   maximumnewaxiscumsumargmaxclipr$   reshape)r'   rA   r   	log_sigmadistslow_idxhigh_idxlowhighr1   rI   r   r   r   r   v  s   ,z!DPMSolverSDEScheduler._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).r+   r   g      @r	   )r!   r   rc   r   )	r'   r   r=   r>   rhorampmin_inv_rhomax_inv_rhor}   r   r   r   r     s   z(DPMSolverSDEScheduler._convert_to_karrasc                 C   s
   | j d u S r3   )r   r   r   r   r   r     s   
z*DPMSolverSDEScheduler.state_in_first_orderTrq   model_outputreturn_dicts_noisec                 C   s  | j du r
| | | jdu r(| j| jdk  | j }}t|||| j| _dtj	dtj	fdd}dtj	dtj	fdd	}	| j
rP| j| j  }
| j| j d
  }n| j| j d
  }
| j| j  }d}|	|
|	|}}|| }|||  }| jjdkr| j
r~|
n||}|||  }n9| jjdkr| j
r|
n||}|| |d d
 d   ||d d
   }n| jjdkrtdtd| jj d|dkr|| |
 }||
 }|||  }ni| j
r|}n| j}||}||}t||d |d |d   |d  d }|d |d  d }|	|}|||| | ||  |  }|| ||||| |  }| j
r:|| _||| _nd| _d| _|  jd
7  _|sM|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` or `np.ndarray`):
                The direct output from learned diffusion model.
            timestep (`float` or `torch.Tensor`):
                The current discrete timestep in the diffusion chain.
            sample (`torch.Tensor` or `np.ndarray`):
                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_utils.SchedulerOutput`] or tuple.
            s_noise (`float`, *optional*, defaults to 1.0):
                Scaling factor for noise added to the sample.

        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.
        Nr   r   r   c                 S      |    S r3   )negrK   r   r   r   r   r     r   z,DPMSolverSDEScheduler.step.<locals>.sigma_fnr   c                 S   r   r3   )r   r   r   r   r   r   r     r   z(DPMSolverSDEScheduler.step.<locals>.t_fnr	   ro   rb   v_predictionr   r   z+prediction_type not implemented yet: samplezprediction_type given as z, must be one of `epsilon`, or `v_prediction`)prev_sample)r   r   rz   r}   rQ   r   r9   rk   r   r   r   r   ri   rt   rN   r   expm1r   r{   r   )r'   r   r   r   r   r   	min_sigma	max_sigmar   r   rA   rB   r   rI   t_nextr   r   r   pred_original_sample
derivativedtr   
sigma_fromsigma_tosigma_up
sigma_downancestral_tr   r   r   step  sn   


 * 
zDPMSolverSDEScheduler.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   rM   r   rL   c                    r   r   )r   )r   rI   r   r'   r   r   r   !  r   z3DPMSolverSDEScheduler.add_noise.<locals>.<listcomp>r   r+   )r}   r~   r   rM   typer   is_floating_pointr   rS   r   r   r$   flattenr#   	unsqueeze)r'   r   r   r   r}   step_indicesrA   noisy_samplesr   r   r   	add_noise  s"   


zDPMSolverSDEScheduler.add_noisec                 C   s   | j jS r3   )r   rd   r   r   r   r   __len__0  s   zDPMSolverSDEScheduler.__len__)
r^   r_   r`   ra   Nrb   FNrc   r   r3   )r   )NN)Trq   )'r4   r5   r6   r7   r
   _compatiblesorderr   intr   r   r   r   r   ndarrayr   boolr*   r   r   propertyr   r   r   r   r   r   r   r   ry   r   r   r   r   r   r   r   r   r   r   r   r   r   r[   {   s    #	

'





I


p
!r[   )rC   rD   )rE   typingr   r   r   r   numpyr   r   r   configuration_utilsr   r   scheduling_utilsr
   r   r   r   r9   rZ   r[   r   r   r   r   <module>   s   
,