o
    pi1*                     @   s   d dl mZ d dlmZmZm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 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broadcast_to_shape_from_leftc                	   @   sh   e Zd ZU eed< ej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dejfddZdS )	EulerDiscreteSchedulerStatecommoninit_noise_sigma	timestepssigmasNnum_inference_stepsc                 C   s   | ||||dS )Nr   r   r   r    )clsr   r   r   r   r   r   q/home/ubuntu/SoloSpeech/.venv/lib/python3.10/site-packages/diffusers/schedulers/scheduling_euler_discrete_flax.pycreate)   s   z"EulerDiscreteSchedulerState.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 ) FlaxEulerDiscreteSchedulerOutputstateN)r   r   r   r   r   r   r   r   r   r"   0   s   
 r"   c                   @   s4  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ejfdededededeej dededejfddZd1dee defddZdedejdedejfddZ	 d2ded!ed"edefd#d$Z	%d3ded&ejdedejd'edeeef fd(d)Zded*ejd+ejd,ejdejf
d-d.Zd/d0 ZdS )4FlaxEulerDiscreteSchedulera  
    Euler scheduler (Algorithm 2) from Karras et al. (2022) https://arxiv.org/abs/2206.00364. . Based on the original
    k-diffusion implementation by Katherine Crowson:
    https://github.com/crowsonkb/k-diffusion/blob/481677d114f6ea445aa009cf5bd7a9cdee909e47/k_diffusion/sampling.py#L51


    [`~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.

    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` or `scaled_linear`.
        trained_betas (`jnp.ndarray`, optional):
            option to pass an array of betas directly to the constructor to bypass `beta_start`, `beta_end` etc.
        prediction_type (`str`, default `epsilon`, optional):
            prediction type of the scheduler function, one of `epsilon` (predicting the noise of the diffusion
            process), `sample` (directly predicting the noisy sample`) or `v_prediction` (see section 2.4
            https://imagen.research.google/video/paper.pdf)
        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>R   s    z%FlaxEulerDiscreteScheduler.<listcomp>dtypec                 C   s   dS )NTr   selfr   r   r   	has_stateV   s   z$FlaxEulerDiscreteScheduler.has_statei  g-C6?g{Gz?linearNepsilonlinspacenum_train_timesteps
beta_startbeta_endbeta_scheduletrained_betasprediction_typetimestep_spacingc	           	      C   s
   || _ d S Nr)   )	r+   r0   r1   r2   r3   r4   r5   r6   r)   r   r   r   __init__Z   s   
z#FlaxEulerDiscreteScheduler.__init__r   returnc                 C   s   |d u r	t | }td| jj d d d }d|j |j d }t|tdt	||}t
|tjdg| jdg}| jjdv rH| }n
| d d d }tj||||d	S )
Nr   r	         ?        r8   r/   trailingr   r   )r
   r   r   arangeconfigr0   roundalphas_cumprodinterplenconcatenatearrayr)   r6   maxr   )r+   r   r   r   r   r   r   r   create_stateh   s   

z'FlaxEulerDiscreteScheduler.create_stater#   sampletimestepc                 C   s@   t j|j|kdd\}|d }|j| }||d d d  }|S )a  
        Scales the denoising model input by `(sigma**2 + 1) ** 0.5` to match the Euler algorithm.

        Args:
            state (`EulerDiscreteSchedulerState`):
                the `FlaxEulerDiscreteScheduler` state data class instance.
            sample (`jnp.ndarray`):
                current instance of sample being created by diffusion process.
            timestep (`int`):
                current discrete timestep in the diffusion chain.

        Returns:
            `jnp.ndarray`: scaled input sample
        r	   sizer   r   r<   )r   wherer   r   )r+   r#   rJ   rK   
step_indexsigmar   r   r   scale_model_input~   s
   
z,FlaxEulerDiscreteScheduler.scale_model_inputr   r   shapec                 C   s  | j jdkrtj| j jd d|| jd}n.| j jdkr:| j j| }td||  ddd  	t
}|d7 }n	td| j j d|jj |jj d	 }t|tdt||}t|tjd
g| jdg}| j jdv ru| }n
| d d d	 }|j||||dS )a  
        Sets the timesteps used for the diffusion chain. Supporting function to be run before inference.

        Args:
            state (`EulerDiscreteSchedulerState`):
                the `FlaxEulerDiscreteScheduler` state data class instance.
            num_inference_steps (`int`):
                the number of diffusion steps used when generating samples with a pre-trained model.
        r/   r	   r   r8   leadingNr;   z=timestep_spacing must be one of ['linspace', 'leading'], got r<   r=   r>   r   )r   r   r   r   )rA   r6   r   r/   r0   r)   r@   rB   copyastypefloat
ValueErrorr   rC   rD   rE   rF   rG   rH   replace)r+   r#   r   rR   r   
step_ratior   r   r   r   r   set_timesteps   s*   (

z(FlaxEulerDiscreteScheduler.set_timestepsTmodel_outputreturn_dictc                 C   s   |j du r	tdtj|j|kdd\}|d }|j| }| jjdkr*|||  }n&| jjdkrF|| |d d d	   ||d d   }n
td
| jj d|| | }	|j|d  | }
||	|
  }|sk||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 (`EulerDiscreteSchedulerState`):
                the `FlaxEulerDiscreteScheduler` 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.
            order: coefficient for multi-step inference.
            return_dict (`bool`): option for returning tuple rather than FlaxEulerDiscreteScheduler class

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

        NzaNumber of inference steps is 'None', you need to run 'set_timesteps' after creating the schedulerr	   rL   r   r.   v_predictionr   r<   zprediction_type given as z, must be one of `epsilon`, or `v_prediction`)prev_sampler#   )	r   rW   r   rN   r   r   rA   r5   r"   )r+   r#   r[   rK   rJ   r\   rO   rP   pred_original_sample
derivativedtr^   r   r   r   step   s(   

,zFlaxEulerDiscreteScheduler.steporiginal_samplesnoiser   c                 C   s*   |j |  }t||j}|||  }|S r7   )r   flattenr   rR   )r+   r#   rc   rd   r   rP   noisy_samplesr   r   r   	add_noise   s   z$FlaxEulerDiscreteScheduler.add_noisec                 C   s   | j jS r7   )rA   r0   r*   r   r   r   __len__  s   z"FlaxEulerDiscreteScheduler.__len__r7   )r   )T)r   r   r   __doc__r   _compatiblesr   r)   r   propertyr,   r   float32r    rV   strr   r   r9   r
   r   rI   rQ   r   rZ   boolr   r"   rb   rg   rh   r   r   r   r   r$   5   s   
 

	
/

=
r$   )dataclassesr   typingr   r   r   flax	jax.numpynumpyr   configuration_utilsr   r   scheduling_utils_flaxr
   r   r   r   r   structr   r"   r$   r   r   r   r   <module>   s   	