
    wisW                         d dl Z d dlmZmZmZmZ d dlZd dlZddl	m
Z
mZ ddlmZmZmZ 	 	 dd	Z G d
 dee
          ZdS )    N)ListOptionalTupleUnion   )ConfigMixinregister_to_config   )KarrasDiffusionSchedulersSchedulerMixinSchedulerOutput+?cosinec           
      F   |dk    rd }n|dk    rd }nt          d|           g }t          |           D ]J}|| z  }|dz   | z  }|                    t          d ||           ||          z  z
  |                     Kt	          j        |t          j                  S )a  
    Create a beta schedule that discretizes the given alpha_t_bar function, which defines the cumulative product of
    (1-beta) over time from t = [0,1].

    Contains a function alpha_bar that takes an argument t and transforms it to the cumulative product of (1-beta) up
    to that part of the diffusion process.


    Args:
        num_diffusion_timesteps (`int`): the number of betas to produce.
        max_beta (`float`): the maximum beta to use; use values lower than 1 to
                     prevent singularities.
        alpha_transform_type (`str`, *optional*, default to `cosine`): the type of noise schedule for alpha_bar.
                     Choose from `cosine` or `exp`

    Returns:
        betas (`np.ndarray`): the betas used by the scheduler to step the model outputs
    r   c                 \    t          j        | dz   dz  t           j        z  dz            dz  S )NgMb?gT㥛 ?r   )mathcospits    }/root/.openclaw/workspace/chatterbox_venv_py311/lib/python3.11/site-packages/diffusers/schedulers/scheduling_heun_discrete.pyalpha_bar_fnz)betas_for_alpha_bar.<locals>.alpha_bar_fn3   s,    8QY%/$'9A=>>!CC    expc                 0    t          j        | dz            S )Ng      ()r   r   r   s    r   r   z)betas_for_alpha_bar.<locals>.alpha_bar_fn8   s    8AI&&&r   z"Unsupported alpha_transform_type: r
   dtype)
ValueErrorrangeappendmintorchtensorfloat32)num_diffusion_timestepsmax_betaalpha_transform_typer   betasit1t2s           r   betas_for_alpha_barr,      s    . x''	D 	D 	D 	D 
	&	&	' 	' 	' 	' T>RTTUUUE*++ M M((!e..S\\"--R0@0@@@(KKLLLL<U]3333r   c                      e Zd ZdZd eD             ZdZe	 	 	 	 	 	 	 	 	 	 	 d5dede	de	de
deeej        ee	         f                  de
dee         dee         de	de
defd            Zd6dZed             Zed             Zed             Zd7defdZd ej        d!ee	ej        f         d"ej        fd#Z	 	 	 	 d8d$ee         d%ee
ej        f         dee         d&eee                  fd'Zd( Zd)ej        d"ej        fd*Zed+             Zd, Z 	 d9d.eej        ej        f         d!ee	ej        f         d eej        ej        f         d/ed"ee!e"f         f
d0Z#d1ej        d2ej        d&ej        d"ej        fd3Z$d4 Z%dS ):HeunDiscreteScheduleru  
    Scheduler with Heun steps for discrete beta schedules.

    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.
        beta_start (`float`, defaults to 0.0001):
            The starting `beta` value of inference.
        beta_end (`float`, defaults to 0.02):
            The final `beta` value.
        beta_schedule (`str`, defaults to `"linear"`):
            The beta schedule, a mapping from a beta range to a sequence of betas for stepping the model. Choose from
            `linear` or `scaled_linear`.
        trained_betas (`np.ndarray`, *optional*):
            Pass an array of betas directly to the constructor to bypass `beta_start` and `beta_end`.
        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).
        clip_sample (`bool`, defaults to `True`):
            Clip the predicted sample for numerical stability.
        clip_sample_range (`float`, defaults to 1.0):
            The maximum magnitude for sample clipping. Valid only when `clip_sample=True`.
        use_karras_sigmas (`bool`, *optional*, defaults to `False`):
            Whether to use Karras sigmas for step sizes in the noise schedule during the sampling process. If `True`,
            the sigmas are determined according to a sequence of noise levels {σi}.
        timestep_spacing (`str`, defaults to `"linspace"`):
            The way the timesteps should be scaled. Refer to Table 2 of the [Common Diffusion Noise Schedules and
            Sample Steps are Flawed](https://huggingface.co/papers/2305.08891) for more information.
        steps_offset (`int`, defaults to 0):
            An offset added to the inference steps, as required by some model families.
    c                     g | ]	}|j         
