
    +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  SS	KJr  \" 5       (       a  S SKr\R0                  " \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)randn_tensor   )SchedulerMixinc                   8    \ rS rSr% Sr\R                  \S'   Srg)FlowMatchLCMSchedulerOutput"   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       h/home/james-whalen/.local/lib/python3.13/site-packages/diffusers/schedulers/scheduling_flow_match_lcm.pyr   r   "   s     """r   r   c            !          \ rS rSrSr/ rSr\               S<S\S\	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S=S\4S jjrS\	4S jrS\4S jr S>S\R0                  S\\	\R0                  4   S\\R0                     S\R0                  4S  jjrS! rS"\	S#\	S$\R8                  4S% jrS$\R8                  S\R8                  4S& jr     S?S'\\   S(\\\R>                  4   S)\\\	      S"\\	   S*\\\	      4
S+ jjr S>S, jr!S- r"  S@S.\R0                  S\\	\R0                  4   S\R0                  S/\\RF                     S0\
S\\$\%4   4S1 jjr&S2\R8                  S\R8                  4S3 jr'S2\R8                  S'\S\R8                  4S4 jr( SAS2\R8                  S'\S5\	S6\	S\R8                  4
S7 jjr)S8 r*S9 r+S: r,S;r-g)BFlowMatchLCMScheduler0   av  
LCM scheduler for Flow Matching.

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".
    scale_factors ('list', defaults to None)
        It defines how to scale the latents at which predictions are made.
    upscale_mode ('str', defaults to 'bicubic')
        Upscaling method, applied if scale-wise generation is considered
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scale_factorsupscale_modec                 d   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UU-  nU(       d  UU-  SUS-
  U-  -   -  nUU-  U l        S U l        S U l        X l        S U l        Xl        Xl        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
_init_size_scale_factors_upscale_modesigmasitem	sigma_min	sigma_max)selfr$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   rD   rK   s                     r    __init__FlowMatchLCMScheduler.__init__]   sv   & ;;&&/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0#V^qEAI+?'?@F"55 +)ii&R--/Q,,.r   c                     U R                   $ )z
The value used for shifting.
rG   rO   s    r    r%   FlowMatchLCMScheduler.shift   s    
 {{r   c                     U R                   $ )zW
The index counter for current timestep. It will increase 1 after each scheduler step.
)rE   rT   s    r    
step_index FlowMatchLCMScheduler.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.
rF   rT   s    r    begin_index!FlowMatchLCMScheduler.begin_index   s    
    r   r[   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.
NrZ   )rO   r[   s     r    set_begin_index%FlowMatchLCMScheduler.set_begin_index   s
     (r   c                     Xl         g NrS   )rO   r%   s     r    	set_shiftFlowMatchLCMScheduler.set_shift   s    r   c                     Xl         X l        g)z
Sets scale factors for a scale-wise generation regime.

Args:
    scale_factors (`list`):
        The scale factors for each step
    upscale_mode (`str`):
        Upscaling method
