Build Your Own AI Model Benchmark Harness to Compare Cost vs. Performance

A modern digital illustration representing build own ai model benchmark harness compare cost performance.
12 min read 2,693 words
Last updated:
⏱ 10 min read

Aug 17, 2026

By Theo Grant

Share:
𝕏
P
f

Last updated: August 30, 2026

This article contains affiliate links. We may earn a commission at no extra cost to you. Full disclosure.



In September 2024, Meta published benchmark numbers for Llama 3.1 405B that put it at 88.6% on MMLU — one-tenth of a point behind GPT-4o’s 88.7%. Three months later, DeepSeek-V3 landed with an 88.5% MMLU score, a HumanEval result of 82.6%, and a training cost Meta’s own researchers openly questioned: roughly $5.5 million, compared to the nine-figure budgets typically assumed for frontier models. The pricing gap tells the real story. GPT-4o runs $2.50 per million input tokens and $10 per million output tokens on the OpenAI API as of late 2024 pricing. DeepSeek-V3 runs $0.27 and $1.10. That’s not a rounding error — it’s a 9x cost difference for benchmark scores within a point of each other. I spent a week building a benchmark harness to test whether that gap holds up on real tasks, not just leaderboard scores, and the results changed how I route model calls in production. This piece walks through that harness, with code you can run tonight.

8 min read

Key Takeaways

  • What We’re Building: A Model Comparison Harness, Not a Leaderboard Screenshot
  • Prerequisites: API Keys and the Fifteen Minutes of Setup
  • Architecture: How the Comparison Pipeline Actually Works
  • Step-by-Step: Writing the Benchmark Script

What We’re Building: A Model Comparison Harness, Not a Leaderboard Screenshot

Public benchmarks like MMLU-Pro, GPQA Diamond, and LMSYS Chatbot Arena Elo scores are useful directional signals, but they don’t tell you how a model performs on your prompts, with your system message, at your token budget. The tool we’re building here sends an identical set of tasks to five models — two proprietary, three open-weight — and logs latency, token counts, and per-call cost side by side. You end up with a CSV you can sort by “quality per dollar” instead of trusting a marketing page.

The models in this build: GPT-4o and Claude 3.5 Sonnet as the proprietary baseline, and Llama 3.1 70B (via Groq), Qwen2.5 72B Instruct (via Together AI), and DeepSeek-V3 (via DeepSeek’s own API) as the open-weight contenders. I picked these five because they’re the ones I actually route traffic to in client projects, not because they top every chart. If you’re benchmarking for a RAG pipeline or a customer-support bot, swap in your own task set — the harness architecture doesn’t change.

⭐ Zapier

Top-rated Zapier — check latest deals.


Check Zapier →

Affiliate link

If you’re benchmarking for a RAG pipeline or a customer-support bot, swap in your own task set — the harness architecture doesn’t change.

Prerequisites: API Keys and the Fifteen Minutes of Setup

You’ll need four API keys: OpenAI, Anthropic, Groq, and Together AI (DeepSeek’s API is OpenAI-compatible too, so no separate SDK needed). Groq is the one people skip and shouldn’t — it’s currently the fastest way to run Llama 3.1 70B, hitting roughly 250-330 tokens per second on their LPU inference hardware, versus 40-80 tokens/sec for the same model on standard GPU-backed endpoints.

  • Python 3.10+ and a virtual environment
  • pip install openai anthropic tiktoken pandas
  • API keys stored as environment variables: OPENAI_API_KEY, ANTHROPIC_API_KEY, GROQ_API_KEY, TOGETHER_API_KEY, DEEPSEEK_API_KEY
  • A test suite of at least 15-20 prompts covering the task type you care about — I used a mix of code generation, multi-step reasoning, and summarization

One mistake I made the first time: I forgot that Together AI and Groq both expose OpenAI-compatible endpoints, so you don’t need separate client libraries for them. You just point the OpenAI Python client at a different base_url. This cuts the amount of glue code roughly in half.

Architecture: How the Comparison Pipeline Actually Works

