o
    pi0                     @   s   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
 ddlmZmZ ddlmZmZmZmZmZmZ ejjG dd	 d	ZeG d
d deZG dd deeZdS )    )	dataclass)OptionalTupleUnionN   )ConfigMixinregister_to_config   )CommonSchedulerStateFlaxKarrasDiffusionSchedulersFlaxSchedulerMixinFlaxSchedulerOutputadd_noise_commonget_velocity_commonc                   @   sX   e Zd ZU eed< ejed< ejed< dZee	 ed< e
dedejdejfddZdS )DDPMSchedulerStatecommoninit_noise_sigma	timestepsNnum_inference_stepsc                 C   s   | |||dS )Nr   r   r    )clsr   r   r   r   r   g/home/ubuntu/SoloSpeech/.venv/lib/python3.10/site-packages/diffusers/schedulers/scheduling_ddpm_flax.pycreate,   s   zDDPMSchedulerState.create)__name__
__module____qualname__r
   __annotations__jnpndarrayr   r   intclassmethodr   r   r   r   r   r   #   s   
 

 r   c                   @   s   e Zd ZU eed< dS )FlaxDDPMSchedulerOutputstateN)r   r   r   r   r   r   r   r   r   r"   1   s   
 r"   c                   @   s  e Zd ZU dZdd eD Zejed< e	dd Z
eddd	d
ddddejf	dededededeej dedededejfddZd7dee defddZ	d7dedejdee dejfd d!Z	"d8ded#ed$edefd%d&Zd9defd'd(Z		d:ded)ejdedejd*eej d+edeeef fd,d-Zded.ejd/ejd0ejdejf
d1d2Z dedejd/ejd0ejdejf
d3d4Z!d5d6 Z"dS );FlaxDDPMSchedulera  
    Denoising diffusion probabilistic models (DDPMs) explores the connections between denoising score matching and
    Langevin dynamics sampling.

    [`~ConfigMixin`] takes care of storing all config attributes that are passed in the scheduler's `__init__`
    function, such as `num_train_timesteps`. They can be accessed via `scheduler.config.num_train_timesteps`.
    [`SchedulerMixin`] provides general loading and saving functionality via the [`SchedulerMixin.save_pretrained`] and
    [`~SchedulerMixin.from_pretrained`] functions.

    For more details, see the original paper: https://arxiv.org/abs/2006.11239

    Args:
        num_train_timesteps (`int`): number of diffusion steps used to train the model.
        beta_start (`float`): the starting `beta` value of inference.
        beta_end (`float`): the final `beta` value.
        beta_schedule (`str`):
            the beta schedule, a mapping from a beta range to a sequence of betas for stepping the model. Choose from
            `linear`, `scaled_linear`, or `squaredcos_cap_v2`.
        trained_betas (`np.ndarray`, optional):
            option to pass an array of betas directly to the constructor to bypass `beta_start`, `beta_end` etc.
        variance_type (`str`):
            options to clip the variance used when adding noise to the denoised sample. Choose from `fixed_small`,
            `fixed_small_log`, `fixed_large`, `fixed_large_log`, `learned` or `learned_range`.
        clip_sample (`bool`, default `True`):
            option to clip predicted sample between -1 and 1 for numerical stability.
        prediction_type (`str`, default `epsilon`):
            indicates whether the model predicts the noise (epsilon), or the samples. One of `epsilon`, `sample`.
            `v-prediction` is not supported for this scheduler.
        dtype (`jnp.dtype`, *optional*, defaults to `jnp.float32`):
            the `dtype` used for params and computation.
    c                 C   s   g | ]}|j qS r   )name).0er   r   r   
<listcomp>W   s    zFlaxDDPMScheduler.<listcomp>dtypec                 C   s   dS NTr   selfr   r   r   	has_state[   s   zFlaxDDPMScheduler.has_statei  g-C6?g{Gz?linearNfixed_smallTepsilonnum_train_timesteps
beta_startbeta_endbeta_scheduletrained_betasvariance_typeclip_sampleprediction_typec
           
      C   s
   |	| _ d S Nr)   )
r,   r1   r2   r3   r4   r5   r6   r7   r8   r)   r   r   r   __init___   s   
zFlaxDDPMScheduler.__init__r   returnc                 C   sP   |d u r	t | }tjd| jd}td| jj d d d }t	j|||dS )N      ?r:   r   r   )
r
   r   r   arrayr)   arangeconfigr1   roundr   )r,   r   r   r   r   r   r   create_staten   s   
