o
    pi;                     @   s   d dl Z d dlmZ d dl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 ddlmZ dd	lmZ eG d
d deZ		dddZG dd deeZdS )    N)	dataclass)OptionalTupleUnion   )ConfigMixinregister_to_config)
BaseOutput)randn_tensor   )SchedulerMixinc                   @   s&   e Zd ZU dZejed< ejed< dS )RePaintSchedulerOutputal  
    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_samplepred_original_sampleN)__name__
__module____qualname____doc__torchTensor__annotations__ r   r   e/home/ubuntu/SoloSpeech/.venv/lib/python3.10/site-packages/diffusers/schedulers/scheduling_repaint.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_fnH   s    z)betas_for_alpha_bar.<locals>.alpha_bar_fnexpc                 S   s   t | d S )Ng      ()r   r!   r   r   r   r   r    M   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_bar/   s   

"r1   c                   @   s"  e Zd ZdZdZe								d1d
ededededede	e
j defddZd2dejde	e dejfddZ			d3dedededeeejf fddZdd  Z			d4d!ejdedejd"ejd#ejd$e	ej d%edeeef fd&d'Zd2d(d)Zd*ejd+ejd,ejdejfd-d.Zd/d0 ZdS )5RePaintSchedulerah  
    `RePaintScheduler` is a scheduler for DDPM inpainting inside a given mask.

    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`, `scaled_linear`, `squaredcos_cap_v2`, or `sigmoid`.
        eta (`float`):
            The weight of noise for added noise in diffusion step. If its value is between 0.0 and 1.0 it corresponds
            to the DDIM scheduler, and if its value is between -0.0 and 1.0 it corresponds to the DDPM scheduler.
        trained_betas (`np.ndarray`, *optional*):
            Pass an array of betas directly to the constructor to bypass `beta_start` and `beta_end`.
        clip_sample (`bool`, defaults to `True`):
            Clip the predicted sample between -1 and 1 for numerical stability.

    r     -C6?{Gz?linear        NTnum_train_timesteps
beta_startbeta_endbeta_scheduleetatrained_betasclip_samplec           	      C   s(  |d urt || _nR|dkrt j|||t jd| _nB|dkr1t j|d |d |t jdd | _n,|dkr;t|| _n"|dkrSt dd	|}t |||  | | _n
t| d
| j d| j | _	t j
| j	dd| _t d| _t d| _d| _d | _t td|d d d  | _|| _d S )Nr6   r"   scaled_linear      ?r   squaredcos_cap_v2sigmoidi   z is not implemented for       ?r   )dim)r   
from_numpyr-   linspacer)   r1   rB   NotImplementedError	__class__alphascumprodalphas_cumprodr(   onefinal_alpha_cumprodinit_noise_sigmanum_inference_stepsnparangecopy	timestepsr<   )	selfr8   r9   r:   r;   r<   r=   r>   r-   r   r   r   __init__x   s(   $"
zRePaintScheduler.__init__sampletimestepreturnc                 C   s   |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.
        r   )rV   rX   rY   r   r   r   scale_model_input   s   z"RePaintScheduler.scale_model_input
   rQ   jump_lengthjump_n_sampledevicec           
      C   s   t | jj|}|| _g }i }td|| |D ]}|d ||< q|}|dkrR|d }|| ||ddkrN|| d ||< t|D ]}	|d }|| qB|dks%t|| jj| j  }t	
||| _dS )u  
        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. If used,
                `timesteps` must be `None`.
            jump_length (`int`, defaults to 10):
                The number of steps taken forward in time before going backward in time for a single jump (“j” in
                RePaint paper). Take a look at Figure 9 and 10 in the paper.
            jump_n_sample (`int`, defaults to 10):
                The number of times to make a forward time jump for a given chosen time sample. Take a look at Figure 9
                and 10 in the paper.
            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   N)r'   configr8   rQ   r%   r&   getrR   arrayr   rG   torU   )
rV   rQ   r]   r^   r_   rU   jumpsjr   _r   r   r   set_timesteps   s$   

zRePaintScheduler.set_timestepsc                 C   s\   || j j| j  }| j| }|dkr| j| n| j}d| }d| }|| d||   }|S )Nr   r   )r`   r8   rQ   rM   rO   )rV   r   prev_timestepalpha_prod_talpha_prod_t_prevbeta_prod_tbeta_prod_t_prevvariancer   r   r   _get_variance   s   
	zRePaintScheduler._get_variancemodel_outputoriginal_imagemask	generatorreturn_dictc                 C   s.  |}|| j j| j  }	| j| }
|	dkr| j|	 n| j}d|
 }||d |  |
d  }| j jr7t|dd}|j}t	|j
|||jd}| j| |d  }d}|dkr]| jdkr]|| }d| |d  d | }|d | | | }|d | d| d |  }|| d| |  }|s||fS t||dS )	aO  
        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 (`int`):
                The current discrete timestep in the diffusion chain.
            sample (`torch.Tensor`):
                A current instance of a sample created by the diffusion process.
            original_image (`torch.Tensor`):
                The original image to inpaint on.
            mask (`torch.Tensor`):
                The mask where a value of 0.0 indicates which part of the original image to inpaint.
            generator (`torch.Generator`, *optional*):
                A random number generator.
            return_dict (`bool`, *optional*, defaults to `True`):
                Whether or not to return a [`~schedulers.scheduling_repaint.RePaintSchedulerOutput`] or `tuple`.

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

        r   r   r@   rF   rr   r_   r#   r   rD   )r   r   )r`   r8   rQ   rM   rO   r>   r   clampr_   r
   shaper#   r<   rn   r   )rV   ro   rY   rX   rp   rq   rr   rs   r   rh   ri   rj   rk   r   r_   noise	std_dev_trm   pred_sample_directionprev_unknown_partprev_known_partpred_prev_sampler   r   r   step   s.   $

zRePaintScheduler.stepc                 C   s   | j j| j }t|D ]8}| j||  }|jjdkr*t|j|j	|d}|
|j}nt|j||j|j	d}d| d | |d |  }q|S )Nmps)r#   rr   rt   r   r@   )r`   r8   rQ   r%   r-   r_   typer
   rv   r#   rc   )rV   rX   rY   rr   nr.   betarw   r   r   r   	undo_stepO  s   zRePaintScheduler.undo_steporiginal_samplesrw   rU   c                 C   s   t d)NzCUse `DDPMScheduler.add_noise()` to train for sampling with RePaint.)rI   )rV   r   rw   rU   r   r   r   	add_noise`  s   zRePaintScheduler.add_noisec                 C   s   | j jS N)r`   r8   )rV   r   r   r   __len__h  s   zRePaintScheduler.__len__)r3   r4   r5   r6   r7   NTr   )r\   r\   N)NT)r   r   r   r   orderr   intfloatstrr   rR   ndarrayboolrW   r   r   r[   r   r_   rg   rn   	Generatorr   r   r}   r   	IntTensorr   r   r   r   r   r   r2   [   s     *
/
	

Y
r2   )r   r   )r   dataclassesr   typingr   r   r   numpyrR   r   configuration_utilsr   r   utilsr	   utils.torch_utilsr
   scheduling_utilsr   r   r1   r2   r   r   r   r   <module>   s   
,