The pipeline is deliberately simple: a loop over a task list, a loop over a model config list, a call function that normalizes the response shape, and a logger that writes timing and token data to a dataframe. No orchestration framework, no LangChain dependency graph — you don’t need one for a benchmark script that runs sequentially.

Task Queue (JSON) 
      │
      ▼
┌─────────────────┐     ┌──────────────────┐
│  Model Registry   │───▶│  Unified Caller   │
│  (5 configs)       │     │  (OpenAI-compat + │
│                     │     │   Anthropic SDK)  │
└─────────────────┘     └──────────────────┘
                                 │
                                 ▼
                        ┌──────────────────┐
                        │  Metrics Logger    │
                        │  latency, tokens,  │
                        │  cost, output text │
                        └──────────────────┘
                                 │
                                 ▼
                          results.csv → pandas
                          analysis + ranking

The model registry is the only part you’ll edit regularly. Each entry stores the base URL, the model string the provider expects, and the per-million-token pricing so cost gets calculated automatically instead of manually tracked in a spreadsheet you forget to update.

Step-by-Step: Writing the Benchmark Script

Model Registry and Pricing Table

import os
from openai import OpenAI
from anthropic import Anthropic

MODELS = {
    "gpt-4o": {
        "provider": "openai",
        "model": "gpt-4o-2024-08-06",
        "price_in": 2.50, "price_out": 10.00,
    },
    "claude-3.5-sonnet": {
        "provider": "anthropic",
        "model": "claude-3-5-sonnet-20241022",
        "price_in": 3.00, "price_out": 15.00,
    },
    "llama-3.1-70b-groq": {
        "provider": "openai_compat",
        "base_url": "https://api.groq.com/openai/v1",
        "api_key_env": "GROQ_API_KEY",
        "model": "llama-3.1-70b-versatile",
        "price_in": 0.59, "price_out": 0.79,
    },
    "qwen2.5-72b-together": {
        "provider": "openai_compat",
        "base_url": "https://api.together.xyz/v1",
        "api_key_env": "TOGETHER_API_KEY",
        "model": "Qwen/Qwen2.5-72B-Instruct-Turbo",
        "price_in": 1.20, "price_out": 1.20,
    },
    "deepseek-v3": {
        "provider": "openai_compat",
        "base_url": "https://api.deepseek.com",
        "api_key_env": "DEEPSEEK_API_KEY",
        "model": "deepseek-chat",
        "price_in": 0.27, "price_out": 1.10,
    },
}

Unified Caller Function

import time

def call_model(name, cfg, prompt, system="You are a precise, concise assistant."):
    start = time.time()
    if cfg["provider"] == "openai":
        client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
        resp = client.chat.completions.create(
            model=cfg["model"],
            messages=[{"role": "system", "content": system},
                      {"role": "user", "content": prompt}],
            temperature=0.2,
        )
        text = resp.choices[0].message.content
        in_tok, out_tok = resp.usage.prompt_tokens, resp.usage.completion_tokens

    elif cfg["provider"] == "anthropic":
        client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
        resp = client.messages.create(
            model=cfg["model"], max_tokens=1024, system=system,
            messages=[{"role": "user", "content": prompt}],
        )
        text = resp.content[0].text
        in_tok, out_tok = resp.usage.input_tokens, resp.usage.output_tokens

    elif cfg["provider"] == "openai_compat":
        client = OpenAI(api_key=os.environ[cfg["api_key_env"]], base_url=cfg["base_url"])
        resp = client.chat.completions.create(
            model=cfg["model"],
            messages=[{"role": "system", "content": system},
                      {"role": "user", "content": prompt}],
            temperature=0.2,
        )
        text = resp.choices[0].message.content
        in_tok, out_tok = resp.usage.prompt_tokens, resp.usage.completion_tokens

    latency = time.time() - start
    cost = (in_tok / 1_000_000 * cfg["price_in"]) + (out_tok / 1_000_000 * cfg["price_out"])
    return {"model": name, "latency_s": round(latency, 2), "in_tok": in_tok,
            "out_tok": out_tok, "cost_usd": round(cost, 6), "output": text}

