
    Z jB              	       ^   S SK r S SKrS SKrS SKrS SKJrJr  S SKJr  SSK	J
r
  SSKJrJr  \" 5       (       a2  S SKrS SKJr  Sr\R$                  R'                  5       (       a  S SKrS	rOSr\
R*                  " \5      rS
 r\R2                  " S5      rS\S\4S jrS r S!S\S-  S\S\S-  4S jjrS!S\S-  S\S\S-  4S jjr S\RB                  4S jr"S r#\R2                  " S5      r$S r%S r&S\S-  4S jr'   S"S\S\S\4S jjr(\" SS9\   S#S\S-  S\S\4S  jj5       5       r)g)$    N)contextmanagerredirect_stdout)StringIO   )logging)is_torch_availablerequires)	save_fileFTc                      [         (       a#  [        R                  R                  5       (       d  g[        R                  R	                  5       S:H  $ )z7Return True if rank=0 or we aren't running distributed.Tr   )_torch_distributed_availabletorchdistributedis_initializedget_rank     s/root/GenerationalWealth/GenerationalWealth/venv/lib/python3.13/site-packages/transformers/model_debugging_utils.py_is_rank_zeror   ,   s9    ((U->->-M-M-O-O%%'1,,r   zobject at 0x[0-9A-Fa-f]+x_strreturnc                 .    [         R                  SU 5      $ )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                 R    [        5       (       a  S[        U R                  5       3$ g)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   
