SSD Nodes Learn 🎉 VPS $5.50/माह से
गाइड Matt Connorलेखक: Matt Connor

KV cache और prompt cache में क्या अंतर है?

KV cache और prompt cache के बीच के तकनीकी अंतर को समझें। KV cache सर्वर की RAM पर निर्भर है जबकि prompt cache एक बिलिंग फीचर है। जानें कि कौन सा आपके मॉडल को क्रैश कर सकता है।

KV cache बनाम prompt cache: संक्षिप्त उत्तर

KV cache और किसी provider का prompt cache केवल एक शब्द साझा करते हैं, बाकी उनमें लगभग कुछ भी समान नहीं है। KV cache प्रति-अनुरोध (per-request) वर्किंग मेमोरी है। यह एक अनुरोध के पूरे जीवनकाल के दौरान आपके सर्वर की RAM या VRAM में रहता है, और यह context length तथा एक साथ चल रहे अनुरोधों की संख्या के साथ बढ़ता है। Provider prompt caching एक बिलिंग और लेटेंसी फीचर है। आपके प्रॉम्प्ट का एक स्थिर prefix provider के सर्वर पर स्टोर किया जाता है, और जब आप इसे दोबारा भेजते हैं, तो आपसे रियायती दर पर शुल्क लिया जाता है।

एक वह मेमोरी है जिसे आप हार्डवेयर के रूप में खरीदते हैं। दूसरी वह मेमोरी है जिसे कोई और रखता है और आपसे उसका किराया लेता है।

व्यावहारिक अंतर परिभाषा से अधिक महत्वपूर्ण है। KV cache खत्म हो सकता है, और जब ऐसा होता है, तो मॉडल लोड होने से मना कर देता है या अनुरोध अस्वीकार कर दिया जाता है। आप prompt cache से बाहर नहीं हो सकते। आप केवल इसे हिट करने में विफल हो सकते हैं, और ऐसी स्थिति में आप चुपचाप पूरी कीमत चुकाते हैं।

KV cache में क्या होता है, और यह क्यों मौजूद है

एक transformer जो token संख्या 500 generate कर रहा है, उसे अपने से पहले के सभी 499 tokens पर ध्यान (attend) देना होता है। उन सभी tokens में से प्रत्येक के लिए, हर layer को एक key vector और एक value vector की आवश्यकता होती है। हर नए token के लिए उन सभी की पुनर्गणना (recomputing) करने से generation का समय length के वर्ग (square) के अनुपात में बढ़ जाएगा, इसलिए runtime उन्हें सुरक्षित रखता है। वह store ही KV cache (key/value cache) है।

यह प्रति-अनुरोध (per-request) स्थिति है क्योंकि यह उस अनुरोध के सटीक token sequence से निर्मित होती है। दो उपयोगकर्ता जो अलग-अलग prompts भेज रहे हैं, वे इसे साझा नहीं कर सकते, जब तक कि runtime prefix caching न करे, जो कि एक अलग feature है जिसका वर्णन बाद में किया गया है।

Serving दो चरणों में होती है। Prefill आपके पूरे prompt को पढ़ता है और cache को भरता है, और यह compute द्वारा सीमित होता है। Decode एक बार में एक token produce करता है और उसे cache में जोड़ता है, और यह memory bandwidth द्वारा सीमित होता है। यही विभाजन कारण है कि prompt processing और token generation अलग-अलग गति की रिपोर्ट करते हैं जब आप अपने सिस्टम पर tokens per second मापते हैं

KV cache कितनी मेमोरी का उपयोग करता है?

किसी वेंडर टेबल को खोजने की आवश्यकता नहीं है। इसका आकार एक गणितीय गणना है जिसे आप किसी भी मॉडल के लिए दोबारा कर सकते हैं:

bytes per token = 2 * layers * kv_heads * head_dim * bytes per element

2 का अंक key और value को दर्शाता है। अन्य सभी संख्याएँ मॉडल के config.json से आती हैं, जो मॉडल के Hugging Face पेज पर प्रकाशित होते हैं।

Llama 3.1 8B का उदाहरण लें। इसके config में num_hidden_layers 32 और num_key_value_heads 8 सूचीबद्ध हैं। 4096 के hidden_size को 32 attention heads में विभाजित करने पर 128 का head dimension प्राप्त होता है। f16 पर प्रत्येक element 2 bytes का होता है:

2 * 32 * 8 * 128 * 2 = 131072 bytes = 128 KiB per token

