@@ -117,7 +117,7 @@ def __call__(self, input_ids, scores, **kwargs):
117117 base_sequence = torch .cat ([base_sequence [:last_dot_index + 1 ], torch .tensor (end_think_token , device = model .device )])
118118
119119 # Add newline token before action calculations
120- newline_token_id = tokenizer .encode ("\n \n " , add_special_tokens = False ) # always >99% probability for double_newline token after </think>
120+ newline_token_id = tokenizer .encode ("\n \n Action: " , add_special_tokens = False ) # always >99% probability for double_newline token after </think>
121121 extended_sequence = torch .cat ([base_sequence , torch .tensor (newline_token_id , device = model .device )])
122122 generated_text = tokenizer .decode (extended_sequence , skip_special_tokens = False )
123123 print (generated_text [generated_text .find ("<think>" ):])
@@ -154,12 +154,19 @@ def __call__(self, input_ids, scores, **kwargs):
154154 total_log_prob = 0.0
155155 current_logits = last_logits
156156 current_past_key_values = past_key_values
157+ token_probabilities = [] # Store individual token probabilities
158+ token_texts = [] # Store individual token texts
157159
158160 for i , token_id in enumerate (action_token_ids ):
159161 # Get probability of this token
160162 probs = torch .softmax (current_logits , dim = - 1 )
161163 token_prob = probs [token_id ].item ()
162- total_log_prob += math .log (max (token_prob , 1e-10 ))
164+ token_log_prob = math .log (max (token_prob , 1e-10 ))
165+ total_log_prob += token_log_prob
166+
167+ # Store token info
168+ token_probabilities .append (token_prob * 100 ) # Convert to percentage
169+ token_texts .append (tokenizer .decode ([token_id ]))
163170
164171 # If not the last token, get next logits using cached states
165172 if i < len (action_token_ids ) - 1 :
@@ -176,11 +183,11 @@ def __call__(self, input_ids, scores, **kwargs):
176183 token_normalized_prob = total_log_prob / num_tokens if num_tokens > 0 else total_log_prob
177184 word_normalized_prob = total_log_prob / num_words if num_words > 0 else total_log_prob
178185
179- results .append ((action , total_log_prob , token_normalized_prob , word_normalized_prob ))
186+ results .append ((action , total_log_prob , token_normalized_prob , word_normalized_prob , token_texts , token_probabilities ))
180187
181188 # Create separate results for each normalization method
182- token_results = [(action , log_prob , token_norm ) for action , log_prob , token_norm , _ in results ]
183- word_results = [(action , log_prob , word_norm ) for action , log_prob , _ , word_norm in results ]
189+ token_results = [(action , log_prob , token_norm , token_texts , token_probs ) for action , log_prob , token_norm , _ , token_texts , token_probs in results ]
190+ word_results = [(action , log_prob , word_norm , token_texts , token_probs ) for action , log_prob , _ , word_norm , token_texts , token_probs in results ]
184191
185192 # Sort both by their respective normalized probabilities (descending)
186193 token_results .sort (key = lambda x : x [2 ], reverse = True )
@@ -302,36 +309,46 @@ def main():
302309 print ("-" * 40 )
303310 print (format_game_context (engine ))
304311
305- print ("\n 📊 AVAILABLE ACTIONS AND PROBABILITIES (Token Normalization):" )
306- print ("-" * 40 )
307- print (f"{ 'Action' :<40} { 'Log P' :<12} { 'Normalized' :<12} { 'Confidence' :<12} " )
308- print ("-" * 40 )
309-
310- for action , log_prob , norm_prob in token_norm_results [:10 ]: # Show top 10
311- action_text = action .command_perspective [:37 ] + "..." if len (action .command_perspective ) > 40 else action .command_perspective
312- print (f"{ action_text :<40} { log_prob :<12.4f} { norm_prob :<12.4f} { math .exp (norm_prob ):.4%} " )
313-
314- print ("\n 📊 AVAILABLE ACTIONS AND PROBABILITIES (Word Normalization):" )
315- print ("-" * 40 )
316- print (f"{ 'Action' :<40} { 'Log P' :<12} { 'Normalized' :<12} { 'Confidence' :<12} " )
317- print ("-" * 40 )
312+ print ("\n 📊 DETAILED ACTION PROBABILITY BREAKDOWN:" )
313+ print ("=" * 120 )
314+ print (f"{ 'Action' :<30} { 'Tokens' :<25} { 'Token Probabilities (%)' :<35} { 'W/O Norm' :<12} { 'Token Norm' :<12} { 'Word Norm' :<12} " )
315+ print ("=" * 120 )
318316
319- for action , log_prob , norm_prob in word_norm_results [:10 ]: # Show top 10
320- action_text = action .command_perspective [:37 ] + "..." if len (action .command_perspective ) > 40 else action .command_perspective
321- print (f"{ action_text :<40} { log_prob :<12.4f} { norm_prob :<12.4f} { math .exp (norm_prob ):.4%} " )
317+ for action , log_prob , token_norm_prob , token_texts , token_probs in token_norm_results [:10 ]:
318+ # Find corresponding word norm result
319+ word_norm_prob = next ((w_norm for w_action , _ , w_norm , _ , _ in word_norm_results if w_action == action ), token_norm_prob )
320+
321+ action_text = action .command_perspective [:27 ] + "..." if len (action .command_perspective ) > 30 else action .command_perspective
322+
323+ # Format tokens as [token1, token2, ...]
324+ token_list = "[" + ", " .join ([repr (t ) for t in token_texts ]) + "]"
325+ if len (token_list ) > 25 :
326+ token_list = token_list [:22 ] + "...]"
327+
328+ # Format probabilities as [prob1, prob2, ...]
329+ prob_list = "[" + ", " .join ([f"{ p :.3f} " for p in token_probs ]) + "]"
330+ if len (prob_list ) > 35 :
331+ prob_list = prob_list [:32 ] + "...]"
332+
333+ # Calculate action probability without normalization (geometric mean)
334+ action_prob_wo_norm = math .exp (log_prob ) * 100 # Convert to percentage
335+
336+ print (f"{ action_text :<30} { token_list :<25} { prob_list :<35} { action_prob_wo_norm :<11.4f} { math .exp (token_norm_prob )* 100 :<11.4f} { math .exp (word_norm_prob )* 100 :<11.4f} " )
322337
323338 # Most probable action
324339 print ("\n 🎯 MOST PROBABLE ACTION (Token Normalization):" )
325340 print ("-" * 40 )
326- best_action_token , best_log_prob_token , best_norm_prob_token = token_norm_results [0 ]
341+ best_action_token , best_log_prob_token , best_norm_prob_token , best_tokens , best_token_probs = token_norm_results [0 ]
327342 print (f"Action: { best_action_token .command_perspective } " )
343+ print (f"Tokens: { best_tokens } " )
344+ print (f"Token Probabilities: { [f'{ p :.3f} %' for p in best_token_probs ]} " )
328345 print (f"Log Probability: { best_log_prob_token :.4f} " )
329346 print (f"Normalized Probability: { best_norm_prob_token :.4f} " )
330347 print (f"Confidence Score: { math .exp (best_norm_prob_token ):.4%} " )
331348
332349 print ("\n 🎯 MOST PROBABLE ACTION (Word Normalization):" )
333350 print ("-" * 40 )
334- best_action_word , best_log_prob_word , best_norm_prob_word = word_norm_results [0 ]
351+ best_action_word , best_log_prob_word , best_norm_prob_word , _ , _ = word_norm_results [0 ]
335352 print (f"Action: { best_action_word .command_perspective } " )
336353 print (f"Log Probability: { best_log_prob_word :.4f} " )
337354 print (f"Normalized Probability: { best_norm_prob_word :.4f} " )
0 commit comments