Skip to content

Commit 7f56685

Browse files
committed
Fix(analysis): Various fixes to llm as judge
1 parent 5772eab commit 7f56685

4 files changed

Lines changed: 28 additions & 12 deletions

File tree

codeclash/analysis/llm_as_judge/big_questions.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ def pretty_print(self) -> None:
6666

6767
class ModelConfig(BaseModel):
6868
model_name: str
69+
model_class: str | None = None
6970
model_kwargs: dict[str, Any]
7071

7172

@@ -90,7 +91,7 @@ def extract_triple_backticks(text: str) -> str:
9091
class BigQuestions:
9192
def __init__(self, config: BigQuestionsConfig):
9293
self.config = config
93-
self.model = get_model(config.model.model_name, config={"model_kwargs": config.model.model_kwargs})
94+
self.model = get_model(config.model.model_name, config={"model_kwargs": config.model.model_kwargs, "model_class": config.model.model_class})
9495

9596
@property
9697
def data_id(self) -> str:
@@ -145,20 +146,24 @@ def _get_messages(self, instance: Instance) -> list[dict[str, Any]]:
145146

146147
def _should_skip(self, target_path: Path, instance: Instance) -> bool:
147148
if not target_path.exists():
149+
logger.debug(f"Not skipping: {target_path} does not exist")
148150
return False
149151
content = target_path.read_text()
150152
if not content.strip():
153+
logger.debug(f"Not skipping: {target_path} is empty")
151154
return False
152155
data = json.loads(content)
153156
if self.data_id not in data:
157+
logger.debug(f"Not skipping: {self.data_id} not in {target_path}")
154158
return False
155-
if instance.instance_id in data[self.data_id]:
156-
return True
157-
return False
159+
if instance.instance_id not in data[self.data_id]:
160+
logger.debug(f"Not skipping: {instance.instance_id} not in {target_path} under key {self.data_id}")
161+
return False
162+
return True
158163

159164
def _save_response(self, target_path: Path, response_data: dict[str, Any], instance: Instance) -> None:
160165
# atomic write with file lock in case other analyses are also writing
161-
with FileLock(target_path):
166+
with FileLock(target_path.with_suffix(".lock")):
162167
# read again if changed in the meantime
163168
data = {}
164169
if target_path.exists():

codeclash/analysis/llm_as_judge/big_questions.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ instance_prompt: |
209209
210210
{{ trajectory_message_str }}
211211
model:
212-
model_name: gpt-5
212+
model_name: 'openai/gpt-5'
213+
# model_class: portkey
213214
model_kwargs:
214215
reasoning_effort: high

codeclash/analysis/llm_as_judge/get_instances.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
parser.add_argument("-o", "--output-file", type=Path, help="Path to the output file", default="instances.json")
1414
args = parser.parse_args()
1515

16-
SELECTED_ROUNDS = [1, 5, 10, 15]
16+
SELECTED_ROUNDS = [1, 2, 3, 5, 10, 15]
1717
SELECTED_GAME = "BattleSnake"
1818

1919
# first get all instances, then filter
@@ -28,11 +28,13 @@
2828
# instance per combination of game, lm, and round
2929
unique = {}
3030
for instance in instances:
31-
key = (instance.tournament_name, instance.get_lm_name(), instance.round_number)
31+
key = (*instance.get_lm_name_self_opponent(), instance.round_number)
3232
if key not in unique:
3333
unique[key] = instance
3434
instances = list(unique.values())
35-
print(f"Filtered to {len(instances)} instances after deduplication for game repetitions")
35+
unique_models = set([instance.get_lm_name_self_opponent()[0] for instance in instances])
36+
print(unique_models)
37+
print(f"Filtered to {len(instances)} instances after deduplication for game repetitions for {len(unique_models)} unique model matchups")
3638

3739
batch = InstanceBatch(instances=instances)
3840
args.output_file.write_text(batch.model_dump_json())

codeclash/analysis/llm_as_judge/utils.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,13 @@ class Instance(BaseModel):
3232
def instance_id(self) -> str:
3333
return f"{self.tournament_name}__{self.player_name}__r{self.round_number}"
3434

35-
def get_lm_name(self) -> str:
35+
def get_lm_name_self_opponent(self) -> tuple[str, str]:
3636
metadata_path = self.trajectory_path.parent.parent.parent / "metadata.json"
3737
metadata = json.loads(metadata_path.read_text())
38-
return metadata["config"]["players"][self.player_name]["config"]["model"]["model_name"]
38+
player_configs = metadata["config"]["players"]
39+
player_config = [pc for pc in player_configs if pc["name"] == self.player_name][0]
40+
other_player_config = [pc for pc in player_configs if pc["name"] != self.player_name][0]
41+
return player_config["config"]["model"]["model_name"].removeprefix("@"), other_player_config["config"]["model"]["model_name"].removeprefix("@")
3942

4043

4144
class InstanceBatch(BaseModel):
@@ -47,10 +50,15 @@ def find_tournament_folders(input_dir: Path) -> list[Path]:
4750

4851

4952
def parse_trajectory_name(trajectory_path: Path) -> Instance:
53+
try:
54+
round_number = int(trajectory_path.name.removesuffix(".traj.json").split("_r")[1])
55+
except:
56+
print(trajectory_path)
57+
raise
5058
return Instance(
5159
trajectory_path=trajectory_path,
5260
player_name=trajectory_path.parent.name,
53-
round_number=int(trajectory_path.name.split(".")[0].split("_r")[1]),
61+
round_number=round_number,
5462
tournament_name=trajectory_path.parent.parent.parent.name,
5563
)
5664

0 commit comments

Comments
 (0)