Wildbench Integration#72
Conversation
|
Notes:
|
|
Although this PR adds Wildbench, it was hard to ingerate it. Thus I have proposed more cleaner solution in #74. We should discuss this possibly toward making it file-based (task=yaml file) |
| self.wildbench = WildBenchArgs() | ||
| if self.model.name is None: | ||
| raise ValueError("model.name is required for WildBench tasks.") | ||
| if self.judge.temperature is None: |
There was a problem hiding this comment.
WildBench’s judge temperature is defaulted to 0 here, but the evaluated model keeps backend defaults. For vLLM that currently means temperature 0.6/top-p 0.95 and the shared 32k output budget, while the official WildBench launch uses temperature 0/top-p 1/max-tokens 4096. As a result the example configs are stochastic and not leaderboard-comparable. Could we set or require explicit WildBench generation defaults and maybe record deviations?
There was a problem hiding this comment.
I agree, we should add this to the config file. Thanks for catching it
| "baseline_output": baseline, | ||
| "prompt": prompt, | ||
| } | ||
| if not candidate.strip() and not baseline.strip(): |
There was a problem hiding this comment.
The synthetic empty-response choices match the official evaluator, but the official leaderboard does not feed them into metrics this way. WB-Score keeps score=1 in the overall mean but excludes empty rows from category/task-macro values. WB-Reward excludes empties from win/loss counts and categories; because its overall denominator remains the full result count, an empty row contributes 0 rather than ±100.
There was a problem hiding this comment.
I will add a filtering as the last step, thanks
| normalized = value.strip().upper().replace(" ", "") | ||
| if normalized in _CHOICE_TO_A_REWARD: | ||
| return normalized | ||
| matches = re.findall(r"A\+\+|B\+\+|A=B|A\+|B\+", strip_thinking_tags(text)) |
There was a problem hiding this comment.
This fallback scans the entire response for verdict tokens. The required JSON schema contains a "reason of A=B" key, so a truncated or malformed response without choice is silently parsed as A=B instead of missing. It would be better to restrict fallback parsing to the choice field or a tightly scoped final-choice pattern.
| pending_ids = [] | ||
| records = [] | ||
| for session_id, example in examples.iterrows(): | ||
| output = candidate_outputs.loc[str(session_id)] |
There was a problem hiding this comment.
output is passed directly to the score prompt, unlike the reward path. Consequently, cfg.judge.strip_thinking_before_judging has no effect for WB-Score. I think we should apply strip_thinking_tags(output) here.
geoalgo
left a comment
There was a problem hiding this comment.
LGTM overall we can merge once you have addressed @ErlisLushtaku comments.
| @@ -0,0 +1,14 @@ | |||
| task: wildbench-reward | |||
| model: | |||
| name: VLLM/utter-project/EuroLLM-9B | |||
There was a problem hiding this comment.
perhaps we can comment this from user POV?
| name: VLLM/utter-project/EuroLLM-9B | |
| name: VLLM/utter-project/EuroLLM-9B # model to be evaluated |
| # Set an integer K to tie slight wins caused by responses longer by >K chars. | ||
| # Omit this field to disable the length penalty. |
There was a problem hiding this comment.
Is this the default in the paper? If so:
| # Set an integer K to tie slight wins caused by responses longer by >K chars. | |
| # Omit this field to disable the length penalty. | |
| # Set an integer K to tie slight wins caused by responses longer by >K chars. | |
| # Omit this field to disable the length penalty. Default to paper value. |
| model: | ||
| name: VLLM/utter-project/EuroLLM-9B | ||
| judge: | ||
| model: OpenRouter/openai/gpt-4o |
There was a problem hiding this comment.
question: should we rather use gemma4-31B for such defaults?
I see the point to default to the paper but this model is going to be replaced and is pareto dominated by gemma4.
|
|
||
| def load_instructions(dataset: str, n_instructions: int | None = None) -> pd.DataFrame: | ||
| if dataset == "mt-bench": | ||
| if dataset in {"wildbench-score", "wildbench-reward"}: |
There was a problem hiding this comment.
FYI, I was wondering about this (lists were more natural to me, this choice is PEP compliant):
# are there in coding guideline for membership tests in python?
Yes. For membership tests against a literal collection, PEP 8 and common style guidance favor a set (or frozenset) when checking in, because set lookups are O(1) versus O(n) for lists. So {"wildbench-score", "wildbench-reward"} is generally preferred.
However, with only two string elements the performance difference is negligible, and some style guides (or linters like Ruff's C0201/SIM rules) actually flag the opposite direction depending on configuration. Ruff's literal-membership rule (PLR6201) specifically recommends converting list/tuple literals to sets in membership tests, which endorses the first form.
Practical guidance: use a set literal for membership checks. Use a tuple ("a", "b") if you want to signal immutability without the set overhead and order matters, or a list only if the collection is used elsewhere as an actual list. For your case, the set version is the idiomatic choice.
| ## ✨ Key Features | ||
|
|
||
| 🎯 **Flexible Benchmarking** – Evaluate models on `Alpaca-Eval`, `Arena-Hard`, `m-Arena-Hard` and others | ||
| 🎯 **Flexible Benchmarking** – Evaluate models on `Alpaca-Eval`, `Arena-Hard`, `m-Arena-Hard`, `WildBench V2` and others |
There was a problem hiding this comment.
Perhaps we add a column for wildbench in the table l18?
Summary
This PR closes #68.
wildbench-score: checklist-based individual scoring.wildbench-reward: pairwise evaluation using one custom baseline or the threeofficial reference models.
Implementation
Example