
    +h4_                         S SK r S SKrS SKJr  S SKJrJrJrJr  S SK	r
S SKrS SKrS SKJr  SSKJrJr  SSKJr  SS	KJrJr  \ " S
 S\5      5       r  SS jr " S S\\5      rg)    N)	dataclass)ListOptionalTupleUnion)	integrate   )ConfigMixinregister_to_config)
BaseOutput   )KarrasDiffusionSchedulersSchedulerMixinc                   `    \ rS rSr% Sr\R                  \S'   Sr\	\R                     \S'   Sr
g)LMSDiscreteSchedulerOutput   aM  
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_sampleNpred_original_sample )__name__
__module____qualname____firstlineno____doc__torchTensor__annotations__r   r   __static_attributes__r       f/home/james-whalen/.local/lib/python3.13/site-packages/diffusers/schedulers/scheduling_lms_discrete.pyr   r      s'    
 37(5<<07r   r   c           
      &   US:X  a  S nOUS:X  a  S nO[        SU 35      e/ n[        U 5       H<  nXP-  nUS-   U -  nUR                  [        SU" U5      U" U5      -  -
  U5      5        M>     [        R
                  " U[        R                  S9$ )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
cosinec                 h    [         R                  " U S-   S-  [         R                  -  S-  5      S-  $ )NgMb?gT㥛 ?r	   )mathcospits    r    alpha_bar_fn)betas_for_alpha_bar.<locals>.alpha_bar_fnJ   s-    88QY%/$''9A=>!CCr   expc                 4    [         R                  " U S-  5      $ )Ng      ()r$   r+   r'   s    r    r)   r*   O   s    88AI&&r   z"Unsupported alpha_transform_type: r   dtype)
ValueErrorrangeappendminr   tensorfloat32)num_diffusion_timestepsmax_betaalpha_transform_typer)   betasit1t2s           r    betas_for_alpha_barr<   1   s    . x'	D 
	&	' =>R=STUUE*+(!e..S\"-R0@@@(KL , <<U]]33r   c                      \ rS rSrSr\ V Vs/ s H  oR                  PM     snn rSr\	           S1S\
S\S\S\S	\\\R                   \\   4      S
\\   S\\   S\\   S\S\S\
4S jj5       r\S 5       r\S 5       r\S 5       rS2S\
4S jjrS\R4                  S\\\R4                  4   S\R4                  4S jrS rS3S\
S\\\R:                  4   4S jjrS3S jrS r S  r!S!\R4                  S\R4                  4S" jr"S!\R4                  S\
S\R4                  4S# jr# S4S!\R4                  S\
S$\S%\S\R4                  4
S& jjr$  S5S'\R4                  S\\\R4                  4   S\R4                  S(\
S)\S\\%\&4   4S* jjr'S+\R4                  S,\R4                  S-\R4                  S\R4                  4S. jr(S/ r)S0r*gs  snn f )6LMSDiscreteScheduler]   u"	  
A linear multistep scheduler for discrete beta schedules.

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` or `scaled_linear`.
    trained_betas (`np.ndarray`, *optional*):
        Pass an array of betas directly to the constructor to bypass `beta_start` and `beta_end`.
    use_karras_sigmas (`bool`, *optional*, defaults to `False`):
        Whether to use Karras sigmas for step sizes in the noise schedule during the sampling process. If `True`,
        the sigmas are determined according to a sequence of noise levels {σi}.
    use_exponential_sigmas (`bool`, *optional*, defaults to `False`):
        Whether to use exponential sigmas for step sizes in the noise schedule during the sampling process.
    use_beta_sigmas (`bool`, *optional*, defaults to `False`):
        Whether to use beta sigmas for step sizes in the noise schedule during the sampling process. Refer to [Beta
        Sampling is All You Need](https://huggingface.co/papers/2407.12173) for more information.
    prediction_type (`str`, defaults to `epsilon`, *optional*):
        Prediction type of the scheduler function; can be `epsilon` (predicts the noise of the diffusion process),
        `sample` (directly predicts the noisy sample`) or `v_prediction` (see section 2.4 of [Imagen
        Video](https://imagen.research.google/video/paper.pdf) paper).
    timestep_spacing (`str`, defaults to `"linspace"`):
        The way the timesteps should be scaled. Refer to Table 2 of the [Common Diffusion Noise Schedules and
        Sample Steps are Flawed](https://huggingface.co/papers/2305.08891) for more information.
    steps_offset (`int`, defaults to 0):
        An offset added to the inference steps, as required by some model families.
r   Nnum_train_timesteps
beta_startbeta_endbeta_scheduletrained_betasuse_karras_sigmasuse_exponential_sigmasuse_beta_sigmasprediction_typetimestep_spacingsteps_offsetc                 ~   [        U R                  R                  U R                  R                  U R                  R                  /5      S:  a  [        S5      eUb)  [        R                  " U[        R                  S9U l	        OUS:X  a*  [        R                  " X#U[        R                  S9U l	        OkUS:X  a4  [        R                  " US-  US-  U[        R                  S9S-  U l	        O1US:X  a  [        U5      U l	        O[        U S	U R                   35      eS
U R                  -
  U l        [        R                  " U R                  SS9U l        ["        R$                  " SU R                   -
  U R                   -  S-  5      n["        R&                  " US S S2   S//5      R)                  ["        R                  5      n[        R*                  " U5      U l        S U l        X`l        U R1                  US 5        / U l        SU l        S U l        S U l        U R,                  R;                  S5      U l        g )Nr   znOnly one of `config.use_beta_sigmas`, `config.use_exponential_sigmas`, `config.use_karras_sigmas` can be used.r-   linearscaled_linear      ?r	   squaredcos_cap_v2z is not implemented for       ?r   )dim        Fcpu)sumconfigrG   rF   rE   r/   r   r3   r4   r8   linspacer<   NotImplementedError	__class__alphascumprodalphas_cumprodnparrayconcatenateastype