zFlaxDDPMScheduler.create_stater#   sampletimestepc                 C   s   |S )a  
        Args:
            state (`PNDMSchedulerState`): the `FlaxPNDMScheduler` state data class instance.
            sample (`jnp.ndarray`): input sample
            timestep (`int`, optional): current timestep

        Returns:
            `jnp.ndarray`: scaled input sample
        r   )r,   r#   rD   rE   r   r   r   scale_model_input}   s   z#FlaxDDPMScheduler.scale_model_inputr   r   shapec                 C   s8   | j j| }td||  ddd }|j||dS )a  
        Sets the discrete timesteps used for the diffusion chain. Supporting function to be run before inference.

        Args:
            state (`DDIMSchedulerState`):
                the `FlaxDDPMScheduler` state data class instance.
            num_inference_steps (`int`):
                the number of diffusion steps used when generating samples with a pre-trained model.
        r   Nr>   )r   r   )rA   r1   r   r@   rB   replace)r,   r#   r   rG   
step_ratior   r   r   r   set_timesteps   s   zFlaxDDPMScheduler.set_timestepsc                 C   s  |j j| }t|dk|j j|d  tjd| jd}d| d|  |j j|  }|d u r1| jj}|dkr>tj	|dd}|S |dkrNt
tj	|dd}|S |d	krZ|j j| }|S |d
krit
|j j| }|S |dkro|S |dkr|}|j j| }	|d d }
|
|	 d|
 |  }|S )Nr   r	   r=   r:   r/   g#B;)a_minfixed_small_logfixed_largefixed_large_loglearnedlearned_ranger   )r   alphas_cumprodr   wherer?   r)   betasrA   r6   cliplog)r,   r#   tpredicted_variancer6   alpha_prod_talpha_prod_t_prevvariancemin_logmax_logfracr   r   r   _get_variance   s2   *	zFlaxDDPMScheduler._get_variancemodel_outputkeyreturn_dictc                    s  | du rt jd tjdkr3jd |jd d kr3jjdv r3tj|jd dd\ndj	j
 }tdkj	j
d  tjdjd}d| }	d| }
jjd	krk||	d
   |d
  }n&jjdkrt}njjdkr|d
 | |	d
   }n
tdjj djjrt|dd}|d
 j	j  |	 }j	j d
 |
 |	 }|| ||  } fdd}tdk| tjjjd}|| }|s|fS t|dS )a  
        Predict the sample at the previous timestep by reversing the SDE. Core function to propagate the diffusion
        process from the learned model outputs (most often the predicted noise).

        Args:
            state (`DDPMSchedulerState`): the `FlaxDDPMScheduler` state data class instance.
            model_output (`jnp.ndarray`): direct output from learned diffusion model.
            timestep (`int`): current discrete timestep in the diffusion chain.
            sample (`jnp.ndarray`):
                current instance of sample being created by diffusion process.
            key (`jax.Array`): a PRNG key.
            return_dict (`bool`): option for returning tuple rather than FlaxDDPMSchedulerOutput class

        Returns:
            [`FlaxDDPMSchedulerOutput`] or `tuple`: [`FlaxDDPMSchedulerOutput`] if `return_dict` is True, otherwise a
            `tuple`. When returning a tuple, the first element is the sample tensor.

        Nr   r	   r   )rO   rP   )axisr=   r:   r0         ?rD   v_predictionzprediction_type given as z? must be one of `epsilon`, `sample`  for the FlaxDDPMScheduler.r>   c                     sB   t jj ddd } t jj| jjd}jdd | S )Nr	   )numr   )rG   r)   )rW   rc   )jaxrandomsplitnormalrG   r)   r^   )	split_keynoiser`   r_   rW   r,   r#   rV   r   r   random_variance  s   z/FlaxDDPMScheduler.step.<locals>.random_variance)prev_sampler#   )rf   rg   r`   lenrG   rA   r6   r   rh   r   rQ   rR   r?   r)   r8   
ValueErrorr7   rT   rS   alphaszerosr"   )r,   r#   r_   rE   rD   r`   ra   rX   rY   beta_prod_tbeta_prod_t_prevpred_original_samplepred_original_sample_coeffcurrent_sample_coeffpred_prev_samplerm   rZ   r   rl   r   step   s@   *"zFlaxDDPMScheduler.steporiginal_samplesrk   r   c                 C      t |j|||S r9   )r   r   )r,   r#   rz   rk   r   r   r   r   	add_noise     zFlaxDDPMScheduler.add_noisec                 C   r{   r9   )r   r   )r,   r#   rD   rk   r   r   r   r   get_velocity%  r}   zFlaxDDPMScheduler.get_velocityc                 C   s   | j jS r9   )rA   r1   r+   r   r   r   __len__.  s   zFlaxDDPMScheduler.__len__r9   )r   )NNr*   )#r   r   r   __doc__r   _compatiblesr   r)   r   propertyr-   r   float32r    floatstrr   r   boolr;   r
   r   rC   rF   r   rJ   r^   rf   Arrayr   r"   ry   r|   r~   r   r   r   r   r   r$   6   s   
  

	


'

Y
	
	r$   )dataclassesr   typingr   r   r   flaxrf   	jax.numpynumpyr   configuration_utilsr   r   scheduling_utils_flaxr
   r   r   r   r   r   structr   r"   r$   r   r   r   r   <module>   s    
