22
33import argparse
44import os
5+ import sys
56import importlib
67from pathlib import Path
78
9+ # Add parent directory to path for imports
10+ sys .path .insert (0 , os .path .join (os .path .dirname (__file__ ), '..' ))
11+
812from transformers import AutoTokenizer , AutoModelForCausalLM , AutoModelForImageTextToText , AutoConfig
913import torch
1014import numpy as np
11-
12- ### If you want to dump RoPE activations, apply this monkey patch to the model
13- ### class from Transformers that you are running (replace apertus.modeling_apertus
14- ### with the proper package and class for your model
15- ### === START ROPE DEBUG ===
16- # from transformers.models.apertus.modeling_apertus import apply_rotary_pos_emb
17-
18- # orig_rope = apply_rotary_pos_emb
19- # torch.set_printoptions(threshold=float('inf'))
20- # torch.set_printoptions(precision=6, sci_mode=False)
21-
22- # def debug_rope(q, k, cos, sin, position_ids=None, unsqueeze_dim=1):
23- # # log inputs
24- # summarize(q, "RoPE.q_in")
25- # summarize(k, "RoPE.k_in")
26-
27- # # call original
28- # q_out, k_out = orig_rope(q, k, cos, sin, position_ids, unsqueeze_dim)
29-
30- # # log outputs
31- # summarize(q_out, "RoPE.q_out")
32- # summarize(k_out, "RoPE.k_out")
33-
34- # return q_out, k_out
35-
36- # # Patch it
37- # import transformers.models.apertus.modeling_apertus as apertus_mod # noqa: E402
38- # apertus_mod.apply_rotary_pos_emb = debug_rope
39- ### == END ROPE DEBUG ===
40-
41-
42- def summarize (tensor : torch .Tensor , name : str , max_seq : int = 3 , max_vals : int = 3 ):
43- """
44- Print a tensor in llama.cpp debug style.
45-
46- Supports:
47- - 2D tensors (seq, hidden)
48- - 3D tensors (batch, seq, hidden)
49- - 4D tensors (batch, seq, heads, dim_per_head) via flattening heads × dim_per_head
50-
51- Shows first and last max_vals of each vector per sequence position.
52- """
53- t = tensor .detach ().to (torch .float32 ).cpu ()
54-
55- # Determine dimensions
56- if t .ndim == 3 :
57- _ , s , _ = t .shape
58- elif t .ndim == 2 :
59- _ , s = 1 , t .shape [0 ]
60- t = t .unsqueeze (0 )
61- elif t .ndim == 4 :
62- _ , s , _ , _ = t .shape
63- else :
64- print (f"Skipping tensor due to unsupported dimensions: { t .ndim } " )
65- return
66-
67- ten_shape = t .shape
68-
69- print (f"ggml_debug: { name } = (f32) ... = {{{ ten_shape } }}" )
70- print (" [" )
71- print (" [" )
72-
73- # Determine indices for first and last sequences
74- first_indices = list (range (min (s , max_seq )))
75- last_indices = list (range (max (0 , s - max_seq ), s ))
76-
77- # Check if there's an overlap between first and last indices or if we're at the edge case of s = 2 * max_seq
78- has_overlap = bool (set (first_indices ) & set (last_indices )) or (max_seq * 2 == s )
79-
80- # Combine indices
81- if has_overlap :
82- # If there's overlap, just use the combined unique indices
83- indices = sorted (list (set (first_indices + last_indices )))
84- separator_index = None
85- else :
86- # If no overlap, we'll add a separator between first and last sequences
87- indices = first_indices + last_indices
88- separator_index = len (first_indices )
89-
90- for i , si in enumerate (indices ):
91- # Add separator if needed
92- if separator_index is not None and i == separator_index :
93- print (" ..." )
94-
95- # Extract appropriate slice
96- vec = t [0 , si ]
97- if vec .ndim == 2 : # 4D case: flatten heads × dim_per_head
98- flat = vec .flatten ().tolist ()
99- else : # 2D or 3D case
100- flat = vec .tolist ()
101-
102- # First and last slices
103- first = flat [:max_vals ]
104- last = flat [- max_vals :] if len (flat ) >= max_vals else flat
105- first_str = ", " .join (f"{ v :12.4f} " for v in first )
106- last_str = ", " .join (f"{ v :12.4f} " for v in last )
107-
108- print (f" [{ first_str } , ..., { last_str } ]" )
109-
110- print (" ]," )
111- print (" ]" )
112- print (f" sum = { t .sum ().item ():.6f} \n " )
113-
114-
115- def debug_hook (name ):
116- def fn (_m , input , output ):
117- if isinstance (input , torch .Tensor ):
118- summarize (input , name + "_in" )
119- elif isinstance (input , (tuple , list )) and len (input ) > 0 and isinstance (input [0 ], torch .Tensor ):
120- summarize (input [0 ], name + "_in" )
121- if isinstance (output , torch .Tensor ):
122- summarize (output , name + "_out" )
123- elif isinstance (output , (tuple , list )) and len (output ) > 0 and isinstance (output [0 ], torch .Tensor ):
124- summarize (output [0 ], name + "_out" )
125-
126- return fn
127-
128-
129- unreleased_model_name = os .getenv ("UNRELEASED_MODEL_NAME" )
15+ from utils .common import debug_hook
13016
13117parser = argparse .ArgumentParser (description = "Process model with specified path" )
13218parser .add_argument ("--model-path" , "-m" , help = "Path to the model" )
13319parser .add_argument ("--prompt-file" , "-f" , help = "Optional prompt file" , required = False )
20+ parser .add_argument ("--verbose" , "-v" , action = "store_true" , help = "Enable verbose debug output" )
13421args = parser .parse_args ()
13522
13623model_path = os .environ .get ("MODEL_PATH" , args .model_path )
@@ -139,6 +26,12 @@ def fn(_m, input, output):
13926 "Model path must be specified either via --model-path argument or MODEL_PATH environment variable"
14027 )
14128
29+ ### If you want to dump RoPE activations, uncomment the following lines:
30+ ### === START ROPE DEBUG ===
31+ # from utils.common import setup_rope_debug
32+ # setup_rope_debug("transformers.models.apertus.modeling_apertus")
33+ ### == END ROPE DEBUG ===
34+
14235
14336print ("Loading model and tokenizer using AutoTokenizer:" , model_path )
14437tokenizer = AutoTokenizer .from_pretrained (model_path , trust_remote_code = True )
@@ -156,6 +49,7 @@ def fn(_m, input, output):
15649print ("BOS token id: " , config .bos_token_id )
15750print ("EOS token id: " , config .eos_token_id )
15851
52+ unreleased_model_name = os .getenv ("UNRELEASED_MODEL_NAME" )
15953if unreleased_model_name :
16054 model_name_lower = unreleased_model_name .lower ()
16155 unreleased_module_path = (
@@ -184,9 +78,10 @@ def fn(_m, input, output):
18478 model_path , device_map = "auto" , offload_folder = "offload" , trust_remote_code = True , config = config
18579 )
18680
187- for name , module in model .named_modules ():
188- if len (list (module .children ())) == 0 : # only leaf modules
189- module .register_forward_hook (debug_hook (name ))
81+ if args .verbose :
82+ for name , module in model .named_modules ():
83+ if len (list (module .children ())) == 0 : # only leaf modules
84+ module .register_forward_hook (debug_hook (name ))
19085
19186model_name = os .path .basename (model_path )
19287# Printing the Model class to allow for easier debugging. This can be useful
0 commit comments