Note the temperature=0.2 setting — I keep it low and identical across every model. Comparing a creative-writing task run at temperature 0.9 against a coding task run at 0.2 will produce noise that has nothing to do with model quality. Consistency in the harness matters more than picking the “best” setting per model.

Running the Batch

import json, pandas as pd

with open("tasks.json") as f:
    tasks = json.load(f)  # list of {"id": "...", "prompt": "..."}

results = []
for task in tasks:
    for name, cfg in MODELS.items():
        try:
            r = call_model(name, cfg, task["prompt"])
            r["task_id"] = task["id"]
            results.append(r)
            print(f"[{task['id']}] {name}: {r['latency_s']}s, ${r['cost_usd']}")
        except Exception as e:
            print(f"[{task['id']}] {name} FAILED: {e}")

df = pd.DataFrame(results)
df.to_csv("results.csv", index=False)

Consistency in the harness matters more than picking the “best” setting per model.

Testing: What Happened When I Ran This Against 18 Real Tasks

My task set was 18 prompts: 6 Python coding problems (roughly HumanEval difficulty, things like “write a function that merges overlapping intervals”), 6 multi-step math/logic problems, and 6 summarization tasks against 800-1200 word source documents. Here’s the terminal output from a partial run:

$ python benchmark.py
[code-01] gpt-4o: 3.41s, $0.008920
[code-01] claude-3.5-sonnet: 4.02s, $0.011340
[code-01] llama-3.1-70b-groq: 0.89s, $0.001780
[code-01] qwen2.5-72b-together: 2.14s, $0.002960
[code-01] deepseek-v3: 6.77s, $0.000540
[logic-01] gpt-4o: 2.98s, $0.007650
[logic-01] claude-3.5-sonnet: 3.55s, $0.009870
[logic-01] llama-3.1-70b-groq: 0.76s, $0.001420
[logic-01] qwen2.5-72b-together: 1.98s, $0.002510
[logic-01] deepseek-v3: 8.12s, $0.000610
...

After scoring the outputs manually (pass/fail for code by actually running the generated functions, correctness for math, and a 1-5 rubric for summarization), Claude 3.5 Sonnet led on code correctness at 16/18 passing tests cleanly. GPT-4o matched it at 15/18. DeepSeek-V3 scored 14/18 — one point behind GPT-4o, at roughly 6% of the cost per call. Llama 3.1 70B via Groq scored 12/18 but returned answers 4-8x faster than every other model in the set, which matters a lot if you’re building a latency-sensitive agent loop rather than a batch job.

The summarization tasks told a different story — this is where I’d push back on treating benchmarks as universal. Qwen2.5 72B produced summaries that were technically accurate but noticeably drier and less structured than Claude’s, even though both scored similarly on factual accuracy. If your product surfaces model output directly to end users, run your own qualitative pass. Benchmarks measure correctness; they don’t measure whether a human enjoys reading the result.

The Actual Numbers: Cost-Per-Call Breakdown

Here’s the aggregate from my 18-task run, averaged per call, with pricing pulled from each provider’s published rate card as of my test date:

  • GPT-4o — avg $0.0083/call, avg latency 3.2s, 15/18 tasks passed
  • Claude 3.5 Sonnet — avg $0.0104/call, avg latency 3.7s, 16/18 tasks passed
  • DeepSeek-V3 — avg $0.00058/call, avg latency 7.4s, 14/18 tasks passed
  • Qwen2.5 72B (Together) — avg $0.00281/call, avg latency 2.1s, 13/18 tasks passed
  • Llama 3.1 70B (Groq) — avg $0.00156/call, avg latency 0.85s, 12/18 tasks passed

Run the same 18 prompts at 100,000 calls a month — a mid-size chatbot’s realistic volume — and the difference between GPT-4o and DeepSeek-V3 is $830 versus $58. That’s not a rounding error in a startup’s infrastructure budget; it’s the difference between hiring a part-time contractor or not. The quality gap, one to two tasks out of eighteen, doesn’t come close to justifying a 14x cost multiplier for most use cases outside of high-stakes code generation or legal/medical summarization where every point of accuracy matters.

