بلاگ پر واپس جائیں

ماڈلز اور موازنہگائیڈ

اپنے ٹاسک پر دو LLMs کا منصفانہ موازنہ: فریق بدلیں اور لاگت کا لاگ

اپنے ٹکٹس پر دو ماڈلز کا آمنے سامنے موازنہ چلائیں: یکساں سیٹنگز، ہر جوڑے کا دونوں ترتیبوں میں جائزہ، اور ایک calls.jsonl لاگ جو رن کی لاگت بتاتا ہے۔

از CheapTokens Teamشائع شدہ 9 منٹ کا مطالعہ

کور: دو ماڈلز کا منصفانہ موازنہ، تین مرحلوں کے بہاؤ کے ساتھ: وہی پرامپٹ، فریق بدلیں، ہر کال لاگ کریں
اس صفحہ پر
  1. ایک عوامی ٹورنامنٹ کیا کرتا ہے جو آپ ادھار لے سکتے ہیں
  2. ٹاسک: 30 سپورٹ ٹکٹس کے جوابات کا مسودہ تیار کرنا
  3. فریق بدلیں: ہر جوڑے کا دو بار جائزہ
  4. ہر کال لاگ کریں، پھر رن کی قیمت لگائیں
  5. پوری رن شروع کرنے سے پہلے
  6. خود کو بے وقوف بنائے بغیر نتیجہ پڑھنا

آپ نے تین پرامپٹس دو ماڈلز کے ذریعے چلائے، اور دوسرے نے جیت لیا۔ اس پر بھروسہ کرنے سے پہلے، چیک کریں کہ کون سا دوسرے نمبر پر تھا۔ ایک منصفانہ موازنے کے لیے تین چیزیں ضروری ہیں: دونوں ماڈلز کے لیے یکساں سیٹنگز، ہر جوڑے کا دونوں ترتیبوں میں جائزہ، اور فی کال ٹوکنز کا لاگ، تاکہ آپ کو معلوم ہو کہ پوری رن پر کتنا خرچ آیا۔ نیچے ایک چھوٹا Python اسکرپٹ ہے جو آپ کے اپنے ٹاسک پر یہ تینوں کام کرتا ہے۔

ایک عوامی ٹورنامنٹ کیا کرتا ہے جو آپ ادھار لے سکتے ہیں#

Dwarkesh Patel کا Clocktower Bench ایک غیر سرکاری تحقیقی پروجیکٹ ہے جس میں لینگویج ماڈلز ایک دوسرے کے خلاف سماجی استدلال کا کھیل Blood on the Clocktower کھیلتے ہیں۔ یہاں کھیل مقصود نہیں؛ ہارنس مقصود ہے۔ پروجیکٹ کے About page کے مطابق (8 نومبر 2026 کو چیک کیا گیا)، یہ کچھ چیزیں کرتا ہے جو کسی بھی آمنے سامنے موازنے کو کرنی چاہئیں:

  • ایک ماڈل تمام اچھی نشستیں کھیلتا ہے اور دوسرا تمام بری نشستیں، اور ہر ڈیل دو بار فریق بدل کر کھیلی جاتی ہے، تاکہ کوئی خوش قسمت نشست نتیجہ طے نہ کرے؛
  • تمام ماڈلز کو یکساں سیٹنگز ملتی ہیں: وہی reasoning effort، فی ٹرن 8,000 ٹوکن کی حد اور تقریر پر 150 الفاظ کی حد؛
  • Storyteller اسکرپٹ شدہ ہے، اس لیے کوئی ماڈل کھیل کی ریفرینگ نہیں کرتا؛
  • ہر API کال اپنے ٹوکنز اور لاگت کے ساتھ calls.jsonl میں لکھی جاتی ہے۔ صفحہ کہتا ہے کہ ایک کھیل کی لاگت تقریباً $2 سے $50 تک ہوتی ہے، ماڈلز پر منحصر (OpenAI اور Anthropic APIs پر)۔