S  )name).0es     r   
<listcomp>z HeunDiscreteScheduler.<listcomp>k   s    >>>qAF>>>r   r     _QK?~jt?linearNepsilonF      ?linspacer   num_train_timesteps
beta_startbeta_endbeta_scheduletrained_betasprediction_typeuse_karras_sigmasclip_sampleclip_sample_rangetimestep_spacingsteps_offsetc                    |&t          j        |t           j                  | _        n|dk    r(t          j        |||t           j                  | _        n|dk    r1t          j        |dz  |dz  |t           j                  dz  | _        nS|dk    rt          |d          | _        n6|d	k    rt          |d	          | _        nt          | d
| j                   d| j        z
  | _        t          j	        | j        d          | _
        |                     |d |           || _        d | _        d | _        | j                            d          | _        d S )Nr   r8   scaled_linear      ?r   squaredcos_cap_v2r   )r'   r   z is not implemented for r:   r   )dimcpu)r"   r#   r$   r(   r;   r,   NotImplementedError	__class__alphascumprodalphas_cumprodset_timestepsrB   _step_index_begin_indexsigmasto)selfr<   r=   r>   r?   r@   rA   rB   rC   rD   rE   rF   s               r   __init__zHeunDiscreteScheduler.__init__n   se    $m5=IIIDJJh&&
H>QY^YfgggDJJo--
C3H[chcpqqquvvDJJ111,-@W_```DJJe##,-@W\]]]DJJ%&`&`PTP^&`&`aaaDJ&#mDKQ??? 	.6IJJJ!2 knnU++r   c                     || j         }||k                                    }t          |          dk    rdnd}||                                         S )Nr
   r   )	timestepsnonzerolenitem)rW   timestepschedule_timestepsindicesposs        r   index_for_timestepz(HeunDiscreteScheduler.index_for_timestep   sW    %!%%1::<< w<<!##aas|  """r   c                     | j         j        dv r| j                                        S | j                                        dz  dz   dz  S )N)r;   trailingr   r
   rI   )configrE   rU   maxrW   s    r   init_noise_sigmaz&HeunDiscreteScheduler.init_noise_sigma   sH     ;'+CCC;??$$$!!Q&*s22r   c                     | j         S )zg
        The index counter for current timestep. It will increase 1 after each scheduler step.
        )rS   rg   s    r   
step_indexz HeunDiscreteScheduler.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.
        rT   rg   s    r   begin_indexz!HeunDiscreteScheduler.begin_index   s    
   r   rm   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.
        Nrl   )rW   rm   s     r   set_begin_indexz%HeunDiscreteScheduler.set_begin_index   s     (r   sampler^   returnc                 ~    | j         |                     |           | j        | j                  }||dz  dz   dz  z  }|S )a  
        Ensures interchangeability with schedulers that need to scale the denoising model input depending on the
        current timestep.

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

        Returns:
            `torch.Tensor`:
                A scaled input sample.
        Nr   r
   rI   )rj   _init_step_indexrU   )rW   rp   r^   sigmas       r   scale_model_inputz'HeunDiscreteScheduler.scale_model_input   sJ    & ?"!!(+++DO,E1HqLS01r   num_inference_stepsdevicerZ   c           	          ||t          d          ||t          d          | j        j        rt          d          |pt          |          }| _        |p j        j        }|"t          j        |t          j                  }nr j        j	        dk    rBt          j
        d|dz
  |t          j                  ddd	                                         }n  j        j	        d
k    r|| j        z  }t          j        d|          |z                                  ddd	                                                             t          j                  }| j        j        z  }n j        j	        dk    rh| j        z  }t          j        |d|                                                                                               t          j                  }|dz  }nt           j        j	         d          t          j        d j        z
   j        z  dz            }t          j        |          t          j        |t          j        dt          |                    |          } j        j        r=                     | j                  }t          j         fd|D                       }t          j        |dgg                              t          j                  }t+          j        |                              |          }t+          j        |dd         |dd	                             d          |d	d         g           _        t+          j        |          }t+          j        |dd         |dd                             d          g          }|                    |           _        d _        d _        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.
            num_train_timesteps (`int`, *optional*):
                The number of diffusion steps used when training the model. If `None`, the default
                `num_train_timesteps` attribute is used.
            timesteps (`List[int]`, *optional*):
                Custom timesteps used to support arbitrary spacing between timesteps. If `None`, timesteps will be
                generated based on the `timestep_spacing` attribute. If `timesteps` is passed, `num_inference_steps`
                must be `None`, and `timestep_spacing` attribute will be ignored.
        NzEMust pass exactly one of `num_inference_steps` or `custom_timesteps`.zACan only pass one of `num_inference_steps` or `custom_timesteps`.z=Cannot use `timesteps` with `config.use_karras_sigmas = True`r   r;   r   r
   leadingrd   zY is not supported. Please make sure to choose one of 'linspace', 'leading' or 'trailing'.rI   )	in_sigmasrv   c                 <    g | ]}                     |          S r0   )_sigma_to_t)r2   rt   
log_sigmasrW   s     r   r4   z7HeunDiscreteScheduler.set_timesteps.<locals>.<listcomp>   s)    !Z!Z!Z%$"2"25*"E"E!Z!Z!Zr   g        )rw   r   rL   ) r   re   rB   r\   rv   r<   nparrayr$   rE   r;   copyarangeroundastyperF   rQ   loginterp_convert_to_karrasconcatenater"   
from_numpyrV   catrepeat_interleaverU   rZ   prev_derivativedtrS   rT   )rW   rv   rw   r<   rZ   
step_ratiorU   r~   s   `      @r   rR   z#HeunDiscreteScheduler.set_timesteps   s   . &9+<deee*y/D`aaa T[%B \]]]1CS^^#6 1TT[5T "*===II {+z99K+>+BDW_a_ijjjkokomokopuuww		-::0D4LL
  Yq*=>>KRRTTUYUYWYUYZ__aahhikistt	T[55		-;;043KK
  Y':A
{KKRRTTYY[[bbcecmnn	Q		 {3  O  O  O   A 33t7JJsRSSVF^^
9bi3v;;&?&?HH;( 	\,,vSWSk,llF!Z!Z!Z!Z!ZSY!Z!Z!Z[[I#0077
CC!&)),,F,;;iVAbD\-K-KA-N-NPVWYWZWZP[ \]]$Y//	Iy!}im.M.Ma.P.PQRR	"V44  $ knnU++r   c                    t          j        t          j        |d                    }||d d t           j        f         z
  }t          j        |dk    d                              d                              |j        d         dz
            }|dz   }||         }||         }||z
  ||z
  z  }	t          j        |	dd          }	d|	z
  |z  |	|z  z   }
