
    +h,L                         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	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)    N)	dataclass)ListOptionalTupleUnion   )ConfigMixinregister_to_config)
BaseOutputlogging)randn_tensor   )SchedulerMixinc                   `    \ rS rSr% Sr\R                  \S'   Sr\	\R                     \S'   Sr
g)EDMEulerSchedulerOutput   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       c/home/james-whalen/.local/lib/python3.13/site-packages/diffusers/schedulers/scheduling_edm_euler.pyr   r      s'    
 37(5<<07r   r   c                   *   \ rS rSrSr/ rSr\        S6S\S\S\S\	S\
S	\	S
\S\	4S jj5       r\S 5       r\S 5       r\S 5       rS7S\
4S jjrS rS rS rS\R*                  S\\\R*                  4   S\R*                  4S jr   S8S\
S\\	\R0                  4   S\\\R*                  \\   4      4S jjrS9S\R*                  4S jjrS9S\R*                  4S jjrS:S  jrS! rS"S"\" S#5      S$SS%S4S&\R*                  S\\\R*                  4   S\R*                  S'\S(\S)\S*\S+\\R@                     S,\!S-\\R*                     S\\"\#4   4S. jjr$S/\R*                  S0\R*                  S1\R*                  S\R*                  4S2 jr%S3 r&S4 r'S5r(g);EDMEulerScheduler1   a  
Implements the Euler scheduler in EDM formulation as presented in Karras et al. 2022 [1].

[1] Karras, Tero, et al. "Elucidating the Design Space of Diffusion-Based Generative Models."
https://huggingface.co/papers/2206.00364

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:
    sigma_min (`float`, *optional*, defaults to 0.002):
        Minimum noise magnitude in the sigma schedule. This was set to 0.002 in the EDM paper [1]; a reasonable
        range is [0, 10].
    sigma_max (`float`, *optional*, defaults to 80.0):
        Maximum noise magnitude in the sigma schedule. This was set to 80.0 in the EDM paper [1]; a reasonable
        range is [0.2, 80.0].
    sigma_data (`float`, *optional*, defaults to 0.5):
        The standard deviation of the data distribution. This is set to 0.5 in the EDM paper [1].
    sigma_schedule (`str`, *optional*, defaults to `karras`):
        Sigma schedule to compute the `sigmas`. By default, we the schedule introduced in the EDM paper
        (https://huggingface.co/papers/2206.00364). Other acceptable value is "exponential". The exponential
        schedule was incorporated in this model: https://huggingface.co/stabilityai/cosxl.
    num_train_timesteps (`int`, defaults to 1000):
        The number of diffusion steps to train the model.
    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).
    rho (`float`, *optional*, defaults to 7.0):
        The rho parameter used for calculating the Karras sigma schedule, which is set to 7.0 in the EDM paper [1].
    final_sigmas_type (`str`, defaults to `"zero"`):
        The final `sigma` value for the noise schedule during the sampling process. If `"sigma_min"`, the final
        sigma is the same as the last sigma in the training schedule. If `zero`, the final sigma is set to 0.
r   	sigma_min	sigma_max
sigma_datasigma_schedulenum_train_timestepsprediction_typerhofinal_sigmas_typec	           	      r   US;  a  [        SU< S35      eS U l        [        R                  R                  R                  5       (       a  [        R                  O[        R                  n	[        R                  " US-   U	S9U-  n
US:X  a  U R                  U
5      n
OUS:X  a  U R                  U
5      n
U
R                  [        R                  5      n
U R                  U
5      U l        U R                  R                  S:X  a  U
S	   nO?U R                  R                  S
:X  a  SnO"[        SU R                  R                   35      e[        R                   " U
[        R"                  " SXR$                  S9/5      U l        SU l        S U l        S U l        U R&                  R                  S5      U l        g )N)karrasexponentialz-Wrong value for provided for `sigma_schedule=z`.`r   dtyper-   r.   r$   zeror   C`final_sigmas_type` must be one of 'zero', or 'sigma_min', but got r   
fill_valuedeviceFcpu)
ValueErrornum_inference_stepsr   backendsmpsis_availablefloat32float64arange_compute_karras_sigmas_compute_exponential_sigmastoprecondition_noise	timestepsconfigr+   catfullr7   sigmasis_scale_input_called_step_index_begin_index)selfr$   r%   r&   r'   r(   r)   r*   r+   sigmas_dtyperI   
sigma_lasts               r    __init__EDMEulerScheduler.__init__X   so    !::Mn=NcRSS $( (-(:(:(G(G(I(Iu}}u}}1A5\JM``X%008F},55f=F5==)008;;((K7J[[**f4JUVZVaVaVsVsUtu  iiDZXeXe)f gh%*" kknnU+r   c                 @    U R                   R                  S-  S-   S-  $ )Nr   r         ?)rF   r%   rM   s    r    init_noise_sigma"EDMEulerScheduler.init_noise_sigma   s#     %%q(1,44r   c                     U R                   $ )zW
The index counter for current timestep. It will increase 1 after each scheduler step.
)rK   rT   s    r    
step_indexEDMEulerScheduler.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.
rL   rT   s    r    begin_indexEDMEulerScheduler.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.
Nr[   )rM   r\   s     r    set_begin_index!EDMEulerScheduler.set_begin_index   s
     (r   c                 0    U R                  U5      nX-  nU$ N)_get_conditioning_c_in)rM   samplesigmac_inscaled_samples        r    precondition_inputs%EDMEulerScheduler.precondition_inputs   s    **51r   c                     [        U[        R                  5      (       d  [        R                  " U/5      nS[        R                  " U5      -  nU$ )Ng      ?)
isinstancer   r   tensorlog)rM   re   c_noises      r    rD   $EDMEulerScheduler.precondition_noise   s;    %..LL%)E5))r   c                 h   U R                   R                  nUS-  US-  US-  -   -  nU R                   R                  S:X  a  X4-  US-  US-  -   S-  -  nOSU R                   R                  S:X  a  U* U-  US-  US-  -   S-  -  nO#[        SU R                   R                   S35      eXQ-  Xb-  -   nU$ )Nr   epsilonrS   v_predictionzPrediction type z is not supported.)rF   r&   r)   r9   )rM   rd   model_outputre   r&   c_skipc_outdenoiseds           r    precondition_outputs&EDMEulerScheduler.precondition_outputs   s    [[++
Q%(Z]":;;;&&)3&%(Z]*Bs)JJE[[((N:FZ'5!8j!m+C*KKE/0K0K/LL^_``?U%99r   rd   timestepreturnc                     U R                   c  U R                  U5        U R                  U R                      nU R                  X5      nSU l        U$ )a  
Ensures interchangeability with schedulers that need to scale the denoising model input depending on the
current timestep. Scales the denoising model input by `(sigma**2 + 1) ** 0.5` to match the Euler algorithm.

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

Returns:
    `torch.Tensor`:
        A scaled input sample.
T)rX   _init_step_indexrI   rh   rJ   )rM   rd   ry   re   s       r    scale_model_input#EDMEulerScheduler.scale_model_input   sK     ??"!!(+DOO,))&8%)"r   Nr:   r7   rI   c           	         Xl         [        R                  R                  R	                  5       (       a  [        R
                  O[        R                  nUc"  [        R                  " SSU R                   US9nO;[        U[        5      (       a  [        R                  " X4S9nOUR                  U5      nU R                  R                  S:X  a  U R                  U5      nO+U R                  R                  S:X  a  U R                  U5      nUR                  [        R
                  US9nU R!                  U5      U l        U R                  R$                  S:X  a  US	   nO?U R                  R$                  S
:X  a  SnO"['        SU R                  R$                   35      e[        R(                  " U[        R*                  " SXSR,                  S9/5      U l        SU l        SU l        U R.                  R                  S5      U l        g)aJ  
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.
    sigmas (`Union[torch.Tensor, List[float]]`, *optional*):
        Custom sigmas to use for the denoising process. If not defined, the default behavior when
        `num_inference_steps` is passed will be used.
Nr   r   r/   r-   r.   )r0   r7   r$   r1   r2   r3   r4   r5   r8   )r:   r   r;   r<   r=   r>   r?   linspacerk   floatrl   rC   rF   r'   rA   rB   rD   rE   r+   r9   rG   rH   r7   rI   rK   rL   )rM   r:   r7   rI   rN   rO   s         r    set_timestepsEDMEulerScheduler.set_timesteps   s   $ $7 (-(:(:(G(G(I(Iu}}u}}>^^Aq$*B*B,WF&&\\&=FYY|,F;;%%1008F[[''=855f=Fv>008;;((K7J[[**f4JUVZVaVaVsVsUtu  iiDZXeXe)f gh kknnU+r   c                     U=(       d    U R                   R                  nU=(       d    U R                   R                  nU R                   R                  nUSU-  -  nUSU-  -  nXaXV-
  -  -   U-  nU$ )z6Constructs the noise schedule of Karras et al. (2022).r   )rF   r$   r%   r*   )rM   rampr$   r%   r*   min_inv_rhomax_inv_rhorI   s           r    rA   (EDMEulerScheduler._compute_karras_sigmas	  sm    6!6!6	6!6!6	kkooAG,AG,(A BBsJr   c                 N   U=(       d    U R                   R                  nU=(       d    U R                   R                  n[        R                  " [
        R                  " U5      [
        R                  " U5      [        U5      5      R                  5       R                  S5      nU$ )zImplementation closely follows k-diffusion.

https://github.com/crowsonkb/k-diffusion/blob/6ab5146d4a5ef63901326489f31f1d8e7dd36b48/k_diffusion/sampling.py#L26
r   )
rF   r$   r%   r   r   mathrm   lenexpflip)rM   r   r$   r%   rI   s        r    rB   -EDMEulerScheduler._compute_exponential_sigmas  sn    
 6!6!6	6!6!6	 3TXXi5H#d)TXXZ__`ab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   )rE   nonzeror   item)rM   ry   schedule_timestepsindicesposs        r    index_for_timestep$EDMEulerScheduler.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 rb   )
r\   rk   r   r   rC   rE   r7   r   rK   rL   )rM   ry   s     r    r|   "EDMEulerScheduler._init_step_index.  sX    #(ELL11#;;t~~'<'<=#66x@D#00Dr           infg      ?Trs   s_churns_tmins_tmaxs_noise	generatorreturn_dictr   c                    [        U[        [        R                  [        R                  45      (       a  [        S5      eU R                  (       d  [        R                  S5        U R                  c  U R                  U5        UR                  [        R                  5      nU R                  U R                     nX[s=::  a  U::  a(  O  O%[        U[        U R                  5      S-
  -  S5      OSnXS-   -  nUS:  aA  [!        UR"                  UR$                  UR&                  US9nX-  nX?US-  US-  -
  S	-  -  -   nU
c  U R)                  X1U5      n
X:-
  U-  nU R                  U R                  S-      U-
  nUUU-  -   nUR                  UR$                  5      nU =R*                  S-  sl        U	(       d  UU
4$ [-        UU
S
9$ )ar  
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.
    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.
    return_dict (`bool`):
        Whether or not to return a [`~schedulers.scheduling_euler_discrete.EDMEulerSchedulerOutput`] or tuple.

Returns:
    [`~schedulers.scheduling_euler_discrete.EDMEulerSchedulerOutput`] or `tuple`:
        If return_dict is `True`, [`~schedulers.scheduling_euler_discrete.EDMEulerSchedulerOutput`] 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 `EDMEulerScheduler.step()` is not supported. Make sure to pass one of the `scheduler.timesteps` as a timestep.zThe `scale_model_input` function should be called before `step` to ensure correct denoising. See `StableDiffusionPipeline` for a usage example.r   g4y?r   r   )r0   r7   r   r   rS   )r   r   )rk   intr   	IntTensor
LongTensorr9   rJ   loggerwarningrX   r|   rC   r>   rI   minr   r   shaper0   r7   rw   rK   r   )rM   rs   ry   rd   r   r   r   r   r   r   r   re   gamma	sigma_hatnoiseeps
derivativedtr   s                      r    stepEDMEulerScheduler.step6  s   P heoou7G7G HIIG  ))NNE
 ??"!!(+ 5==)DOO,EKE^X^E^Gs4;;/!34jAdgQY'	19 "",*<*<\EXEXdmE /CY\E1H%<$DDDF  '#'#<#<VS\#]  3y@
