Ë
    S^(hê-  ã                   ó   — d dl Z d dlZd dlZd dlZd dlmZ d dlmZ d dlm	Z	 ddl
mZ  e«       rd dlZd dlZd dlmZ ddlmZ dd	l
mZ  ej$                  e«      Zej*                  j-                  «       Zd
„ Z ej2                  d«      Zdedefd„Zd„ Zd„ Zd„ Zd„ Z defd„Z! e	d¬«      d„ «       Z" e	d¬«      eddee   fd„«       «       Z#y)é    N)Úcontextmanager)ÚOptional)Úexporté   )Úis_torch_available)Únn)ÚPreTrainedModel)Úloggingc                  óŽ   — t         rt        j                  j                  «       syt        j                  j	                  «       dk(  S )z7Return True if rank=0 or we aren't running distributed.Tr   )Ú_torch_distributed_availableÚtorchÚdistributedÚis_initializedÚget_rank© ó    ú`/var/www/skyplay_api_hub/venv/lib/python3.12/site-packages/transformers/model_debugging_utils.pyÚ_is_rank_zeror   ,   s3   € å(¬U×->Ñ->×-MÑ-MÔ-OØÜ×Ñ×%Ñ%Ó'¨1Ñ,Ð,r   zobject at 0x[0-9A-Fa-f]+Úx_strÚreturnc                 ó.   — t         j                  d| «      S )z™
    Replace memory addresses in an object's repr with a stable placeholder
    so that beautiful JSON diffs won't be ruined by ephemeral addresses.
    zobject at 0xXXXXXXXX)ÚMEMORY_ADDRESS_REGEXÚsub)r   s    r   Ú_sanitize_repr_for_diffr   6   s   € ô
  ×#Ñ#Ð$:¸EÓBÐBr   c                 óH   — t        «       rdt        | j                  «      › �S y)z@Return a stable string representation for a DTensor-like object.zDTensor (rank0) -> zDTensor(non-rank0))r   ÚreprÚ_local_tensor)Úxs    r   Ú_dtensor_reprr   >   s!   € ä„Ø$¤T¨!¯/©/Ó%:Ð$;Ð<Ð<Ør   c                 ó„  — t        | t        t        f«      r| D �cg c]  }t        |«      ‘Œ c}S t        | t        «      r-| j                  «       D ��ci c]  \  }}|t        |«      “Œ c}}S t        | d«      rRt        | j                  j                  «      t        | j                  j                  «      t        t        | «      «      dœS t        | t        j                  «      r>t        | j                  «      t        | j                  «      t        t        | «      «      dœS t        t        | «      «      S c c}w c c}}w )a½  
    Recursively build a JSON-serializable Python structure from `value`.
    Tensors and DTensors become sanitized repr strings.
    Lists/tuples/dicts are recursed into.
    All memory addresses are replaced with a stable placeholder.

    Args:
        value: Any Python object, often including torch Tensors, lists, dicts, etc.

    Returns:
        A nested Python structure (list, dict, or sanitized string) that is safe to json.dump.
    r   )ÚshapeÚdtypeÚvalue)Ú
isinstanceÚlistÚtupleÚ_serialize_ioÚdictÚitemsÚhasattrr   r   r!   r"   r   r   ÚTensor)r#   ÚvÚks      r   r'   r'   E   sú   € ô �%œ$¤˜Ô'Ø*/Ö0 Q”˜aÕ Ò0Ð0ä�%œÔØ05·±³×>©¨¨1�”= Ó#Ñ#Ó>Ð>äˆu�oÔ&ô ˜%×-Ñ-×3Ñ3Ó4Ü˜%×-Ñ-×3Ñ3Ó4Ü,¬T°%«[Ó9ñ
ð 	
ô �%œŸ™Ô&ô ˜eŸk™kÓ*´T¸%¿+¹+Ó5FÔQhÔimÐnsÓitÓQuÑvÐvô #¤4¨£;Ó/Ð/ùò' 1ùó ?s   ›D7ÁD<c                 óv   — | j                  d«      r(| j                  dd «       | d   D ]  }t        |«       Œ y y )NÚchildrenÚoutputs)ÚgetÚpopÚprune_outputs_if_children)ÚnodeÚchilds     r   r3   r3   i   s?   € ð ‡x�x�
ÔØ�‰�˜DÔ!Ø˜*Ñ%ò 	-ˆEÜ% eÕ,ñ	-ð r   c                 óÖ  — | rF	 t        j                  | d¬«       t         j                  j                  | |j                  dz   «      }n|j                  dz   }t        j                  d|› �«       t        |d«      5 }t        |j                  «       t        j                  |j                  |d¬	«       d d d «       y # t
        $ r}t        d| › d|› �«      ‚d }~ww xY w# 1 sw Y   y xY w)
