
    biE+                         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 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
             Ze G d de             Z G d dee      Zy)    )	dataclass)OptionalTupleUnionN)	integrate   )ConfigMixinregister_to_config   )CommonSchedulerStateFlaxKarrasDiffusionSchedulersFlaxSchedulerMixinFlaxSchedulerOutputbroadcast_to_shape_from_leftc            	          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<   dZ
eej                     ed<   ededej                  dej                  dej                  fd       Zy)	LMSDiscreteSchedulerStatecommoninit_noise_sigma	timestepssigmasNnum_inference_stepsderivativesc                      | ||||      S )Nr   r   r   r    )clsr   r   r   r   s        l/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/diffusers/schedulers/scheduling_lms_discrete_flax.pycreatez LMSDiscreteSchedulerState.create-   s     &3Cyaghh    )__name__
__module____qualname__r   __annotations__jnpndarrayr   r   intr   classmethodr   r   r   r   r   r       s       kk!{{KK)-#- *.K#++&-i)i=@[[iUXU`U`ijmjujui ir   r   c                       e Zd ZU eed<   y)FlaxLMSSchedulerOutputstateN)r    r!   r"   r   r#   r   r   r   r)   r)   4   s    $$r   r)   c                   R   e Zd ZU dZeD  cg c]  }|j
                   c}} Zej                  e	d<   e
d        Ze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j                  fd       Zd%dee   defdZdedej$                  dedej$                  fdZdefdZ	 d&dedededefdZ	 	 d'dedej$                  dedej$                  dededeeef   fdZded ej$                  d!ej$                  d"ej$                  dej$                  f
d#Zd$ Z yc c}} w )(FlaxLMSDiscreteSchedulera  
    Linear Multistep Scheduler for discrete beta schedules. Based on the original k-diffusion implementation by
    Katherine Crowson:
    https://github.com/crowsonkb/k-diffusion/blob/481677d114f6ea445aa009cf5bd7a9cdee909e47/k_diffusion/sampling.py#L181

    [`~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.
    dtypec                      y)NTr   selfs    r   	has_statez"FlaxLMSDiscreteScheduler.has_stateY   s    r   i  -C6?g{Gz?linearNepsilonnum_train_timesteps
beta_startbeta_endbeta_scheduletrained_betasprediction_typec                     || _         y Nr-   )r0   r5   r6   r7   r8   r9   r:   r-   s           r   __init__z!FlaxLMSDiscreteScheduler.__init__]   s     
r   r   returnc                 <   |t        j                  |       }t        j                  d| j                  j
                        j                         d d d   }d|j                  z
  |j                  z  dz  }|j                         }t        j                  ||||      S )Nr   r         ?r   )
r   r   r$   arangeconfigr5   roundalphas_cumprodmaxr   )r0   r   r   r   r   s        r   create_statez%FlaxLMSDiscreteScheduler.create_statej   s    >)006FJJq$++"A"ABHHJ4R4P	v,,,0E0EE#M "::<(//-	 0 
 	
r   r*   sampletimestepc                     t        j                  |j                  |k(  d      \  }|d   }|j                  |   }||dz  dz   dz  z  }|S )a	  
        Scales the denoising model input by `(sigma**2 + 1) ** 0.5` to match the K-LMS algorithm.

        Args:
            state (`LMSDiscreteSchedulerState`):
                the `FlaxLMSDiscreteScheduler` 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   rB   )r$   wherer   r   )r0   r*   rI   rJ   
step_indexsigmas         r   scale_model_inputz*FlaxLMSDiscreteScheduler.scale_model_input{   sR     		%//X"=AF]
Z(E1HqLS01r   c                     fd}t        j                  |j                     j                  dz      d      d   }|S )z
        Compute a linear multistep coefficient.

        Args:
            order (TODO):
            t (TODO):
            current_order (TODO):
        c                     d}t              D ]F  }|k(  r	|| j                  |z
     z
  j                  z
     j                  |z
     z
  z  z  }H |S )N      ?)ranger   )tauprodkcurrent_orderorderr*   ts      r   lms_derivativezDFlaxLMSDiscreteScheduler.get_lms_coefficient.<locals>.lms_derivative   sv    D5\ n A%u||AE22u||ADU7VY^YeYefgjkfkYl7lmmn Kr   r   r2   )epsrelr   )r   quadr   )r0   r*   rY   rZ   rX   r[   integrated_coeffs    ````  r   get_lms_coefficientz,FlaxLMSDiscreteScheduler.get_lms_coefficient   sD    	 %>>.%,,q/5<<XY\]X]K^gklmnor   r   shapec                    t        j                  | j                  j                  dz
  d|| j                        }t        j
                  |      j                  t         j                        }t        j                  |      j                  t         j                        }t        j                  |d      }d|j                  j                  z
  |j                  j                  z  dz  }d|z
  ||   z  |||   z  z   }t        j                  |t        j                  dg| j                        g      }|j                  t         j                        }t        j                  d|z   | j                        }	|j                  ||||	      S )	a  
        Sets the timesteps used for the diffusion chain. Supporting function to be run before inference.

        Args:
            state (`LMSDiscreteSchedulerState`):
                the `FlaxLMSDiscreteScheduler` 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=   rS   rB   g        )r   )r   r   r   r   )r$   linspacerD   r5   r-   floorastypeint32ceilmodr   rF   concatenatearrayzerosreplace)
r0   r*   r   r`   r   low_idxhigh_idxfracr   r   s
             r   set_timestepsz&FlaxLMSDiscreteScheduler.set_timesteps   s7    LL!@!@1!DaI\dhdndno	))I&--cii888I&--cii8wwy#&u||222ell6Q6QQVYYd(fWo-vh7G0GG&#))SE*L!MN$$SYY/	 iiuDJJ?}} 3#	  
 	