N)rI   rJ   )rO   r1   r2   s      r    set_scale_factors'FlowMatchLCMScheduler.set_scale_factors   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.
)devicer7   mpsr6   r   r8         ?)rK   rC   rl   r7   typer   is_floating_pointrD   r@   r[   index_for_timesteprW   shapeflattenlen	unsqueeze)	rO   rg   rh   ri   rK   schedule_timestepststep_indicessigmas	            r    scale_noise!FlowMatchLCMScheduler.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                  -  $ ra   r:   r$   )rO   ry   s     r    _sigma_to_t!FlowMatchLCMScheduler._sigma_to_t   s    {{6666r   mury   rw   c                     U R                   R                  S:X  a  U R                  XU5      $ U R                   R                  S:X  a  U R                  XU5      $ g )Nr5   r4   )r:   r0   _time_shift_exponential_time_shift_linearrO   r   ry   rw   s       r    
time_shift FlowMatchLCMScheduler.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   r8   )r:   r,   )rO   rw   one_minus_zscale_factorstretched_ts        r    stretch_shift_to_terminal/FlowMatchLCMScheduler.stretch_shift_to_terminal   s=      !e"2!dkk.H.H*HI;56r   num_inference_stepsrl   rK   rD   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 providedrn   r   )	in_sigmasr   )r7   rl   )rl   )$r:   r&   r=   rt   r   r>   arrayastyper@   r?   r~   rN   rM   r$   r   r%   r,   r   r-   _convert_to_karrasr.   _convert_to_exponentialr/   _convert_to_betar   rB   rC   r+   catonesrl   zerosrD   rK   rE   rF   )rO   r   rl   rK   r   rD   is_timesteps_provideds          r    set_timesteps#FlowMatchLCMScheduler.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   )rD   nonzerort   rL   )rO   rh   rv   indicesposs        r    rq   (FlowMatchLCMScheduler.index_for_timestept  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 ra   )
r[   
isinstancer   TensorrC   rD   rl   rq   rE   rF   )rO   rh   s     r    _init_step_index&FlowMatchLCMScheduler._init_step_index  sX    #(ELL11#;;t~~'<'<=#66x@D#00Dr   model_output	generatorreturn_dictc                 6   [        U[        5      (       d>  [        U[        R                  5      (       d  [        U[        R                  5      (       a  [        S5      eU R                  (       aK  U R                  (       a:  [        U R                  5      [        U R                  5      S-   :w  a  [        S5      eU R                  b  U R                  c  UR                  5       SS U l
        U R                  c  U R                  U5        UR                  [        R                  5      nU R                   U R                     nU R                   U R                  S-      nX6U-  -
  nU R                  (       a  U R                  (       a  U R"                  [        U R                  5      :  ar  U R                   V	s/ s H(  n	[%        U R                  U R"                     U	-  5      PM*     sn	n	[        R&                  R(                  R+                  XU R                  S9n[-        UR.                  XHR0                  UR2                  S9n
SU-
  U-  Xz-  -   nU =R"                  S-  sl        UR                  UR2                  5      nU(       d  U4$ [5        US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.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.
    generator (`torch.Generator`, *optional*):
        A random number generator.
    return_dict (`bool`):
        Whether or not to return a [`~schedulers.scheduling_flow_match_lcm.FlowMatchLCMSchedulerOutput`] or
        tuple.

Returns:
    [`~schedulers.scheduling_flow_match_lcm.FlowMatchLCMSchedulerOutput`] or `tuple`:
        If return_dict is `True`, [`~schedulers.scheduling_flow_match_lcm.FlowMatchLCMSchedulerOutput`] 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 `FlowMatchLCMScheduler.step()` is not supported. Make sure to pass one of the `scheduler.timesteps` as a timestep.r   z]`_scale_factors` should have the same length as `timesteps` - 1, if `_scale_factors` are set.Nr   )sizemode)r   rl   r7   )r   )r   intr   	IntTensor
LongTensorr=   rI   rJ   rt   rD   rH   rW   r   r   rC   r@   rK   rE   roundnn
functionalinterpolater   rr   rl   r7   r   )rO   r   rh   rg   r   r   ry   
sigma_nextx0_predr   ri   r   s               r    stepFlowMatchLCMScheduler.step  s   @ x%%(EOO44(E$4$455G  4#5#5#dnn:MQTUYUhUhQilmQm:mo  ??"doo&=*//1!"5DO??"!!(+ 5==)DOO,[[1!45
<//4#5#5#d&9&9"::X\XgXghXgPTd11$2B2BCdJKXgh((--99'SWSeSe9fW]]i^e^k^kl:~0:3EE 	A!nn\%7%78>!*{CC is   9/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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).rM   NrN   r8   r   g      @r   )hasattrr:   rM   rN   rL   r>   r?   )
rO   r   r   rM   rN   rhorampmin_inv_rhomax_inv_rhorK   s
             r    r   (FlowMatchLCMScheduler._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.rM   NrN   r8   r   )
r   r:   rM   rN   rL   r>   expr?   mathlog)rO   r   r   rM   rN   rK   s         r    r   -FlowMatchLCMScheduler._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)rM   NrN   r8   r   r   )r   r:   rM   rN   rL   r>   r   r?   scipystatsr   ppf)
rO   r   r   r   r   rM   rN   rh   r   rK   s
             r    r   &FlowMatchLCMScheduler._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    r   -FlowMatchLCMScheduler._time_shift_exponential*  s/    xx|txx|q1uqyU.BBCCr   c                 "    XSU-  S-
  U-  -   -  $ r   r   r   s       r    r   (FlowMatchLCMScheduler._time_shift_linear-  s    1q519..//r   c                 .    U R                   R                  $ ra   r}   rT   s    r    __len__FlowMatchLCMScheduler.__len__0  s    {{...r   )rF   rH   rI   rG   rE   rJ   r   rN   rM   rK   rD   )i  rn   Fg      ?gffffff?   i   FNFFFr5   Nbicubic)r   ra   )NNNNN)NT)333333?r   ).r   r   r   r   r   _compatiblesorderr
   r   floatboolr   strr   rP   propertyr%   rW   r[   r^   rb   listre   r   r   r   rz   r~   r   r   r   rl   r   rq   r   	Generatorr   r   r   r   r   r   r   r   r   r   r   r   r    r"   r"   0   s   'R LE $(%*&)%),/+/#*.,116*/,/3&/!0/ 0/ 0/ #	0/
 UO0/ E?0/ %SM0/ $C=0/ 0/ !0/ $D>0/ !)0/ "$0/ 0/  U,0/  sm!0/ 0/d       ! !(3 (u *t *" .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 04 ND''ND u0001ND !!	ND
 EOO,ND ND 
*E1	2NDb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   utils.torch_utilsr   scheduling_utilsr   scipy.statsr   
get_loggerr   loggerr   r"   r   r   r    <module>r      sq     ! / /   A ; ; , , 			H	% 
#* 
# 
#A/NK A/r   