o
    ߥih                     @   s|   d dl Z d dlZd dlmZmZmZmZ ddgZdd Zdd Z	d	d
 Z
dd Zdd Z			dddZG dd deZdS )    N)
DPM_SolverNoiseScheduleVPmodel_wrappermodel_wrapper_guided_diffusionGaussianDiffusionbeta_schedulec                 C   s>   d| | t ||  }| | d t |  }d||  S )Ng               ?)torchexp)mu1logvar1mu2logvar2ab r   e/home/ubuntu/.local/lib/python3.10/site-packages/modelscope/models/multi_modal/diffusion/diffusion.pykl_divergence   s   r   c                 C   s2   ddt tdtj | dt | d     S )Nr	         ?       @gHm?   )r
   tanhmathsqrtpipow)xr   r   r   standard_normal_cdf   s   "r   c                 C   s   | j |j   kr|j ksJ  J | | }t| }t||d  }t||d  }t|jdd}td| jdd}|| }	t| dk |t| dk|t|	jdd}
|
j | j ksbJ |
S )Ngp?g-q=)minr   g++?)shaper
   r   r   logclampwhere)x0mean	log_scalecxinv_stdvcdf_pluscdf_minlog_cdf_pluslog_one_minus_cdf_min	cdf_delta	log_probsr   r   r   #discretized_gaussian_log_likelihood   s    "r0   c                 C   s:   |  |j} |dfd|jd   }| | | |S )Nr      r2   )todevicesizendimview)tensortr   r!   r   r   r   _i*   s   r:   c                 C   s    t | d d t j d d S )NgMb?gT㥛 ?r   )r   cosr   )ur   r   r   	cosine_fn0   s    r=     c           	      C   s   | dkrd| }|p|d }|p|d }t j|||t jdS | dkr:|p%d}|p)d}t j|d	 |d	 |t jdd
 S | dkrig }t|D ]}|| }|d | }|tdt|t|  d qDt j|t jdS td|  )Nlinear     @@g-C6?g{Gz?dtype	quadraticg~jtX?g+?r	   r   cosiner2   r   r    zUnsupported schedule: )	r
   linspacefloat64rangeappendr   r=   r8   
ValueError)	schedulenum_timesteps	init_beta	last_betascalebetasstept1t2r   r   r   r   4   s0   
"c                   @   s  e Zd Z				d.ddZd/dd	Zd
d Zdd Ze i ddddfddZ	e i ddddfddZ
i dddfddZe i ddddddddddf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e i ddddfddZe i ddddfd d!Ze i dddddfd"d#Ze i dddddfd$d%Zi dfd&d'Zi ddfd(d)Ze i ddfd*d+Zd,d- ZdS )0r   epslearned_rangemseFc                 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 )NrA   r   r2   )r%   x_{t-1}rS   )learnedrT   fixed_largefixed_small)rU   rescaled_mseklrescaled_kll1rescaled_l1dimr   g#B;)!
isinstancer
   DoubleTensorr8   rF   r   maxrO   lenrK   	mean_typevar_type	loss_typerescale_timestepscumprodalphas_cumprodcatnew_onesalphas_cumprod_prev	new_zerosalphas_cumprod_nextr   sqrt_alphas_cumprodsqrt_one_minus_alphas_cumprodr"   log_one_minus_alphas_cumprodsqrt_recip_alphas_cumprodsqrt_recipm1_alphas_cumprodposterior_variancer#   posterior_log_variance_clippedposterior_mean_coef1posterior_mean_coef2)selfrO   rf   rg   rh   ri   alphasr   r   r   __init__Q   s`   




zGaussianDiffusion.__init__Nc                 C   s:   |d u r	t |n|}t| j||| t| j|||  S N)r
   
randn_liker:   rq   rr   )rz   r%   r9   noiser   r   r   q_sample   s   zGaussianDiffusion.q_samplec                 C   s<   t | j||| }t d| j ||}t | j||}|||fS )Nr   )r:   rq   rk   rs   )rz   r%   r9   muvarlog_varr   r   r   q_mean_variance   s   
z!GaussianDiffusion.q_mean_variancec                 C   sJ   t | j||| t | j|||  }t | j||}t | j||}|||fS r}   )r:   rx   ry   rv   rw   )rz   r%   xtr9   r   r   r   r   r   r   q_posterior_mean_variance   s   
z+GaussianDiffusion.q_posterior_mean_variancec	              	   C   s   |  |||||||\}	}
}}t|}dd|jd   }|d j| }|d urA||| |fi |}|	 |
|   }	|	|td|  |  }||fS )N)ra   r1   r2   r   r	   )	p_mean_variancer
   r~   r6   nefloatr7   _scale_timestepsr   )rz   r   r9   modelmodel_kwargsr#   