NF)Úexist_okz_debug_tree.jsonz"Unexpected or existing debug_path=z. zWriting model trace at Úwé   )Úindent)ÚosÚmakedirsÚpathÚjoinÚ_debugger_module_dump_nameÚ	ExceptionÚ
ValueErrorÚloggerÚinfoÚopenr3   Ú
_call_treeÚjsonÚdump)Ú
debug_pathÚmodelÚoutput_pathÚeÚoutfiles        r   Úlog_model_debug_tracerM   r   sØ   € Ùð	UÜ�K‰K˜
¨UÕ3ÜŸ'™'Ÿ,™, z°5×3SÑ3SÐVhÑ3hÓi‰Kð ×6Ñ6Ð9KÑKˆÜ
‡K�KÐ)¨+¨Ð7Ô8Ü	ˆk˜3Ó	ð 7 7Ü! %×"2Ñ"2Ô3Ü�	‰	�%×"Ñ" G°AÕ6÷7ð 7øô ò 	UÜÐAÀ*ÀÈRÐPQÈsÐSÓTÐTûð	Uú÷
7ð 7ús$   „AB= Á<8CÂ=	CÃCÃCÃC(rH   c                 óÐ  ‡ ‡‡‡— ‰d d g dœ‰ _         g ‰ _        ‰‰ _        ˆ fd„}‰ j                  «       D ]  \  }}|dk(  rŒ ||‰› d|› �«       Œ ‰ j                  Št        j                  ‰«      ˆˆ ˆfd„«       }|‰ _        ˆˆ fd„}‰ j                  |«       ddg}|D ]E  }	t        ‰ |	d «      }
|
sŒt        |
t        j                  t        f«      sŒ4|
j                  |«        y  y )	N©Úmodule_pathÚinputsr0   r/   c                 ór   •‡ ‡‡— ‰ j                   Št        j                  ‰«      ˆˆˆ ˆfd„«       }|‰ _         y )Nc                  ón  •— t        «       rU| |dœ}|D �ci c]  }t        ||   «      dkD  sŒ|||   “Œ }}‰t        |«      d g dœ}‰j                  j	                  |«       t        j                  «       5   ‰
| i |¤Ž}d d d «       t        «       r”t        d„ ‰	j                  «       D «       «      dkD  rd d<   nt        «      d<   ‰j                  j                  «       }|d   s|j                  d«       ‰j                  r!‰j                  d   d   j	                  |«       S c c}w # 1 sw Y   Œ®xY w)N©ÚargsÚkwargsr   rO   c              3   ó    K  — | ]  }d –— Œ y­w)r   Nr   )Ú.0Ú_s     r   ú	<genexpr>zX_attach_debugger_logic.<locals>.wrap_forward.<locals>.wrapped_forward.<locals>.<genexpr>š   s   è ø€ Ò:˜Q”qÑ:ùs   ‚r0   r/   éÿÿÿÿ)
r   Úlenr'   Ú_debugger_model_call_stackÚappendr   Úinference_modeÚsumÚnamed_childrenr2   )ÚinpsÚkwsÚdict_inputsr-   r4   ÚoutÚfinishedÚ	full_pathrI   ÚmoduleÚorig_forwards          €€€€r   Úwrapped_forwardzE_attach_debugger_logic.<locals>.wrap_forward.<locals>.wrapped_forwardŠ   s2  ø€ äŒØ'+°sÑ;�Ø:EÖa°QÌÈ[ÐYZÉ^ÓI\Ð_`ÓI`˜q +¨a¡.Ñ0Ða�Ðaà#,Ü+¨KÓ8Ø#Ø "ñ	�ð ×0Ñ0×7Ñ7¸Ô=Ü×%Ñ%Ó'ñ 1Ù" DÐ0¨CÑ0�÷1ô ŒÜÑ: &×"7Ñ"7Ó"9Ô:Ó:¸QÒ>Ø&*�D˜’Oä&3°CÓ&8�D˜‘Oà ×;Ñ;×?Ñ?ÓA�à 
Ò+Ø—L‘L Ô,à×3Ò3Ø×4Ñ4°RÑ8¸ÑD×KÑKÈHÔUØˆJùò1 b÷1ð 1ús   •D&¬D&Á5	D+Ä+D4)ÚforwardÚ	functoolsÚwraps)rh   rg   rj   ri   rI   s   `` @€r   Úwrap_forwardz,_attach_debugger_logic.<locals>.wrap_forward‡   s0   û€ Ø—~‘~ˆä	�‰˜Ó	&ö	ó 
'ð	ð: )ˆ�r   Ú ú.c                  ó6  •— t        «       r1‰› d�t        | |dœ«      d g dœ}‰j                  j                  |«        ‰| i |¤Ž}t        «       rÅ‰j                  r¹t        |«      d<   ‰j                  j	                  «       }|d   ‰j
                  d<   |d   ‰j
                  d<   |d   ‰j
                  d<   t        ‰j
                  j                  «       «      D �cg c].  }‰j
                  |   rŒ‰j
                  j	                  |d «      ‘Œ0 c} |S c c}w )Nz (top-level)rT   rO   r0   rQ   r/   )r   r'   r]   r^   r2   rE   r%   Úkeys)	rb   rc   Útop_nodere   rf   r-   Ú
