Skip to content

Commit 41b7d36

Browse files
committed
feat: token probability table and capitalize action commands and inject "**Action:"
1 parent 3d2ea00 commit 41b7d36

2 files changed

Lines changed: 47 additions & 30 deletions

File tree

scripts/calculate_action_probabilities.py

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -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\nAction:", 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}")

src/among_them/models/action.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,27 +25,27 @@ def __init__(
2525

2626
def set_stories(self):
2727
if self.type == ActionType.MOVE:
28-
self.command_perspective = f"move to {self.target_location.value}"
28+
self.command_perspective = f" Move to {self.target_location.value}"
2929
self.agent_perspective = f"You moved to {self.target_location.value}."
3030
self.observer_perspective = f"You saw {self.player_name} move to {self.target_location.value}."
3131
self.global_perspective = f"{self.player_name} moved to {self.target_location.value}."
3232
elif self.type == ActionType.WAIT:
33-
self.command_perspective = "wait"
33+
self.command_perspective = " Wait"
3434
self.agent_perspective = "You waited."
3535
self.observer_perspective = f"You noticed {self.player_name} was waiting."
3636
self.global_perspective = f"{self.player_name} waited."
3737
elif self.type == ActionType.TASK:
38-
self.command_perspective = f"{self.target_task.name}"
38+
self.command_perspective = f" {self.target_task.name}"
3939
self.agent_perspective = f"You completed the {self.target_task.name} task."
4040
self.observer_perspective = f"You saw {self.player_name} complete the {self.target_task.name} task."
4141
self.global_perspective = f"{self.player_name} completed the {self.target_task.name} task."
4242
elif self.type == ActionType.REPORT:
43-
self.command_perspective = f"report the dead body of {str(self.target_player_name)}"
43+
self.command_perspective = f" Report the dead body of {str(self.target_player_name)}"
4444
self.agent_perspective = f"You reported the dead body of {str(self.target_player_name)} and started a discussion."
4545
self.observer_perspective = f"You saw {self.player_name} report the dead body of {str(self.target_player_name)} to everyone. Discussion started."
4646
self.global_perspective = f"{self.player_name} reported the dead body of {str(self.target_player_name)}. Discussion started."
4747
elif self.type == ActionType.KILL:
48-
self.command_perspective = f"kill {str(self.target_player_name)}"
48+
self.command_perspective = f" Kill {str(self.target_player_name)}"
4949
self.agent_perspective = f"You killed {str(self.target_player_name)}."
5050
self.observer_perspective = f"You witnessed {self.player_name} kill {str(self.target_player_name)}!"
5151
self.global_perspective = f"{self.player_name} killed {str(self.target_player_name)}."
@@ -54,12 +54,12 @@ def set_stories(self):
5454
self.observer_perspective = f"System said: {self.target_message}"
5555
self.global_perspective = f"System said: {self.target_message}"
5656
elif self.type == ActionType.VOTE:
57-
self.command_perspective = f"vote for {str(self.target_player_name)}"
57+
self.command_perspective = f" Vote for {str(self.target_player_name)}"
5858
self.agent_perspective = f"You voted for {str(self.target_player_name)}."
5959
self.observer_perspective = f"You heard {self.player_name} vote for {str(self.target_player_name)}."
6060
self.global_perspective = f"{self.player_name} voted for {str(self.target_player_name)}."
6161
elif self.type == ActionType.PRETEND:
62-
self.command_perspective = f"pretend to do task: {self.target_task.name}"
62+
self.command_perspective = f" Pretend to do task: {self.target_task.name}"
6363
self.agent_perspective = f"You pretended to do the {self.target_task.name} task."
6464
self.observer_perspective = f"You saw {self.player_name} complete the {self.target_task.name} task."
6565
self.global_perspective = f"{self.player_name} pretended to do the {self.target_task.name} task."

0 commit comments

Comments
 (0)