percentilecondition_fnguide_scaler   r   r   r%   r   r!   maskgradxt_1r   r   r   p_sample   s   
zGaussianDiffusion.p_samplec                 C   sd   |  \}}	}
}|}t| jdD ]}tj|f|tj|jd}| ||||||||\}}q|S Nr   rB   r4   )	r5   r
   arangerK   flipfulllongr4   r   )rz   r   r   r   r#   r   r   r   r   chwr   rP   r9   _r   r   r   p_sample_loop   s   

zGaussianDiffusion.p_sample_loopc                 C   s  |d u r|||  |fi |}net|trt|dksJ | jdks%J |||  |fi |d }	|||  |fi |d }
|
d d d df }||	d d d df |
d d d df   }|	d d dd f }tj|| |gdd}| jdkr|jddd\}}t	|}nh| jdkr|jddd\}}t
| j||}t
t| j||}|d d	 }|| d| |  }t	|}n3| jd
krt
t| jdd | jdd  g||}t|}n| jdkrt
| j||}t
| j||}| jdkr|}t
d| j ||| t
| j| j |||  }n5| jdkr%|}| |||\}}}n"| jdkrGt
| j||| t
| j|||  }| |||\}}}|d ur||dkrV|dksXJ tj|d |ddddddd}t|t| || }n|d ur|| |}||||fS )Nr   rS   r   r2   r   r_   rW   rT   r   rX   rY   rV   r   r%   ra   )r   rb   listre   rf   r
   rl   rg   chunkr   r:   rw   r"   rO   rv   rx   ry   r   rt   ru   quantileflattenabsclamp_r7   r   rd   r#   )rz   r   r9   r   r   r#   r   r   outy_outu_outr   r   r   r   r   fractionmin_log_varmax_log_varr   r%   r   sr   r   r   r      sv   	,


"


z!GaussianDiffusion.p_mean_variance   T
dpm_solverc                 C   sf   t d| j d}t||| j| j|||| j| j|
|	d}t||d}|j	||||||||||d
}|S )a  Sample using DPM-Solver-based method.
            - condition_fn: for classifier-based guidance (guided-diffusion).
            - guide_scale: for classifier-free guidance (glide/dalle-2).
            Please check all the parameters in `dpm_solver.sample` before using.
        discrete)rJ   rO   )r   noise_schedulerg   rf   r   r#   r   ri   rK   r   r   )model_fnr   )	stepsorder	skip_typemethodsolver_typet_startt_endlower_order_finaldenoise_to_zero)
r   rO   r   r   rg   rf   ri   rK   r   sample)rz   r   r   r   r   r   r   r#   r   r   r   dpm_solver_timestepsr   r   r   r   r   r   r   r   r   r   r   r   dpm_solver_sample_loop
  sB   
z(GaussianDiffusion.dpm_solver_sample_loop        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 )Nr2   r   r   ra   r1   )rK   r   r:   rk   rt   ru   r   r   r#   r
   r~   r   r   r7   r6   )rz   r   r9   r   r   r#   r   r   r   ddim_timestepsetastrider   r%   alpharS   r{   alphas_prevr   r   sigmasr   	directionr   r   r   r   r   ddim_sampleA  s@   



&zGaussianDiffusion.ddim_samplec
                 C   s   |  \}
}}}|}dtd| j| j|  d| jd d}|D ]}tj|
f|tj|jd}| 	||||||||||	
\}}q#|S )Nr2   r   r   )
r5   r
   r   rK   r#   r   r   r   r4   r   )rz   r   r   r   r#   r   r   r   r   r   r   r   r   r   r   r   rP   r9   r   r   r   r   ddim_sample_loopn  s"   

z"GaussianDiffusion.ddim_sample_loopc	              	   C   s   | j | }	| |||||||\}
}
}
}t| j||| | t| j|| }tt| j| jdgg||	 	d| j |}t
|| t
d| |  }||fS )Nr2   r   )rK   r   r:   rt   ru   r
   rl   rk   ro   r#   r   )rz   r   r9   r   r   r#   r   r   r   r   r   r%   rS   alphas_nextr   r   r   r   ddim_reverse_sample  s"   

 z%GaussianDiffusion.ddim_reverse_samplec                 C   sl   |  \}}	}
}|}td| j| j| }|D ]}tj|f|tj|jd}| ||||||||\}}q|S r   )r5   r
   r   rK   r   r   r4   r   )rz   r%   r   r   r#   r   r   r   r   r   r   r   r   r   rP   r9   r   r   r   r   ddim_reverse_sample_loop  s   


z*GaussianDiffusion.ddim_reverse_sample_loopc
                    s   j |	  fdd}