یہ ہارنس OpenAI اور Anthropic ماڈلز کے لیے بنایا گیا ہے، اور آپ کا ٹاسک شاید بورڈ گیم نہیں ہے۔ لیکن تین عادتیں منتقل ہوتی ہیں: یکساں سیٹنگز، بدلے ہوئے فریق، اور لاگت کا لاگ۔ اس گائیڈ کا باقی حصہ انہیں کسی عام چیز پر لاگو کرتا ہے۔

ہر ٹکٹ دونوں ماڈلز کو جاتا ہے؛ جج جوڑا دو بار، مخالف ترتیبوں میں دیکھتا ہے
ایک ٹکٹ کے لیے فریق بدلنے کا لوپ

ٹاسک: 30 سپورٹ ٹکٹس کے جوابات کا مسودہ تیار کرنا#

فرض کریں آپ ایک چھوٹا سپورٹ ڈیسک چلاتے ہیں اور جاننا چاہتے ہیں کہ DeepSeek-V4-Flash بہتر پہلا مسودہ لکھتا ہے یا GLM-5.3-Flash۔ آپ کے پاس ایک فائل tickets.jsonl ہے جس میں 30 حقیقی ٹکٹس ہیں، فی لائن ایک JSON آبجیکٹ: {"id": 1, "text": "..."}۔

API OpenAI-compatible ہے، اس لیے سرکاری openai پیکیج CheapTokens پر https://api.cheaptokens.dev/v1 کے ساتھ کام کرتا ہے۔ ڈاکس سے مکمل ماڈل آئی ڈیز استعمال کریں: deepseek-ai/DeepSeek-V4-Flash-0731 اور zai-org/GLM-5.3-Flash۔ دونوں ماڈلز کو ایک تیسرا ماڈل بطور جج بھی ملتا ہے، MiniMaxAI/MiniMax-M2.7، تاکہ کوئی بھی مقابلہ کرنے والا اپنا کام خود گریڈ نہ کرے۔

اس حصے سے شروع کریں جو لاگ کو ممکن بناتا ہے: ایک فنکشن جس سے ہر کال گزرتی ہے۔

python
import json, os, re
from openai import OpenAI

client = OpenAI(base_url="https://api.cheaptokens.dev/v1",
                api_key=os.environ["CHEAPTOKENS_API_KEY"])

CONTESTANTS = {"deepseek": "deepseek-ai/DeepSeek-V4-Flash-0731",
               "glm": "zai-org/GLM-5.3-Flash"}
JUDGE = "MiniMaxAI/MiniMax-M2.7"
SETTINGS = {"temperature": 0.2, "max_tokens": 800}   # same for both

def call(model, messages, role, ticket_id, **settings):
    r = client.chat.completions.create(model=model, messages=messages, **settings)
    with open("calls.jsonl", "a", encoding="utf-8") as f:
        f.write(json.dumps({
            "role": role, "ticket": ticket_id, "model": model,
            "input_tokens": r.usage.prompt_tokens,
            "output_tokens": r.usage.completion_tokens,
            "finish": r.choices[0].finish_reason}) + "\n")
    return r.choices[0].message.content or ""

def draft(model, ticket):
    msgs = [{"role": "system", "content": "You answer support tickets. "
             "Reply in under 80 words, politely, with no promises about refunds."},
            {"role": "user", "content": ticket["text"]}]
    return call(model, msgs, "draft", ticket["id"], **SETTINGS)

calls.jsonl میں موجود فیلڈز وہ ہیں جو یہ اسکرپٹ منتخب کرتا ہے؛ usage نمبرز API جواب کے usage آبجیکٹ سے آتے ہیں۔ دونوں ماڈلز کو وہی سسٹم پرامپٹ، وہی temperature اور وہی max_tokens ملتا ہے۔ ایک ماڈل کے لیے ان میں سے کوئی ایک بدلیں اور آپ سیٹنگز کا موازنہ کر رہے ہوں گے، ماڈلز کا نہیں۔

فریق بدلیں: ہر جوڑے کا دو بار جائزہ#