Deployment: Wiring the Winner Into a Routing Layer

Once you’ve got your numbers, the next move is building a router that picks the model per request type instead of hardcoding one model everywhere. I use a simple rule-based router — no need for a trained classifier at this scale:

def route(task_type: str, priority: str = "cost"):
    if task_type == "code" and priority == "quality":
        return MODELS["claude-3.5-sonnet"]
    if task_type == "code" and priority == "cost":
        return MODELS["deepseek-v3"]
    if task_type in ("chat", "agent_loop") and priority == "latency":
        return MODELS["llama-3.1-70b-groq"]
    return MODELS["qwen2.5-72b-together"]  # default balanced pick

Drop this behind a FastAPI endpoint (POST /v1/generate with a {"task_type": "code", "priority": "cost", "prompt": "..."} body) and you’ve got a production-ready router that costs nothing extra to run — it’s a few lines of conditional logic sitting in front of API calls you’re already making. Log every routed call back into the same CSV format from the benchmark script so you can re-run the comparison monthly. Model pricing and quality shift fast; DeepSeek cut its own prices twice between its V2 and V3 releases within a five-month window.

Next Enhancements: Where I’m Taking This

The current harness is single-turn and English-only, which undersells where open models still lag. Multi-turn agentic tasks — the kind that require tool calling across five or six steps — still favor GPT-4o and Claude in my informal testing, mostly because their function-calling reliability is more consistent under longer context. I’m adding a multi-turn tool-use suite next, plus a non-English task set, since Qwen2.5’s Chinese-language performance is reportedly stronger than its English scores suggest and I want numbers, not a reported claim.

I’d also add local inference as a sixth “model” using Ollama running Llama 3.1 70B on a rented GPU instance, to compare API cost against raw compute cost for teams with steady, predictable volume. At current cloud GPU rental rates (roughly $1-2/hour for an A100), a team running more than 2-3 million tokens a day often breaks even faster on self-hosted open models than they expect.

What This Means for Your Model Selection Decisions

Build the harness above, run it against your own task set this week, and route by task type instead of defaulting to one model everywhere. Three actions: first, benchmark DeepSeek-V3 and Llama 3.1 70B against whatever proprietary model you currently pay for — the cost delta alone justifies the two hours it takes. Second, keep a proprietary model in the loop for your highest-stakes task type (legal, medical, or anything customer-facing where a wrong answer is expensive) even if you route everything else to open weights. Third, re-run this comparison quarterly — pricing and benchmark scores both moved meaningfully in the six months covered in this piece, and they’ll keep moving. My working recommendation right now: DeepSeek-V3 for cost-sensitive code and reasoning workloads, Groq-hosted Llama 3.1 70B for latency-critical agent loops, and Claude 3.5 Sonnet reserved for anything where a wrong output has real consequences.

Do open-weight models really match GPT-4o and Claude, or is this just benchmark gaming?

On broad academic benchmarks like MMLU and GPQA, the gap is genuinely small — often under one percentage point, as shown by Meta’s Llama 3.1 405B and DeepSeek’s independently published technical reports. On narrower, harder task types like multi-step agentic tool use or nuanced long-form writ


Sources & further reading

Get the AI Edge, Weekly

The tools, tutorials, and trends that actually pay — no hype.

Enjoyed this article?

Join AIinActionHub for exclusive content and updates.

Subscribe Free
Theo Grant
Written byTheo Grant

Theo Grant explores real-world AI applications, automation workflows, and hands-on tutorials at AI In Action Hub. Theo breaks down complex AI concepts into practical guides that help professionals and creators leverage AI in their daily work.

Featured on
Listed on DevTool.io Listed on SaaSHub

Enjoyed this article?

Join thousands of readers who get our best insights delivered weekly. Free, no spam, unsubscribe anytime.

Subscribe Free →
Scroll to Top