
    
3jF@                         S r SSKJr  SSKrSSKJrJr  SSKJrJ	r	  SSK
Jr  SS	KJr  \	R                  " \5      r\ " S
 S\5      5       r " S S\\5      rg)aM  
LTXEulerAncestralRFScheduler

This scheduler implements a K-diffusion style Euler-Ancestral sampler specialized for flow / CONST parameterization,
closely mirroring ComfyUI's `sample_euler_ancestral_RF` implementation used for LTX-Video.

Reference implementation (ComfyUI):
    comfy.k_diffusion.sampling.sample_euler_ancestral_RF
    )	dataclassN   )ConfigMixinregister_to_config)
BaseOutputlogging)randn_tensor   )SchedulerMixinc                   8    \ rS rSr% Sr\R                  \S'   Srg)"LTXEulerAncestralRFSchedulerOutput&   z
Output class for the scheduler's `step` function output.

Args:
    prev_sample (`torch.FloatTensor`):
        Updated sample for the next step in the denoising process.
prev_sample N)	__name__
__module____qualname____firstlineno____doc__torchFloatTensor__annotations____static_attributes__r       p/home/wildlama/miniconda3/lib/python3.13/site-packages/diffusers/schedulers/scheduling_ltx_euler_ancestral_rf.pyr   r   &   s     """r   r   c                      \ rS rSrSrS/rSr\   S"S\S\	S\	4S jj5       r
\S	\4S
 j5       r\S	\4S j5       rS#S\4S jjr S$S\	\R                   -  S\R                   S-  S	\4S jjrS\	\R                   -  4S jr     S%S\S-  S\\R(                  -  S-  S\\	   \R                   -  S-  S\\	   \R                   -  S-  S\	S-  4
S jjrS\R                   S\R                   S	\R                   4S jr  S&S\R0                  S\	\R                   -  S\R0                  S\R2                  S-  S\S	\\\R0                     -  4S jjrS	\4S  jrS!rg)'LTXEulerAncestralRFScheduler3   a  
Euler-Ancestral scheduler for LTX-Video (RF / CONST parametrization).

This scheduler is intended for models where the network is trained with a CONST-like parameterization (as in LTXV /
FLUX). It approximates ComfyUI's `sample_euler_ancestral_RF` sampler and is useful when reproducing ComfyUI
workflows inside diffusers.

The scheduler can either:
- reuse the [`FlowMatchEulerDiscreteScheduler`] sigma / timestep logic when only `num_inference_steps` is provided
  (default diffusers-style usage), or
- follow an explicit ComfyUI-style sigma schedule when `sigmas` (or `timesteps`) are passed to [`set_timesteps`].

Args:
    num_train_timesteps (`int`, defaults to 1000):
        Included for config compatibility; not used to build the schedule.
    eta (`float`, defaults to 1.0):
        Stochasticity parameter. `eta=0.0` yields deterministic DDIM-like sampling; `eta=1.0` matches ComfyUI's
        default RF behavior.
    s_noise (`float`, defaults to 1.0):
        Global scaling factor for the stochastic noise term.
FlowMatchEulerDiscreteSchedulerr
   num_train_timestepsetas_noisec                 J    S U l         S U l        S U l        S U l        S U l        g N)num_inference_stepssigmas	timesteps_step_index_begin_index)selfr    r!   r"   s       r   __init__%LTXEulerAncestralRFScheduler.__init__N   s*     )- +/.2 $!%r   returnc                     U R                   $ r$   )r(   r*   s    r   
step_index'LTXEulerAncestralRFScheduler.step_index\   s    r   c                     U R                   $ )z
The index for the first timestep. It can be set from a pipeline with `set_begin_index` to support
image-to-image like workflows that start denoising part-way through the schedule.
r)   r/   s    r   begin_index(LTXEulerAncestralRFScheduler.begin_index`   s        r   r4   c                     Xl         g)zs
Included for API compatibility; not strictly needed here but kept to allow pipelines that call
`set_begin_index`.
Nr3   )r*   r4   s     r   set_begin_index,LTXEulerAncestralRFScheduler.set_begin_indexh   s
    
 (r   Ntimestepschedule_timestepsc                 f   Uc$  U R                   c  [        S5      eU R                   n[        U[        R                  5      (       a  UR                  UR                  5      nX!:H  R                  5       n[        U5      S:  a  SOSn[        U5      S:X  a  [        S5      eX4   R                  5       $ )an  
Map a (continuous) `timestep` value to an index into `self.timesteps`.

This follows the convention used in other discrete schedulers: if the same timestep value appears multiple
times in the schedule (which can happen when starting in the middle of the schedule), the *second* occurrence
is used for the first `step` call so that no sigma is accidentally skipped.
8Timesteps have not been set. Call `set_timesteps` first.r
   r   zaPassed `timestep` is not in `self.timesteps`. Make sure to use values from `scheduler.timesteps`.)
r'   
ValueError
isinstancer   Tensortodevicenonzerolenitem)r*   r9   r:   indicesposs        r   index_for_timestep/LTXEulerAncestralRFScheduler.index_for_timestepo   s     %~~% ![\\!%h--{{#5#<#<=H%1::< w<!#aw<1s  |  ""r   c                 &   U R                   c  [        S5      e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)z?
Initialize the internal step index based on a given timestep.
Nr<   )r'   r=   r4   r>   r   r?   r@   rA   rG   r(   r)   )r*   r9   s     r   _init_step_index-LTXEulerAncestralRFScheduler._init_step_index   sp     >>!WXX#(ELL11#;;t~~'<'<=#66x@D#00Dr   r%   rA   r&   r'   muc                    Uc  Uc  Uc  [        S5      eSSKJn  UR                  U R                  5      nUR                  UUSUSS9  UR                  U l        UR                  R                  US9U l        UR                  R                  US9U l	        SU l
        SU l        gUc  Un[        U[        5      (       a$  [        R                  " U[        R                   S9n	OU[        U[        R"                  5      (       a  UR                  [        R                   S9n	O[%        S['        U5       S	35      eU	R(                  S:w  a"  [        S
[+        U	R,                  5       S	35      eU	S   R/                  5       R1                  5       S:  a'  [2        R5                  SU	S   R1                  5       5        Ub  U	R                  U5      n	Xl        [7        [9        U R                  SS5      5      n
X-  U l	        Ub5  U[;        U5      S-
  :w  a#  [2        R5                  SU[;        U5      S-
  5        [;        U5      S-
  U l        SU l
        SU l        g)a  
Set the sigma / timestep schedule for sampling.

When `sigmas` or `timesteps` are provided explicitly, they are used as the RF sigma schedule (ComfyUI-style)
and are expected to include the terminal 0.0. When both are `None`, the scheduler reuses the
[`FlowMatchEulerDiscreteScheduler`] logic to generate sigmas from `num_inference_steps` and the stored config
(including any resolution-dependent shifting, Karras/beta schedules, etc.).

Args:
    num_inference_steps (`int`, *optional*):
        Number of denoising steps. If provided together with explicit `sigmas`/`timesteps`, they are expected
        to be consistent and are otherwise ignored with a warning.
    device (`str` or `torch.device`, *optional*):
        Device to move the internal tensors to.
    sigmas (`list[float]` or `torch.Tensor`, *optional*):
        Explicit sigma schedule, e.g. `[1.0, 0.99, ..., 0.0]`.
    timesteps (`list[float]` or `torch.Tensor`, *optional*):
        Optional alias for `sigmas`. If `sigmas` is None and `timesteps` is provided, timesteps are treated as
        sigmas.
    mu (`float`, *optional*):
        Optional shift parameter used when delegating to [`FlowMatchEulerDiscreteScheduler.set_timesteps`] and
        `config.use_dynamic_shifting` is `True`.
NzzLTXEulerAncestralRFScheduler.set_timesteps requires either explicit `sigmas`/`timesteps` or a `num_inference_steps` value.r
   )r   )r%   rA   r&   rL   r'   )rA   )dtypez-`sigmas` must be a list or torch.Tensor, got .z(`sigmas` must be a 1D tensor, got shape gư>zThe last sigma in the schedule is not zero (%.6f). For best compatibility with ComfyUI's RF sampler, the terminal sigma should be 0.0.r      z{Provided `num_inference_steps=%d` does not match `len(sigmas)-1=%d`. Overriding `num_inference_steps` with `len(sigmas)-1`.)r=   $scheduling_flow_match_euler_discreter   from_configconfigset_timestepsr%   r&   r@   r'   r(   r)   r>   listr   tensorfloat32r?   	TypeErrortypendimtupleshapeabsrD   loggerwarningfloatgetattrrC   )r*   r%   rA   r&   r'   rL   kwargsr   base_schedulersigmas_tensor	num_trains              r   rU   *LTXEulerAncestralRFScheduler.set_timesteps   s:   B >i/"* 8  ^<HHUN(($7 )  (6'I'ID$ )//22&2ADK+55888GDN#D $D >Ffd##!LLu}}EM--"IIEMMI:MKDQWL>YZ[\\"GmNaNaHbGccdeff  "'')D0NN! b!&&(	 ),,V4M $
 '$++/DdKL	&2*/Bc&kTUo/UNNI#Fa	 $'v;?  r   sigmasamplec                     UR                   UR                   :  a:  UR                  " / UR                  QSP76 nUR                   UR                   :  a  M:  U$ )z>
Helper to broadcast a scalar sigma to the shape of `sample`.
r
   )r[   viewr]   )r*   rh   ri   s      r   _sigma_broadcast-LTXEulerAncestralRFScheduler._sigma_broadcast  sE     jj6;;&JJ//Q/E jj6;;&r   model_output	generatorreturn_dictc                 Z   [        U[        [        R                  [        R                  45      (       a  [        S5      eU R                  b  U R                  c  [        S5      eU R                  c  U R                  U5        U R                  nU[        U R                  5      S-
  :  a  UnGO7UR                  [        R                  5      nUR                  [        R                  5      n	U R                  U   n
U R                  US-      nU R                  U
R                  S5      U5      nU R                  UR                  S5      U5      nXU	-  -
  nUR                  5       R!                  5       S:  a  UnGON[#        U R$                  R&                  5      n[#        U R$                  R(                  5      nSX-  S-
  U-  -   nUU-  nSU-
  nSU-
  nU R                  UR                  S5      U5      nU R                  UR                  S5      U5      nU R                  UR                  S5      U5      nUU-  nUU-  SU-
  U-  -   nUS:  ax  US:  ar  US-  US-  US-  -  US-  S-   -  -
  R+                  SS	9R-                  5       n[/        UR0                  XHR2                  UR4                  S
9nUUS-   -  U-  UU-  U-  -   nUR                  UR4                  5      n[7        U R                  S-   [        U R                  5      S-
  5      U l        U(       d  U4$ [9        US9$ )a  
Perform a single Euler-Ancestral RF update step.

Args:
    model_output (`torch.FloatTensor`):
        Raw model output at the current step. Interpreted under the CONST parametrization as `v_t`, with
        denoised state reconstructed as `x0 = x_t - sigma_t * v_t`.
    timestep (`float` or `torch.Tensor`):
        The current sigma value (must match one entry in `self.timesteps`).
    sample (`torch.FloatTensor`):
        Current latent sample `x_t`.
    generator (`torch.Generator`, *optional*):
        Optional generator for reproducible noise.
    return_dict (`bool`):
        If `True`, return a `LTXEulerAncestralRFSchedulerOutput`; otherwise return a tuple where the first
        element is the updated sample.
zPassing integer indices (e.g. from `enumerate(timesteps)`) as timesteps to `LTXEulerAncestralRFScheduler.step()` is not supported. Make sure to pass one of the `scheduler.timesteps` values as `timestep`.zGScheduler has not been initialized. Call `set_timesteps` before `step`.r
   g:0yE>      ?g        r   g-q=)min)ro   rA   rN   )r   )r>   intr   	IntTensor
LongTensorr=   r&   r'   r(   rJ   rC   r@   rX   rl   rk   r^   rD   ra   rT   r!   r"   clampsqrtr	   r]   rA   rN   rs   r   )r*   rn   r9   ri   ro   rp   ir   sample_fmodel_output_frh   
sigma_nextsigma_bsigma_next_bdenoisedxr!   r"   downstep_ratio
sigma_down	alpha_ip1
alpha_downsigma_down_balpha_ip1_balpha_down_bsigma_ratiorenoise_coeffnoises                               r   step!LTXEulerAncestralRFScheduler.step  s   4 heoou7G7G HIIN  ;;$.."8fgg#!!(+DKK 1$$ K yy/H)__U]];NKKNEQU+J++EJJqM8DG001CXNL  N"::H~~$$&-DKKOO, 3 34 "%
(:S(@C'G!G'.8
*,	 :-
  $44Z__Q5GR"33INN14ExP#44Z__Q5GR*W4(*cK.?8-KK 93%q<?[!^+K|]^afOf+gg3 " ) )OO[c[i[iE %u(<=BU]EZ]dEddA$$v||,K t//!3S5E5IJ>!1kJJr   c                 B    [        [        U R                  SS5      5      $ )Nr    rQ   )rt   rb   rT   r/   s    r   __len__$LTXEulerAncestralRFScheduler.__len__~  s     74;;(=tDEEr   )r)   r(   r%   r&   r'   )rQ   rr   rr   )r   r$   )NNNNN)NT) r   r   r   r   r   _compatiblesorderr   rt   ra   r+   propertyr0   r4   r7   r   r?   rG   rJ   strrA   rV   rU   rl   r   	Generatorboolr   r\   r   r   r   r   r   r   r   r   3   s   . 66LE $(	& & & 	& &  C     !S ! !(3 ( Y]#,#BG,,QUBU#	#B1)= 1  +/,0487;m! 4Zm! ell"T)m! Uell*T1	m!
 ;-4m! DLm!^ell ELL U\\  -1 gK''gK %,,&gK !!	gK
 ??T)gK gK 
,eE4E4E.F	FgKRF Fr   r   )r   dataclassesr   r   configuration_utilsr   r   utilsr   r   utils.torch_utilsr	   scheduling_utilsr   
get_loggerr   r_   r   r   r   r   r   <module>r      s]    "  A ' , , 
		H	% 	# 	# 	#NF>; NFr   