|
                    |j                  }
|
S )Ng|=r   )axisr   )rf   r
   )	r   r   maximumnewaxiscumsumargmaxclipshapereshape)rW   rt   r~   	log_sigmadistslow_idxhigh_idxlowhighwr   s              r   r}   z!HeunDiscreteScheduler._sigma_to_t4  s    F2:eU3344	 Jqqq"*}55 )UaZq11188a8@@EE*JZ[\J]`aJaEbbQ;!(# 9_t,GAq! UgH,IIek""r   r{   c                 z   t          | j        d          r| j        j        }nd}t          | j        d          r| j        j        }nd}||n|d                                         }||n|d                                         }d}t          j        dd|          }|d|z  z  }|d|z  z  }||||z
  z  z   |z  }	|	S )z6Constructs the noise schedule of Karras et al. (2022).	sigma_minN	sigma_maxry   r   g      @r
   )hasattrre   r   r   r]   r   r;   )
rW   r{   rv   r   r   rhorampmin_inv_rhomax_inv_rhorU   s
             r   r   z(HeunDiscreteScheduler._convert_to_karrasL  s    
 4;,, 	-III4;,, 	-III!*!6IIIbM<N<N<P<P	!*!6IIIaL<M<M<O<O	{1a!455AG,AG,k(A BBsJr   c                     | j         d u S N)r   rg   s    r   state_in_first_orderz*HeunDiscreteScheduler.state_in_first_ordere  s    w$r   c                     | j         Ut          |t          j                  r|                    | j        j                  }|                     |          | _        d S | j	        | _        d S r   )
rm   
isinstancer"   TensorrV   rZ   rw   rb   rS   rT   )rW   r^   s     r   rs   z&HeunDiscreteScheduler._init_step_indexj  sb    #(EL11 >#;;t~'<==#66x@@D#0Dr   Tmodel_outputreturn_dictc                    | j         |                     |           | j        r(| j        | j                  }| j        | j         dz            }n'| j        | j         dz
           }| j        | j                  }d}||dz   z  }| j        j        dk    r| j        r|n|}	||	|z  z
  }