اب جج۔ ایک جج ماڈل کسی خاص سلاٹ میں جواب کی طرف جھک سکتا ہے، اس لیے ایک واحد فیصلہ معیار کو پوزیشن کے ساتھ ملا دیتا ہے۔ Clocktower کی چال بخوبی فٹ بیٹھتی ہے: ہر جوڑا دونوں کرداروں میں دکھائیں۔ کوئی جواب ٹکٹ صرف اسی صورت جیتتا ہے جب جج اسے دونوں ترتیبوں میں منتخب کرے۔ اگر فیصلہ جواب کے بجائے سلاٹ کی پیروی کرے، تو ٹکٹ برابر ہے۔

python
def judge(ticket, first, second):
    prompt = (f"Ticket:\n{ticket['text']}\n\nReply A:\n{first}\n\nReply B:\n{second}\n\n"
              "Which reply is better for the customer? Finish with a last line: Verdict: A or Verdict: B.")
    out = call(JUDGE, [{"role": "user", "content": prompt}], "judge",
               ticket["id"], temperature=0, max_tokens=1000)
    letters = re.findall(r"Verdict:\s*([AB])\b", out)
    return letters[-1] if letters else None

tickets = [json.loads(l) for l in open("tickets.jsonl", encoding="utf-8")]
wins = {"deepseek": 0, "glm": 0, "tie": 0}

for t in tickets:
    a = draft(CONTESTANTS["deepseek"], t)
    b = draft(CONTESTANTS["glm"], t)
    v1 = judge(t, a, b)   # DeepSeek's reply shown as A
    v2 = judge(t, b, a)   # GLM's reply shown as A
    pick1 = {"A": "deepseek", "B": "glm"}.get(v1)
    pick2 = {"A": "glm", "B": "deepseek"}.get(v2)
    wins[pick1 if pick1 and pick1 == pick2 else "tie"] += 1

print(wins)

دو تفصیلیں آسانی سے نظر انداز ہو جاتی ہیں۔ جج temperature=0 پر چلتا ہے تاکہ اس کے فیصلے زیادہ مستحکم رہیں؛ ہر ماڈل اس سیٹنگ کا احترام نہیں کرتا، اس لیے بھروسہ کرنے سے پہلے چند جوڑے دوبارہ چلائیں اور فیصلوں کا موازنہ کریں۔ فیصلہ صرف آخری Verdict: لائن سے پڑھا جاتا ہے، اور کیپس فراخ ہیں (مسودوں کے لیے 800، جج کے لیے 1000) تاکہ جواب دینے سے پہلے سوچنے والا ماڈل سوچ کے بیچ میں نہ کٹے؛ نیچے تخمینہ عام سائز استعمال کرتا ہے، کیپس نہیں۔ ناقابلِ تجزیہ جواب None دیتا ہے، جو رن کو کریش کرنے کے بجائے برابر میں گر جاتا ہے۔

خود آزمائیںآزمائیں: جج نے ٹکٹ 7 کے لیے دونوں ترتیبوں میں "A" کہا۔ وہ ٹکٹ کون جیتتا ہے؟جواب دکھائیں

کوئی نہیں۔ پہلی ترتیب میں A DeepSeek کا جواب تھا، دوسری ترتیب میں A GLM کا جواب تھا، اس لیے جج نے سلاٹ کو ترجیح دی، کسی ماڈل کو نہیں۔ کوڈ اسے برابر گنتا ہے۔ ایسے برابر کا ڈھیر خود ایک نتیجہ ہے: دونوں ماڈلز آپ کے ٹاسک پر قریب ہیں، یا آپ کا جج پرامپٹ بہت مبہم ہے۔

ترتیب ٹیسٹ کو جھکانے کا صرف ایک طریقہ ہے۔ سیٹنگز، پرامپٹس اور لاگنگ بھی اسے جھکا سکتے ہیں، اس لیے پورا سیٹ اپ چیک کریں، صرف یہ نہیں کہ کون پہلے جاتا ہے۔ یہاں وہی تجربہ پہلے اور بعد میں ہے۔

موازنہ کریں

جب آپ اتفاقی موازنہ چھوڑتے ہیں تو کیا بدلتا ہے

اتفاقی