इसे अपने द्वारा मांगे गए context से गुणा करें, और फिर एक साथ चल रहे requests की संख्या से गुणा करें।

ChartLlama 3.1 8B KV cache at f16, in GiB
The data behind this chart
[
  {
    "label": "2k context",
    "one_request_gib": 0.25,
    "four_requests_gib": 1
  },
  {
    "label": "8k context",
    "one_request_gib": 1,
    "four_requests_gib": 4
  },
  {
    "label": "32k context",
    "one_request_gib": 4,
    "four_requests_gib": 16
  },
  {
    "label": "128k context",
    "one_request_gib": 16,
    "four_requests_gib": 64
  }
]

8k context पर cache 1 GiB है। 32k पर यह 4 GiB है, जो कि 4-bit weights के समान ही है। मॉडल के पूर्ण 128k context पर, एक request के लिए यह 16 GiB है, और यदि चार requests इसे भरते हैं तो यह 64 GiB है। weights कभी नहीं बदले। केवल cache का आकार बदला है।

Grouped query attention (GQA) इस संख्या में महत्वपूर्ण भूमिका निभाता है। Llama 3.1 8B में 32 query heads के लिए 8 key/value heads हैं, इसलिए चार query heads एक stored key/value pair साझा करते हैं। जिस मॉडल का num_key_value_heads उसके num_attention_heads के बराबर होता है, वह समान parameter count पर चार गुना अधिक cache का उपयोग करता है। यह मानने से पहले कि दो 8B मॉडलों को serve करने की लागत समान है, उस एक field की जाँच अवश्य करें।

2k पर चलने वाला मॉडल 32k पर लोड क्यों नहीं होता

इसका कारण यह है कि मॉडल लोड होते समय रनटाइम KV cache को आरक्षित (reserve) कर लेता है। इसका आकार आपके द्वारा कॉन्फ़िगर की गई context length के आधार पर तय होता है, न कि आपके द्वारा भेजे गए प्रॉम्प्ट के आधार पर। Ollama की डिफ़ॉल्ट context window 4096 टोकन है। यदि आप इसे बढ़ाकर 32k करते हैं, तो आप एक भी टोकन आने से पहले ही 4 GiB अतिरिक्त मेमोरी आवंटन की मांग कर रहे होते हैं।

OLLAMA_CONTEXT_LENGTH=32768 ollama serve

इंटरैक्टिव प्रॉम्प्ट से प्रति सत्र (per session) समान सेटिंग:

ollama run llama3.1:8b
/set parameter num_ctx 32768

यह विफलता हर स्टैक पर अलग तरह से दिखती है। vLLM स्टार्टअप पर ही गणना की जाँच करता है और चलने से मना कर देता है:

ValueError: The model's max seq len (131072) is larger than the maximum number of tokens that can be stored in KV cache (78336). Try increasing `gpu_memory_utilization` or decreasing `max_model_len` when initializing the engine.

केवल CPU वाले VPS पर ऐसी कोई जाँच नहीं होती, क्योंकि आवंटन सामान्य सिस्टम RAM से होता है। इसके बजाय, कर्नेल का out-of-memory killer प्रक्रिया को समाप्त कर देता है, और इसके प्रमाण कर्नेल रिंग बफर में रह जाते हैं:

dmesg -T | grep -i "killed process"

एक ऐसी लाइन जिसमें आपकी सर्विंग प्रक्रिया का नाम हो, इसका मतलब है कि सर्वर ने उपलब्ध मेमोरी से अधिक का वादा किया था। इसका समाधान एक छोटा context है, न कि बड़ी swap file: डिस्क पर पेज की गई KV cache को हर उत्पन्न टोकन पर पढ़ा जाता है, जिससे जनरेशन की गति इतनी धीमी हो जाती है कि वह अनुपयोगी हो जाती है। एक उचित संख्या चुनने के बारे में Ollama में num_ctx और context length के लिए हमारी गाइड में बताया गया है।

Concurrency का संख्या पर प्रभाव

प्रत्येक in-flight request का अपना KV cache होता है। यह वह बिंदु है जिसे अधिकांश capacity plans में नजरअंदाज कर दिया जाता है। चार users, जिनमें से प्रत्येक के पास 32k का context है, को weights के अतिरिक्त कुल 16 GiB की आवश्यकता होती है।

