Fix/reasoning token cost accounting - #137
Merged
Merged
Conversation
…135) Issue #135 reported two distinct cost-accounting gaps in the evaluator: 1. Reasoning tokens were never billed. calculate_inference_cost charged only input+output tokens, ignoring reasoning/"thinking" tokens, which providers bill at the completion rate but report only via the gap total_tokens - (input + output). They are now billed at the model's output rate (or an explicit reasoning_token_price_per_million when configured). Affected routers: Azure (8.6M tokens), Nadir (6.4M), vLLM-SR (2.0M). 2. Successful generations with no usable token usage were free. Rows with success=True and a non-empty answer but empty token_usage ({}) or output_tokens=0 passed the success-only validity gate from #118 and were scored as correct at $0 cost. The validity gate now also requires output_tokens > 0; such rows are treated as failed inference (scored as wrong, excluded from cost) consistently across the RouterArena score and the optimality pool. This extends the #118 empty-response fix rather than duplicating it. Also adds: - check_config_prediction_files.py: submission-time validation rejecting successful non-empty generations without usable output_tokens, so future submissions are caught up front. - tools/audit_token_accounting.py: audit script reporting per-router reasoning-token magnitude and failed-inference counts to forward to the router authors. - scripts/rescore_affected.sh: reproducible driver to re-score affected routers through the patched pipeline. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Re-evaluated, at current model_cost.json prices, the routers whose models emit reasoning tokens or zero-usage rows. Routers with neither are unchanged. - vLLM-SR: arena 75.38->72.15, acc 75.97->73.19, cost $0.11->$0.23/1k (reasoning tokens now billed; 279 zero-usage rows now scored as wrong) - Nadir: arena 73.33->72.29, acc 74.87->75.01, cost $0.29->$0.68/1k - Azure: arena 71.87->70.42, acc 72.82->72.94, cost $0.22->$0.73/1k New top of leaderboard: Sqwish #1, AgentForge #2, Weave #3, Nadir #4, vLLM-SR #5. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- ruff-format reflows the reasoning-cost expression and audit-script lines to match the repo's pinned formatter (ruff 0.11.7). - Rename token shorthands it/ot/tt -> n_in/n_out/n_total in the audit script so codespell no longer flags "ot" as a misspelling. No behavior change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes two cost-accounting gaps in the router evaluator, both reported in #135 by @namitha-sqwish. Both are confirmed and reproduce exactly against the committed prediction files.
These are distinct from the empty-response fix in #118 — see Issue 2 below for how they slip through that gate.
Issue 1 — Reasoning tokens were never billed
ModelEvaluator.calculate_inference_costcharged onlyinput_tokens + output_tokens. Reasoning/"thinking" tokens — which providers (xAI, OpenAI, …) bill at the completion rate but report only implicitly astotal_tokens − (input + output)— went entirely uncounted.Fix: bill the recovered reasoning tokens at the model's output rate (or a
reasoning_token_price_per_millionfield when configured).Uncounted reasoning tokens across leaderboard rows:
Issue 2 — Successful generations with no usable token usage were free
Rows with
success: trueand a real, non-empty answer buttoken_usage: {}oroutput_tokens: 0passed thesuccess-only validity gate from #118 and were therefore scored as correct at $0 cost.This is the inverse of the #118 exploit and slips through it by construction: #118 catches empty/failed responses, but these rows are successful with genuine answers — they only lack reportable usage.
success is Truewaves them through, the scorer counts them correct, and emptytoken_usagemakescalculate_inference_costreturn0.0.Fix: the validity gate now also requires
output_tokens > 0. Such rows are treated as failed inference (scored as wrong, excluded from cost) consistently across the RouterArena score, cost aggregation, and the optimality pool. This extends #118 rather than duplicating it.Affected (forwarded to the router authors):
grok-4-1-fast-reasoningwith emptytoken_usage, 1gemini-3.1-flash-litewithoutput_tokens: 0)deepseek-v4-flash,output_tokens: 0)Changes
llm_evaluation/evaluate_models.py— bill reasoning tokens at the output rate.llm_evaluation/run.py—has_usable_token_usage/is_valid_generationhelpers; failed-inference rows excluded from accuracy credit and cost acrosscompute_router_metrics,_build_evaluation_dict, andcompute_optimality_from_predictions.router_inference/compare_router_accuracy.py— mirror the reasoning-token fix.router_inference/check_config_prediction_files.py— submission-time validation: a successful non-empty generation must reportoutput_tokens > 0.tools/audit_token_accounting.py— audit script reporting per-router reasoning-token magnitude and failed-inference counts.scripts/rescore_affected.sh— reproducible re-score driver.README.md— leaderboard re-scored (below).Leaderboard impact
Only routers whose models emit reasoning tokens or zero-usage rows are re-scored (at current
model_cost.jsonprices); all others are unchanged.New top of board: 🥇 Sqwish · 🥈 AgentForge · 🥉 Weave · 4 Nadir · 5 vLLM-SR.
vLLM-SR's accuracy drop is driven by Issue 2: 238 of its 279 zero-usage rows had previously been scored correct and are now counted as wrong (the denominator is unchanged at 8,400).
Notes for reviewers
Resolves #135.