فی ماڈل ایک پرامپٹ، ڈیفالٹس برقرار، جوڑا ایک ترتیب میں دکھایا گیا، اور بل مہینے کے آخر میں ڈیش بورڈ سے پڑھا گیا۔ جیتنے والا شاید وہ ماڈل ہو جو اتفاق سے پہلے درج تھا۔

منصفانہ

ایک مشترکہ سسٹم پرامپٹ اور وہی temperature اور max_tokens، ہر جوڑے کا دونوں ترتیبوں میں جائزہ، اور ہر کال کے لیے calls.jsonl میں ایک لائن۔ جیتنے والا وہ ہے جو دونوں نشستوں سے جیتے۔

ہر کال لاگ کریں، پھر رن کی قیمت لگائیں#

لاگ وہ چیز ہے جو موازنے کو بجٹ میں بدل دیتا ہے۔ رن کے بعد، فی ماڈل ٹوکنز جمع کریں:

python
from collections import defaultdict

totals = defaultdict(lambda: [0, 0, 0])
for line in open("calls.jsonl", encoding="utf-8"):
    c = json.loads(line)
    s = totals[c["model"]]
    s[0] += c["input_tokens"]; s[1] += c["output_tokens"]; s[2] += 1

for model, (tin, tout, n) in totals.items():
    print(model, n, "calls", tin, "input", tout, "output")

آپ کو فی ماڈل ایک لائن ملے گی جس میں کال کاؤنٹ، ان پٹ ٹوکنز اور آؤٹ پٹ ٹوکنز ہوں گے۔ ماڈل کی دو قیمتوں (ان پٹ اور آؤٹ پٹ الگ بل کیے جاتے ہیں) سے ضرب دیں یا، آسان طریقہ، ٹوٹلز کو لائیو کاسٹ مارکر میں پیسٹ کریں۔

آپ رن سے پہلے تخمینہ بھی لگا سکتے ہیں۔ فرض کریں ہر ٹکٹ اور سسٹم پرامپٹ مل کر تقریباً 300 ان پٹ ٹوکنز ہیں، ایک مسودہ تقریباً 250 آؤٹ پٹ ٹوکنز ہے، اور جج تقریباً 800 ان پٹ ٹوکنز دیکھتا ہے (ٹکٹ اور دونوں جوابات اور سوال) اور تقریباً 200 ٹوکنز کے ساتھ جواب دیتا ہے (فیصلے کی لائن اور سوچنے کے لیے تھوڑی گنجائش):

  • مسودے: 30 ٹکٹس × 2 ماڈلز = 60 کالز، فی مقابلہ کرنے والا 30 × 300 = 9000 ان پٹ اور 30 × 250 = 7500 آؤٹ پٹ ٹوکنز؛
  • فیصلے: 30 ٹکٹس × 2 ترتیبیں = 60 کالز، جج پر 60 × 800 = 48000 ان پٹ اور 60 × 200 = 12000 آؤٹ پٹ ٹوکنز۔

موجودہ قیمتوں پر، ایک مقابلہ کرنے والے کے 30 مسودوں کی لاگت DeepSeek-V4-Flash پر $0.00089 اور GLM-5.3-Flash پر $0.00048 ہے۔ MiniMax-M2.7 پر 60 فیصلوں کی لاگت $0.0042 ہے۔ تینوں جمع کریں اور ایک بھی درخواست بھیجنے سے پہلے آپ کے پاس پورے موازنے کی قیمت ہوگی۔ تینوں ماڈلز پر وہی مسودہ سازی کا کام، ان پٹ اور آؤٹ پٹ ملا کر:

ماڈل لاگت OpenRouter
GLM-5.3-Flash $0.00048 $0.00092
DeepSeek-V4-Flash $0.00089 $0.0017
MiniMax-M2.7 $0.0016 $0.0189

کل 9,000 ان پٹ اور 7,500 آؤٹ پٹ ٹوکنز۔ فی 1M ٹوکنز کی قیمتیں موجودہ ہیں اور ہمارے ٹیرف کے ساتھ تبدیل ہوتی ہیں؛ OpenRouter کالم اسی ورک لوڈ کے لیے حوالہ جاتی قیمتیں دکھاتا ہے۔