debug_pathuse_reprpath_to_valuec                    [         R                  " SS9  U(       a  [        U 5      nOU(       a  UR                  S5      (       d  US-  nU(       a  [        R
                  R                  X5      OUn[        SU R                  5       R                  5       R                  5       0U5        SU 3nO[        SU< SU< S35      e[        U R                  5      [        U R                  5      US	.nU R                  [         R                  [         R                   [         R"                  1;   a  UR%                  ['        [        U R)                  5       5      5      ['        [        U R+                  5       5      5      ['        [        U R-                  5       5      5      ['        [        U R/                  5       5      5      S
.5        U$ )aa  
Converts Tensors and DTensors to a JSON-serializable dictionary representation.

Args:
    value: Any Python object, often including torch Tensors, lists, dicts, etc.
    debug_path (`str`, *optional*, defaults to `None`): Directory to dump debug JSON and SafeTensors files.
    use_repr (bool, *optional*, defaults to `True`): Whether to save a `repr()`-ized version of the tensor as the
        `value` property in the asscoiated FULL_TENSORS.json file, or to store the full tensors in separate
        SafeTensors file and store the relative path to that file in the `value` property in the dictionary.
    path_to_value (`str`, *optional*, defaults to `None`): The file name for the SafeTensors file holding the full
        tensor value if `use_repr=False`.

Returns:
    A nested Python structure (list, dict, or sanitized string) that is safe to json.dump.
T)sci_modez.safetensorsdataz./z	use_repr=z and path_to_value=z cannot both be falsy.)shapedtypevalue)meanstdminmax)r   set_printoptions_repr_to_listendswithospathjoinr
   
contiguousdetachcpu
ValueErrorr   r&   r'   float16float32bfloat16updater   r)   r*   r+   r,   )r(   r    r!   r"   	value_outfilepathouts          r   _serialize_tensor_like_ior>   E   sO   $ 
D)!%(		%%n55^+M>H277<<
:m65++-446::<=xH(	IH;&:M+;;QRSS ekk"ekk"C
 {{u}}emmU^^DD

/UZZ\0BC.tEIIK/@A.tEIIK/@A.tEIIK/@A		
 Jr   c                     [        U [        [        45      (       a-  [        U 5       VVs/ s H  u  pE[	        XQX# SU 3S9PM     snn$ [        U [
        5      (       a3  U R                  5        VVs0 s H  u  peU[	        XQX# SU 3S9_M     snn$ [        U S5      (       a  [        U R                  XUS9$ [        U [        R                  5      (       a
  [        XX#S9$ [        [        U 5      5      $ s  snnf s  snnf )aR  
Recursively build a JSON-serializable Python structure from `value`.
Tensors and DTensors become either sanitized repr strings, or are saved to disk as SafeTensors files and their
relative paths are recorded in the returned Python structure.
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.
    debug_path (`str`, *optional*, defaults to `None`): Directory to dump debug JSON and SafeTensors files.
    use_repr (bool, *optional*, defaults to `True`): Whether to save a `repr()`-ized version of the tensors as the
        `value` property in the asscoiated FULL_TENSORS.json file, or to store full tensors in separate SafeTensors
        files and store the relative path to that file in the `value` property.
    path_to_value (`str`, *optional*, defaults to `None`): The file name for the SafeTensors file holding the full
        tensor value if `use_repr=False`.

Returns:
    A nested Python structure (list, dict, or sanitized string) that is safe to json.dump.
_r    r!   r"   r   )
isinstancelisttuple	enumerate_serialize_iodictitemshasattrr>   r   r   Tensorr   r   )r(   r    r!   r"   ivks          r   rF   rF   v   s   ( %$'' "%(
( !XWffghigjUkl(
 	

 % 
% }QZiijkljmXnoo%
 	

 uo&&(JYf
 	
 %&&(PXvv"4;//'

s   C41C:r(   c                 &   [         R                  " SSS9  [        5        n[        U5         [	        U 5        UR                  5       nSSS5        SSS5        [        W5      R                  5       $ ! , (       d  f       N/= f! , (       d  f       N8= f)z
Converts a tensor into a sanitized multi-line string representation.

Args:
    value (`torch.Tensor`): The tensor to represent.

Returns:
    `list[str]`: List of string lines representing the tensor.
Tx   )r$   	linewidthN)r   r-   r   r   printgetvaluer   
splitlines)r(   bufraws      r   r.   r.      s_     
DC8	sOC0elln 1 #3'2244 10s"   BA1B1
A?	;B
Bc                     U R                  S5      (       a*  U R                  SS 5        U S    H  n[        U5        M     g g )Nchildrenoutputs)getpopprune_outputs_if_children)nodechilds     r   r[   r[      s=     xx
D!*%E%e, & r   z(.*)\.(\d+)$c                    ^ [         R                  U R                  SS5      5      nU(       a  U R                  S5      (       d  gUR                  S5      m[	        U4S jU S    5       5      $ )z
Checks whether a node represents a layer block with submodules.

Args:
    node (`dict`): A node from the call tree.

Returns:
    `bool`: Whether the node is a layer block.
module_path rW   F   c              3   V   >#    U  H  nS T S 3UR                  SS5      ;   v   M      g7f).r_   r`   NrY   ).0r]   numbers     r   	<genexpr>!is_layer_block.<locals>.<genexpr>   s+     [JZ6(!}		- <<JZs   &))LAYER_SUFFIX_REmatchrY   groupany)r\   rj   rf   s     @r   is_layer_blockrm      sW     !!$((=""=>E,,[[^F[$zJZ[[[r   c                    U R                  S5      (       d  g[        U S   5       VVs/ s H  u  p[        U5      (       d  M  X4PM     nnn[        U5      S:  aF  USS  VVs/ s H  u  pUPM	     nnn[        U S   5       VVs/ s H  u  pX;  d  M  UPM     snnU S'   U S    H  n[	        U5        M     gs  snnf s  snnf s  snnf )z
Recursively removes intermediate layers from the tree to improve readability.
Keeps at least the first and last layers if many consecutive layers are present.

Args:
    node (`dict`): The root or subnode to prune recursively.
rW   Nra   r   )rY   rE   rm   lenprune_intermediate_layers)r\   rK   r]   layer_blocksr@   	to_removes         r   rq   rq      s     88J/8j9I/Jd/J81n]bNcJQJ/JLd
<1#/"#56#541Q#5	62;D<L2Md2MhaQRQcE2MdZj!!%( " e 7ds   B:B:$C CCc                   ^ U (       aC   [         R                  " U SS9  [         R                  R                  XR                  S-   5      nOUR                  S-   n[        R                  SU S35        US-   nUS	-   n[        UR                  5        [        US
5       n[        R                  " UR                  USS9  S S S 5        U4S jm[        R                  " [        R                  " UR                  5      5      nT" U5        [        US
5       n[        R                  " XvSS9  S S S 5        g ! [
         a  n[        SU  S35      UeS nAff = f! , (       d  f       N= f! , (       d  f       g = f)NTexist_ok_debug_tree"Unexpected or existing debug_path=rc   zWriting model trace at z.jsonz_FULL_TENSORS.jsonz_SUMMARY.jsonwra   )indentc                    >^ U4S jmT" U R                  S0 5      5        T" U R                  S0 5      5        U R                  S/ 5       H  nT" U5        M     g )Nc                    > [        U [        5      (       a2  U R                  SS 5        U R                  5        H  nT" U5        M     g [        U [        5      (       a  U  H  nT" U5        M     g g )Nr(   )rB   rG   rZ   valuesrC   )valrL   itemcleans      r   r   :log_model_debug_trace.<locals>.strip_values.<locals>.clean   sX    #t$$&A!H &C&&D$K   'r   inputsrX   rW   rd   )r\   r]   r   strip_valuess     @r   r   +log_model_debug_trace.<locals>.strip_values   sM    	  	dhhx$%dhhy"%&XXj"-E .r   )r0   makedirsr1   r2   _debugger_module_dump_name	Exceptionr6   loggerinfor[   
_call_treeopenjsondumploadsdumps)	r    modelbasee	full_pathsummary_pathf	tree_copyr   s	           @r   log_model_debug_tracer      s6   	XKK
T277<<
,L,L},\]D //-?
KK)$u56++I/)Le../	i			%""Aa0 
   

4::e&6&678I	lC	 A		)q) 
!	 E  	XA*QOPVWW	X 
	. 
!	 s0   AD5 !EE(5
E?EE
E%(
E6do_prune_layersc                   ^ ^^^^	^
 T R                   R                  m	T	SS/ S.T l        / T l        T	T l        T(       a   [
        R                  " TSS9  UU U4S jnT R                  5        H  u  pgUS:X  a  M  U" UT	 SU 35        M     T R                  m
[        R                  " T
5      U	UUU U
U4S	 j5       nUT l
        g! [         a  n[        ST S35      UeSnAff = f)
a  
Attaches a debugging wrapper to every module in the model.

This records structured inputs and outputs during the forward pass into a call tree.

Args:
    model (`PreTrainedModel`, `nn.Module`): Model to wrap.
    debug_path (`str`): Optional directory to dump debug JSON files.
    do_prune_layers (`bool`, *optional*, defaults to `True`): Whether to prune intermediate layers.
    use_repr (bool, *optional*, defaults to `True`): Whether to save a `repr()`-ized version of the tensors as the
        `value` property in the associated FULL_TENSORS.json file, or to store full tensors in separate SafeTensors
        files and store the relative path to that file in the `value` property.
Nr_   r   rX   rW   Tru   rx   rc   c                 z   >^ ^^ T R                   m[        R                  " T5      UUUU UU4S j5       nUT l         g )Nc                    > [        5       (       a[  XS.nU Vs0 s H  n[        X#   5      S:  d  M  X2U   _M     nnT[        UTTT S3S9S / S.nT	R                  R	                  U5        [
        R                  " 5          T" U 0 UD6nS S S 5        [        5       (       a  [        S T
R                  5        5       5      S:  a  S WS'   O[        WTTT S3S9WS'   T	R                  R                  5       nUS	   (       d  UR                  S	5        T	R                  (       a!  T	R                  S
   S	   R	                  U5        W$ s  snf ! , (       d  f       N= f)Nargskwargsr   _inputsrA   r   c              3   &   #    U  H  nS v   M	     g7f)r   Nr   )re   r@   s     r   rg   X_attach_debugger_logic.<locals>.wrap_forward.<locals>.wrapped_forward.<locals>.<genexpr>F  s     :"9Qq"9s   rX   _outputsrW   ro   )
r   rp   rF   _debugger_model_call_stackappendr   no_gradsumnamed_childrenrZ   )inpskwsdict_inputsrM   r\   r=   finishedr    r   r   moduleorig_forwardr!   s          r   wrapped_forwardE_attach_debugger_logic.<locals>.wrap_forward.<locals>.wrapped_forward1  sS   '+;:Ea+Q[^I\_`I`0qa.0+a#,+##-!))27&;	  $ "
 0077="D0C0 ! :&"7"7"9::Q>&*DO&3#-!))28&<	'DO !;;??A
+LL,3344R8DKKHUJE b !s   E	E	E
E)forward	functoolswraps)r   r   r   r   r    r   r!   s   `` @r   wrap_forward,_attach_debugger_logic.<locals>.wrap_forward.  s6    ~~		&%	 %	 
'%	N )r   r`   c                    > [        5       (       a4  T S3[        XS.TTT S3S9S / S.nT	R                  R                  U5        T
" U 0 UD6n[        5       (       a  T	R                  (       a  [        UTTT S3S9WS'   T	R                  R	                  5       nUS   T	R
                  S'   US   T	R
                  S'   US	   T	R
                  S	'   [        T	R
                  R                  5       5       Vs/ s H5  nT	R
                  U   (       a  M  T	R
                  R	                  US 5      PM7       nT(       a  [        T	R
                  5        [        TT	S
9  U$ s  snf )Nz (top-level)r   r   rA   r   r   rX   r   rW   )r    r   )
r   rF   r   r   rZ   r   rC   keysrq   r   )r   r   top_noder=   r   rM   
class_namer    r   r   real_top_forwardr!   s         r   top_wrapped_forward3_attach_debugger_logic.<locals>.top_wrapped_forwardd  sa   ??",\:'!1)%%/L"8	  
H ,,33H=,,??u??"/%!!+H5	#HY 77;;=H)1();EX&*29*=EY'+3J+?EZ(489I9I9N9N9P4Qm4QqY^YiYijkYl*U!!!T*4Qm )%*:*:;!ZuE
 ns   4E E)	__class____name__r   r   r   r0   r   r   r6   named_modulesr   r   r   )r   r    r   r!   r   r   name	submoduler   r   r   s   ````     @@r   _attach_debugger_logicr     s    & ))J (2Td`bcE')E$'1E$	XKK
T2+)\ !..02:Y:,av 67 1 }}__%&# # '#J (EM  	XA*QOPVWW	Xs   C 
C"CC")r   )backendsc              #   8  #    U R                  5        VVs0 s H  u  pEXUR                  _M     nnnU R                  X`'   [        XX#5         U v   UR                  5        H  u  pxXl        M     gs  snnf ! UR                  5        H  u  pxXl        M     f = f7f)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 file.
If `use_repr=True` (the default), the JSON file will record a `repr()`-ized version of the tensors as a list of
strings. If `use_repr=False`, the full tensors will be stored in separate SafeTensors files and the JSON file will
provide a relative path to that file.

To note, this context manager enforces `torch.no_grad()`.

## Usage

add the context manager to a model to debug

```python
import torch

from PIL import Image
from transformers import LlavaProcessor, LlavaForConditionalGeneration, model_addition_debugger_context

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)

# 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, debug_path="Your_debug_path", do_prune_layers=False):
    output = model.forward(**inputs)
```

N)r   r   r   rH   )	r   r    r   r!   r@   morig_forwardsmodule_instanceforward_methods	            r   model_addition_debugger_contextr     s     f /4.A.A.CD.CdaQ		\.CMD ==M5oH5/</B/B/D+O&4# 0E E 0=/B/B/D+O&4# 0Es'   BA0BA6 &B6!BB)NTN)rc   TT)NTT)*r   r   r0   re
contextlibr   r   ior   utilsr   utils.import_utilsr   r	   r   safetensors.torchr
   r   r   is_availabletorch.distributed.tensor
get_loggerr   r   r   compiler   strr   r   boolr>   rF   rJ   r.   r[   ri   rm   rq   r   r   r   r   r   r   <module>r      s      	 	 6   < +#( %%''''+$#(  
		H	%- zz"=> C3 C3 C  ^b.Tz.48.PSVZPZ.b(0S4Z (0$ (0^adh^h (0V5 5"- **_-\")((*cDj (*Z  	|(|( |( 	|(~ 
: " 	85d
85 85 	85  85r   