
    
3j                         S SK Jr  S SKrSSKJrJrJrJr  SrSr	\ " S S5      5       r
 " S	 S
\5      r " S S\5      r " S S\5      r " S S\5      rS\R                  R                   S\
SS4S jrg)    )	dataclassN   )	BaseStateHookRegistry	ModelHookStateManagertext_kv_cache_transformertext_kv_cache_blockc                       \ rS rSrSrSrg)TextKVCacheConfig   aQ  Enable exact (lossless) text K/V caching for transformer models.

Pre-computes per-block text key and value projections once before the denoising loop and reuses them across all
steps. Positive and negative prompts are distinguished via a stable cache key captured by a transformer-level hook
before any intermediate tensor allocations.
 N)__name__
__module____qualname____firstlineno____doc____static_attributes__r       W/home/wildlama/miniconda3/lib/python3.13/site-packages/diffusers/hooks/text_kv_cache.pyr   r      s     	r   r   c                   $    \ rS rSrSrS rS rSrg)TextKVCacheState&   a  Shared state between the transformer-level and block-level hooks.

The transformer hook writes the stable ``encoder_hidden_states`` ``data_ptr()`` (captured *before* ``txt_norm``) so
that block hooks can use it as a reliable cache key across denoising steps.
c                     S U l         g Nkeyselfs    r   __init__TextKVCacheState.__init__-   s	    #r   c                     S U l         g r   r   r   s    r   resetTextKVCacheState.reset0   s	    r   r   Nr   r   r   r   r   r    r#   r   r   r   r   r   r   &   s    $r   r   c                   $    \ rS rSrSrS rS rSrg)TextKVCacheBlockState4   z:Per-block state holding cached text key/value projections.c                     0 U l         g r   kv_cacher   s    r   r    TextKVCacheBlockState.__init__7   s	    FHr   c                 8    U R                   R                  5         g r   )r+   clearr   s    r   r#   TextKVCacheBlockState.reset:   s    r   r*   Nr%   r   r   r   r'   r'   4   s    DIr   r'   c                      ^  \ rS rSrSrSrS\4U 4S jjrS\R                  R                  4S jrS\R                  R                  4S jrS	rU =r$ )
TextKVCacheTransformerHook>   z|Captures ``encoder_hidden_states.data_ptr()`` before ``txt_norm``
and writes it to shared state for the block hooks to read.Tstate_managerc                 .   > [         TU ]  5         Xl        g r   )superr    r3   )r   r3   	__class__s     r   r    #TextKVCacheTransformerHook.__init__D   s    *r   modulec                 $   U R                   R                  c  U R                   R                  S5        UR                  S5      nUb/  U R                   R	                  5       nUR                  5       Ul        U R                  R                  " U0 UD6$ )N	inferenceencoder_hidden_states)	r3   _current_contextset_contextget	get_statedata_ptrr   fn_reforiginal_forward)r   r8   argskwargsr;   states         r   new_forward&TextKVCacheTransformerHook.new_forwardH   s|    ..6**;7 &

+B C ,&*&8&8&B&B&DE-668EI{{++T<V<<r   c                 :    U R                   R                  5         U$ r   )r3   r#   r   r8   s     r   reset_state&TextKVCacheTransformerHook.reset_stateR   s      "r   )r3   r   r   r   r   r   _is_statefulr   r    torchnnModulerF   rJ   r   __classcell__r6   s   @r   r1   r1   >   sI    B L+l +=%((// =%((//  r   r1   c                      ^  \ rS rSrSrSrS\S\4U 4S jjrS\R                  R                  4S jrS\R                  R                  4S	 jrS
rU =r$ )TextKVCacheBlockHookW   zmCaches ``(txt_key, txt_value)`` per block per unique prompt using
the stable cache key from the shared state.Tr3   block_state_managerc                 :   > [         TU ]  5         Xl        X l        g r   )r5   r    r3   rV   )r   r3   rV   r6   s      r   r    TextKVCacheBlockHook.__init__]   s    *#6 r   r8   c                    SSK Jn  U R                  R                  c  U R                  R	                  S5        U R
                  R                  c  U R
                  R	                  S5        SU;   a  US   nOUS   nSU;   a  US   nO[        U5      S:  a  US   nOS nU R                  R                  5       nUR                  nU R
                  R                  5       n	XR                  ;  a  UR                  U5      n
UR                  nUR                  UR                  -  nUR                  U-  nUR                  U
5      R!                  SUS45      nUR#                  U
5      R!                  SUS45      nUR$                  b  UR%                  U5      nUb  Uu  nnU" UUS	S
9nX4U	R                  U'   U	R                  U   u  pUR'                  S5      =(       d    0 nUUS'   UUS'   UUS'   U R(                  R*                  " U0 UD6$ )N   )_apply_rotary_emb_nucleusr:   r;   r   image_rotary_emb   F)use_realattention_kwargscached_txt_keycached_txt_value)0models.transformers.transformer_nucleusmoe_imager[   r3   r<   r=   rV   lenr?   r   r+   encoder_projattn	inner_dimheadsinner_kv_dim
add_k_proj	unflatten
add_v_projnorm_added_kr>   rA   rB   )r   r8   rC   rD   r[   r;   r\   rE   	cache_keyblock_statecontextrf   head_dimnum_kv_headstxt_key	txt_value_	txt_freqsattn_kwargss                      r   rF    TextKVCacheBlockHook.new_forwardb   s   `..6**;7##44<$$00="f,$*+B$C!$(G!'%&89Y]#Aw#"&"4"4">">"@II	-1-E-E-O-O-Q000))*?@G;;D~~3H,,8Loog.88lB=OPG0::2b?QRI  ,++G4+/93GYQVW/6.BK  +(11)<jj!34:(/$%*3&'%0!"{{++T<V<<r   c                 :    U R                   R                  5         U$ r   )rV   r#   rI   s     r   rJ    TextKVCacheBlockHook.reset_state   s      &&(r   )rV   r3   rL   rR   s   @r   rT   rT   W   sP    3 L7l 7 7
4=%((// 4=l%((//  r   rT   r8   configreturnc                    SSK Jn  [        R                  " U 5        [	        [
        5      n[        U5      n[        R                  " U 5      nUR                  U[        5        U R                  5        H]  u  pg[        Xr5      (       d  M  [	        [        5      n[        X85      n	[        R                  " U5      n
U
R                  U	[        5        M_     g )NrZ   )NucleusMoEImageTransformerBlock)rc   r~   r   check_if_exists_or_initializer   r   r1   register_hook_TEXT_KV_CACHE_TRANSFORMER_HOOKnamed_modules
isinstancer'   rT   _TEXT_KV_CACHE_BLOCK_HOOK)r8   r{   r~   r3   transformer_hookregistryru   	submodulerV   hookblock_registrys              r   apply_text_kv_cacher      s    b..v6 !12M1-@99&AH+-LM,,.iAA"./D"E'KD)GG	RN((/HI /r   )dataclassesr   rN   hooksr   r   r   r   r   r   r   r   r'   r1   rT   rO   rP   r   r   r   r   <module>r      s    "  C C #> 1  	 	 	y I  2C9 CLJ J9J Jt Jr   