ٹیبل OpenRouter حوالہ بھی دکھاتی ہے، تاکہ آپ دیکھ سکیں کہ ٹوٹل کیسا موازنہ کرتا ہے۔ ٹوکن مفروضے آپ کے بدلنے کے لیے ہیں: اگر آپ کے ٹکٹ لمبے ہیں، تو جج کا ان پٹ سب سے تیزی سے بڑھتا ہے، کیونکہ وہ دونوں جوابات دو بار اٹھاتا ہے۔ اگر آپ کا جج جواب دینے سے پہلے بلند آواز میں سوچتا ہے، تو اس کا آؤٹ پٹ نمبر بھی بڑھتا ہے، اور آپ کا لاگ اسے دکھائے گا۔ درخواست سے پہلے ٹوکنز گننے کی عادت کے لیے، دیکھیں count tokens before you send a request۔

وہی کیپ جو Clocktower استعمال کرتا ہے، ادھار لینے کے قابل ہے۔ یہ فی ٹرن 8,000 ٹوکنز مقرر کرتا ہے، اور آپ کے پاس پہلے سے max_tokens موجود ہے۔ اسے SETTINGS میں رکھیں اور کوئی بے قابو جواب چپکے سے آپ کے تخمینے کو نہیں بڑھا سکتا۔

پوری رن شروع کرنے سے پہلے#

چیک لسٹ

منصفانہ موازنے کے لیے پری فلائٹ

وہ آخری آئٹم اہم ہے۔ تین ٹکٹس چلائیں، calls.jsonl کھولیں اور پڑھیں۔ چیک کریں کہ finish میں stop لکھا ہے نہ کہ length؛ اگر کوئی مسودہ max_tokens سے کٹ گیا، تو ہو سکتا ہے ایک ماڈل صرف اس لیے ہار رہا ہو کہ اس کا جواب کاٹ دیا گیا۔ یہی جج کی کالز پر بھی لاگو ہوتا ہے: وہاں ایک length خاموش برابر میں بدل جاتا ہے، اس لیے None فیصلے بھی گنیں۔ اگر آپ کے ٹاسک کا ایک ہی درست جواب ہے، تو آپ کو جج کی ضرورت ہی نہ ہو: test your prompt on 20 cases with exact-match grading۔

خود کو بے وقوف بنائے بغیر نتیجہ پڑھنا#

wins میں تین نمبر دیکھیں۔ تیس ٹکٹس ایک چھوٹا نمونہ ہیں: 12 بمقابلہ 9 اور 9 برابر جیسی تقسیم آپ کو بتاتی ہے کہ ماڈلز قریب ہیں، یہ نہیں کہ ایک بہتر ہے۔ لاگ یہاں مدد کرتا ہے۔ اگر ایک ماڈل تھوڑا جیتتا ہے لیکن بہت زیادہ آؤٹ پٹ استعمال کرتا ہے، تو اصل سوال جیت کی گنتی نہیں بلکہ ٹاسک کی قیمت ہے؛ price per 1M tokens versus cost per task اس موازنے پر روشنی ڈالتا ہے۔

اگر نتیجہ قریب ہے، تو ٹاسک کے لیے سستا ماڈل چنیں، یا مزید ٹکٹس شامل کریں اور دوبارہ چلائیں۔ دونوں آزمانا سستا ہے کیونکہ پوری مشینری پہلے سے ایک لوپ ہے۔ جب آپ کسی اور ماڈل پر یہ مشق دہرانا چاہیں، تو اوپر کے تین ماڈلز ایک API اور ایک key کے پیچھے ہیں: docs میں سیٹ اپ ہر ایک کے لیے یکساں ہے، اور pricing page بتاتا ہے کہ ہر ایک کی ابھی کیا قیمت ہے۔ Dwarkesh Patel کی اپنی دریافت OpenAI بمقابلہ Anthropic ماڈلز پر (detection بمقابلہ deception) اس کے کھیل کے لیے اس کا نتیجہ ہے؛ آپ کا نتیجہ آپ کے ٹکٹس سے آئے گا۔