class_namerI   Úreal_top_forwards	         €€€r   Útop_wrapped_forwardz3_attach_debugger_logic.<locals>.top_wrapped_forward³   s  ø€ äŒ?à", ¨\Ð:Ü'°ÀÑ(EÓFØØñ	ˆHð ×,Ñ,×3Ñ3°HÔ=á Ð,¨Ñ,ˆäŒ?˜u×?Ò?Ü"/°Ó"4ˆH�YÑØ×7Ñ7×;Ñ;Ó=ˆHØ)1°(Ñ);ˆE×Ñ˜XÑ&Ø*2°9Ñ*=ˆE×Ñ˜YÑ'Ø+3°JÑ+?ˆE×Ñ˜ZÑ(ä48¸×9IÑ9I×9NÑ9NÓ9PÓ4QÖm¨qÐY^×YiÑYiÐjkÓYlˆU×Ñ×!Ñ! ! TÕ*Ómàˆ
ùò ns   ÃDÃ3Dc                 ó  •— t        «       r\‰j                  rP‰j                  j                  «       }|d   ‰j                  d<   |d   ‰j                  d<   |d   ‰j                  d<   t        «       rt	        ‰‰¬«       y y )NrQ   r0   r/   )rH   rI   )r   r]   r2   rE   rM   )rY   rQ   r0   rf   rH   rI   s       €€r   Ú
final_hookz*_attach_debugger_logic.<locals>.final_hookÎ   sw   ø€ ÜŒ?˜u×?Ò?Ø×7Ñ7×;Ñ;Ó=ˆHØ)1°(Ñ);ˆE×Ñ˜XÑ&Ø*2°9Ñ*=ˆE×Ñ˜YÑ'Ø+3°JÑ+?ˆE×Ñ˜ZÑ(äŒ?Ü!¨Z¸uÖEð r   Úlanguage_modelrI   )rE   r]   r?   Únamed_modulesrk   rl   rm   Úregister_forward_hookÚgetattrr$   r   ÚModuler	   )rI   rt   rH   rn   ÚnameÚ	submodulerv   rx   Úpossible_model_callsÚ
model_callÚthis_model_callru   s   ```        @r   Ú_attach_debugger_logicrƒ   �   sÿ   û€ à'1¸TÈdÐ`bÑc€EÔØ')€EÔ$Ø'1€EÔ$ô!)ðH !×.Ñ.Ó0ò 8‰ˆˆiØ�2Š:ØÙ�Y : ,¨a°¨vÐ 6Õ7ð8ð —}‘}Ðä‡_�_Ð%Ó&õó 'ðð. (€E„MõFð 
×Ñ 
Ô+ð -¨gÐ6ÐØ*ò ˆ
Ü! %¨°TÓ:ˆÚœz¨/¼B¿I¹IÄÐ;WÕXØ×1Ñ1°*Ô=Ùñ	r   )r   )Úbackendsc                 ó€   ‡ ‡— ‰ j                   Št        j                  ‰ j                   «      ˆ ˆfd„«       }|‰ _         ‰ S )a­  
    # Model addition debugger - a model adder tracer
    This decorator is a power user tool intended for model adders.
    It tracks all forward calls within a model forward and logs a slice of each input and output on a nested Json.
    To note, this decorator enforces `torch.inference_mode()`.
    ## Usage

    add decorator to your model class
    ```python
    from ...modeling_utils import model_addition_debugger

    @model_addition_debugger
    class MyModel(nn.Module) # Can inherit from PreTrainedModel too
        # ... nothing else changes
    ```
    Then, in a separate script (example is for Llava)

    ```python
    import torch
    from PIL import Image
    import requests
    from transformers import LlavaProcessor, LlavaForConditionalGeneration
    torch.random.manual_seed(673)

    # load pretrained model and processor
    model_id = "llava-hf/llava-1.5-7b-hf"
    processor = LlavaProcessor.from_pretrained(model_id)
    model = LlavaForConditionalGeneration.from_pretrained(model_id, low_cpu_mem_usage=True)

    # create random image input
    random_image = Image.fromarray(torch.randint(0, 256, (224, 224, 3), dtype=torch.uint8).numpy())

    # prompt
    prompt = "<image>Describe this image."

    # process inputs
    inputs = processor(text=prompt, images=random_image, return_tensors="pt")

    # call forward method (not .generate!)
    with torch.no_grad():
        output = model.forward(**inputs)
    ```

    c                 óJ   •—  ‰| g|¢­i |¤Ž t        | ‰j                  «       y ©N)rƒ   Ú__name__)ÚselfrU   rV   ÚclsÚ	orig_inits      €€r   Úwrapped_initz-model_addition_debugger.<locals>.wrapped_init  s#   ø€ á�$Ð(˜Ò( Ò(Ü˜t S§\¡\Õ2r   )Ú__init__rl   rm   )rŠ   rŒ   r‹   s   ` @r   Úmodel_addition_debuggerrŽ   ä   s<   ù€ ð\ —‘€Iä‡_�_�S—\‘\Ó"ô3ó #ð3ð  €C„LØ€Jr   c              #   ób   K  — t        | | j                  j                  |«       	 | –— y# w xY w­w)aÜ  
    # Model addition debugger - context manager for model adders
    This context manager is a power user tool intended for model adders.
    It tracks all forward calls within a model forward and logs a slice of each input and output on a nested Json.
    To note, this context manager enforces `torch.inference_mode()`.

    ## Usage

    add the context manager to a model to debug

    ```python
    import torch
    from PIL import Image
    import requests
    from transformers import LlavaProcessor, LlavaForConditionalGeneration
    torch.random.manual_seed(673)

    # load pretrained model and processor
    model_id = "llava-hf/llava-1.5-7b-hf"
    processor = LlavaProcessor.from_pretrained(model_id)
    model = LlavaForConditionalGeneration.from_pretrained(model_id, low_cpu_mem_usage=True)

    # create random image input
    random_image = Image.fromarray(torch.randint(0, 256, (224, 224, 3), dtype=torch.uint8).numpy())

    # prompt
    prompt = "<image>Describe this image."

    # process inputs
    inputs = processor(text=prompt, images=random_image, return_tensors="pt")

    # call forward method (not .generate!)
    with model_addition_debugger_context(model):
        output = model.forward(**inputs)
    ```

    N)rƒ   Ú	__class__rˆ   )rI   rH   s     r   Úmodel_addition_debugger_contextr‘     s/   è ø€ ôP ˜5 %§/¡/×":Ñ":¸JÔGðØŠàøˆüs   ‚"/¥* ©/ª,¬/r‡   )$rl   rF   r;   ÚreÚ
contextlibr   Útypingr   Útransformers.utils.import_utilsr   Úutilsr   r   Útorch.distributed.tensorr   Úmodeling_utilsr	   r
   Ú
get_loggerrˆ   rB   r   Úis_availabler   r   Úcompiler   Ústrr   r   r'   r3   rM   rƒ   rŽ   r‘   r   r   r   ú<module>r�      sú   ðó  Û Û 	Û 	Ý %Ý å 2å %ñ ÔÛÛ#Ýå/å ð 
ˆ×	Ñ	˜HÓ	%€ð  %×0Ñ0×=Ñ=Ó?Ð ò-ð "�r—z‘zÐ"=Ó>Ð ðC 3ð C¨3ó Cò ò!0òH-ò7ð`¸#ó `ñF �Ôñ5ó ð5ñp �ÔØñ*°xÀ±}ò *ó ó ñ*r   