Local LLM पर Tokens per second कैसे मापें
GPU रेंटल और प्रति टोकन API शुल्क में से क्या सस्ता है यह जानने के लिए सही तरीके से थ्रूपुट मापें। यह गाइड आपको concurrency sweep के जरिए सटीक गणना करना सिखाती है।
Tokens per second यह क्यों तय करता है कि GPU का उपयोग किफायती है या नहीं
Tokens per second वह दर है जिस पर आपका सर्वर आउटपुट टेक्स्ट तैयार करता है। यही वह संख्या है जो यह तय करती है कि GPU किराए पर लेना, प्रति टोकन API शुल्क देने से सस्ता है या नहीं। GPU बॉक्स का बिल प्रति घंटे के हिसाब से आता है, चाहे वह व्यस्त हो या खाली। होस्ट की गई API का बिल प्रति टोकन के हिसाब से आता है। इसलिए, GPU तभी फायदेमंद होता है जब आप उन अधिकांश घंटों में, जिनका आप भुगतान कर रहे हैं, पर्याप्त उच्च आउटपुट दर बनाए रखें।
इसका मतलब है कि आपको एक माप (measurement) की आवश्यकता है, न कि कहीं पढ़ी हुई किसी संख्या की। यह पृष्ठ उन चार संख्याओं को परिभाषित करता है जिन्हें रिकॉर्ड करना आवश्यक है, फिर वे कमांड देता है जो उन्हें उत्पन्न करते हैं, और वह गणित बताता है जो उन्हें एक निर्णय में बदल देता है।
प्रकाशित tokens per second का आंकड़ा आपका वास्तविक नंबर क्यों नहीं है
DigitalOcean ने जुलाई 2026 में vLLM के तहत FP8 (8-bit floating point) में llama3.3-70b-instruct चलाने वाले एक NVIDIA H200 के लिए throughput के आंकड़े प्रकाशित किए। ये आंकड़े उपयोगी हैं, लेकिन ये आपके लिए नहीं हैं।
इस चार्ट के पीछे का डेटा
[
{
"config": "H200, one stream",
"tok_s": "47"
},
{
"config": "H100, saturated",
"tok_s": "236"
},
{
"config": "H200, saturated",
"tok_s": "2,036"
},
{
"config": "H200, saturated, in+out",
"tok_s": "4,071.6"
}
]ऊपर दी गई हर पंक्ति उसी पेज से ली गई है, और उनमें से दो उस रेंज का निचला स्तर हैं जो वह देता है, इसलिए उन दो को एक न्यूनतम सीमा (floor) के रूप में पढ़ें। इस चार्ट में कुछ भी हमारे द्वारा मापा नहीं गया है।
अंतिम दो पंक्तियों से शुरुआत करें। मुख्य हेडलाइन 4,071.6 tok/s है, जबकि केवल-आउटपुट दर 2,036 tok/s है। हेडलाइन इनपुट और आउटपुट tokens को मिलाकर गिनती करती है। उस टेस्ट में 1,024 इनपुट tokens के मुकाबले 1,024 आउटपुट tokens का उपयोग किया गया था, इसलिए हेडलाइन का लगभग आधा हिस्सा आउटपुट है। यह विभाजन मायने रखता है क्योंकि आउटपुट धीमा हिस्सा है। Prefill (प्रॉम्प्ट पढ़ना) सभी इनपुट tokens को एक बार में प्रोसेस करता है। Decode (उत्तर लिखना) एक बार में एक token तैयार करता है। कुल-थ्रूपुट हेडलाइन एक सस्ते नंबर का एक महंगे नंबर के साथ औसत निकालती है।
अब पहली पंक्ति देखें। वही H200 एक बार में एक request सर्व करते हुए 47 tok/s देता है, इसलिए सैचुरेटेड आंकड़ा समान हार्डवेयर पर चालीस गुना से अधिक है। यह अंतर इसलिए है क्योंकि एक सिंगल decode स्टेप GPU को उसके अधिकांश समय के लिए मेमोरी पर प्रतीक्षा करने के लिए छोड़ देता है, और concurrent requests उस खाली समय को भर देते हैं। दूसरी पंक्ति, 236 tok/s, उसी मॉडल पर एक सिंगल H100 है, जो KV cache (key and value cache, वह प्रति-request मेमोरी जिसे एक सर्व की गई बातचीत कार्ड पर रखती है) के कारण पीछे रह जाता है। एक 80 GB कार्ड 70B मॉडल के लिए कम concurrent requests को होल्ड कर पाता है, इसलिए यह कम पर सैचुरेट होता है।
मॉडल बदलें या इनपुट-टू-आउटपुट अनुपात बदलें, तो ऊपर दिया गया हर नंबर बदल जाएगा। प्रकाशित आंकड़े आपकी अपेक्षाएं निर्धारित करते हैं, आपका बजट नहीं। यही नियम डिस्क और नेटवर्क पर ईमानदारी से VPS की बेंचमार्किंग करने पर भी लागू होता है।
महत्वपूर्ण चार संख्याएँ
- Time to first token, TTFT. अनुरोध भेजने और पहले आउटपुट टोकन के आने के बीच की देरी। यह प्रीफिल समय और कतार (queue) समय का योग है। उपयोगकर्ता इसे सीधे महसूस करता है।
- Output tokens per second, per stream. एक बार शुरू होने के बाद एक उत्तर कितनी तेजी से लिखा जाता है। लगभग 20 tok/s से अधिक की गति अधिकांश लोगों की पढ़ने की गति से तेज होती है, इसलिए इससे अधिक गति का बहुत कम लाभ मिलता है।
- Saturated total output throughput. सर्वर के पूरी तरह लोड होने पर सभी समवर्ती (concurrent) स्ट्रीम का कुल योग। यह क्षमता को दर्शाने वाली संख्या है, और यही वह संख्या है जो GPU के खर्च को उचित ठहराती है।
- p50 और p99 TTFT समवर्ती स्थिति में। p50 मध्य का अनुरोध है। p99 वह मान है जिसके अंतर्गत 100 में से 99 अनुरोध पूरे हो जाते हैं। कतार (queueing) का प्रभाव हमेशा सबसे पहले p99 में दिखाई देता है।
सर्वर के शांत रहने पर पहली दो संख्याएँ बेहतर होती हैं। सर्वर के व्यस्त रहने पर तीसरी संख्या बेहतर होती है। ये एक-दूसरे के विपरीत काम करती हैं, यही कारण है कि कोई भी एक संख्या सर्विंग बॉक्स की पूरी क्षमता का वर्णन नहीं कर सकती।
माप लेने से पहले इनपुट और आउटपुट की लंबाई निर्धारित करें
Throughput ट्रैफिक के स्वरूप पर निर्भर करता है। 4,000-token का प्रॉम्प्ट और 50-token का उत्तर prefill-heavy कार्य है। 200-token का प्रॉम्प्ट और 2,000-token का उत्तर decode-heavy कार्य है। एक ही सर्वर इन दोनों स्थितियों के लिए tokens per second के बहुत अलग आंकड़े देता है, इसलिए एक अनुपात चुनें, उसे अपने द्वारा रिकॉर्ड किए गए प्रत्येक नंबर के साथ लिखें, और कभी भी अलग-अलग अनुपातों की तुलना न करें। 1,024 इनपुट और 1,024 आउटपुट एक उचित डिफ़ॉल्ट है क्योंकि कई वेंडर इसी अनुपात पर आंकड़े प्रकाशित करते हैं। यदि आप अपने वास्तविक ट्रैफिक को जानते हैं, तो उसी का उपयोग करें।
आउटपुट की लंबाई को भी बाध्य करें। जो मॉडल 60 tokens के बाद अपने स्टॉप टोकन पर पहुँच जाता है, वह एक छोटा रन देता है जिसकी तुलना पूर्ण रन से नहीं की जा सकती: इसमें TTFT का हिस्सा बड़ा हो जाता है, जो बेंचमार्क की गणना के अनुसार आउटपुट throughput को कम कर देता है, भले ही प्रत्येक अनुरोध जल्दी पूरा हो जाए। vLLM बेंचमार्क क्लाइंट में --ignore-eos फ्लैग प्रत्येक अनुरोध को ठीक उतनी ही संख्या में जनरेट करने के लिए मजबूर करता है जितनी मांगी गई है, जिससे दो रन आपस में तुलना योग्य बने रहते हैं। किसी भी फ्लैग की तुलना में मॉडल का चयन इन आंकड़ों को अधिक प्रभावित करता है: एक सिंगल VPS GPU पर Qwen 3 मॉडल को फिट करना उस चयन के मेमोरी पक्ष को कवर करता है।
सबसे पहले एक स्ट्रीम को मापें
सबसे सरल स्थिति से शुरुआत करें। यह एक sanity check है और यह अधिकतम क्षमता (ceiling) को दर्शाता है। Ollama अपनी टाइमिंग खुद प्रिंट करता है।
ollama run llama3.1:8b --verbose "Write 200 words about disk scheduling."जिस लाइन को पढ़ना है वह eval rate है, जो प्रति सेकंड आउटपुट टोकन (output tokens per second) दर्शाती है। prompt eval rate प्रीफिल रेट (prefill rate) है, और load duration मॉडल को VRAM में लोड करने में लगा समय है। कोल्ड स्टार्ट के बाद पहली कॉल पर load duration बड़ा होता है, इसलिए total duration भ्रामक हो सकता है। कमांड को दो बार चलाएं और दूसरे परिणाम को पढ़ें। Ollama डिफ़ॉल्ट रूप से पांच मिनट के बाद निष्क्रिय मॉडल को अनलोड कर देता है, इसलिए रन के बीच लंबा अंतराल आपको वापस कोल्ड स्टार्ट वाली स्थिति में ले आता है।
यही फील्ड्स API से भी प्राप्त होते हैं, जिसे स्क्रिप्ट करना आसान है।
curl -s http://127.0.0.1:11434/api/generate -d '{
"model": "llama3.1:8b",
"prompt": "Write 200 words about disk scheduling.",
"stream": false
}' | jq '{eval_count, eval_duration,
tok_s: (.eval_count / (.eval_duration / 1000000000))}'eval_duration नैनोसेकंड में है, इसलिए 1,000,000,000 से विभाजित करने पर सेकंड प्राप्त होते हैं। Ollama का अपना API डॉक्यूमेंटेशन प्रति सेकंड टोकन के लिए ठीक इसी विभाजन का सुझाव देता है। यदि सर्वर अभी तक चालू नहीं है, तो Ollama के साथ VPS पर LLM को self-host करना में इंस्टॉलेशन और systemd यूनिट की जानकारी दी गई है।
TTFT के लिए स्ट्रीमिंग रिक्वेस्ट की आवश्यकता होती है, और curl आपके लिए उसका समय माप सकता है।
curl -s -o /dev/null -N \
-w 'ttfb=%{time_starttransfer}s total=%{time_total}s\n' \
http://127.0.0.1:8000/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{"model":"Qwen/Qwen3-8B",
"messages":[{"role":"user","content":"Write 200 words about disk scheduling."}],
"stream":true,"max_tokens":256}'time_starttransfer वह क्षण है जब रिस्पॉन्स बॉडी का पहला बाइट प्राप्त होता है। स्ट्रीमिंग चैट कंप्लीशन पर, वह बाइट पहले सर्वर-सेंड इवेंट (server-sent event) से संबंधित होता है, जो या तो पहला कंटेंट टोकन होता है या उससे ठीक पहले भेजा गया केवल-रोल (role-only) डेल्टा। इसलिए इस मान को एक इवेंट के अंतर के साथ TTFT मानें। यह एक ही सर्वर पर दो रन की तुलना करने के लिए पर्याप्त सटीक है।
सिंगल-स्ट्रीम संख्याएं बॉक्स की क्षमता को बढ़ा-चढ़ाकर दिखाती हैं। TTFT सबसे बेहतरीन स्थिति में होता है, क्योंकि आपके आगे कुछ भी कतार में नहीं है। प्रति-स्ट्रीम दर भी सबसे बेहतरीन होती है, क्योंकि पूरा कार्ड केवल एक रिक्वेस्ट को सर्व कर रहा है। इनमें से कोई भी यह नहीं बताता कि बॉक्स वास्तव में कितना लोड संभाल सकता है।
Concurrency sweep कैसे चलाएं?
एक sweep एक निश्चित workload को बढ़ती हुई concurrency पर चलाता है और हर चरण पर होने वाले परिणामों को रिकॉर्ड करता है। vLLM इसके लिए client प्रदान करता है, जो OpenAI API का उपयोग करता है, इसलिए यह Ollama और किसी भी अन्य OpenAI-compatible सेवा के साथ काम करता है।
vllm bench serve \
--backend openai-chat \
--base-url http://127.0.0.1:8000 \
--endpoint /v1/chat/completions \
--model Qwen/Qwen3-8B \
--dataset-name random \
--random-input-len 1024 \
--random-output-len 1024 \
--ignore-eos \
--num-prompts 160 \
--max-concurrency 16 \
--percentile-metrics ttft,tpot,itl,e2el \
--metric-percentiles 50,99--max-concurrency इन-फ्लाइट requests की संख्या को सीमित करता है, और यही वह variable है जिसे आप sweep कर रहे हैं। --num-prompts कुल भेजी गई requests की संख्या है, इसलिए स्थिर औसत प्राप्त करने के लिए इसे concurrency के लगभग दस गुना पर रखें। सारांश Output token throughput (tok/s): और Total token throughput (tok/s): को प्रिंट करता है, फिर Time to First Token हेडिंग के अंतर्गत Mean TTFT (ms):, Median TTFT (ms): और P99 TTFT (ms): को दिखाता है।
उस output में प्रति-stream दर नहीं होती है, लेकिन इसे एक साधारण division से निकाला जा सकता है। Mean TPOT (ms): पहले token के बाद प्रति output token लगने वाला औसत समय है, इसलिए 25 ms प्रति token का मतलब है 40 tokens प्रति सेकंड प्रति stream। Output throughput को concurrency से विभाजित करने पर भी यही उत्तर मिलता है।
इसके बाद, हर run को save करते हुए इसे loop में चलाएं।
for C in 1 4 16 32 64 128; do
vllm bench serve \
--backend openai-chat \
--base-url http://127.0.0.1:8000 \
--endpoint /v1/chat/completions \
--model Qwen/Qwen3-8B \
--dataset-name random \
--random-input-len 1024 \
--random-output-len 1024 \
--ignore-eos \
--num-prompts $(( C * 10 )) \
--max-concurrency "$C" \
--percentile-metrics ttft,tpot,itl,e2el \
--metric-percentiles 50,99 \
--save-result --result-filename "sweep-c$C.json"
doneSaved JSON files को पढ़ना
हर run एक file लिखता है, इसलिए उन सभी से एक साथ वे fields निकालें जिनकी आपको आवश्यकता है।
for f in sweep-c*.json; do
jq -r --arg f "$f" \
'[$f, .output_throughput, .total_token_throughput,
.median_ttft_ms, .p99_ttft_ms] | @tsv' "$f"
doneoutput_throughput प्रति सेकंड output tokens की संख्या है। total_token_throughput इसमें input tokens को जोड़ता है, इसलिए 1:1 ratio पर यह लगभग दोगुना हो जाता है। p99_ttft_ms तब भी वहां होगा भले ही --metric-percentiles न हो, क्योंकि वह flag डिफ़ॉल्ट रूप से 99 पर सेट होता है। command में दिया गया 50 वह मान है जो median_ttft_ms के बगल में p50_ttft_ms जोड़ता है, जिसे --percentile-metrics में नामित प्रत्येक metric के लिए दिखाया जाता है। यदि आप किसी ऐसे percentile के लिए पूछें जिसे आपने request नहीं किया है, जैसे कि .p90_ttft_ms, तो jq null प्रिंट करेगा।
Concurrency sweep वास्तव में क्या दर्शाता है?
इस चार्ट के पीछे का डेटा
[
{
"label": "1 stream",
"per_stream_tok_s": 92,
"total_tok_s": 92,
"ttft_p50_ms": 48,
"ttft_p99_ms": 61
},
{
"label": "4 streams",
"per_stream_tok_s": 88,
"total_tok_s": 352,
"ttft_p50_ms": 71,
"ttft_p99_ms": 96
},
{
"label": "16 streams",
"per_stream_tok_s": 71,
"total_tok_s": 1136,
"ttft_p50_ms": 152,
"ttft_p99_ms": 244
},
{
"label": "32 streams",
"per_stream_tok_s": 54,
"total_tok_s": 1728,
"ttft_p50_ms": 287,
"ttft_p99_ms": 498
},
{
"label": "64 streams",
"per_stream_tok_s": 34,
"total_tok_s": 2176,
"ttft_p50_ms": 611,
"ttft_p99_ms": 1240
},
{
"label": "128 streams",
"per_stream_tok_s": 18,
"total_tok_s": 2304,
"ttft_p50_ms": 1490,
"ttft_p99_ms": 3820
}
]ये 6 पंक्तियाँ एक छोटे रेंटल GPU बॉक्स पर sweep द्वारा उत्पन्न आकार का उदाहरण हैं, जो संभावित परिमाण (orders of magnitude) पर आधारित हैं। ये आपके सर्वर का मापन नहीं हैं और न ही किसी वेंडर द्वारा दिए गए आंकड़े हैं। ऊपर दिए गए लूप को चलाएं और उन्हें अपने डेटा से बदलें।
आकार को समझें, क्योंकि यही वह चीज है जो सामान्यीकृत (generalize) होती है। एक स्ट्रीम पर पूरा बॉक्स 92 tokens प्रति सेकंड उत्पन्न करता है, जिसका p99 TTFT 61 ms है। 128 streams पर कुल थ्रूपुट 2304 tokens प्रति सेकंड तक पहुँच जाता है, जो पच्चीस गुना अधिक है, जबकि प्रत्येक व्यक्तिगत स्ट्रीम 18 tokens प्रति सेकंड तक गिर जाती है और p99 TTFT 3820 ms तक पहुँच जाता है। कुल थ्रूपुट इसलिए बढ़ता है क्योंकि batching बेकार मेमोरी वेटिंग को उपयोगी कार्य में बदल देती है। प्रति-स्ट्रीम गति इसलिए गिरती है क्योंकि अब समान compute साझा किया जा रहा है।
अंतिम बार दोगुना करना ही मुख्य संकेत है। 64 से 128 स्ट्रीम तक जाने पर कुल थ्रूपुट में छह प्रतिशत से भी कम की वृद्धि होती है, जबकि p99 TTFT लगभग तीन गुना हो जाता है। इसका अर्थ है कि अनुरोध प्रोसेस होने के बजाय कतार (queue) में लग रहे हैं, या तो इसलिए कि KV cache भर गया है या सर्वर vLLM की max_num_seqs जैसी शेड्यूलिंग सीमा तक पहुँच गया है। उपयोगी ऑपरेटिंग पॉइंट इससे पहले आता है: 32 स्ट्रीम पर बॉक्स अभी भी 1728 tokens प्रति सेकंड देता है, जो इसके पीक का 75 प्रतिशत है, जिसमें 54 tokens प्रति सेकंड प्रति स्ट्रीम और p99 TTFT 498 ms है। उस पॉइंट को अपनी क्षमता के रूप में रिपोर्ट करें। कर्व का पीक वह संख्या है जहाँ से आप उपयोगकर्ताओं को सेवा नहीं दे सकते।
Ollama और vLLM एक ही चीज को नहीं मापते हैं
उस sweep को एक default Ollama सर्वर पर चलाएं और कुल परिणाम में शायद ही कोई बदलाव दिखे। OLLAMA_NUM_PARALLEL default रूप से 1 पर सेट होता है, इसलिए एक request चलती है जबकि बाकी प्रतीक्षा करती हैं, और यही queue p99 TTFT को बढ़ाती है जबकि कुल output स्थिर रहता है। कुछ भी मापने से पहले इसे बढ़ाएं।
sudo systemctl edit ollama.service[Service]
Environment="OLLAMA_NUM_PARALLEL=8"sudo systemctl restart ollama के साथ restart करें, फिर पुष्टि करें कि model अभी भी fit बैठता है। प्रत्येक parallel slot को context window का अपना हिस्सा मिलता है, इसलिए Ollama का documentation बताता है कि 4 parallel requests के साथ 2K context, 8K allocate करता है। slot count को इतना बढ़ाएं कि model VRAM से बाहर हो जाए। ollama ps की जाँच करें: यदि PROCESSOR column में 48%/52% CPU/GPU जैसा कुछ दिखाई देता है, तो इसका मतलब है कि model का कुछ हिस्सा CPU पर है, और concurrency बढ़ाने पर throughput बढ़ने के बजाय अब गिरेगा। parallel slots के बाद, requests OLLAMA_MAX_QUEUE तक queue में लग जाती हैं, जो default रूप से 512 है, जिसके बाद सर्वर 503 error देता है।
vLLM continuous batching का उपयोग करता है, इसलिए यह slots खाली होने पर चल रहे batch में नई requests को शामिल कर लेता है, और इसका curve तब तक ऊपर चढ़ता रहता है जब तक कि कोई संसाधन समाप्त न हो जाए: आमतौर पर KV cache, हालांकि max_num_seqs जैसी configured limit या CPU scheduling overhead इसे पहले ही स्थिर कर सकते हैं। Ollama एक model, एक मशीन और कम setup cost के लिए optimize करता है। इसलिए ये दोनों engines एक ही sweep के अलग-अलग परिणाम देते हैं, जो कि serving engines के रूप में Ollama और vLLM की तुलना का वास्तविक विषय है। प्रत्येक संख्या किस engine और किस version द्वारा उत्पन्न की गई है, इसका record रखें।
गलत चीजों को मापने के पाँच तरीके
- क्लाइंट बहुत दूर है। इंटरनेट के माध्यम से अपने लैपटॉप से बेंचमार्किंग करने पर हर TTFT में आपका राउंड ट्रिप समय जुड़ जाता है, इसलिए आप वास्तव में अपने होम कनेक्शन को माप रहे होते हैं। क्लाइंट को सर्वर वाले ही रीजन (region) में चलाएं।
- मॉडल 'कोल्ड' था। पहली रिक्वेस्ट में वेट लोडिंग (weight loading) का समय लगता है, और vLLM पर इसमें ग्राफ कैप्चर का समय भी लग सकता है। एक वार्मअप बैच भेजें और उसके परिणाम को छोड़ दें।
- प्रीफिक्स कैशिंग (prefix caching) ने आपके लिए उत्तर दिया। vLLM डिफ़ॉल्ट रूप से ऑटोमैटिक प्रीफिक्स कैशिंग को इनेबल करता है, इसलिए बार-बार एक ही प्रॉम्प्ट भेजने से प्रीफिल (prefill) के बजाय कैश मापा जाता है, और TTFT वास्तविक मान के एक छोटे से अंश तक गिर जाता है।
--dataset-name randomइससे बचाता है क्योंकि हर प्रॉम्प्ट अलग होता है। सुनिश्चित करने के लिए, सर्वर को--no-enable-prefix-cachingके साथ शुरू करें। - आउटपुट बहुत छोटे थे। 32-टोकन वाले उत्तरों के साथ, TTFT हर रिक्वेस्ट पर हावी रहता है और आपका 'टोकन प्रति सेकंड' वास्तव में केवल प्रीफिल का वर्णन कर रहा होता है। एक यथार्थवादी आउटपुट लंबाई के साथ
--ignore-eosका उपयोग करें। - आपने केवल 1 की कॉन्करेंसी (concurrency) रिपोर्ट की। यह शीट पर सबसे अनुकूल TTFT देता है, और यह केवल तभी सही लागत इनपुट है यदि आपकी वास्तविक रिक्वेस्ट कभी ओवरलैप न हों। यदि वे ओवरलैप होती हैं, तो लागत उस थ्रूपुट पर निर्भर करती है जिसे आप अपने ट्रैफिक द्वारा उत्पन्न कॉन्करेंसी पर बनाए रखते हैं, इसलिए वहाँ भी मापें।
मापे गए आंकड़ों के आधार पर निर्णय लें
अपने sweep द्वारा दिखाए गए output throughput को उस concurrency पर लें जो आपका वास्तविक traffic प्राप्त करता है, और इसकी तुलना प्रति-token मूल्य निर्धारण से करें। यह केवल तभी saturated आंकड़ा है यदि पर्याप्त requests एक साथ चल रही हों ताकि batch भरा रहे; जो workload एक बार में एक request भेजता है, उसे अपनी single-stream दर का उपयोग करना होगा। ब्रेक-ईवन (break-even) एक division है, जब आप उन input tokens की कीमत जोड़ लेते हैं जो प्रत्येक output token के साथ आते हैं:
cost_per_million_output = price_out + price_in * (input_tokens / output_tokens)
break_even_tok_s = (price_per_hour / cost_per_million_output) * 1000000 / 3600इसे DigitalOcean की July 2026 की कीमतों के साथ समझें। उनका H200 dedicated inference endpoint $4.47 प्रति घंटा था, और serverless Llama 3.3 70B की कीमत input के लिए $0.65 प्रति मिलियन tokens और output के लिए $0.65 प्रति मिलियन tokens थी। ऊपर उपयोग किए गए 1:1 ratio पर, हर मिलियन output tokens के साथ एक मिलियन input tokens आते हैं, इसलिए प्रभावी कीमत $1.30 प्रति मिलियन output tokens है। अतः 4.47 को 1.30 से विभाजित करने पर लगभग 3.44 मिलियन output tokens प्रति घंटा मिलते हैं, और 3,600 सेकंड से विभाजित करने पर लगभग 955 output tokens प्रति सेकंड मिलते हैं, या input और output को मिलाकर लगभग 1,910 tokens प्रति सेकंड। कीमतें उनकी हैं। विभाजन हमारा है। जब हमने 25 October 2026 को जाँच की, तो H200 endpoint अभी भी $4.47 प्रति घंटा था, लेकिन DigitalOcean ने 18 August 2026 को serverless Llama 3.3 70B को बंद कर दिया और उपयोगकर्ताओं को Llama 4 Maverick की ओर निर्देशित किया, जिसकी कीमत $0.25 प्रति मिलियन input tokens और $0.87 प्रति मिलियन output tokens सूचीबद्ध है। यह एक अलग model है, इसलिए तुलना करने से पहले इसे अपने स्वयं के sweep की आवश्यकता है।
इस निर्णय को तय करने वाला शब्द है sustained (निरंतर)। दिन में दो घंटे saturation पर 955 output tokens प्रति सेकंड तक पहुँचना 955 output tokens प्रति सेकंड sustained नहीं है, क्योंकि आप बाकी बाईस घंटों के लिए भी भुगतान करते हैं। कार्ड को GPU Droplet के रूप में किराए पर लेने से भी स्थिति नहीं बदलती: 25 October 2026 को DigitalOcean की Droplet मूल्य सूची में H200 की कीमत on-demand $4.47 प्रति घंटा थी, जो endpoint के समान है, और उनके सबसे सस्ते NVIDIA Droplets, जैसे $0.76 प्रति घंटा पर RTX 4000 और $1.57 प्रति घंटा पर L40S या RTX 6000, इतने छोटे हैं कि उनमें FP8 में 70B model नहीं आ सकता। इसलिए ऊपर दिए गए आंकड़ों के आधार पर, एक H200 जो 2,036 output tokens प्रति सेकंड पर saturate होता है, उसे $0.65 प्रति मिलियन tokens (input और output) की बराबरी करने के लिए आपके द्वारा भुगतान किए गए हर घंटे में उस peak का लगभग 47 प्रतिशत औसत बनाए रखना होगा, और उससे नीचे प्रति-token कीमत बेहतर विकल्प बन जाती है। आमतौर पर self-hosting को विफल करने का कारण धीमे tokens नहीं, बल्कि खाली GPU घंटे होते हैं।
इसलिए आपके निर्णय के दो इनपुट हैं। Sweep आपको अधिकतम सीमा (ceiling) देता है। आपका traffic pattern आपको उस सीमा का वह हिस्सा देता है जिसे आप वास्तव में उपयोग करते हैं। उन्हें गुणा करें, फिर परिणाम को GPU VPS बनाम प्रति-token API ब्रेक-ईवन पर ले जाएं और अपने volume के लिए उत्तर देखें।
FAQ
self-hosted LLM के लिए tokens per second की अच्छी दर क्या है?
इसके दो उत्तर हैं, क्योंकि यह metric दो अलग काम करता है। यदि कोई व्यक्ति output पढ़ रहा है, तो प्रति stream लगभग 20 tokens per second से अधिक की गति पढ़ने की सामान्य गति से तेज होती है, इसलिए इससे अधिक गति का कोई विशेष लाभ नहीं है। लागत के मामले में, महत्वपूर्ण संख्या वह कुल output throughput है जिसे आप अपने वास्तविक load के तहत बनाए रख सकते हैं, और 'अच्छी' दर वह है जो आपके break-even point को पूरा करे। $4.47 प्रति घंटे की लागत वाले सर्वर पर, $0.65 प्रति दस लाख tokens (input और output दोनों) की दर से, यह सीमा 1:1 के अनुपात और July 2026 की कीमतों पर लगभग 955 output tokens per second के sustained throughput पर स्थित है। एक बड़े model पर एक single stream कभी भी इस स्तर तक नहीं पहुँचता, यही कारण है कि batching का उपयोग किया जाता है।
concurrent requests जोड़ने पर मेरा Ollama throughput स्थिर क्यों रहता है?
OLLAMA_NUM_PARALLEL का default मान 1 होता है, इसलिए सर्वर प्रति model एक समय में केवल एक request process करता है और बाकी को queue में डाल देता है, जो 503 error देने से पहले OLLAMA_MAX_QUEUE (default रूप से 512) तक हो सकती है। जब तक p99 TTFT बढ़ता है, कुल output स्थिर रहता है, जो GPU के व्यस्त होने के बजाय queue के होने का संकेत है। systemd drop-in में इस variable को set करें और restart करें, फिर ollama ps की जाँच करें, क्योंकि प्रत्येक parallel slot आवंटित context को बढ़ा देता है और model के कुछ हिस्से को CPU पर धकेल सकता है।
क्या मुझे time to first token मापना चाहिए या tokens per second?
दोनों को मापें, क्योंकि load बढ़ने पर ये विपरीत दिशाओं में चलते हैं। TTFT वह है जो user अनुभव करता है, और saturated output throughput वह है जो आपके बिल में दिखता है। हर concurrency स्तर पर p50 और p99 TTFT को record करें, फिर वह उच्चतम concurrency चुनें जहाँ p99 TTFT आपके लिए स्वीकार्य हो। उस बिंदु पर प्राप्त throughput को अपनी क्षमता के रूप में रिपोर्ट करें, न कि curve के उच्चतम बिंदु से प्राप्त अधिकतम मान को।
क्या tokens per second की उच्च संख्या का मतलब हमेशा प्रति token कम लागत होता है?
नहीं। प्रति token लागत, प्रति घंटे की कीमत को उस घंटे में सर्वर द्वारा वास्तव में उत्पन्न tokens से विभाजित करके निकाली जाती है, इसलिए एक तेज सर्वर जो दिन भर खाली रहता है, उसकी प्रति token लागत अधिक होती है। यह peak speed से नहीं, बल्कि utilisation से तय होता है। units का भी ध्यान रखें: एक quoted total token throughput में input tokens भी गिने जाते हैं, इसलिए 1:1 के input-to-output अनुपात पर यह output दर से लगभग दोगुना होता है। यदि आप जिस API से तुलना कर रहे हैं, वह output के साथ-साथ input tokens के लिए भी शुल्क लेता है, तो तुलना करने से पहले दोनों हिस्सों की कीमत का आकलन करें।