
    +h]                         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Jr  SSKJr  \" 5       (       a  S SKr\R,                  " \5      r\ " S	 S
\5      5       r " S S\\5      rg)    N)	dataclass)ListOptionalTupleUnion   )ConfigMixinregister_to_config)
BaseOutputis_scipy_availablelogging   )SchedulerMixinc                   8    \ rS rSr% Sr\R                  \S'   Srg)%FlowMatchEulerDiscreteSchedulerOutput!   a2  
Output class for the scheduler's `step` function output.

Args:
    prev_sample (`torch.FloatTensor` 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.
prev_sample N)	__name__
__module____qualname____firstlineno____doc__torchFloatTensor__annotations____static_attributes__r       s/home/james-whalen/.local/lib/python3.13/site-packages/diffusers/schedulers/scheduling_flow_match_euler_discrete.pyr   r   !   s     """r   r   c                   "   \ rS rSrSr/ rSr\              SCS\S\	S\
S	\\	   S
\\	   S\\   S\\   S\
S\\	   S\\
   S\\
   S\\
   S\S\
4S jj5       r\S 5       r\S 5       r\S 5       rSDS\4S jjrS\	4S jr SES\R*                  S\\	\R*                  4   S\\R*                     S\R*                  4S jjrS  rS!\	S"\	S#\R2                  4S$ jrS#\R2                  S\R2                  4S% jr     SFS&\\   S'\\\R8                  4   S(\\\	      S!\\	   S)\\\	      4
S* jjrSES+ jrS, r S-S-\	" S.5      SSSS/4S0\R*                  S\\	\R*                  4   S\R*                  S1\	S2\	S3\	S4\	S5\\RB                     S6\\R2                     S7\
S\\"\#4   4S8 jjr$S9\R2                  S\R2                  4S: jr%S9\R2                  S&\S\R2                  4S; jr& SGS9\R2                  S&\S<\	S=\	S\R2                  4
S> jjr'S? r(S@ r)SA r*SBr+g)HFlowMatchEulerDiscreteScheduler/   a  
Euler scheduler.

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.
    shift (`float`, defaults to 1.0):
        The shift value for the timestep schedule.
    use_dynamic_shifting (`bool`, defaults to False):
        Whether to apply timestep shifting on-the-fly based on the image resolution.
    base_shift (`float`, defaults to 0.5):
        Value to stabilize image generation. Increasing `base_shift` reduces variation and image is more consistent
        with desired output.
    max_shift (`float`, defaults to 1.15):
        Value change allowed to latent vectors. Increasing `max_shift` encourages more variation and image may be
        more exaggerated or stylized.
    base_image_seq_len (`int`, defaults to 256):
        The base image sequence length.
    max_image_seq_len (`int`, defaults to 4096):
        The maximum image sequence length.
    invert_sigmas (`bool`, defaults to False):
        Whether to invert the sigmas.
    shift_terminal (`float`, defaults to None):
        The end value of the shifted timestep schedule.
    use_karras_sigmas (`bool`, defaults to False):
        Whether to use Karras sigmas for step sizes in the noise schedule during sampling.
    use_exponential_sigmas (`bool`, defaults to False):
        Whether to use exponential sigmas for step sizes in the noise schedule during sampling.
    use_beta_sigmas (`bool`, defaults to False):
        Whether to use beta sigmas for step sizes in the noise schedule during sampling.
    time_shift_type (`str`, defaults to "exponential"):
        The type of dynamic resolution-dependent timestep shifting to apply. Either "exponential" or "linear".
    stochastic_sampling (`bool`, defaults to False):
        Whether to use stochastic sampling.
r         ?Nnum_train_timestepsshiftuse_dynamic_shifting
base_shift	max_shiftbase_image_seq_lenmax_image_seq_leninvert_sigmasshift_terminaluse_karras_sigmasuse_exponential_sigmasuse_beta_sigmastime_shift_typestochastic_samplingc                 <   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S;  a  [        S5      e[        R                  " SX[        R                  S9S S S2   R                  5       n[        R                  " U5      R                  [        R                  S9nX-  nU(       d  UU-  SUS-
  U-  -   -  nUU-  U l        S U l        S U l        X l        UR                  S5      U l        U R&                  S   R)                  5       U l        U R&                  S	   R)                  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.>   linearexponentialz;`time_shift_type` must either be 'exponential' or 'linear'.dtypecpur   )configr/   r   ImportErrorsumr.   r-   
ValueErrornplinspacefloat32copyr   
from_numpyto	timesteps_step_index_begin_index_shiftsigmasitem	sigma_min	sigma_max)selfr$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   rC   rG   s                    r   __init__(FlowMatchEulerDiscreteScheduler.__init__Z   s`   $ ;;&&/A/C/CZ[[++T[[-O-OQUQ\Q\QnQnopstt A  ";;Z[[KK#6SUS]S]^_cac_cdiik	$$Y/222G	0#V^qEAI+?'?@F"55 ii&R--/Q,,.r   c                     U R                   $ )z
The value used for shifting.
rF   rK   s    r   r%   %FlowMatchEulerDiscreteScheduler.shift   s    
 {{r   c                     U R                   $ )zW
The index counter for current timestep. It will increase 1 after each scheduler step.
)rD   rP   s    r   
step_index*FlowMatchEulerDiscreteScheduler.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.
rE   rP   s    r   begin_index+FlowMatchEulerDiscreteScheduler.begin_index   s    
    r   rW   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.
NrV   )rK   rW   s     r   set_begin_index/FlowMatchEulerDiscreteScheduler.set_begin_index   s
     (r   c                     Xl         g NrO   )rK   r%   s     r   	set_shift)FlowMatchEulerDiscreteScheduler.set_shift   s    r   sampletimestepnoisereturnc                    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-  SU-
  U-  -   nU$ s  snf )z
Forward process in flow-matching

Args:
    sample (`torch.FloatTensor`):
        The input sample.
    timestep (`int`, *optional*):
        The current timestep in the diffusion chain.

Returns:
    `torch.FloatTensor`:
        A scaled input sample.
)devicer6   mpsr5   r   r7   r#   )rG   rB   re   r6   typer   is_floating_pointrC   r?   rW   index_for_timesteprS   shapeflattenlen	unsqueeze)	rK   r`   ra   rb   rG   schedule_timestepststep_indicessigmas	            r   scale_noise+FlowMatchEulerDiscreteScheduler.scale_noise   s   ( v}}FLLI==&5+B+B8+L+L!%!2!26==!2!V{{6=={FH!%!2!26==!A{{6==1H #T\]T\q33AJT\L]L__( OO,x~~a/@@L !,,-q0AAL$,,.%++V\\!22OOB'E %++V\\!22 #+!77 ^s   Hc                 2    XR                   R                  -  $ r]   r9   r$   )rK   rq   s     r   _sigma_to_t+FlowMatchEulerDiscreteScheduler._sigma_to_t   s    {{6666r   murq   ro   c                     U R                   R                  S:X  a  U R                  XU5      $ U R                   R                  S:X  a  U R                  XU5      $ g )Nr4   r3   )r9   r0   _time_shift_exponential_time_shift_linearrK   rx   rq   ro   s       r   
time_shift*FlowMatchEulerDiscreteScheduler.time_shift   sQ    ;;&&-7//1==[[((H4**2a88 5r   c                 \    SU-
  nUS   SU R                   R                  -
  -  nSX#-  -
  nU$ )a  
Stretches and shifts the timestep schedule to ensure it terminates at the configured `shift_terminal` config
value.

Reference:
https://github.com/Lightricks/LTX-Video/blob/a01a171f8fe3d99dce2728d60a73fecf4d4238ae/ltx_video/schedulers/rf.py#L51

Args:
    t (`torch.Tensor`):
        A tensor of timesteps to be stretched and shifted.

Returns:
    `torch.Tensor`:
        A tensor of adjusted timesteps such that the final value equals `self.config.shift_terminal`.
r   r7   )r9   r,   )rK   ro   one_minus_zscale_factorstretched_ts        r   stretch_shift_to_terminal9FlowMatchEulerDiscreteScheduler.stretch_shift_to_terminal   s=      !e"2!dkk.H.H*HI;56r   num_inference_stepsre   rG   rC   c                    U R                   R                  (       a  Uc  [        S5      eUb&  Ub#  [        U5      [        U5      :w  a  [        S5      eUb0  Ub  [        U5      U:w  d  Ub  [        U5      U:w  a  [        S5      eOUb  [        U5      O
[        U5      nXl        USLnU(       a3  [
        R                  " U5      R                  [
        R                  5      nUcf  UcJ  [
        R                  " U R                  U R                  5      U R                  U R                  5      U5      nXPR                   R                  -  nO>[
        R                  " U5      R                  [
        R                  5      n[        U5      nU R                   R                  (       a  U R                  USU5      nO%U R                  U-  SU R                  S-
  U-  -   -  nU R                   R                   (       a  U R#                  U5      nU R                   R$                  (       a  U R'                  X1S9nOUU R                   R(                  (       a  U R+                  X1S9nO*U R                   R,                  (       a  U R/                  X1S9n[0        R2                  " U5      R5                  [0        R                  US9nU(       d  X0R                   R                  -  nO2[0        R2                  " U5      R5                  [0        R                  US9nU R                   R6                  (       aS  SU-
  nX0R                   R                  -  n[0        R8                  " U[0        R:                  " SUR<                  S	9/5      nO5[0        R8                  " U[0        R>                  " SUR<                  S	9/5      nXPl         X0l!        SU l"        SU l#        g)
ar  
Sets the discrete timesteps used for the diffusion chain (to be run before inference).

Args:
    num_inference_steps (`int`, *optional*):
        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.
    sigmas (`List[float]`, *optional*):
        Custom values for sigmas to be used for each diffusion step. If `None`, the sigmas are computed
        automatically.
    mu (`float`, *optional*):
        Determines the amount of shifting applied to sigmas when performing resolution-dependent timestep
        shifting.
    timesteps (`List[float]`, *optional*):
        Custom values for timesteps to be used for each diffusion step. If `None`, the timesteps are computed
        automatically.
NzC`mu` must be passed when `use_dynamic_shifting` is set to be `True`z4`sigmas` and `timesteps` should have the same lengthzq`sigmas` and `timesteps` should have the same length as num_inference_steps, if `num_inference_steps` is providedr#   r   )	in_sigmasr   )r6   re   )re   )$r9   r&   r<   rl   r   r=   arrayastyper?   r>   rv   rJ   rI   r$   r}   r%   r,   r   r-   _convert_to_karrasr.   _convert_to_exponentialr/   _convert_to_betar   rA   rB   r+   catonesre   zerosrC   rG   rD   rE   )rK   r   re   rG   rx   rC   is_timesteps_provideds          r   set_timesteps-FlowMatchEulerDiscreteScheduler.set_timesteps   s   4 ;;++
bcc)"76{c)n, !WXX*"s6{6I'I%#i.<O*O  H  281C#f+Y#6  !* 5 +222::>I> KK$$T^^4d6F6Ft~~6VXk	 !@!@@FXXf%,,RZZ8F"%f+ ;;++__Rf5FZZ&(Aa60I,IJF ;;%%33F;F ;;((,,v,gF[[//11F1lF[[((**V*eF !!&),,5==,P$!@!@@I((366U]]SY6ZI
 ;;$$6\F!@!@@IYY

1V]](KLMFYYAfmm(LMNF" 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   )rC   nonzerorl   rH   )rK   ra   rn   indicesposs        r   ri   2FlowMatchEulerDiscreteScheduler.index_for_timestep_  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]   )
rW   
isinstancer   TensorrB   rC   re   ri   rD   rE   )rK   ra   s     r   _init_step_index0FlowMatchEulerDiscreteScheduler._init_step_indexm  sX    #(ELL11#;;t~~'<'<=#66x@D#00Dr   g        infTmodel_outputs_churns_tmins_tmaxs_noise	generatorper_token_timestepsreturn_dictc                    [        U[        5      (       d>  [        U[        R                  5      (       d  [        U[        R                  5      (       a  [        S5      eU R                  c  U R                  U5        UR                  [        R                  5      nU	b[  XR                  R                  -  nU R                  SS2SS4   nXS   S-
  :  nX-  nUR                  SS9u  pUS   nUS   nUU-
  nO6U R                  nU R                  U   nU R                  US-      nUnUnUU-
  nU R                  R                  (       a-  UUU-  -
  n[        R                  " U5      nSU-
  U-  UU-  -   nOUUU-  -   nU =R                   S-  sl        U	c  UR                  UR"                  5      nU
(       d  U4$ [%        US	9$ )
aA  
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.FloatTensor`):
        The direct output from learned diffusion model.
    timestep (`float`):
        The current discrete timestep in the diffusion chain.
    sample (`torch.FloatTensor`):
        A current instance of a sample created by the diffusion process.
    s_churn (`float`):
    s_tmin  (`float`):
    s_tmax  (`float`):
    s_noise (`float`, defaults to 1.0):
        Scaling factor for noise added to the sample.
    generator (`torch.Generator`, *optional*):
        A random number generator.
    per_token_timesteps (`torch.Tensor`, *optional*):
        The timesteps for each token in the sample.
    return_dict (`bool`):
        Whether or not to return a
        [`~schedulers.scheduling_flow_match_euler_discrete.FlowMatchEulerDiscreteSchedulerOutput`] or tuple.

Returns:
    [`~schedulers.scheduling_flow_match_euler_discrete.FlowMatchEulerDiscreteSchedulerOutput`] or `tuple`:
        If return_dict is `True`,
        [`~schedulers.scheduling_flow_match_euler_discrete.FlowMatchEulerDiscreteSchedulerOutput`] is returned,
        otherwise a tuple is returned where the first element is the sample tensor.
zPassing integer indices (e.g. from `enumerate(timesteps)`) as timesteps to `FlowMatchEulerDiscreteScheduler.step()` is not supported. Make sure to pass one of the `scheduler.timesteps` as a timestep.Ngư>r   )dim).Nr   r#   )r   )r   intr   	IntTensor
LongTensorr<   rS   r   rB   r?   r9   r$   rG   maxr1   
randn_likerD   r6   r   )rK   r   ra   r`   r   r   r   r   r   r   r   per_token_sigmasrG   
lower_masklower_sigmas_current_sigma
next_sigmadt	sigma_idxrq   
sigma_nextx0rb   r   s                            r   step$FlowMatchEulerDiscreteScheduler.stepu  s   Z x%%(EOO44(E$4$455G  ??"!!(+ 5==)*2[[5T5TT[[D$/F4"84"??J%.L*..1.5OL,Y7M%i0J+BIKK	*EY]3J!M#Je#B;;**-,66B$$V,E+r1J4FFK 2#44K 	A&%..););<K>!4MMr   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).rI   NrJ   r7   r   g      @r   )hasattrr9   rI   rJ   rH   r=   r>   )
rK   r   r   rI   rJ   rhorampmin_inv_rhomax_inv_rhorG   s
             r   r   2FlowMatchEulerDiscreteScheduler._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.rI   NrJ   r7   r   )
r   r9   rI   rJ   rH   r=   expr>   mathlog)rK   r   r   rI   rJ   rG   s         r   r   7FlowMatchEulerDiscreteScheduler._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)rI   NrJ   r7   r   r   )r   r9   rI   rJ   rH   r=   r   r>   scipystatsr   ppf)
rK   r   r   r   r   rI   rJ   ra   r   rG   s
             r   r   0FlowMatchEulerDiscreteScheduler._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 c                 t    [         R                  " U5      [         R                  " U5      SU-  S-
  U-  -   -  $ Nr   )r   r   r|   s       r   rz   7FlowMatchEulerDiscreteScheduler._time_shift_exponential*  s/    xx|txx|q1uqyU.BBCCr   c                 "    XSU-  S-
  U-  -   -  $ r   r   r|   s       r   r{   2FlowMatchEulerDiscreteScheduler._time_shift_linear-  s    1q519..//r   c                 .    U R                   R                  $ r]   ru   rP   s    r   __len__'FlowMatchEulerDiscreteScheduler.__len__0  s    {{...r   )rE   rF   rD   r   rJ   rI   rG   rC   )i  r#   Fg      ?gffffff?   i   FNFFFr4   F)r   r]   )NNNNN)333333?r   ),r   r   r   r   r   _compatiblesorderr
   r   floatboolr   strrL   propertyr%   rS   rW   rZ   r^   r   r   r   rr   rv   r   r}   r   re   r   r   ri   r   	Generatorr   r   r   r   r   r   rz   r{   r   r   r   r   r   r!   r!   /   s   %N LE $(%*&)%),/+/#*.,116*/,$)+/ +/ +/ #	+/
 UO+/ E?+/ %SM+/ $C=+/ +/ !+/ $D>+/ !)+/ "$+/ +/ "+/ +/Z       ! !(3 (u  .2	.!!. u0001. ))*	.
 
		.`79U 95 9U\\ 95<< ELL . .2+/(,"+/d!%c]d! c5<<'(d! e%	d!
 UOd! DK(d!L#1 e/36: cN''cN u0001cN !!	cN
 cN cN cN cN EOO,cN &ell3cN cN 
4e;	<cNLELL RWR^R^ 4 TW \a\h\h . dg<?HM[`	>D0/r   r!   )r   dataclassesr   typingr   r   r   r   numpyr=   r   configuration_utilsr	   r
   utilsr   r   r   scheduling_utilsr   scipy.statsr   
get_loggerr   loggerr   r!   r   r   r   <module>r      sn     ! / /   A ; ; , 			H	% 
#J 
# 
#B/nk B/r   