fdd}|
|}ttdkr<|||\}}|
|| d}|| d }nHttdkrMd| td	  d }n7ttd
krfd| dtd	   dtd   d }nttdkrd| dtd	   dtd   dtd   d }|||\}}|||fS )Nc              	      s    | | \}}}}d urRtj|| }tj|| |  | tj||  }|d|  | |fi   }tj|| |  tj|| |  }tj|| |  | tj||  }|S )Nr2   )r   r:   rk   rt   ru   r   r   )r   r9   r   r%   r   rS   )r#   r   r   r   r   r   rz   r   r   compute_eps  s0   

z2GaussianDiffusion.plms_sample.<locals>.compute_epsc                    sh   t  j| t  j||   }t  j| d}td| |  }t|| | }||fS )Nr   r2   )r:   rt   ru   rk   r#   r
   r   )rS   r9   r%   r   r   r   )rz   r   r   r   r   
compute_x0  s   z1GaussianDiffusion.plms_sample.<locals>.compute_x0r   r   r2   r   ra   r            g      (@7   ;   %   	   g      8@)rK   re   	eps_cacher#   )rz   r   r9   r   r   r#   r   r   r   plms_timestepsr   r   rS   r   r%   eps_next	eps_primer   )	r#   r   r   r   r   r   rz   r   r   r   plms_sample  s0   




zGaussianDiffusion.plms_samplec	                 C   s   |  \}	}
}}|}dtd| j| j|  d| jd d}g }|D ]/}tj|	f|tj|jd}| 	||||||||||
\}}}|
| t|dkrT|d q%|S )Nr2   r   r      )r5   r
   r   rK   r#   r   r   r   r4   r   rH   re   pop)rz   r   r   r   r#   r   r   r   r   r   r   r   r   r   r   r   rP   r9   r   rS   r   r   r   plms_sample_loop  s.   



z"GaussianDiffusion.plms_sample_loopc                    sJ  |d u r	t |n|}| j|||d}| jdv r/| |||||\}}| jdkr-|| j }|S | jdv r||| |fi |}	d}
| jdv rw|	jddd	\}	}t j	|	
 |gdd	 | j||| fd
dd\}
}| jdrw|
| j d }
||| |||d d| j }|	| | jdrdnd djdd	}||
 }|S )N)r   )r[   r\   r\   )rU   rZ   r]   r^   r   )rW   rT   r   r2   r_   c                     s    S r}   r   )argskwargsfrozenr   r   <lambda>8  s    z(GaussianDiffusion.loss.<locals>.<lambda>)r   	rescaled_r@   r   )rS   r%   rV   r]   )r
   r~   r   rh   variational_lower_boundrK   r   rg   r   rl   detach
startswithr   rf   r   endswithr   r   r&   )rz   r%   r9   r   r   r   r   lossr   r   loss_vlbr   targetr   r   r   r   #  sF   





zGaussianDiffusion.lossc                 C   s   |  |||\}}	}
| ||||||\}}	}}t||
||}|djddtd }t||d| d }|djddtd }t	|dk||}||fS )Nr2   r_   r   r	   )r&   r'   r   )
r   r   r   r   r&   r   r"   r0   r
   r$   )rz   r%   r   r9   r   r   r#   r   r   r   log_var1r   log_var2r[   nllvlbr   r   r   r   I  s   	
z)GaussianDiffusion.variational_lower_boundc              
   C   sv  |  \}}}}	g g g d}
t| jdD ]d}tj|f|tj|jd}t|}| 	|||}| 
|||||||\}}t| j||| | t| j|| }|
d | |
d ||  djdd |
d ||  djdd qd	d
 |
 D }
| ||\}}}t||t|t|}|djddtd }||
d< |
d jdd| |
d< |
S )N)r   rU   x0_mser   r   r   r   r2   r_   rU   c                 S   s    i | ]\}}|t j|d dqS )r2   r_   )r
   stack).0kvr   r   r   
<dictcomp>  s     zBGaussianDiffusion.variational_lower_bound_loop.<locals>.<dictcomp>r   prior_bits_per_dimtotal_bits_per_dim)r5   r
   r   rK   r   r   r   r4   r~   r   r   r:   rt   ru   rH   squarer   r&   itemsr   r   
zeros_liker   r"   sum)rz   r%   r   r   r#   r   r   r   r   r   metricsrP   r9   r   r   r   pred_x0rS   r   r   r   kl_priorr   r   r   variational_lower_bound_loopc  s8   
z.GaussianDiffusion.variational_lower_bound_loopc                 C   s   | j r| d | j S |S )Nr@   )ri   r   rK   )rz   r9   r   r   r   r     s   z"GaussianDiffusion._scale_timesteps)rS   rT   rU   Fr}   )__name__
__module____qualname__r|   r   r   r   r
   no_gradr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   O   s    

6
D6,E +
*)r>   NN)r   r
   0modelscope.models.multi_modal.dpm_solver_pytorchr   r   r   r   __all__r   r   r0   r:   r=   r   objectr   r   r   r   r   <module>   s   
