
    +hf                         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JrJr  SSKJrJr  SSKJrJr  \" 5       (       a  S SKr\ " S	 S
\5      5       r  SS jr " S S\\5      rg)    N)	dataclass)ListOptionalTupleUnion   )ConfigMixinregister_to_config)
BaseOutputis_scipy_available   )KarrasDiffusionSchedulersSchedulerMixinc                   `    \ rS rSr% Sr\R                  \S'   Sr\	\R                     \S'   Sr
g)KDPM2DiscreteSchedulerOutput   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       j/home/james-whalen/.local/lib/python3.13/site-packages/diffusers/schedulers/scheduling_k_dpm_2_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_fnL   s-    88QY%/$''9A=>!CCr   expc                 4    [         R                  " U S-  5      $ )Ng      ()r$   r+   r'   s    r    r)   r*   Q   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<   3   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\	           S0S\
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S1S\
4S jjrS\R4                  S\\\R4                  4   S\R4                  4S jr  S2S\
S\\\R8                  4   S\\
   4S jjr\S 5       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                  \R                   4   S\\\R4                  4   S\\R4                  \R                   4   S(\S\\%\&4   4
S) jjr'S*\R4                  S+\R4                  S,\R4                  S\R4                  4S- jr(S. r)S/r*gs  snn f )6KDPM2DiscreteScheduler_   u	  
KDPM2DiscreteScheduler is inspired by the DPMSolver2 and Algorithm 2 from the [Elucidating the Design Space of
Diffusion-Based Generative Models](https://huggingface.co/papers/2206.00364) paper.

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.00085):
        The starting `beta` value of inference.
    beta_end (`float`, defaults to 0.012):
        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                  (       a  [        5       (       d  [        S5      e[	        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        U R'                  US U5        S U l        S U l        U R,                  R/                  S5      U l        g )Nz:Make sure to install scipy if you want to use beta sigmas.r   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 g      ?r   dimcpu)configrG   r   ImportErrorsumrF   rE   r/   r   r3   r4   r8   linspacer<   NotImplementedError	__class__alphascumprodalphas_cumprodset_timesteps_step_index_begin_indexsigmasto)selfr@   rA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   s               r    __init__KDPM2DiscreteScheduler.__init__   s{    ;;&&/A/C/CZ[[++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? 	.6IJ kknnU+r   c                     U R                   R                  S;   a  U R                  R                  5       $ U R                  R                  5       S-  S-   S-  $ )N)rV   trailingr   r   rN   )rS   rI   r_   maxra   s    r    init_noise_sigma'KDPM2DiscreteScheduler.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.
)r]   rg   s    r    
step_index!KDPM2DiscreteScheduler.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.
r^   rg   s    r    begin_index"KDPM2DiscreteScheduler.begin_index   s    
    r   ro   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.
Nrn   )ra   ro   s     r    set_begin_index&KDPM2DiscreteScheduler.set_begin_index   s
     (r   sampletimestepreturnc                     U R                   c  U R                  U5        U R                  (       a  U R                  U R                      nOU R                  U R                      nXS-  S-   S-  -  nU$ )aN  
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 (`int`, *optional*):
        The current timestep in the diffusion chain.

Returns:
    `torch.Tensor`:
        A scaled input sample.
r   r   rN   )rk   _init_step_indexstate_in_first_orderr_   sigmas_interpol)ra   rt   ru   sigmas       r    scale_model_input(KDPM2DiscreteScheduler.scale_model_input   se    & ??"!!(+$$KK0E((9E1HqLS01r   num_inference_stepsdevicec           	         Xl         U=(       d    U R                  R                  nU R                  R                  S:X  a>  [        R
                  " SUS-
  U[        R                  S9SSS2   R                  5       nGO<U R                  R                  S:X  a  X0R                   -  n[        R                  " SU5      U-  R                  5       SSS2   R                  5       R                  [        R                  5      nX@R                  R                  -  nOU R                  R                  S:X  af  X0R                   -  n[        R                  " U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$                  (       aS  U R'                  XaS9n[        R                  " U Vs/ s H  oR)                  X5      PM     sn5      R                  5       nOU R                  R*                  (       aE  U R-                  XaS9n[        R                  " U Vs/ s H  oR)                  X5      PM     sn5      nO_U R                  R.                  (       aD  U R1                  XaS9n[        R                  " U Vs/ s H  oR)                  X5      PM     sn5      n[2        R4                  " U5      R7                  US9U l        [        R:                  " US//5      R                  [        R                  5      n[2        R4                  " U5      R7                  US9nUR                  5       R=                  UR?                  S5      R                  5       S
5      RA                  5       n	[2        RB                  " USS USS RE                  S5      USS /5      U l#        [2        RB                  " U	SS U	SS RE                  S5      U	SS /5      U l$        [2        R4                  " U5      R7                  U5      nU	RK                  5       n	U R8                  RK                  5       n[        R                  " U	 V
s/ s H  oR)                  X5      PM     sn
5      n[2        R4                  " U5      R7                  X$RL                  S9n[2        RN                  " USS2S4   USS2S4   4SS9RQ                  5       n[2        RB                  " USS U/5      U l)        SU l*        SU l+        SU l,        U RF                  R7                  S5      U l#        gs  snf 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.
rV   r   r   r-   Nleadingre   zY is not supported. Please make sure to choose one of 'linspace', 'leading' or 'trailing'.rN   )	in_sigmasr~   )r   g        r   rP   rR   )-r~   rS   r@   rI   nprV   r4   copyarangeroundastyperJ   r/   arrayr[   loginterplenrE   _convert_to_karras_sigma_to_trF   _convert_to_exponentialrG   _convert_to_betar   
from_numpyr`   
log_sigmasconcatenatelerprollr+   catrepeat_interleaver_   rz   rR   r.   stackflatten	timestepsrt   r]   r^   )ra   r~   r   r@   r   
step_ratior_   r   r{   rz   sigma_interpoltimesteps_interpolinterleaved_timestepss                r    r\   $KDPM2DiscreteScheduler.set_timesteps   s    $7 1TT[[5T5T ;;'':5A':Q'>@S[][e[efgkikgklqqsI[[))Y6,0H0HHJ 1&9:ZGNNPQUSUQUV[[]ddegeoeopI111I[[))Z7,/G/GGJ #6J;GNNPUUW^^_a_i_ijINI;;//0  1J  K  A 3 33t7J7JJsRSVVF^
9bii3v;&?H;;((,,v,gFSY!ZSY%"2"25"ESY!Z[aacI[[//11F1lFSY!ZSY%"2"25"ESY!Z[I[[((**V*eFSY!ZSY%"2"25"ESY!Z[I**:6999H#077

C!!&),,F,; !**,++FKKN,>,>,@#FJJLiiVABZ-I-I!-LfUWUXk Z[$yyRa /!""5"G"G"JO\^\_L`a 
 $$Y/226:	 *--/__((*
XXP_`P_nn9P_`
 #--.@ADDVSbSbDc %-?"d
-KYWXWY[_W_M`,agi j r r tIbqM3H#IJ kknnU+K "[ "[ "[( as   7W%WW"W'c                     U R                   S L $ N)rt   rg   s    r    ry   +KDPM2DiscreteScheduler.state_in_first_orderH  s    {{d""r   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)ra   ru   schedule_timestepsindicesposs        r    index_for_timestep)KDPM2DiscreteScheduler.index_for_timestepM  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 r   )
ro   
isinstancer   r   r`   r   r   r   r]   r^   )ra   ru   s     r    rx   'KDPM2DiscreteScheduler._init_step_index\  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   )rf   r   )	r   r   maximumnewaxiscumsumargmaxclipshapereshape)ra   r{   r   	log_sigmadistslow_idxhigh_idxlowhighwr(   s              r    r   "KDPM2DiscreteScheduler._sigma_to_te  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 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Sn[
        R                  " SSU5      nUSU-  -  nUSU-  -  nXXx-
  -  -   U-  n	U	$ )z6Constructs the noise schedule of Karras et al. (2022).	sigma_minN	sigma_maxr   r   g      @r   )hasattrrS   r   r   r   r   rV   )
ra   r   r~   r   r   rhorampmin_inv_rhomax_inv_rhor_   s
             r    r   )KDPM2DiscreteScheduler._convert_to_karras}  s    
 4;;,,--II4;;,,--II!*!6IIbM<N<N<P	!*!6IIaL<M<M<O	{{1a!45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   r   r   )
r   rS   r   r   r   r   r+   rV   r$   r   )ra   r   r~   r   r   r_   s         r    r   .KDPM2DiscreteScheduler._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   r   r   r   )r   rS   r   r   r   r   r   rV   scipystatsr   ppf)
ra   r   r~   r   r   r   r   ru   r   r_   s
             r    r   'KDPM2DiscreteScheduler._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_outputreturn_dictc                 *   U R                   c  U R                  U5        U R                  (       aR  U R                  U R                      nU R                  U R                   S-      nU R                  U R                   S-      nONU R                  U R                   S-
     nU R                  U R                      nU R                  U R                      nSnXXS-   -  n	U R
                  R                  S:X  a  U R                  (       a  U	OUn
X:U-  -
  nOU R
                  R                  S:X  a2  U R                  (       a  U	OUn
X* U
S-  S-   S-  -  -  X:S-  S-   -  -   nOHU R
                  R                  S:X  a  [        S	5      e[        S
U R
                  R                   S35      eU R                  (       a  X;-
  U	-  nXi-
  nX0l	        OX;-
  U-  nXy-
  nU R                  nSU l	        U =R                  S-  sl
        X<U-  -   nU(       d  UU4$ [        XS9$ )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`):
        The current discrete timestep in the diffusion chain.
    sample (`torch.Tensor`):
        A current instance of a sample created by the diffusion process.
    return_dict (`bool`):
        Whether or not to return a [`~schedulers.scheduling_k_dpm_2_discrete.KDPM2DiscreteSchedulerOutput`] or
        tuple.

Returns:
    [`~schedulers.scheduling_k_dpm_2_discrete.KDPM2DiscreteSchedulerOutput`] or `tuple`:
        If return_dict is `True`, [`~schedulers.scheduling_k_dpm_2_discrete.KDPM2DiscreteSchedulerOutput`] is
        returned, otherwise a tuple is returned where the first element is the sample tensor.
Nr   r   epsilonv_predictionr   rN   rt   z+prediction_type not implemented yet: samplezprediction_type given as z, must be one of `epsilon`, or `v_prediction`)r   r   )rk   rx   ry   r_   rz   rS   rH   rW   r/   rt   r]   r   )ra   r   ru   rt   r   r{   r   
sigma_nextgamma	sigma_hatsigma_inputr   
derivativedtr   s                  r    stepKDPM2DiscreteScheduler.step  s   6 ??"!!(+$$KK0E!11$//A2EFNT__q%89J KK! 34E!11$//BNT__5J
 QY'	 ;;&&)3'+'@'@)nK#),,F#F [[((N:'+'@'@)nK#/<;PQ>TUCUZ]B]3]#^q.1,-$  [[((H4%&STT+DKK,G,G+HHtu  $$ 79DJ+B !K !7>IJ 'B[[FDK 	AB.$ 
 ,oor   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 )N)r   r.   mpsr-   r   r   )r_   r`   r   r.   typer   is_floating_pointr   r4   ro   r   rk   r   r   r   	unsqueeze)
ra   r   r   r   r_   r   r(   step_indicesr{   noisy_sampless
             r    	add_noise KDPM2DiscreteScheduler.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   )rS   r@   rg   s    r    __len__KDPM2DiscreteScheduler.__len__L  s    {{...r   )r^   r]   rY   r[   r8   r   r~   rt   r_   rz   r   )i  g_QK?g~jt?rL   NFFFr   rV   r   )r   )NNr   )333333?r   )T)+r   r   r   r   r   r   name_compatiblesorderr
   intfloatstrr   r   r   ndarrayr   boolrb   propertyrh   rk   ro   rr   r   r   r|   r   r\   ry   r   rx   r   r   r   r   r   r   r   r   r   r   ).0es   00r    r>   r>   _   s   $L %>>$=qFF$=>LE $(#%BF,116*/( *), ), ), 	),
 ),  bjj$u+&= >?), $D>), !)), "$), ), ), ), ),V 3 3     ! !(3 ( u||+, 
	B ,0-1	R, R, c5<<'(R, &c]	R,h # ##10ELL RWR^R^ 4 TW \a\h\h . dg<?HM[`	H !\pELL"**45\p u||+,\p ellBJJ./	\p
 \p 
+U2	3\p~,, || <<	
 
B/M ?s   G,r>   )g+?r"   )r$   dataclassesr   typingr   r   r   r   numpyr   r   configuration_utilsr	   r
   utilsr   r   scheduling_utilsr   r   scipy.statsr   r   r<   r>   r   r   r    <module>r      si     ! / /   A 2 G  8: 8 8( !)4Xn/^[ n/r   