Runtimes इस मामले में कितने सख्त हैं, इसमें अंतर होता है। Ollama और llama.cpp मॉडल लोड होते ही आपके द्वारा मांगे गए context को reserve कर लेते हैं, इसलिए memory commit हो जाती है, चाहे कोई उसका उपयोग करे या न करे। vLLM पूल को fixed-size blocks में विभाजित करता है और जैसे-जैसे प्रत्येक request बढ़ती है, उन्हें ये blocks आवंटित करता है, इसलिए 500-token की request केवल 500 tokens के बराबर memory लेती है। किसी भी स्थिति में, पूल सीमित होता है और एक बार भर जाने पर, नई requests चलने के बजाय queue में चली जाती हैं। वह queueing response times को कैसे प्रभावित करती है, इसका विवरण एक self-hosted LLM कितने concurrent users को serve कर सकता है में दिया गया है।

KV cache को छोटा करने के चार तरीके

  1. Context length को कम करें। यह सबसे प्रभावी तरीका है और आमतौर पर सबसे सस्ता भी। अधिकांश chat workloads कभी भी 32k के करीब नहीं पहुँचते हैं।
  2. Cache को ही quantise करें। Ollama का OLLAMA_KV_CACHE_TYPE डिफ़ॉल्ट रूप से f16 का उपयोग करता है और q8_0 को स्वीकार करता है, जो लगभग आधी मेमोरी का उपयोग करता है, और q4_0, जो लगभग एक-चौथाई मेमोरी का उपयोग करता है। llama.cpp के समकक्ष -ctk q8_0 और -ctv q8_0 हैं।
  3. कम key/value heads या कम layers वाले model का चयन करें। 40 GB weights डाउनलोड करने से पहले config.json पढ़ें।
  4. एक बार में कम requests serve करें और बाकी को queue में रखें।

q4_0 पर Llama 3.1 8B का आंकड़ा प्रति token 128 KiB से घटकर लगभग 32 KiB हो जाता है, इसलिए 32k context की लागत 4 GiB के बजाय लगभग 1 GiB होती है। यह बचत मुफ्त नहीं है। Keys और values को कम precision के साथ store किया जाता है, इसलिए इसे स्थायी रूप से लागू करने से पहले अपने prompts पर output की तुलना अवश्य करें।

Provider prompt caching वास्तव में क्या लाभ देता है

Provider prompt caching एक अलग उत्पाद है जिसकी गणना की इकाई अलग है। आप एक स्थिर prefix को चिह्नित करते हैं, provider उसे store करता है, और बाद में जो calls उसी prefix को दोहराती हैं, उनसे पूरी input कीमत के बजाय कम दर पर शुल्क लिया जाता है।

अगस्त 2026 तक Anthropic द्वारा प्रकाशित multipliers इस प्रकार हैं: 5-minute cache write की लागत base input token कीमत का 1.25 गुना है। 1-hour write की लागत 2 गुना है, और cache read की लागत 0.1 गुना है। यदि आप इन आंकड़ों के पीछे 20,000-token का system prompt रखते हैं, तो सौदे का स्वरूप स्पष्ट हो जाता है।

ChartCost of a 20,000 token prefix, in base input token equivalents
The data behind this chart
[
  {
    "label": "No caching, every call",
    "billed_token_equivalents": "20,000"
  },
  {
    "label": "First call, 5 minute cache write",
    "billed_token_equivalents": "25,000"
  },
  {
    "label": "First call, 1 hour cache write",
    "billed_token_equivalents": "40,000"
  },
  {
    "label": "Every later call, cache hit",
    "billed_token_equivalents": "2,000"
  }
]

इसे अंकगणित के रूप में समझें। 5-minute write का प्रीमियम पहली call पर 5,000 token equivalents है: 25,000 बनाम 20,000, यदि इसे बिना cache के भेजा जाए। विंडो के भीतर हर बाद की call पर 20,000 के बजाय 2,000 का शुल्क लगता है, जो 18,000 की बचत है। इसलिए 5-minute cache दूसरी call से ही फायदे में आ जाता है।

1-hour cache एक अलग दांव है। यह write पर 40,000 का शुल्क लेता है, जो 20,000 token equivalents का प्रीमियम है, इसलिए फायदे में आने से पहले इसे एक घंटे के भीतर दो hits की आवश्यकता होती है। यह आपके traffic pattern के बारे में एक प्रश्न है, न कि model के बारे में। पूरी गणना, जिसमें यह भी शामिल है कि window को कैसे चुनें, Claude prompt caching के लिए break-even गणित में दी गई है।

