o
    ߥi1$                     @   s<   d dl Z ddgZdd Z			d	ddZG dd deZdS )
    NGaussianDiffusionbeta_schedulec                 C   s:   |  |j} |dfd|jd   }| | | |S )z?Index tensor using t and format the output according to x.
    r      r   )todevicesizendimview)tensortxshape r   k/home/ubuntu/.local/lib/python3.10/site-packages/modelscope/models/multi_modal/video_synthesis/diffusion.py_i
   s   r     c                 C   s6   | dkrt j|d |d |t jdd S td|  )N	linear_sdg      ?dtype   zUnsupported schedule: )torchlinspacefloat64
ValueError)schedulenum_timesteps	init_beta	last_betar   r   r   r      s   c                   @   s   e Zd ZdZ					dddZi d	d	d	fd
dZdd Ze i d	d	d	d	ddfddZ	e i d	d	d	d	ddfddZ
dd Zd	S )r   z Diffusion Model for DDIM.
    "Denoising diffusion implicit models." by Song, Jiaming, Chenlin Meng, and Stefano Ermon.
    See https://arxiv.org/abs/2010.02502
    epslearned_rangemse-q=Fc                 C   s  t |tjstj|tjd}t|dkrt|dksJ |dv s"J |dv s(J |dv s.J || _t|| _	|| _
|| _|| _|| _|| _d| j }tj|dd| _t|dg| jd d g| _t| jdd  |dgg| _t| j| _td	| j | _td	| j | _td	| j | _td	| j d | _|d	| j  d	| j  | _t| jd
| _|t| j d	| j  | _ d	| j t| d	| j  | _!d S )Nr   r   r   )x0zx_{t-1}r   )learnedr    fixed_largefixed_small)r!   rescaled_mseklrescaled_kll1rescaled_l1charbonnierdim      ?g#B;)"
isinstancer   DoubleTensorr   r   minmaxbetaslenr   	mean_typevar_type	loss_typeepsilonrescale_timestepscumprodalphas_cumprodcatnew_onesalphas_cumprod_prev	new_zerosalphas_cumprod_nextsqrtsqrt_alphas_cumprodsqrt_one_minus_alphas_cumprodloglog_one_minus_alphas_cumprodsqrt_recip_alphas_cumprodsqrt_recipm1_alphas_cumprodposterior_varianceclampposterior_log_variance_clippedposterior_mean_coef1posterior_mean_coef2)selfr5   r7   r8   r9   r:   r;   alphasr   r   r   __init__$   sb   




zGaussianDiffusion.__init__Nc                 C   s  |du r|||  |fi |}npt|trt|dksJ |||  |fi |d }	|||  |fi |d }
| jdrE|	dn|	dd }|
ddd|f }||	ddd|f |
ddd|f   }|	dd|df }tj|| |gdd}| jdkrt	| j
||}t	| j||}| jdkrt	| j||| t	| j|||  }| |||\}}}|dur|dkr|dksJ tj|d |ddd	d
ddd}t|t| || }n|dur|| |}||||fS )z*Distribution of p(x_{t-1} | x_t).
        Nr   r   r   fixedr-   r&   r   r0   r/   )_scale_timestepsr1   listr6   r8   
startswithr   r   r>   r   rJ   rL   r7   rH   rI   q_posterior_mean_variancequantileflattenabsclamp_r
   r3   r4   rK   )rO   xtr   modelmodel_kwargsrK   
percentileguide_scaleouty_outu_outr.   abcvarlog_varr#   mu_sr   r   r   p_mean_variance]   sH   ,

z!GaussianDiffusion.p_mean_variancec                 C   sJ   t | j||| t | j|||  }t | j||}t | j||}|||fS )z/Distribution of q(x_{t-1} | x_t, x_0).
        )r   rM   rN   rJ   rL   )rO   r#   r[   r   rh   rf   rg   r   r   r   rV      s   
z+GaussianDiffusion.q_posterior_mean_variance   g        c              	   C   s  | j |	 }| |||||||\}}}}|durWt| j||}t| j||| | t| j|| }|d|  ||| |fi |  }t| j||| t| j|||  }t| j||| | t| j|| }t| j||}t| j|| d|}d| d|  }d||  }|
t	||  }t	
|}t	d| |d  | }|d jdgd|jd  R  }t	|| | || |  }||fS )zSample from p(x_{t-1} | x_t) using DDIM.
            - condition_fn: for classifier-based guidance (guided-diffusion).
            - guide_scale: for classifier-free guidance (glide/dalle-2).
        Nr   r   r   r/   r   )r   rk   r   r=   rH   rI   rC   rS   rK   r   
randn_likenefloatr
   r	   )rO   r[   r   r\   r]   rK   r^   condition_fnr_   ddim_timestepsetastrideri   r#   alphar   rP   alphas_prevrc   rd   sigmasnoise	directionmaskxt_1r   r   r   ddim_sample   s@   



&zGaussianDiffusion.ddim_samplec
                 C   s   | d}
|}dtd| j| j|  d| jd d}|D ]}tj|
f|tj|jd}| 	||||||||||	
\}}q |S )Nr   r   )r   r   )
r   r   aranger   rK   flipfulllongr   r{   )rO   rw   r\   r]   rK   r^   rp   r_   rq   rr   rd   r[   stepsstepr   ri   r   r   r   ddim_sample_loop   s"   


z"GaussianDiffusion.ddim_sample_loopc                 C   s   | j r| d | j S |S )Ng     @@)r;   ro   r   )rO   r   r   r   r   rS      s   z"GaussianDiffusion._scale_timesteps)r   r    r!   r"   F)__name__
__module____qualname____doc__rQ   rk   rV   r   no_gradr{   r   rS   r   r   r   r   r      sB    
=
0	0)r   NN)r   __all__r   r   objectr   r   r   r   r   <module>   s   	