from_numpysigmasnum_inference_stepsset_timestepsderivativesis_scale_input_called_step_index_begin_indexto)selfr@   rA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   rb   s                r    __init__LMSDiscreteScheduler.__init__   s    ++T[[-O-OQUQ\Q\QnQnopstt A  $m5==IDJh&
>QY^YfYfgDJo-
C3H[chcpcpquvvDJ11,-@ADJ%7OPTP^P^O_&`aaDJJ&#mmDKKQ?A 3 33t7J7JJsRS"u 56==bjjI&&v. $( !2.5%*" kknnU+r   c                     U R                   R                  S;   a  U R                  R                  5       $ U R                  R                  5       S-  S-   S-  $ )N)rW   trailingr	   r   rN   )rV   rI   rb   maxrj   s    r    init_noise_sigma%LMSDiscreteScheduler.init_noise_sigma   sH     ;;''+CC;;??$$!Q&*s22r   c                     U R                   $ )zW
The index counter for current timestep. It will increase 1 after each scheduler step.
)rg   rp   s    r    
step_indexLMSDiscreteScheduler.step_index   s    
 r   c                     U R                   $ )za
The index for the first timestep. It should be set from pipeline with `set_begin_index` method.
rh   rp   s    r    begin_index LMSDiscreteScheduler.begin_index   s    
    r   rx   c                     Xl         g)z
Sets the begin index for the scheduler. This function should be run from pipeline before the inference.

Args:
    begin_index (`int`):
        The begin index for the scheduler.
Nrw   )rj   rx   s     r    set_begin_index$LMSDiscreteScheduler.set_begin_index   s
     (r   sampletimestepreturnc                     U R                   c  U R                  U5        U R                  U R                      nXS-  S-   S-  -  nSU l        U$ )aV  
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 (`float` or `torch.Tensor`):
        The current timestep in the diffusion chain.

Returns:
    `torch.Tensor`:
        A scaled input sample.
r	   r   rN   T)rt   _init_step_indexrb   rf   )rj   r}   r~   sigmas       r    scale_model_input&LMSDiscreteScheduler.scale_model_input   sP      ??"!!(+DOO,1HqLS01%)"r   c                    ^ ^^^ UUU U4S jn[         R                  " UT R                  T   T R                  TS-      SS9S   nU$ )z`
Compute the linear multistep coefficient.

Args:
    order ():
    t ():
    current_order ():
c                    > Sn[        T5       HH  nTU:X  a  M  XTR                  TU-
     -
  TR                  TT-
     TR                  TU-
     -
  -  -  nMJ     U$ )NrP   )r0   rb   )tauprodkcurrent_orderorderrj   r(   s      r    lms_derivative@LMSDiscreteScheduler.get_lms_coefficient.<locals>.lms_derivative   sm    D5\ A%t{{1q511dkk!mBS6TW[WbWbcdghchWi6ijj " Kr   r   -C6?)epsrelr   )r   quadrb   )rj   r   r(   r   r   integrated_coeffs   ````  r    get_lms_coefficient(LMSDiscreteScheduler.get_lms_coefficient   sI    	 	 %>>.$++a.$++VWZ[V[J\eijklmr   rc   devicec           	         Xl         U R                  R                  S:X  aR  [        R                  " SU R                  R
                  S-
  U[        R                  S9SSS2   R                  5       nGOzU R                  R                  S:X  a  U R                  R
                  U R                   -  n[        R                  " SU5      U-  R                  5       SSS2   R                  5       R                  [        R                  5      nX0R                  R                  -  nOU R                  R                  S:X  a  U R                  R
                  U R                   -  n[        R                  " U R                  R
                  SU* 5      R                  5       R                  5       R                  [        R                  5      nUS-  nO"[        U R                  R                   S	35      e[        R                  " SU R                  -
  U R                  -  S
-  5      n[        R                  " U5      n[        R                   " U[        R                  " S[#        U5      5      U5      nU R                  R$                  (       aE  U R'                  US9n[        R                  " U Vs/ s H  opR)                  Xv5      PM     sn5      nOU R                  R*                  (       aE  U R-                  XQS9n[        R                  " U Vs/ s H  opR)                  Xv5      PM     sn5      nO_U R                  R.                  (       aD  U R1                  XQS9n[        R                  " U Vs/ s H  opR)                  Xv5      PM     sn5      n[        R2                  " US//5      R                  [        R                  5      n[4        R6                  " U5      R9                  US9U l        [4        R6                  " U5      R9                  U[4        R                  S9U l        SU l        SU l         U R:                  R9                  S5      U l        / U l!        gs  snf s  snf s  snf )au  
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.
    device (`str` or `torch.device`, *optional*):
        The device to which the timesteps should be moved to. If `None`, the timesteps are not moved.
rW   r   r   r-   NrR   leadingrn   zY is not supported. Please make sure to choose one of 'linspace', 'leading' or 'trailing'.rN   )	in_sigmas)r   rc   rS   )r   r   r.   rT   )"rc   rV   rI   r]   rW   r@   r4   copyarangeroundr`   rJ   r/   r^   r\   loginterplenrE   _convert_to_karras_sigma_to_trF   _convert_to_exponentialrG   _convert_to_betar_   r   ra   ri   rb   	timestepsrg   rh   re   )rj   rc   r   r   
step_ratiorb   
log_sigmasr   s           r    rd   "LMSDiscreteScheduler.set_timesteps  sd    $7  ;;'':5At{{'F'F'JL_gigqgqr"df  [[))Y688D<T<TTJ 1&9:ZGNNPQUSUQUV[[]ddegeoeopI111I[[))Z7884;S;SSJ 4;;#B#BA
{SZZ\aacjjkmkukuvINI;;//0  1J  K  A 3 33t7J7JJsRSVVF^
9bii3v;&?H;;((,,v,>FSY!ZSY%"2"25"ESY!Z[I[[//11F1lFSY!ZSY%"2"25"ESY!Z[I[[((**V*eFSY!ZSY%"2"25"ESY!Z[I#077

C&&v.111@)))477vU]]7[ kknnU+! "[ "[ "[s   *Q
Q*Q c                     Uc  U R                   nX!:H  R                  5       n[        U5      S:  a  SOSnX4   R                  5       $ )Nr   r   )r   nonzeror   item)rj   r~   schedule_timestepsindicesposs        r    index_for_timestep'LMSDiscreteScheduler.index_for_timestepB  sH    %!%%1::< w<!#a|  ""r   c                     U R                   c[  [        U[        R                  5      (       a%  UR	                  U R
                  R                  5      nU R                  U5      U l        g U R                  U l        g N)
rx   
isinstancer   r   ri   r   r   r   rg   rh   )rj   r~   s     r    r   %LMSDiscreteScheduler._init_step_indexQ  sX    #(ELL11#;;t~~'<'<=#66x@D#00Dr   c                    [         R                  " [         R                  " US5      5      nX2S S 2[         R                  4   -
  n[         R                  " US:  SS9R                  SS9R                  UR                  S   S-
  S9nUS-   nX%   nX&   nXs-
  Xx-
  -  n	[         R                  " U	SS5      n	SU	-
  U-  X-  -   n
U
R                  UR                  5      n
U
$ )Ng|=r   )axisr	   )ro   r   )	r]   r   maximumnewaxiscumsumargmaxclipshapereshape)rj   r   r   	log_sigmadistslow_idxhigh_idxlowhighwr(   s              r    r    LMSDiscreteScheduler._sigma_to_tZ  s    FF2::eU34	 q"**}55 ))UaZq188a8@EE*JZJZ[\J]`aJaEbQ;!# _,GGAq! Ug,IIekk"r   r   c                     US   R                  5       nUS   R                  5       nSn[        R                  " SSU R                  5      nUSU-  -  nUSU-  -  nXuXg-
  -  -   U-  nU$ )z6Constructs the noise schedule of Karras et al. (2022).rR   r   g      @r   )r   r]   rW   rc   )	rj   r   	sigma_min	sigma_maxrhorampmin_inv_rhomax_inv_rhorb   s	            r    r   'LMSDiscreteScheduler._convert_to_karrasr  s{     %R=--/	$Q<,,.	{{1a!9!9:AG,AG,(A BBsJr   c                    [        U R                  S5      (       a  U R                  R                  nOSn[        U R                  S5      (       a  U R                  R                  nOSnUb  UOUS   R	                  5       nUb  UOUS   R	                  5       n[
        R                  " [
        R                  " [        R                  " U5      [        R                  " U5      U5      5      nU$ )z)Constructs an exponential noise schedule.r   Nr   rR   r   )
hasattrrV   r   r   r   r]   r+   rW   r$   r   )rj   r   rc   r   r   rb   s         r    r   ,LMSDiscreteScheduler._convert_to_exponential  s    
 4;;,,--II4;;,,--II!*!6IIbM<N<N<P	!*!6IIaL<M<M<O	DHHY$7)9LNabcr   alphabetac           
      J   [        U R                  S5      (       a  U R                  R                  nOSn[        U R                  S5      (       a  U R                  R                  nOSnUb  UOUS   R	                  5       nUb  UOUS   R	                  5       n[
        R                  " S[
        R                  " SSU5      -
   Vs/ s H-  n[        R                  R                  R                  XsU5      PM/     sn Vs/ s H  nXXXe-
  -  -   PM     sn5      n	U	$ s  snf s  snf )zJFrom "Beta Sampling is All You Need" [arXiv:2407.12173] (Lee et. al, 2024)r   Nr   rR   r   r   )r   rV   r   r   r   r]   r^   rW   scipystatsr   ppf)
rj   r   rc   r   r   r   r   r~   r   rb   s
             r    r   %LMSDiscreteScheduler._convert_to_beta  s    4;;,,--II4;;,,--II!*!6IIbM<N<N<P	!*!6IIaL<M<M<O	
 %&Aq:M(N$N$N KK$$(($?$NC I$9:;
 s   4D?D model_outputr   return_dictc           
         U R                   (       d  [        R                  " S5        U R                  c  U R	                  U5        U R
                  U R                     nU R                  R                  S:X  a  X6U-  -
  nOwU R                  R                  S:X  a  X* US-  S-   S-  -  -  X6S-  S-   -  -   nO@U R                  R                  S:X  a  UnO#[        SU R                  R                   S	35      eX7-
  U-  nU R                  R                  U5        [        U R                  5      U:  a  U R                  R                  S
5        [        U R                  S-   U5      n[        U5       V	s/ s H  oR                  X@R                  U	5      PM      n
n	U[!        S [#        U
[%        U R                  5      5       5       5      -   nU =R&                  S-  sl        U(       d  UU4$ [)        XS9$ s  sn	f )a  
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 (`float` or `torch.Tensor`):
        The current discrete timestep in the diffusion chain.
    sample (`torch.Tensor`):
        A current instance of a sample created by the diffusion process.
    order (`int`, defaults to 4):
        The order of the linear multistep method.
    return_dict (`bool`, *optional*, defaults to `True`):
        Whether or not to return a [`~schedulers.scheduling_utils.SchedulerOutput`] or tuple.

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

zThe `scale_model_input` function should be called before `step` to ensure correct denoising. See `StableDiffusionPipeline` for a usage example.epsilonv_predictionr	   r   rN   r}   zprediction_type given as z, must be one of `epsilon`, or `v_prediction`r   c              3   .   #    U  H  u  pX-  v   M     g 7fr   r   ).0coeff
derivatives      r    	<genexpr>,LMSDiscreteScheduler.step.<locals>.<genexpr>  s      #
8c#45E8cs   )r   r   )rf   warningswarnrt   r   rb   rV   rH   r/   re   r1   r   popr2   r0   r   rU   zipreversedrg   r   )rj   r   r~   r}   r   r   r   r   r   
curr_order
lms_coeffsr   s               r    stepLMSDiscreteScheduler.step  s   < ))MME
 ??"!!(+DOO, ;;&&)3#)L,@#@ [[((N:#/6UAX\c<Q3Q#RV\gh`hkl`lVm#n [[((H4#/ +DKK,G,G+HHtu 
 3u<

+t 5(  # DOOa'/ejkpeqreqWa..uoozReq
r s #
8;JQUQaQaHb8c#
  
 

 	A$ 
 *kmm! ss   4%G6original_samplesnoiser   c                     U R                   R                  UR                  UR                  S9nUR                  R                  S:X  av  [
        R                  " U5      (       a[  U R                  R                  UR                  [
        R                  S9nUR                  UR                  [
        R                  S9nO@U R                  R                  UR                  5      nUR                  UR                  5      nU R                  c!  U Vs/ s H  o`R                  Xe5      PM     nnOHU R                  b  U R                  /UR                  S   -  nOU R                  /UR                  S   -  nXG   R                  5       n[        UR                  5      [        UR                  5      :  a?  UR                  S5      n[        UR                  5      [        UR                  5      :  a  M?  XU-  -   n	U	$ s  snf )Nr   mpsr-   r   rR   )rb   ri   r   r.   typer   is_floating_pointr   r4   rx   r   rt   r   flattenr   	unsqueeze)
rj   r   r   r   rb   r   r(   step_indicesr   noisy_sampless
             r    	add_noiseLMSDiscreteScheduler.add_noise  s    '7'>'>FVF\F\]""''50U5L5LY5W5W!%!2!23C3J3JRWR_R_!2!`!%5%<%<EMMRI!%!2!23C3J3J!K!%5%<%<=I #T]^T]q33AJT]L^L__( OO,yq/AAL !,,-	0BBL$,,.%++%5%;%;!<<OOB'E %++%5%;%;!<< )5=8 _s   G;c                 .    U R                   R                  $ r   )rV   r@   rp   s    r    __len__LMSDiscreteScheduler.__len__'  s    {{...r   )rh   rg   rZ   r\   r8   re   rf   rc   rb   r   rE   )i  r   g{Gz?rL   NFFFr   rW   r   )r   r   )333333?r   )   T)+r   r   r   r   r   r   name_compatiblesr   r   intfloatstrr   r   r]   ndarrayr   boolrk   propertyrq   rt   rx   r{   r   r   r   r   r   rd   r   r   r   r   r   r   r   r   r   r   r   r   )r   es   00r    r>   r>   ]   s   #J %>>$=qFF$=>LE $("%BF,116*/( */, /, /, 	/,
 /,  bjj$u+&= >?/, $D>/, !)/, "$/, /, /, /, /,b 3 3     ! !(3 ( eU\\FY@Z _d_k_k 0 ,8 8eCDU>V 8v#10ELL U\\  TW \a\h\h . dg<?HM[`	H  NnllNn u||+,Nn 	Nn
 Nn Nn 
)50	1Nnb,, || <<	
 
B/I ?s   Gr>   )g+?r"   )r$   r   dataclassesr   typingr   r   r   r   numpyr]   scipy.statsr   r   r   configuration_utilsr
   r   utilsr   scheduling_utilsr   r   r   r<   r>   r   r   r    <module>r     sd      ! / /     A  G 8 8 8( !)4XK/>; K/r   