()
| 13 | |
| 14 | |
| 15 | def main(): |
| 16 | model_to_steps = {} |
| 17 | |
| 18 | if not DATA_CACHE.exists(): |
| 19 | tournaments = [x.parent for x in LOCAL_LOG_DIR.rglob("metadata.json")] |
| 20 | for game_log_folder in tqdm(tournaments): |
| 21 | with open(game_log_folder / "metadata.json") as f: |
| 22 | metadata = json.load(f) |
| 23 | try: |
| 24 | p2m = { |
| 25 | x["name"]: x["config"]["model"]["model_name"].strip("@").split("/")[-1] |
| 26 | for x in metadata["config"]["players"] |
| 27 | } |
| 28 | for model in p2m.values(): |
| 29 | if model not in model_to_steps: |
| 30 | model_to_steps[model] = [] |
| 31 | except KeyError: |
| 32 | continue |
| 33 | |
| 34 | for name in p2m.keys(): |
| 35 | traj_files = (game_log_folder / "players" / name).rglob("*.traj.json") |
| 36 | for traj_file in traj_files: |
| 37 | with open(traj_file) as f: |
| 38 | traj = json.load(f) |
| 39 | for message in traj["messages"]: |
| 40 | if message["role"] != "assistant": |
| 41 | continue |
| 42 | content = message.get("content", "") |
| 43 | |
| 44 | # Extract THOUGHT section |
| 45 | thought_match = re.search(r"THOUGHT:(.+?)```bash", content, re.DOTALL | re.IGNORECASE) |
| 46 | if not thought_match: |
| 47 | continue |
| 48 | |
| 49 | thought = thought_match.group(1).strip() |
| 50 | thought_length = len(thought.split()) |
| 51 | model_to_steps[p2m[name]].append(thought_length) |
| 52 | |
| 53 | with open(DATA_CACHE, "w") as f: |
| 54 | json.dump(model_to_steps, f, indent=2) |
| 55 | |
| 56 | with open(DATA_CACHE) as f: |
| 57 | model_to_steps = json.load(f) |
| 58 | |
| 59 | # Plot CDF |
| 60 | plt.figure(figsize=(6, 6)) |
| 61 | for model, thought_length in model_to_steps.items(): |
| 62 | sorted_steps = sorted(thought_length) |
| 63 | yvals = [i / len(sorted_steps) for i in range(len(sorted_steps))] |
| 64 | plt.step(sorted_steps, yvals, label=MODEL_TO_DISPLAY_NAME[model], where="post", color=MODEL_TO_COLOR[model]) |
| 65 | |
| 66 | LIM = 200 |
| 67 | plt.xlim(0, LIM) |
| 68 | plt.xticks(range(0, LIM + 1, 20), fontsize=18, fontproperties=FONT_REG) |
| 69 | plt.yticks([i / 10 for i in range(11)], [f"{i * 10}%" for i in range(11)], fontsize=18, fontproperties=FONT_REG) |
| 70 | plt.xlabel("Thought length (in words) per action", fontproperties=FONT_BOLD, fontsize=18) |
| 71 | # plt.ylabel("Cumulative Probability") |
| 72 | # plt.title("CDF of Thought Length (in Words) per Round by Model") |
no test coverage detected