[[1,-	9zB. "nn\%7%78 	A$ 
 ';Uijjr   original_samplesr   rE   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)r7   r0   r<   r/   r   r1   )rI   rC   r7   r0   typer   is_floating_pointrE   r>   r\   r   rX   r   flattenr   	unsqueeze)
rM   r   r   rE   rI   r   tstep_indicesre   noisy_sampless
             r    	add_noiseEDMEulerScheduler.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                 P    SUS-  U R                   R                  S-  -   S-  -  nU$ )Nr   r   rS   )rF   r&   )rM   re   rf   s      r    rc   (EDMEulerScheduler._get_conditioning_c_in  s.    UAX 6 6 99cABr   c                 .    U R                   R                  $ rb   )rF   r(   rT   s    r    __len__EDMEulerScheduler.__len__  s    {{...r   )rL   rK   rJ   r:   rI   rE   )gMb`?g      T@rS   r-   i  rq   g      @r2   )r   )NNN)NNrb   ))r   r   r   r   r   _compatiblesorderr
   r   strr   rP   propertyrU   rX   r\   r_   rh   rD   rw   r   r   r   r}   r7   r   r   r   rA   rB   r   r|   	Generatorboolr   r   r   r   rc   r   r   r   r   r    r"   r"   1   s   !F LE !&#'(!'*,*, *, 	*,
 *, !*, *, *, *, *,X 5 5     ! !(3 (
 eU\\FY@Z _d_k_k 4 $(+/=A	/, /, c5<<'(/, u||T%[89:	/,d	ell 	SXS_S_ #1 e/3 7;akllak u||+,ak 	ak
 ak ak ak ak EOO,ak ak 'u||4ak 
&-	.akH,, || <<	
 
B/r   r"   )r   dataclassesr   typingr   r   r   r   r   configuration_utilsr	   r
   utilsr   r   utils.torch_utilsr   scheduling_utilsr   
get_loggerr   r   r   r"   r   r   r    <module>r      s_     ! / /  A ' , , 
		H	% 8j 8 8"O/ O/r   