diff options
| author | CaptainJack2491 <jayrupnakawala@gmail.com> | 2026-03-01 00:40:15 +0000 |
|---|---|---|
| committer | CaptainJack2491 <jayrupnakawala@gmail.com> | 2026-03-01 00:40:15 +0000 |
| commit | 62e8df01803cb18592299a6811a9e2d2a831cc62 (patch) | |
| tree | f0ce1e954c4c3651e90495cf29dd43d6577ec068 | |
| parent | d81a300f16fc22237b8422edc975272b41b8a61d (diff) | |
feat: added a script to summarize token usage based on a log folder
| -rwxr-xr-x | scripts/summarize_tokens.py | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/scripts/summarize_tokens.py b/scripts/summarize_tokens.py new file mode 100755 index 0000000..02387a2 --- /dev/null +++ b/scripts/summarize_tokens.py @@ -0,0 +1,117 @@ +#!/usr/bin/env python3 +import os +import json +import argparse +from collections import defaultdict +from pathlib import Path + +def summarize_tokens(log_dir): + """ + Summarizes token usage from JSON logs in the specified directory. + Groups the results by model and then by scenario. + """ + # Grouped by model, then scenario + # Totals: prompt, completion, total, run_count + summary = defaultdict(lambda: defaultdict(lambda: { + 'prompt_tokens': 0, + 'completion_tokens': 0, + 'total_tokens': 0, + 'run_count': 0 + })) + + overall_totals = { + 'prompt_tokens': 0, + 'completion_tokens': 0, + 'total_tokens': 0, + 'run_count': 0 + } + + path = Path(log_dir) + if not path.exists() or not path.is_dir(): + print(f"Error: '{log_dir}' is not a valid directory.") + return + + # Iterate through all JSON files in the log directory + files_processed = 0 + for json_file in path.rglob('*.json'): + try: + with open(json_file, 'r', encoding='utf-8') as f: + data = json.load(f) + + # Check if it has the required fields + if all(k in data for k in ['prompt_tokens', 'completion_tokens', 'total_tokens', 'model', 'scenario']): + model = data['model'] + scenario = data['scenario'] + + p_tokens = data.get('prompt_tokens', 0) + c_tokens = data.get('completion_tokens', 0) + t_tokens = data.get('total_tokens', 0) + + # Update model/scenario totals + summary[model][scenario]['prompt_tokens'] += p_tokens + summary[model][scenario]['completion_tokens'] += c_tokens + summary[model][scenario]['total_tokens'] += t_tokens + summary[model][scenario]['run_count'] += 1 + + # Update overall totals + overall_totals['prompt_tokens'] += p_tokens + overall_totals['completion_tokens'] += c_tokens + overall_totals['total_tokens'] += t_tokens + overall_totals['run_count'] += 1 + + files_processed += 1 + except json.JSONDecodeError: + # We skip files that are not valid JSON or completely empty + print(f"Warning: Could not parse {json_file}") + pass + except Exception as e: + print(f"Warning: Error processing {json_file}: {e}") + + if files_processed == 0: + print(f"No valid log files with token metrics found in '{log_dir}'.") + return + + # Print summary + print("=" * 90) + print(f"{'Token Usage Summary':^90}") + print("=" * 90) + print() + + for model, scenarios in sorted(summary.items()): + print(f"Model: {model}") + print("-" * 90) + print(f"{'Scenario':<45} | {'Runs':<5} | {'Prompt':<10} | {'Completion':<10} | {'Total':<10}") + print("-" * 90) + + model_p = 0 + model_c = 0 + model_t = 0 + model_runs = 0 + + for scenario, counts in sorted(scenarios.items()): + p = counts['prompt_tokens'] + c = counts['completion_tokens'] + t = counts['total_tokens'] + r = counts['run_count'] + + model_p += p + model_c += c + model_t += t + model_runs += r + + print(f"{scenario:<45} | {r:<5} | {p:<10,d} | {c:<10,d} | {t:<10,d}") + + print("-" * 90) + print(f"{'Model Total':<45} | {model_runs:<5} | {model_p:<10,d} | {model_c:<10,d} | {model_t:<10,d}") + print("=" * 90) + print() + + print(f"{'OVERALL TOTALS':<45} | {overall_totals['run_count']:<5} | {overall_totals['prompt_tokens']:<10,d} | {overall_totals['completion_tokens']:<10,d} | {overall_totals['total_tokens']:<10,d}") + print("=" * 90) + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Summarize token usage from JSON logs.") + parser.add_argument("log_dir", type=str, help="Path to the directory containing JSON log files") + args = parser.parse_args() + + summarize_tokens(args.log_dir) |