r   model_outputrY   return_dictc           
      N   |j                   t        d      |j                  |   }| j                  j                  dk(  r	|||z  z
  }n[| j                  j                  dk(  r|| |dz  dz   dz  z  z  ||dz  dz   z  z   }n#t        d| j                  j                   d      ||z
  |z  }	|j                  t        j                  |j                  |	      	      }t        |j                        |kD  r0|j                  t        j                  |j                  d
      	      }t        |dz   |      }t        |      D 
cg c]  }
| j                  ||||
       }}
|t        d t        |t!        |j                              D              z   }|s||fS t#        ||      S c c}
w )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 (`LMSDiscreteSchedulerState`): the `FlaxLMSDiscreteScheduler` 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 FlaxLMSSchedulerOutput class

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

        zaNumber of inference steps is 'None', you need to run 'set_timesteps' after creating the schedulerr4   v_predictionr   r   rB   zprediction_type given as z, must be one of `epsilon`, or `v_prediction`)r   r   c              3   ,   K   | ]  \  }}||z    y wr<   r   ).0coeff
derivatives      r   	<genexpr>z0FlaxLMSDiscreteScheduler.step.<locals>.<genexpr>  s      #
#45*EJ#
s   )prev_sampler*   )r   
ValueErrorr   rD   r:   rk   r$   appendr   lendeleteminrT   r_   sumzipreversedr)   )r0   r*   rp   rJ   rI   rY   rq   rO   pred_original_samplerw   
curr_order
lms_coeffsry   s                r   stepzFlaxLMSDiscreteScheduler.step   s   6 $$,s  X& ;;&&)3#)EL,@#@ [[((N:#/E6UAX\c<Q3Q#RV\`egh`hkl`lVm#n +DKK,G,G+HHtu 
 33u<
#**U5F5F
*STu  !E)MMcjj9J9JA.NMOE HqL%(ejkpeqrWad..ueXzRr
r s #
8;JQVQbQbHc8d#
  
 
 ''%+UKK ss    F"original_samplesnoiser   c                 |    |j                   |   j                         }t        ||j                        }|||z  z   }|S r<   )r   flattenr   r`   )r0   r*   r   r   r   rO   noisy_sampless          r   	add_noisez"FlaxLMSDiscreteScheduler.add_noise  s?     Y'//1,UEKK@(55=8r   c                 .    | j                   j                  S r<   )rD   r5   r/   s    r   __len__z FlaxLMSDiscreteScheduler.__len__  s    {{...r   r<   )r   )   T)!r    r!   r"   __doc__r   name_compatiblesr$   r-   r#   propertyr1   r
   float32r&   floatstrr   r%   r>   r   r   rH   rP   r_   r   ro   boolr   r)   r   r   r   )ru   es   00r   r,   r,   9   s   6 %BBqAFFBL99   $("%/3(;;
 
 
 	

 
  ,
 
 yy
 

8,@#A 
Mf 
"'@ #++ ad ilitit , )B  . Z\"
."
EH"
QV"
	""
T  ?L(?L kk?L 	?L
 ?L ?L ?L 
%u,	-?LB( ++ {{	
 ;; 
/K Cs   D#r,   )dataclassesr   typingr   r   r   flax	jax.numpynumpyr$   scipyr   configuration_utilsr	   r
   scheduling_utils_flaxr   r   r   r   r   structr   r)   r,   r   r   r   <module>r      sy    " ) )    A  i i i& %0 % %b/1; b/r   