
    wiMC                         d dl Z d dlmZ d dlmZmZmZ d dlZddlm	Z	m
Z
 ddlmZmZ ddlmZ dd	lmZ  ej        e          Ze G d
 de                      Z G d dee	          ZdS )    N)	dataclass)OptionalTupleUnion   )ConfigMixinregister_to_config)
BaseOutputlogging)randn_tensor   )SchedulerMixinc                   L    e Zd ZU dZej        ed<   dZeej                 ed<   dS )EDMEulerSchedulerOutputaq  
    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____doc__torchTensor__annotations__r   r        y/root/.openclaw/workspace/chatterbox_venv_py311/lib/python3.11/site-packages/diffusers/schedulers/scheduling_edm_euler.pyr   r      sD         
 
 37(5<077777r   r   c                   V   e Zd ZdZg ZdZe	 	 	 	 	 	 	 d8d
edededede	dedefd            Z
ed             Zed             Zed             Zd9de	fdZd Zd Zd Zdej        deeej        f         dej        fdZd:d e	d!eeej        f         fd"Zd;dej        fd#Zd;dej        fd$Zd:d%Zd& Zd'd' ed(          d)dd*fd+ej        deeej        f         dej        d,ed-ed.ed/ed0eej                 d1edee e!f         fd2Z"d3ej        d4ej        d5ej        dej        fd6Z#d7 Z$dS )<EDMEulerSchedulera  
    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://arxiv.org/abs/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://arxiv.org/abs/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].
    r   Mb`?      T@      ?karras  epsilon      @	sigma_min	sigma_max
sigma_datasigma_schedulenum_train_timestepsprediction_typerhoc                    |dvrt          d|d          d | _        t          j        dd|          }|dk    r|                     |          }	n|dk    r|                     |          }	|                     |	          | _        t          j        |	t          j	        d|	j
                  g          | _        d	| _        d | _        d | _        | j                            d
          | _        d S )N)r"   exponentialz-Wrong value for provided for `sigma_schedule=z`.`r   r   r"   r.   deviceFcpu)
ValueErrornum_inference_stepsr   linspace_compute_karras_sigmas_compute_exponential_sigmasprecondition_noise	timestepscatzerosr0   sigmasis_scale_input_called_step_index_begin_indexto)
selfr&   r'   r(   r)   r*   r+   r,   rampr;   s
             r   __init__zEDMEulerScheduler.__init__U   s     !:::RnRRRSSS $( ~a$788X%%0066FF},,55d;;F0088iQv})M)M)M NOO%*" knnU++r   c                 ,    | j         j        dz  dz   dz  S )Nr   r   r!   )configr'   r@   s    r   init_noise_sigmaz"EDMEulerScheduler.init_noise_sigmav   s     %q(1,44r   c                     | j         S )zg
        The index counter for current timestep. It will increase 1 after each scheduler step.
        )r=   rE   s    r   
step_indexzEDMEulerScheduler.step_index{   s    
 r   c                     | j         S )zq
        The index for the first timestep. It should be set from pipeline with `set_begin_index` method.
        r>   rE   s    r   begin_indexzEDMEulerScheduler.begin_index   s    
   r   r   rK   c                     || _         dS )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.
        NrJ   )r@   rK   s     r   set_begin_indexz!EDMEulerScheduler.set_begin_index   s     (r   c                 F    d|dz  | j         j        dz  z   dz  z  }||z  }|S )Nr   r   r!   )rD   r(   )r@   samplesigmac_inscaled_samples        r   precondition_inputsz%EDMEulerScheduler.precondition_inputs   s3    UAX 6 99cABr   c                     t          |t          j                  st          j        |g          }dt          j        |          z  }|S )Ng      ?)
isinstancer   r   tensorlog)r@   rP   c_noises      r   r7   z$EDMEulerScheduler.precondition_noise   s@    %.. 	*L%))E5)))r   c                 &   | j         j        }|dz  |dz  |dz  z   z  }| j         j        dk    r||z  |dz  |dz  z   dz  z  }nC| j         j        dk    r| |z  |dz  |dz  z   dz  z  }nt          d| j         j         d          ||z  ||z  z   }|S )Nr   r$   r!   v_predictionzPrediction type z is not supported.)rD   r(   r+   r2   )r@   rO   model_outputrP   r(   c_skipc_outdenoiseds           r   precondition_outputsz&EDMEulerScheduler.precondition_outputs   s    [+
Q%(Z]":;;&)33J&%(Z]*Bs)JJEE[(N::FZ'5!8j!m+C*KKEE_0K___```F?U\%99r   rO   timestepreturnc                     | j         |                     |           | j        | j                  }|                     ||          }d| _        |S )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.
        NT)rH   _init_step_indexr;   rS   r<   )r@   rO   r`   rP   s       r   scale_model_inputz#EDMEulerScheduler.scale_model_input   sP     ?"!!(+++DO,))&%88%)"r   Nr3   r0   c                    || _         t          j        dd| j                   }| j        j        dk    r|                     |          }n%| j        j        dk    r|                     |          }|                    t          j        |          }| 	                    |          | _
        t          j        |t          j        d|j                  g          | _        d| _        d| _        | j                            d          | _        dS )	a  
        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.
        r   r   r"   r.   )dtyper0   r/   Nr1   )r3   r   r4   rD   r)   r5   r6   r?   float32r7   r8   r9   r:   r0   r;   r=   r>   )r@   r3   r0   rA   r;   s        r   set_timestepszEDMEulerScheduler.set_timesteps   s     $7 ~aD$<==;%110066FF['=8855d;;Fv>>0088iQv})M)M)M NOO knnU++r   c                     |p| j         j        }|p| j         j        }| j         j        }|d|z  z  }|d|z  z  }||||z
  z  z   |z  }|S )z6Constructs the noise schedule of Karras et al. (2022).r   )rD   r&   r'   r,   )r@   rA   r&   r'   r,   min_inv_rhomax_inv_rhor;   s           r   r5   z(EDMEulerScheduler._compute_karras_sigmas   sc    6!6	6!6	koAG,AG,k(A BBsJr   c                    |p| j         j        }|p| j         j        }t          j        t          j        |          t          j        |          t          |                                                    	                    d          }|S )zImplementation closely follows k-diffusion.

        https://github.com/crowsonkb/k-diffusion/blob/6ab5146d4a5ef63901326489f31f1d8e7dd36b48/k_diffusion/sampling.py#L26
        r   )
rD   r&   r'   r   r4   mathrW   lenexpflip)r@   rA   r&   r'   r;   s        r   r6   z-EDMEulerScheduler._compute_exponential_sigmas   so    
 6!6	6!6	 3 3TXi5H5H#d))TTXXZZ__`abbr   c                     || j         }||k                                    }t          |          dk    rdnd}||                                         S )Nr   r   )r8   nonzerorn   item)r@   r`   schedule_timestepsindicesposs        r   index_for_timestepz$EDMEulerScheduler.index_for_timestep   sW    %!%%1::<< w<<!##aas|  """r   c                     | j         Ut          |t          j                  r|                    | j        j                  }|                     |          | _        d S | j	        | _        d S N)
rK   rU   r   r   r?   r8   r0   rw   r=   r>   )r@   r`   s     r   rc   z"EDMEulerScheduler._init_step_index  sb    #(EL11 >#;;t~'<==#66x@@D#0Dr           infg      ?Tr[   s_churns_tmins_tmaxs_noise	generatorreturn_dictc
                 X   t          |t          t          j        t          j        f          rt          d          | j        st                              d           | j	        | 
                    |           |                    t          j                  }| j        | j	                 }