दो विवरण यह तय करते हैं कि आप cache का उपयोग कर पाएंगे या नहीं। पहला, model की न्यूनतम लंबाई से छोटा prefix चुपचाप cache नहीं किया जाता है: अगस्त 2026 तक, Claude Opus 5 के लिए प्रलेखित न्यूनतम 512 tokens और Claude Sonnet 5 के लिए 1,024 tokens है, और इससे छोटी request सामान्य रूप से process की जाती है और कोई error नहीं मिलता है। दूसरा, lifetime को उस request की शुरुआत से मापा जाता है जो entry को write या read करती है, और हर read इसे बिना किसी अतिरिक्त लागत के refresh कर देती है। इसलिए एक व्यस्त endpoint 5-minute cache को अनिश्चित काल तक जीवित रखता है। एक endpoint जिसे हर दस मिनट में एक बार call किया जाता है, वह हर बार write प्रीमियम का भुगतान करता है और कभी भी लाभ प्राप्त नहीं करता है।

मानने के बजाय response की जाँच करें। usage object cache_creation_input_tokens और cache_read_input_tokens की रिपोर्ट करता है। हर call पर शून्य read count का मतलब है कि आप write के लिए भुगतान कर रहे हैं और बदले में कुछ भी प्राप्त नहीं कर रहे हैं।

जहाँ दोनों caches मिलते हैं

एक लंबा system prompt वह स्थान है जहाँ ये दोनों मिलते हैं, और यह आपको एक साथ दोनों तरफ से प्रभावित करता है।

स्थानीय स्तर पर, 20,000-token का system prompt f16 पर Llama 3.1 8B सर्वर पर लगभग 2.4 GiB की KV cache घेरता है, और यह इसे हर उस concurrent request के लिए अलग से करता है जिसमें यह शामिल होता है। दूरस्थ रूप से, वही prefix एक cache write की लागत लेता है और फिर बाद की प्रत्येक call पर इनपुट का 0.1 गुना खर्च होता है। स्थानीय लागत आपके उपयोगकर्ताओं के साथ बढ़ती है। दूरस्थ लागत आपके traffic के साथ बढ़ती है और आपके idle समय के दौरान रीसेट हो जाती है।

एक स्थानीय सुविधा है जो provider prompt caching जैसी दिखती है और अक्सर इसके साथ भ्रमित हो जाती है: prefix caching। vLLM documentation automatic prefix caching को "मौजूदा queries की KV cache को cache करना" के रूप में वर्णित करता है, ताकि "एक नई query सीधे KV cache का पुन: उपयोग कर सके यदि वह मौजूदा queries में से किसी एक के साथ समान prefix साझा करती है"। llama.cpp सर्वर डिफ़ॉल्ट रूप से प्रति slot एक prompt cache रखता है, और --cache-reuse N उस सबसे छोटे हिस्से को सेट करता है जिसे वह पुन: उपयोग करने का प्रयास करेगा।

prefix caching जो बचाता है वह prefill compute है। आपका 20,000-token का system prompt हर request पर प्रोसेस होने के बजाय एक बार प्रोसेस होता है, जो पहले token के समय को काफी कम कर देता है। vLLM में साझा blocks को डुप्लिकेट करने के बजाय पुन: उपयोग किया जाता है, इसलिए मेमोरी में भी सुधार होता है। यह कभी भी उस cache को छोटा नहीं करता है जिसे आपको वर्तमान में live tokens के लिए रखना होता है। requests के बीच weights को resident रखना एक संबंधित लेकिन अलग lever है, जिसे keeping an Ollama model loaded between requests में कवर किया गया है।

अपने सर्वर पर क्या मापें

अपने target context पर model को load करें, और अनुमान पर भरोसा करने के बजाय वास्तविक आंकड़े देखें।

ollama ps
nvidia-smi --query-gpu=memory.used,memory.total --format=csv
free -g

ollama ps loaded model को उसके size और इस जानकारी के साथ सूचीबद्ध करता है कि वह GPU पर चल रहा है या CPU पर। यदि आप किसी model से पूरी तरह GPU पर रहने की उम्मीद करते हैं, लेकिन वह CPU split दिखाता है, तो इसका मतलब है कि KV cache ने उसके कुछ हिस्से को बाहर धकेल दिया है, और generation speed उसी के अनुसार कम हो जाएगी। nvidia-smi वास्तविक VRAM का आंकड़ा देता है, और free -g CPU-only VPS पर यही काम करता है। Context को चरणों में बढ़ाएं, reload करें, और संख्या में होने वाले बदलाव को देखें। आपकी गणना और रिपोर्ट की गई संख्या एक-दूसरे के करीब होनी चाहिए। जब वे मेल नहीं खाते, तो यह अंतर आमतौर पर runtime के अपने compute buffers के कारण होता है, न कि formula में किसी त्रुटि के कारण।

