o
    Gi02                     @   s   d dl 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mZmZmZmZ ee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 )    )	dataclassN   )ConfigMixinregister_to_config)logging   )CommonSchedulerStateFlaxKarrasDiffusionSchedulersFlaxSchedulerMixinFlaxSchedulerOutputadd_noise_commonget_velocity_commonc                   @   sT   e Zd ZU eed< ejed< ejed< dZ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   ]/home/ubuntu/.local/lib/python3.10/site-packages/diffusers/schedulers/scheduling_ddpm_flax.pycreate/   s   zDDPMSchedulerState.create)__name__
__module____qualname__r   __annotations__jnpndarrayr   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    9   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jdB dedededejfddZd7dedB defddZ	d7dedejdedB 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jdB d+edeeB 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://huggingface.co/papers/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>_   s    zFlaxDDPMScheduler.<listcomp>dtypec                 C   s   dS NTr   selfr   r   r   	has_statec   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   t d |	| _d S )NzFlax classes are deprecated and will be removed in Diffusers v1.0.0. We recommend migrating to PyTorch classes or pinning your version of Diffusers.)loggerwarningr'   )
r*   r/   r0   r1   r2   r3   r4   r5   r6   r'   r   r   r   __init__g   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configr/   roundr   )r*   r   r   r   r   r   r   create_statez   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!   rC   rD   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   )r@   r/   r   r?   rA   replace)r*   r!   r   rF   
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'   betasr@   r4   cliplog)r*   r!   tpredicted_variancer4   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   )rN   rO   )axisr;   r<   r.         ?rC   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   )rF   r'   )rV   rb   )jaxrandomsplitnormalrF   r'   r]   )	split_keynoiser_   r^   rV   r*   r!   rU   r   r   random_variance  s   z/FlaxDDPMScheduler.step.<locals>.random_variance)prev_sampler!   )re   rf   r_   lenrF   r@   r4   r   rg   r   rP   rQ   r>   r'   r6   
ValueErrorr5   rS   rR   alphaszerosr    )r*   r!   r^   rD   rC   r_   r`   rW   rX   beta_prod_tbeta_prod_t_prevpred_original_samplepred_original_sample_coeffcurrent_sample_coeffpred_prev_samplerl   rY   r   rk   r   step   s@   *"zFlaxDDPMScheduler.steporiginal_samplesrj   r   c                 C      t |j|||S N)r   r   )r*   r!   ry   rj   r   r   r   r   	add_noise+     zFlaxDDPMScheduler.add_noisec                 C   rz   r{   )r   r   )r*   r!   rC   rj   r   r   r   r   get_velocity4  r}   zFlaxDDPMScheduler.get_velocityc                 C   s   | j jS r{   )r@   r/   r)   r   r   r   __len__=  s   zFlaxDDPMScheduler.__len__r{   )r   )NNr(   )!r   r   r   __doc__r	   _compatiblesr   r'   r   propertyr+   r   float32r   floatstrr   boolr9   r   r   rB   rE   tuplerI   r]   re   Arrayr    rx   r|   r~   r   r   r   r   r   r"   >   s   
  

	


'
Y
	
	r"   )dataclassesr   flaxre   	jax.numpynumpyr   configuration_utilsr   r   utilsr   scheduling_utils_flaxr   r	   r
   r   r   r   
get_loggerr   r7   structr   r    r"   r   r   r   r   <module>   s    