||
cxk    r|k    r+n n(t          |t          | j                  dz
  z  d          nd}t!          |j        |j        |j        |          }||z  }|
|dz   z  }|dk    r|||d	z  |
d	z  z
  d
z  z  z   }|                     |||          }||z
  |z  }| j        | j	        dz            |z
  }|||z  z   }|                    |j                  }| xj        dz  c_        |	s|fS t-          ||          S )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.
            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.Nr   g4y?rz   )rf   r0   r   r   r   r!   )r   r   )rU   intr   	IntTensor
LongTensorr2   r<   loggerwarningrH   rc   r?   rg   r;   minrn   r   shaperf   r0   r_   r=   r   )r@   r[   r`   rO   r|   r}   r~   r   r   r   rP   gammanoiseeps	sigma_hatr   
derivativedtr   s                      r   stepzEDMEulerScheduler.step  s   N heou7G HII 	G   ) 	NNE  
 ?"!!(+++ 5=))DO,EKuE^E^E^E^X^E^E^E^E^E^Gs4;//!34jAAAdgl&8AT`i
 
 
 goUQY'	199cY\E1H%<$DDDF  $88yYY 33y@
[1,-	9zB. "nn\%788 	A 	">!&;Uijjjjr   original_samplesr   r8   c                 `     j                             |j        |j                  }|j        j        dk    rft          j        |          rR j                            |j        t
          j                  |                    |j        t
          j                  }n9 j                            |j                  |                    |j                  } j	         fd|D             }n4 j
         j
        g|j        d         z  }n j	        g|j        d         z  }||                                         }t          |j                  t          |j                  k     r?|                    d          }t          |j                  t          |j                  k     ?|||z  z   }|S )N)r0   rf   mps)rf   c                 <    g | ]}                     |          S r   )rw   ).0trt   r@   s     r   
<listcomp>z/EDMEulerScheduler.add_noise.<locals>.<listcomp>  s*    ^^^qD33A7IJJ^^^r   r   )r;   r?   r0   rf   typer   is_floating_pointr8   rg   rK   rH   r   flattenrn   	unsqueeze)	r@   r   r   r8   r;   step_indicesrP   noisy_samplesrt   s	   `       @r   	add_noisezEDMEulerScheduler.add_noisep  s    '7'>FVF\]]"'500U5LY5W5W0!%!2!23C3JRWR_!2!`!`!%5%<EMRRII!%!2!23C3J!K!K!%5%<==I #^^^^^T]^^^LL_( O,yq/AALL !,-	0BBL|$,,..%+%5%;!<!<<<OOB''E %+%5%;!<!<<< )55=8r   c                     | j         j        S ry   )rD   r*   rE   s    r   __len__zEDMEulerScheduler.__len__  s    {..r   )r   r    r!   r"   r#   r$   r%   )r   ry   )NN)%r   r   r   r   _compatiblesorderr	   floatstrr   rB   propertyrF   rH   rK   rM   rS   r7   r_   r   r   r   rd   r0   rh   r5   r6   rw   rc   r   	Generatorboolr   r   r   r   r   r   r   r   r   r   1   sJ        @ LE !&#'(, ,, , 	,
 , !, , , , , ,@ 5 5 X5     X  ! ! X!( (3 ( ( ( (  
     eU\FY@Z _d_k    0, , ,eCDU>V , , , ,6	 	el 	 	 	 	 SXS_    # # # #1 1 1 e/3 ]k ]kl]k u|+,]k 	]k
 ]k ]k ]k ]k EO,]k ]k 
&-	.]k ]k ]k ]k@, | <	
 
   B/ / / / /r   r   )rm   dataclassesr   typingr   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 A A A A A A A ' ' ' ' ' ' ' ' , , , , , , , , , , , , 
	H	%	% 8 8 8 8 8j 8 8 8"a/ a/ a/ a/ a/ a/ a/ a/ a/ a/r   