यदि ये आंकड़े आपको ऐसे hardware की ओर ले जाते हैं जिसे आप किराए पर नहीं लेना चाहते, तो प्रति token भुगतान करने की तुलना GPU VPS बनाम API tokens में दी गई है।

FAQ

क्या KV cache और prompt caching एक ही चीज़ हैं?

नहीं। KV cache प्रत्येक request के लिए serving process के भीतर की मेमोरी है, जो current context में हर token के लिए key और value vectors को रखती है। यह आपके RAM या VRAM में रहती है और request समाप्त होने पर release हो जाती है। Provider prompt caching एक billing feature है जो provider के infrastructure पर एक स्थिर prompt prefix को store करता है और जब आप इसे दोबारा भेजते हैं तो कम दर पर शुल्क लेता है। KV cache खत्म होने से model load होना बंद हो जाता है। Prompt cache न होने से केवल आपका invoice बढ़ता है और first token तक का समय अधिक लगता है।

मेरा model 2k context पर क्यों load हो जाता है लेकिन 32k पर fail हो जाता है?

क्योंकि runtime load के समय ही पूरा KV cache allocate कर देता है, जिसका आकार आपके द्वारा configure की गई context length के अनुसार होता है, न कि आपके द्वारा भेजे गए prompt के अनुसार। Llama 3.1 8B के लिए f16 पर cache 128 KiB प्रति token है, इसलिए 2k context की लागत 0.25 GiB है और 32k की लागत 4 GiB है। weights दोनों ही स्थितियों में fit हो जाते हैं। reservation ही वह चीज़ है जो fail होती है। vLLM इसे ValueError के रूप में report करता है, जिसमें उन tokens की अधिकतम संख्या बताई जाती है जिन्हें यह store कर सकता है, और यह gpu_memory_utilization को बढ़ाने या max_model_len को कम करने का सुझाव देता है। केवल CPU वाले box पर, kernel का out-of-memory killer process को ही बंद कर देता है, जिसकी पुष्टि आप dmesg -T | grep -i "killed process" से कर सकते हैं।

मैं अपने model के लिए KV cache size की गणना कैसे करूँ?

layer count, key/value heads की संख्या, head dimension और प्रति element bytes को 2 से गुणा करें। इससे प्रति token bytes प्राप्त होंगे। फिर इसे अपनी context length और concurrent requests की संख्या से गुणा करें। model की config.json से layer और head counts पढ़ें। f16 या bf16 के लिए प्रति element 2 bytes का उपयोग करें। q8_0 cache लगभग इसका आधा होता है, और q4_0 लगभग एक चौथाई।

क्या prompt caching मेरे अपने सर्वर की मेमोरी की आवश्यकता को कम करता है?

Provider prompt caching आपके hardware के लिए कुछ नहीं करता, क्योंकि storage provider की तरफ होता है। इसका स्थानीय विकल्प prefix caching है, जो vLLM और llama.cpp server दोनों द्वारा प्रदान किया जाता है। यह एक साझा prefix के लिए पहले से compute किए गए key और value vectors का पुन: उपयोग करता है, जिससे prefill compute की बचत होती है और first token तक का समय कम हो जाता है। vLLM में साझा blocks को duplicate करने के बजाय पुन: उपयोग किया जाता है, इसलिए मेमोरी में भी सुधार होता है। कोई भी feature वर्तमान में चल रहे tokens के लिए आवश्यक cache को कम नहीं करता है, इसलिए आपकी context और concurrency की गणना ही न्यूनतम सीमा तय करती है।

क्या उस prompt को cache करना उचित है जिसे मैं केवल एक बार भेजता हूँ?

नहीं। अगस्त 2026 तक, 5-minute option के लिए cache write की लागत सामान्य input से 1.25 गुना अधिक है, इसलिए यदि आप उस window के भीतर prefix को दोबारा नहीं भेजते हैं, तो यह सीधा नुकसान है। Caching तब फायदेमंद होती है जब वही prefix बार-बार दोहराया जाता है, जैसे कि एक लंबा system prompt या कोई document जिसके बारे में आप कई सवाल पूछेंगे। यह पुष्टि करने के लिए कि आपको hits मिल रहे हैं और आप writes के लिए भुगतान नहीं कर रहे हैं, API response में cache_read_input_tokens की जाँच करें।