o
    i                     @   sX   d dl Z d dlmZmZ d dlmZ G dd dejZG dd deZdefd	d
Z	dS )    N)ComfyExtensionio)overridec                   @   sH   e Zd ZedejfddZedejjde	de	de	dej
f
dd	Zd
S )
NAGuidancereturnc                 C   sr   t jdddddt jjdddt jjd	d
dddddt jjdd
dddddt jjddddddgt jjddgdS )Nr   zNormalized Attention GuidancezgApplies Normalized Attention Guidance to models, enabling negative prompts on distilled/schnell models.zadvanced/guidanceTmodelzThe model to apply NAG to.)tooltip	nag_scaleg        g      @g      I@g?zOThe guidance scale factor. Higher values push further from the negative prompt.)mindefaultmaxstepr   	nag_alphag      ?      ?g{Gz?zXBlending factor for the normalized attention. 1.0 is full replacement, 0.0 is no effect.nag_taug      ?g      $@)r
   r   r   r   z#The patched model with NAG enabled.)node_iddisplay_namedescriptioncategoryis_experimentalinputsoutputs)r   SchemaModelInputFloatOutput)cls r   4/mnt/c/Users/fbmor/ComfyUI/comfy_extras/nodes_nag.pydefine_schema   s   	zNAGuidance.define_schemar   r	   r   r   c                    s4   |  } fdd}|| |  t|S )Nc                    s  | dd }|d u r| S d|v rd|v s| S | dd }|d ur0| }| d d |d |d f } | jd }|t| }|d}|d}| || ||d   }	| || ||d   }
|	 |
d   }d}tj|	dddd	|}tj|dddd	|}|| }t|t|| }|| }|  |	d    }|d ur|||| ||d  |d |d f< |||| ||d  |d |d f< |S || || ||d  < | S )
Ncond_or_uncond   r   	img_slicer   gư>T)pdimkeepdim)	getshapelenindextorchnorm	clamp_minminimum	full_like)outextra_optionsr!   r#   orig_out
batch_size	half_sizeind_negind_posz_posz_negguidedepsnorm_posnorm_guidedratioscale_factorguided_normalizedz_finalr   r	   r   r   r   nag_attention_output_patch#   s:   


((z6NAGuidance.execute.<locals>.nag_attention_output_patch)cloneset_model_attn1_output_patchdisable_model_cfg1_optimizationr   
NodeOutput)r   r   r	   r   r   mrC   r   rB   r   execute   s
   
1
zNAGuidance.executeN)__name__
__module____qualname__classmethodr   r   r    r   TypefloatrG   rI   r   r   r   r   r      s
    *r   c                   @   s(   e Zd Zedeeej  fddZdS )NagExtensionr   c                    s   t gS N)r   )selfr   r   r   get_node_list[   s   zNagExtension.get_node_listN)	rJ   rK   rL   r   listtyper   	ComfyNoderS   r   r   r   r   rP   Z   s    rP   r   c                      s   t  S rQ   )rP   r   r   r   r   comfy_entrypointb   s   rW   )
r,   comfy_api.latestr   r   typing_extensionsr   rV   r   rP   rW   r   r   r   r   <module>   s    T