o
    i                     @   s   d dl Z d dlmZ d dlmZ d dlmZmZ G dd dejZ	de j
ded	ed
e j
fddZG dd dejZG dd deZd
efddZdS )    N)override)sigma_to_half_log_snr)ComfyExtensionioc                   @   s0   e Zd ZdZedd ZedejfddZdS )EpsilonScalinga  
    Implements the Epsilon Scaling method from 'Elucidating the Exposure Bias in Diffusion Models'
    (https://arxiv.org/abs/2308.15321v6).

    This method mitigates exposure bias by scaling the predicted noise during sampling,
    which can significantly improve sample quality. This implementation uses the "uniform schedule"
    recommended by the paper for its practicality and effectiveness.
    c                 C   s@   t jddt jdt jjdddddt jjd	d
gt j gdS )NzEpsilon Scalingmodel_patches/unetmodelscaling_factorgGz?g      ?g      ?MbP?T)defaultminmaxstepdisplay_modeadvanced)node_idcategoryinputsoutputsr   SchemaModelInputFloatNumberDisplaynumberOutputcls r   4/mnt/c/Users/fbmor/ComfyUI/comfy_extras/nodes_eps.pydefine_schema   s"   
zEpsilonScaling.define_schemareturnc                    s4    dkrd  fdd}|  }|| t|S )Nr   g&.>c                    s,   | d }| d }|| }|  }|| }|S )z
            This function is applied after the CFG guidance has been calculated.
            It recalculates the denoised latent by scaling the predicted noise.
            denoisedinputr   )argsr#   x
noise_predscaled_noise_prednew_denoisedr	   r   r    epsilon_scaling_function-   s   z8EpsilonScaling.execute.<locals>.epsilon_scaling_functionclone#set_model_sampler_post_cfg_functionr   
NodeOutput)r   r   r	   r+   model_cloner   r*   r    execute'   s   

zEpsilonScaling.executeN)	__name__
__module____qualname____doc__classmethodr!   r   r/   r1   r   r   r   r    r      s    
r   snrtsr_ktsr_variancer"   c                 C   s4   t | }| | d | | | d  }t |||S )zCompute the rescaling score ratio in Temporal Score Rescaling.

    See equation (6) in https://arxiv.org/pdf/2510.01184v1.
       )torchisposinfwhere)r7   r8   r9   posinf_maskrescaling_factorr   r   r    compute_tsr_rescaling_factorE   s   
r@   c                   @   s,   e Zd Zedd ZedejfddZdS )TemporalScoreRescalingc                 C   sh   t jdddt jdt jjddddd	d
t jjddt jjddddd	d
t jjddgt jjddgddS )NrA   zTSR - Temporal Score Rescalingr   r   r8   zControls the rescaling strength.
Lower k produces more detailed results; higher k produces smoother results in image generation. Setting k = 1 disables rescaling.gffffff?g{Gz?g      Y@r
   T)tooltipr   r   r   r   r   r   	tsr_sigmazMControls how early rescaling takes effect.
Larger values take effect earlier.g      ?patched_model)display_namez[Post-CFG Function]
TSR - Temporal Score Rescaling (2510.01184)

Rescaling the model's score or noise to steer the sampling diversity.
)r   rE   r   r   r   descriptionr   r   r   r   r    r!   R   s@   
z$TemporalScoreRescaling.define_schemar"   c                    s2   |d  fdd}|  }|| t|S )N   c           
         s   | d }| d }| d }| d } dks|dkr|S |j d}t||}d|  }|dkr1|S t| }||  }	t||	 ||S )	Nr#   r$   sigmar   r:   r   model_samplingrG   )current_patcherget_model_objectr   expr@   r;   lerp)
r%   r#   r&   rH   
curr_modelrI   half_log_snrr7   rescaling_ralphar8   r9   r   r    temporal_score_rescaling   s   
z@TemporalScoreRescaling.execute.<locals>.temporal_score_rescalingr,   )r   r   r8   rC   rS   mr   rR   r    r1      s
   

zTemporalScoreRescaling.executeN)r2   r3   r4   r6   r!   r   r/   r1   r   r   r   r    rA   Q   s
    
.rA   c                   @   s(   e Zd Zedeeej  fddZdS )EpsilonScalingExtensionr"   c                    s
   t tgS N)r   rA   )selfr   r   r    get_node_list   s   z%EpsilonScalingExtension.get_node_listN)	r2   r3   r4   r   listtyper   	ComfyNoderX   r   r   r   r    rU      s    rU   c                      s   t  S rV   )rU   r   r   r   r    comfy_entrypoint   s   r\   )r;   typing_extensionsr   comfy.k_diffusion.samplingr   comfy_api.latestr   r   r[   r   Tensorfloatr@   rA   rU   r\   r   r   r   r    <module>   s"    =
Q	