nj| j        j        dk    r*| j        r|n|}	||	 |	dz  dz   dz  z  z  ||	dz  dz   z  z   }
n0| j        j        dk    r|}
nt          d	| j        j         d
          | j        j        r+|
                    | j        j	         | j        j	                  }
| j        r#||
z
  |z  }||z
  }|| _
        || _        || _        n8||
z
  |z  }| j
        |z   dz  }| j        }| j        }d| _
        d| _        d| _        |||z  z   }| 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.
            return_dict (`bool`):
                Whether or not to return a [`~schedulers.scheduling_utils.SchedulerOutput`] or tuple.

        Returns:
            [`~schedulers.scheduling_utils.SchedulerOutput`] or `tuple`:
                If return_dict is `True`, [`~schedulers.scheduling_utils.SchedulerOutput`] is returned, otherwise a
                tuple is returned where the first element is the sample tensor.
        Nr
   r   r9   v_predictionr   rI   rp   zprediction_type given as z, must be one of `epsilon`, or `v_prediction`)prev_sample)rj   rs   r   rU   re   rA   r   rC   clamprD   r   r   rp   rS   r   )rW   r   r^   rp   r   rt   
sigma_nextgamma	sigma_hatsigma_inputpred_original_sample
derivativer   r   s                 r   stepzHeunDiscreteScheduler.stepr  sb   4 ?"!!(+++$ 	6K0ET_q%89JJ K! 34ET_5J
 UQY'	 ;&)33'+'@P))jK#)K,,F#F  [(N::'+'@P))jK#/K<;PQ>TUCUZ]B]3]#^+q.1,-$   [(H44#/  uDK,Guuu   ;" 	#7#=#=..0M$ $  $ 	 #779DJi'B $.D DG DKK !#77:EJ.;q@J B[F $(D DGDKzB. 	A 	">!;7777r   original_samplesnoisec                 `     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)rw   r   mpsr   c                 <    g | ]}                     |          S r0   )rb   )r2   r   r_   rW   s     r   r4   z3HeunDiscreteScheduler.add_noise.<locals>.<listcomp>  s*    ^^^qD33A7IJJ^^^r   r   ry   )rU   rV   rw   r   typer"   is_floating_pointrZ   r$   rm   rj   r   flattenr\   	unsqueeze)	rW   r   r   rZ   rU   step_indicesrt   noisy_samplesr_   s	   `       @r   	add_noisezHeunDiscreteScheduler.add_noise  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 r   )re   r<   rg   s    r   __len__zHeunDiscreteScheduler.__len__  s    {..r   )r5   r6   r7   r8   Nr9   FFr:   r;   r   r   )r   )NNNN)T)&__name__
__module____qualname____doc__r   _compatiblesorderr	   intfloatstrr   r   r   ndarrayr   boolrX   rb   propertyrh   rj   rm   ro   r"   r   ru   rw   rR   r}   r   r   rs   r   r   r   r   r   r0   r   r   r.   r.   F   s       " "H ?>$=>>>LE $(#%BF(,1&+#& *&, &, &, &, 	&,
 &,  bj$u+&= >?&, &, $D>&, d^&, !&, &, &, &, &, &,R# # # # 3 3 X3     X  ! ! X!( (3 ( ( ( ( u|+, 
	   8 .2+/-1)-P, P,%c]P, c5<'(P, &c]	P,
 DI&P, P, P, P,f  0EL RWR^    2   X1 1 1 !a8 a8EL"*45a8 u|+,a8 elBJ./	a8
 a8 
%	&a8 a8 a8 a8H, | <	
 
   B/ / / / /r   r.   )r   r   )r   typingr   r   r   r   numpyr   r"   configuration_utilsr   r	   scheduling_utilsr   r   r   r,   r.   r0   r   r   <module>r      s     / / / / / / / / / / / /      A A A A A A A A X X X X X X X X X X !)4 )4 )4 )4Xr/ r/ r/ r/ r/NK r/ r/ r/ r/ r/r   