SSD Nodes Learn Hosting plans →
మార్గదర్శకాలు Matt Connorద్వారా Matt Connor · అప్‌డేట్ చేయబడింది 2026-08-30

5 మంది వచ్చినప్పుడు self-hosted LLM ఎందుకు ఆగిపోతుంది

ఒక్క వినియోగదారుతో వేగంగా, ఐదుగురితో నెమ్మదిగా ఎందుకు? Ollama default parallel requests 1; batching, KV cache, prefill, queue depth మీ LLM సామర్థ్యాన్ని నిర్ణయిస్తాయి.

మరింత మంది వినియోగదారులు వచ్చినప్పుడు self-hosted LLM ఎందుకు నెమ్మదిస్తుంది?

5 concurrent users వద్ద self-hosted LLM ఆగిపోవడానికి కారణం, server ఇప్పటికీ ఒకసారి ఒక reply మాత్రమే generate చేయడం. మిగిలిన నలుగురు queue లో వేచి ఉంటారు. Ollama documentation default సెట్టింగ్ గురించి స్పష్టంగా చెబుతుంది: OLLAMA_NUM_PARALLEL అంటే “ప్రతి model ఒకేసారి process చేసే parallel requests గరిష్ఠ సంఖ్య; default 1.” ఏదీ పాడవలేదు. మీ ఐదుగురు వినియోగదారుల్లో నలుగురు తమ వంతు కోసం వేచి ఉన్నారు.

దీనికి పరిష్కారం సాధారణంగా మరింత పెద్ద server కాదు. ఒకే forward pass లో model ద్వారా అనేక requests ను process చేసే serving engine అవసరం. అలాగే ఆ సమయంలో అందరి conversationలను ఉంచేందుకు తగినంత అదనపు memory కూడా అవసరం. ఈ రెండు భాగాలూ ముఖ్యమే. మీ గరిష్ఠ సామర్థ్యాన్ని వాస్తవంగా నిర్ణయించేది రెండవ భాగం.

ప్రతి అభ్యర్థన దాటే రెండు దశలు

Prefill మొత్తం prompt ను ఒకేసారి చదివి, దాని కోసం attention cache ను నిర్మిస్తుంది. ప్రతి prompt token model గుండా కలిసి వెళ్తుంది. అందువల్ల prefill ఒక పెద్ద matrix multiply గా ఉంటుంది. ఇది arithmetic throughput ద్వారా పరిమితమవుతుంది. తరువాత decode సమాధానాన్ని ఒక్కో token చొప్పున రాస్తుంది. ప్రతి token కోసం model యొక్క పూర్తి weights ను మళ్లీ memory నుంచి చదవాలి. అయితే ఆ ఒక్క token పై జరిగే arithmetic చాలా తక్కువగా ఉంటుంది. అందువల్ల decode memory bandwidth ద్వారా పరిమితమవుతుంది.

Batching పనిచేయడానికి ప్రధాన కారణం ఈ అసమానతే. ఒక user కోసం decoding చేస్తున్నప్పుడు ప్రతి token కు ఉదాహరణకు 5 GB weights చదవాలి. Arithmetic units లో ఎక్కువ భాగం ఖాళీగా ఉంటుంది. రెండో request ను జోడిస్తే అదే 5 GB ను ఒక్కసారి చదివి, దాని ఆధారంగా రెండు tokens ను compute చేయవచ్చు. రెండో user వల్ల అదనపు సమయం దాదాపుగా ఉండదు. Requests ను తప్పనిసరిగా ఒకదాని తరువాత ఒకటి serve చేస్తే ఈ ప్రయోజనం కోల్పోతారు.

User అనుభవాన్ని రెండు సంఖ్యలు వివరిస్తాయి. TTFT (time to first token) అనేది queue wait మరియు prefill కలిపిన సమయం. ITL (inter-token latency) అనేది stream అవుతున్న tokens మధ్య వ్యవధి. ఇది decode ద్వారా నిర్ణయించబడుతుంది. Slow server సాధారణంగా వీటిలో ఒకదానిలో slow గా ఉంటుంది. వాటికి అవసరమైన పరిష్కారాలు ఒకేలా ఉండవు. ఏ సమస్యను పరిష్కరిస్తున్నారో setting మార్చే ముందు నిర్ధారించుకోవాలి. prefill మరియు decode ను విడిగా సమయాన్ని కొలవడం ద్వారా అది తెలుస్తుంది.

మందగించిన సమాధానం కోసం అందరూ వేచి ఉండేలా static batching చేస్తుంది

Static batching అనేది సరళమైన విధానం. అప్లికేషన్ code లో మీరే requests ను సమూహాలుగా కలిపితే ఇదే జరుగుతుంది. Engine N requests ను సేకరించి, వాటిని కలిసి నడుపుతుంది. ఆ సమూహంలోని ఎక్కువ generation పూర్తయ్యే వరకు ప్రతి slot ను అలాగే ఉంచుతుంది.

ఒక user 1,200 tokenల summary అడిగితే, ఒకే వరుసలో సమాధానం ఇవ్వాల్సిన నాలుగు requests కూడా batch లోనే నిలిచిపోతాయి. ఎందుకంటే batch లోని అత్యంత మందగించిన request పూర్తయ్యే వరకు ఏ slot కూడా విడుదల కాదు.

దీనివల్ల రెండు రకాల వ్యయాలు ఏర్పడతాయి. పూర్తయిన sequences ఉపయోగకరమైన compute చేయకపోయినా slots ను ఆక్రమిస్తూనే ఉంటాయి. Output lengths మారుతున్నప్పుడు effective throughput తగ్గుతుంది. Chat output lengths లో ఈ మార్పు ఎక్కువగా ఉంటుంది. Batch ఏర్పడిన ఒక step తర్వాత వచ్చిన request ప్రారంభమయ్యే ముందు మొత్తం batch పూర్తిగా ఖాళీ కావాలి. అందువల్ల అది prefill ప్రారంభించకముందే వేచి ఉంటుంది. దాని TTFT మరొకరి పొడవైన essay పై ఆధారపడుతుంది.

Continuous batching ప్రతి token వద్ద అభ్యర్థనలను స్వీకరించి, పూర్తయిన వాటిని తొలగిస్తుంది

Continuous batching ఒక decoding దశ స్థాయిలో scheduling చేస్తుంది. ప్రతి దశ తర్వాత scheduler ఇప్పుడే తమ stop token ను ఉత్పత్తి చేసిన sequences ను తొలగించి, ఖాళీ slots లో వేచి ఉన్న requests ను స్వీకరిస్తుంది. step 40 వద్ద పూర్తయ్యే reply తన slot ను step 40 వద్దనే ఖాళీ చేస్తుంది; batch ముగిసే వరకు వేచి ఉండదు.

ఇది అసాధారణమైన విధానం కాదు. llama-server, -cb, --cont-batching ను "continuous batching (a.k.a dynamic batching) ను enable చేయాలా (default: enabled)"గా document చేస్తుంది, మరియు vLLM ఈ ఆలోచన ఆధారంగానే రూపొందించబడింది. Ollama కూడా parallel requests ను serve చేస్తుంది. Default విలువ సంఖ్యను one కు మాత్రమే పరిమితం చేస్తుంది. అందుకే తమ configuration concurrency ను నిరాకరించినప్పటికీ, తమ hardware concurrency ను నిర్వహించలేదని చాలామంది నిర్ధారిస్తారు.

ప్రచురితమైన continuous batching ఫలితాలను సాధారణంగా spare compute మరియు cache కోసం tens of gigabytes రెండూ కలిగిన datacenter cards పై కొలుస్తారు. ఆ ఫలితాల స్వరూపం మీ box కు కూడా వర్తిస్తుంది. అయితే వాటి పరిమాణం వర్తించదు. దీనికి కారణం కింది memory section లో వివరించబడింది.

Prefill అదే compute వనరుల కోసం decode తో పోటీ పడుతుంది

నాలుగు replies stream అవుతున్న సమయంలో కొత్త request వస్తే, దాని prompt ను ముందుగా prefill చేయాలి. Prefill కు ఎక్కువ compute అవసరం. Scheduler ఆ prefill కోసం ప్రత్యేక step కేటాయిస్తే, ఆ సమయంలో stream అవుతున్న నలుగురు users కు token అందదు. పొడవైన prompt ఉన్నప్పుడు ప్రతి open window లో ఇది స్పష్టమైన pause గా కనిపిస్తుంది. మరొకరు send నొక్కినప్పుడల్లా server hiccup అవుతుందని చెప్పినప్పుడు వారు ఉద్దేశించేది ఈ stutter నే.

Chunked prefill పొడవైన prompt ను భాగాలుగా విభజిస్తుంది. ప్రతి భాగాన్ని ఇప్పటికే నడుస్తున్న decodes తో అదే step లో కలుపుతుంది. vLLM tuning guide ఈ tradeoff ను నేరుగా వివరిస్తుంది: చిన్న chunk budgets “decode ను నెమ్మదింపజేసే prefills తక్కువగా ఉండటం వల్ల మెరుగైన ITL ను అందిస్తాయి”. ఎక్కువ విలువలు “ఒక batch లో ఎక్కువ prefill tokens ను process చేయగలగడం వల్ల మెరుగైన time to first token (TTFT) ను అందిస్తాయి”. మీరు ఎవరి అనుభవాన్ని మెరుగ్గా రక్షించాలో ఎంచుకుంటున్నారు: reply ప్రారంభం కావడానికి వేచి ఉన్న వ్యక్తిదా, లేదా text stream అవడాన్ని చూస్తున్న వ్యక్తులదా?

ఈ ప్రభావం ఎంత తీవ్రంగా ఉంటుందో prompt length నిర్ణయిస్తుంది. 6,000 token prompt కు 200 token answer ఉంటే, 200 decode steps కు వ్యతిరేకంగా 6,000 tokens prefill work చేయాలి. Retrieval-augmented chat మరియు పొడవైన system prompts రెండూ మిమ్మల్ని ఈ పరిస్థితిలోకి నెడతాయి. అందువల్ల prefill చిన్న rounding error గా ఉండదు; users వేచి ఉండే ప్రధాన కారణంగా మారుతుంది. పొడవైన భాగం మళ్లీ మళ్లీ వస్తే prefix caching సహాయపడుతుంది: vLLM --enable-prefix-caching ను అందిస్తుంది. ఇది ప్రతి request కోసం shared prompt prefix ను మళ్లీ compute చేయకుండా, దాని cache ను reuse చేస్తుంది.

ముందుగా ఖాళీ అయ్యేది KV cache

ప్రస్తుతం సక్రియంగా ఉన్న ప్రతి సంభాషణలోని ప్రతి token, model లోని ప్రతి layer వద్ద ఒక key vector మరియు ఒక value vector ను ఉంచుతుంది. దీనినే KV cache (key/value cache) అంటారు. ప్రతి కొత్త token కోసం మొత్తం prompt ను మళ్లీ లెక్కించాల్సిన అవసరం లేకుండా decode చేయడానికి ఇది సహాయపడుతుంది. ప్రతి token కు దీని పరిమాణం model నిర్మాణంపై స్థిరంగా ఆధారపడి ఉంటుంది: 2 (ఒక key, ఒక value) ను layer count తో, key/value heads సంఖ్యతో, head dimension తో, ప్రతి value కు అవసరమైన bytes తో గుణించాలి. ఈ సంఖ్యలను model యొక్క config.json నుంచి తీసుకోండి.

ఈ లెక్కను ఒక్కసారి చేస్తే గరిష్ఠ పరిమితి స్పష్టమవుతుంది. 36 layers, 8 key/value heads, 128 head dimension కలిగిన సాధారణ 8B model లో cache ను 16-bit లో ఉంచితే, ప్రతి token కు 2 36 8 128 2 bytes అవసరం. అంటే 147,456 bytes, సుమారు 144 KiB. 8,192 tokens ఉన్న ఒక సంభాషణకు సుమారు 1.2 GB cache అవసరం. ఇలాంటి ఐదు సంభాషణలకు weights కు అదనంగా సుమారు 6 GB అవసరం. ఎన్ని users సరిపోతారనే ప్రశ్నకు వాస్తవ సమాధానం ఇదే.

Concurrency వల్ల context అవసరం పెరుగుతుంది. Tools కూడా దీన్ని స్పష్టంగా చూపిస్తాయి. Ollama FAQ లో ఇలా ఉంది: "ఒక model కోసం parallel request processing చేస్తే, parallel requests సంఖ్యకు అనుగుణంగా context size పెరుగుతుంది. ఉదాహరణకు, 4 parallel requests తో 2K context ఉంటే, అది 8K context గా మారుతుంది మరియు అదనపు memory allocation అవసరం అవుతుంది." అవసరమైన RAM, OLLAMA_NUM_PARALLEL ను OLLAMA_CONTEXT_LENGTH తో గుణించినంత మేరకు పెరుగుతుంది. llama-server లో, -c ద్వారా మీరు కోరిన context ను -np slots మధ్య పంచుతారు. అందువల్ల slot count ను మాత్రమే పెంచితే, ప్రతి request ఉంచగల context పరిమాణం తగ్గుతుంది. ఊహించకుండా startup log నుంచి ప్రతి slot కు కేటాయించిన context ను చదవండి.

vLLM ముందుగానే memory ను కేటాయిస్తుంది. --gpu-memory-utilization (default 0.92) అనేది "model executor కోసం ఉపయోగించాల్సిన GPU memory భాగం". Weights కేటాయించిన తర్వాత మిగిలిన memory paged KV pool గా మారుతుంది. ఆ pool లో స్థలం తగ్గితే request ను విఫలంగా గుర్తించకుండా scheduler దాన్ని evict చేస్తుంది:

WARNING 05-09 00:49:33 scheduler.py:1057] Sequence group 0 is preempted by PreemptionMode.RECOMPUTE mode because there is not enough KV cache space.

vLLM యొక్క V1 engine లో default preemption mode RECOMPUTE. అందువల్ల evict చేసిన request తన cache ను కోల్పోతుంది. మళ్లీ admit చేసినప్పుడు దాని prefill తిరిగి జరుగుతుంది. ఆ పని రెండుసార్లు జరుగుతుంది. "preemption మరియు recomputation end-to-end latency పై ప్రతికూల ప్రభావం చూపవచ్చు" అని documentation హెచ్చరిస్తుంది. సగటు latency సాధారణంగానే కనిపించినప్పటికీ, ఒక user అందరికంటే చాలా ఎక్కువసేపు ఎందుకు వేచి ఉన్నారో వివరించడానికి ఈ log line అత్యంత ఉపయోగకరంగా ఉంటుంది. మొత్తం count ను log చేయడానికి disable_log_stats=False ను సెట్ చేయండి. లేదా vLLM అందించే Prometheus metrics నుంచి preemption counter ను చదవండి.

2, 5 మరియు 20 సమకాలీన వినియోగదారుల వద్ద ఏమి మారుతుంది

ఇద్దరు వినియోగదారులు. అదనపు cache ఉన్న GPUపై ప్రభావం దాదాపు కనిపించదు, ఎందుకంటే రెండవ decode stream మొదటి stream తో పాటు చాలా తక్కువ అదనపు సమయంలోనే నడుస్తుంది. 4 నుంచి 8 GB RAM ఉన్న CPU-only VPSలో ఇది ఉచితం కాదు: రెండు streams ఒకే కొద్దిమంది vCPUలు మరియు అదే RAM bandwidthను పంచుకుంటాయి. అందువల్ల ప్రతి వినియోగదారుకు tokens per second సుమారు సగానికి తగ్గుతుంది. చాలా తక్కువ cache budgetపై cache అవసరం రెండింతలు అవుతుంది.

ఐదుగురు వినియోగదారులు. ఇక్కడ defaults సరిపోవడం ఆగిపోతుంది. సమస్య మొదట queue సమస్యగా కనిపిస్తుంది. OLLAMA_NUM_PARALLEL విలువ 1గా ఉంటే, దీర్ఘమైన సమాధానం అడిగిన వ్యక్తి పూర్తిచేసే వరకు మిగతా నలుగురు వేచి ఉండాలి. అయితే తమ వంతు వచ్చిన వెంటనే ప్రతి ఒక్కరికీ సాధారణ వేగం కనిపిస్తుంది. parallel count పెంచితే సమస్య స్వరూపం మారుతుంది: ఒక్కో slotకు 8K contextతో ఐదు slots కోసం 40K tokens cache అవసరం. ఇది VRAMలో సరిపోకపోతే engine layersను system RAMకు offload చేస్తుంది. అది RAMలో కూడా సరిపోకపోతే server swapను ఉపయోగిస్తుంది, tokens per second తీవ్రంగా పడిపోతుంది.

ఇరవై మంది వినియోగదారులు. chat UIలో ఇరవై మంది వ్యక్తులు సాధారణంగా ఇరవై సమకాలీన requests కారు. Hardware కొనుగోలు చేసే ముందు అర్థం చేసుకోవాల్సిన ముఖ్యమైన విషయం ఇదే. ఒక వ్యక్తి reply చదివి, తదుపరి turnకు ముందు 20 నుంచి 60 seconds ఆలోచిస్తాడు. అందువల్ల వారి sessionలో ఎక్కువ సమయం idleగా ఉంటుంది. ఇరవై agents లేదా ఇరవై document summarisation jobs మాత్రం idle సమయం లేకుండా నడిచే ఇరవై వాస్తవ streams. అది వేరే రకమైన machine. తమ స్వంత Ollama serverకు coding agentను అనుసంధానించిన ఒక developer మొదటి పరిస్థితికన్నా రెండవ పరిస్థితికి దగ్గరగా ఉంటాడు. ఎందుకంటే task నడుస్తున్నంతకాలం agent requests పంపుతూనే ఉంటుంది. మనిషి చదివే సమయంలో ఉండే విరామాలు అందులో ఉండవు.

మీ వినియోగదారులు ఒకేసారి అభ్యర్థనలు చేస్తున్నారా, లేదా కేవలం login అయి ఉన్నారా?

ఏదైనా పరిమాణాన్ని నిర్ణయించే ముందు ప్రస్తుతం ప్రాసెస్‌లో ఉన్న అభ్యర్థనలను లెక్కించండి. లెక్కింపు సులభమే: ప్రాసెస్‌లో ఉన్న అభ్యర్థనలు = వినియోగదారుల సంఖ్య × ఒక్క turnను రూపొందించడానికి పట్టే సెకన్లు ÷ రెండు turnల మధ్య ఉన్న సెకన్లు.

  1. ముందుగా మీ స్వంత single-stream వేగాన్ని కొలవండి. Prefill మరియు decode రెండింటినీ కొలవాలి. ఇతరుల card నుంచి సంఖ్యను తీసుకోకండి: మీ స్వంత boxలో tokens per secondను కొలవండి మరియు మీకు లభించిన విలువను ఉపయోగించండి.
  2. Duty cycleను అంచనా వేయండి. 12 seconds generation per turn, ప్రతి 90 secondsకు ఒక turn చేసే 20 chat users ఉంటే, 20 * 12 / 90 అవుతుంది. అంటే సుమారు 2.7 requests in flight.
  3. Slot countను ఆ విలువకంటే కొద్దిగా ఎక్కువగా ఉంచండి. తరువాత memoryతో సరిపోల్చండి: slots × ఒక్కో requestకు అవసరమైన context, మీ వద్ద వాస్తవంగా ఉన్న cache tokens పరిమితిలో సరిపోవాలి.
  4. Queueను చిన్నదిగా ఉంచండి. పరిమితి మించితే వైఫల్యం త్వరగా మరియు స్పష్టంగా కనిపించాలి.

అందుబాటులో ఉన్న cache tokens = weights లోడ్ చేసిన తర్వాత మిగిలిన free memory ÷ పై విభాగంలో పేర్కొన్న ఒక్కో tokenకు అయ్యే ఖర్చు. 8B modelను 16-bitలో నడిపే 24 GB card, weights కోసం సుమారు 16 GB ఉపయోగిస్తుంది. Default utilisation వద్ద సుమారు 6 GB usable cache మిగులుతుంది. ఇది దాదాపు ఐదు 8K conversationsకు సరిపోతుంది. మరిన్ని conversationsను సరిపెట్టాలంటే ఒక్కో requestకు ఉండే contextను తగ్గించండి లేదా cacheను 8-bitలో నిల్వ చేయండి (llama-server దీనికి --cache-type-k q8_0 తీసుకుంటుంది). రెండూ ఏదో ఒకదాన్ని త్యాగం చేయడం ద్వారా concurrencyను పెంచుతాయి. Hardware కోసం డబ్బు ఖర్చు చేసే ముందు ఈ trade-off యొక్క వాస్తవ పరిస్థితిని చదవడం మంచిది: GPU VPS, API tokensతో పోలిస్తే ఎక్కడ break-even అవుతుంది.

Ollama డిఫాల్ట్‌లు సరిపోని సందర్భాలు

Parallel count ను service unit ద్వారా పెంచండి. ఎందుకంటే shell export systemd-managed daemon కు చేరదు.

sudo systemctl edit ollama.service
[Service]
Environment="OLLAMA_NUM_PARALLEL=4"
Environment="OLLAMA_CONTEXT_LENGTH=8192"
Environment="OLLAMA_MAX_QUEUE=64"
sudo systemctl daemon-reload
sudo systemctl restart ollama
systemctl show ollama --property=Environment
ollama ps

systemctl show మీరు ఇప్పుడే సెట్ చేసిన మూడు variables ను ప్రింట్ చేయాలి. అలా కాకపోతే drop-in save కాలేదు. మీరు తరువాత చేసే ఏ పని కూడా ఉపయోగపడదు. ollama ps తరువాత loaded model ను చూపుతుంది. ఆ పరిమాణం weights పరిమాణం కంటే ఎక్కువగా ఉంటుంది. ఎందుకంటే 8,192 tokens ఉన్న నాలుగు slots కోసం వాటి పక్కన 32,768 tokens cache reserve అవుతుంది. మొత్తం model GPUలో ఉండాలని మీరు ఆశించినప్పుడు PROCESSOR column modelలో కొంత భాగం CPUపై ఉందని చూపిస్తే, cardలో మిగిలినదానికంటే ఎక్కువ cache మీరు కోరారు అని అర్థం. ఆ రెండు సంఖ్యల్లో ఒకదాన్ని తగ్గించండి. సాధారణంగా context ను తగ్గించడం సురక్షితమైన ఎంపిక. అయితే window చాలా చిన్నగా ఉంటే error ఇవ్వకుండా పొడవైన prompts ను నిశ్శబ్దంగా truncate చేస్తుంది. అందువల్ల model సరిపోయే వరకు సంఖ్యను తగ్గించడం కంటే num_ctx ను ఉద్దేశపూర్వకంగా పరిమాణం నిర్ణయించడం మంచిది.

Queue default ను మరోసారి పరిశీలించాలి. Ollama గరిష్ఠంగా OLLAMA_MAX_QUEUE requests ను queue చేస్తుంది, మరియు "the default is 512". ఆ పరిమితిని దాటితే "with a 503 error indicating the server is overloaded" అని response ఇస్తుంది. ఒకేసారి నాలుగు requests ను మాత్రమే అందించే serverలో 512 requests లోతైన queue ఉంచడం నిలబెట్టుకోలేని హామీ వంటిది. ఎందుకంటే 300వ స్థానంలో ఉన్న client తన వంతు రాకముందే timeout అవుతుంది. చిన్న queue application retry చేయగల లేదా report చేయగల error ను త్వరగా ఇస్తుంది. ఎప్పటికీ పూర్తికాని spinner కంటే ఇది మెరుగైనది.

నిజమైన పరిస్థితిలో పరీక్షించండి. ఒకే సమయంలో రెండు terminals నుంచి రెండు requests పంపి, రెండింటినీ monitor చేయండి. మొదటి request పూర్తయ్యే వరకు రెండవది ఏ output ఇవ్వకపోతే, parallel setting అమల్లోకి రాలేదు.

నిజమైన serving engine తన అదనపు నిర్వహణ ఖర్చును సమర్థించే పరిస్థితి

GPUలో తగినంత headroom ఉండి, సుమారుగా నాలుగు కంటే ఎక్కువ అభ్యర్థనలు వాస్తవంగా ఒకేసారి ప్రాసెస్ అవుతున్నప్పుడు vLLM కోసం అదనపు setup సమర్థవంతంగా ఉంటుంది. దీని scheduler ప్రతి token స్థాయిలో పనిచేస్తుంది. దీని cache paged విధానంలో ఉంటుంది కాబట్టి ఖాళీ fragments ను మళ్లీ ఉపయోగించవచ్చు. అందువల్ల వినియోగం లేకుండా ఉన్న VRAM concurrencyగా మారుతుంది. August 2026 నాటికి documented install మరియు launch రెండు commands తో పూర్తవుతాయి:

uv pip install vllm --torch-backend=auto
vllm serve Qwen/Qwen2.5-1.5B-Instruct
curl http://localhost:8000/v1/chat/completions \
    -H "Content-Type: application/json" \
    -d '{
        "model": "Qwen/Qwen2.5-1.5B-Instruct",
        "messages": [{"role": "user", "content": "Say hello."}]
    }'

choices array ఉన్న reply వస్తే server ప్రారంభమై, model load అయిందని అర్థం. Load సమయంలో ముఖ్యమైన రెండు knobs --max-num-seqs మరియు --max-num-batched-tokens. --max-num-seqs అనేది “ఒక iterationలో process చేయగల sequences గరిష్ఠ సంఖ్య”. --max-num-batched-tokens అనేది “ఒక iterationలో process చేయగల tokens గరిష్ఠ సంఖ్య”. మొదటిది concurrencyకి పరిమితి విధిస్తుంది. రెండవది ముందుగా వివరించిన chunked prefill budget.

ఒకేసారి process అవుతున్న అభ్యర్థనలు నాలుగు కంటే తక్కువగా ఉంటే, లేదా supported GPU లేని ఏ machineలోనైనా vLLM complexity పెంచి, ప్రయోజనం తక్కువగా ఇస్తుంది. దీనికి CUDA-class card అవసరం. ఇది startup సమయంలో memoryలో ఎక్కువ భాగాన్ని వినియోగిస్తుంది. 4 నుంచి 8 GB VPSలో ఇది సరైన trade-off కాదు. అలాంటి సందర్భంలో తక్కువ context ఉన్న చిన్న model మరియు మీరు నియంత్రించే queue ఉత్తమమైన ఎంపిక. Ollama మరియు vLLM serving enginesగా ఎలా భిన్నంగా ఉంటాయి ఎంపికను పూర్తిగా వివరిస్తుంది. VPSలో Qwen 3 8Bను నడపడం ఒక్క అదనపు userను చేర్చే ముందు mid-sized modelకు అవసరమయ్యే వనరులను చూపిస్తుంది.

దాచిపెట్టే సాధారణ నమ్మకంలోని రాజీ

Continuous batching మొత్తం throughput ను పెంచుతుంది. క్యూ‌లో ఉన్న అభ్యర్థన త్వరగా ప్రారంభమవుతుంది కాబట్టి median latency కూడా సాధారణంగా మెరుగుపడుతుంది. అయితే tail latency దీనికి విరుద్ధంగా మారుతుంది. ఈ అంశం గురించి చాలా తక్కువగా ప్రస్తావిస్తారు.

ఒక stepలో చేర్చే ప్రతి అదనపు sequence కొంత పనిని జోడిస్తుంది. అందువల్ల batch నిండుతున్నకొద్దీ అందరి ITL పెరుగుతుంది. కొత్తగా వచ్చిన అభ్యర్థనకు prefill అవసరమవుతుంది. దాని కోసం streaming users కు లభించాల్సిన stepలోని కొంత సమయం వినియోగించబడుతుంది. cache pressure ఉన్నప్పుడు scheduler preempt చేస్తుంది. అప్పుడు సగం వరకు రూపొందిన అభ్యర్థనను దాని prefill ప్రారంభానికి తిరిగి పంపుతుంది.

Chat UIలో averages కాకుండా tail latency కనిపిస్తుంది. మొత్తం completion సమయం మంచిగానే ఉన్నా, వాక్యం మధ్యలో stream రెండు seconds ఆగితే అది విఫలమైనట్లుగా అనిపిస్తుంది. మీరు ఆశించే load కింద p95 TTFT మరియు p95 ITL ను కొలవండి. Mean tokens per second ను అనుభవం యొక్క వివరణగా కాకుండా capacity సంఖ్యగా పరిగణించండి.

దీనినిబట్టి ఆచరణాత్మక setting నిర్ణయించాలి. Memory అనుమతించే పరిమితికి కొద్దిగా తక్కువగా concurrencyని cap చేయండి. అప్పుడు engine కు preempt చేయాల్సిన అవసరం ఉండదు. లోతైన batchలో thrash జరగడం కంటే, చిన్నదిగా మరియు ఊహించగలిగే queue మెరుగైనది. ఎందుకంటే నాలుగు seconds వేచి ఉన్న తర్వాత సజావుగా stream అయ్యే అనుభవం, వెంటనే ప్రారంభమై రెండుసార్లు ఆగిపోయే అనుభవం కంటే వినియోగదారుకు మెరుగ్గా ఉంటుంది.

నెమ్మదిగా ఉన్నప్పుడు పరిశీలించాల్సినవి

ప్రతి వినియోగదారుడి అభ్యర్థన సాధారణంగానే ఉంది, కానీ వేచి ఉండే సమయం ఎక్కువగా ఉంది. ఇది వేగ సమస్య కాదు; ఇది queue సమస్య. ముందుగా parallel setting ను పరిశీలించండి. Model సరిగ్గా సేవలు అందిస్తోంది, కానీ ఒకేసారి ఒక్క request మాత్రమే ప్రాసెస్ చేస్తోంది.

Ollama నుంచి HTTP 503 వస్తోంది. Queue నిండిపోయింది. Server నిజంగా తన capacity ను చేరి ఉండవచ్చు. లేదా load ను తగ్గించడానికి OLLAMA_MAX_QUEUE విలువను ఉద్దేశపూర్వకంగా తక్కువగా ఉంచి ఉండవచ్చు. ఆ setting ఉద్దేశించిన పని ఇదే.

CPU server పై load పెరిగినప్పుడు tokens per second గణనీయంగా తగ్గుతోంది. ఇది జరుగుతున్నప్పుడు vmstat 1 ను అమలు చేయండి. si మరియు so columns లో nonzero విలువలు ఉంటే machine swapping చేస్తోంది. అంటే ప్రతి token కోసం weights ను disk నుంచి చదువుతోంది. దీనిని configuration మార్పుతో పరిష్కరించలేరు. Model size లేదా slot count ను తగ్గించండి.

పది మంది వినియోగదారుల్లో ఒకరు మిగిలిన వారికంటే చాలా ఎక్కువసేపు వేచి ఉంటున్నారు. vLLM log లో preempted కోసం search చేయండి. సాధారణంగా preemption మరియు దాని recompute దీనికి కారణమవుతాయి. మీరు అనుమతించిన context length కు cache oversubscribed అయిందని దీని అర్థం.

Server idle గా ఉన్నప్పటికీ TTFT సరిగా లేదు. ఇది concurrency సమస్య కాదు; ఇది prefill సమస్య. మొదటి token కనిపించే ముందు long prompts కు వాస్తవ సమయం పడుతుంది. అందువల్ల hardware ను పరిశీలించే ముందు prompt size మరియు prefix caching ను పరిశీలించండి. Quiet stretch తర్వాత తిరిగి వచ్చిన మొదటి వ్యక్తికే ఎక్కువ wait కనిపించి, అతని తర్వాత అందరికీ సాధారణంగా ఉంటే, అది prefill కాదు. Ollama model ను unload చేసి, weights ను మళ్లీ disk నుంచి చదువుతూ ఉండవచ్చు. దీన్ని requests మధ్య model ను resident గా ఉంచడం ద్వారా నిర్ధారించండి.

FAQ

నా self-hosted LLMను రెండో వ్యక్తి ఉపయోగించినప్పుడు అది ఎందుకు నెమ్మదిస్తుంది?

చాలా సందర్భాల్లో అది అసలు నెమ్మదించదు. అభ్యర్థన queueలో వేచి ఉంటుంది. Ollamaలో OLLAMA_NUM_PARALLEL విలువ 1గా ఉంటుంది. అందువల్ల రెండో అభ్యర్థన, మొదటి అభ్యర్థన తన చివరి tokenను ఉత్పత్తి చేసే వరకు వేచి ఉంటుంది. ఒక వినియోగదారుడి stream సమయాన్ని కొలుస్తూ, మరో వినియోగదారు వేచి ఉన్నప్పుడు ఈ రెండు పరిస్థితులను వేరు చేయండి. ప్రారంభమైన తర్వాత tokens per second సాధారణంగా ఉంటే, సమస్య queueలో ఉంది. Parallel count పెంచితే అది పరిష్కారమవుతుంది. రెండు streams సగం వేగంతో నడిస్తే, memory bandwidthను నిజంగానే పంచుకుంటున్నారు. అది hardware పరిమితి.

ఒక చిన్న GPU ఎన్ని concurrent usersలకు సేవ అందించగలదు?

వినియోగదారుల సంఖ్యను కాదు, memoryని లెక్కించండి. ముందుగా weights, తరువాత KV cacheను లెక్కించాలి. ప్రతి active conversationలో, ప్రతి tokenకు దాని ఖర్చు 2 times layers times key/value heads times head dimension times bytesగా ఉంటుంది. 36 layers, 8 key/value heads, 128 head dimension కలిగిన సాధారణ 8B model, 16-bitలో ప్రతి tokenకు సుమారు 144 KiB ఉపయోగిస్తుంది. కాబట్టి 8,192 token conversationకు సుమారు 1.2 GB అవసరం. ఆ modelను 16-bitలో ఉంచిన 24 GB cardలో cache కోసం సుమారు 6 GB మిగులుతుంది. ఇది full contextలో సుమారు ఐదు conversationsకు సరిపోతుంది. Contextను తగ్గిస్తే ఇంకా ఎక్కువ conversationsను నిర్వహించవచ్చు.

Continuous batching ప్రతి వినియోగదారుడి replyను నెమ్మదిగా చేస్తుందా?

Median latency సాధారణంగా మెరుగుపడుతుంది. ఎందుకంటే requests మొత్తం batch పూర్తయ్యే వరకు వేచి ఉండవు. Tail latency పెరుగుతుంది. ప్రతి అదనపు sequence ప్రతి decoding stepకు పని పెంచుతుంది. కొత్త arrival వల్ల streaming users కోసం ఒక stepలోని కొంత సమయం వినియోగించబడుతుంది. Preempted requestకు రెండుసార్లు prefill అవసరం. Averageను కాకుండా p95 inter-token latencyను కొలవండి. Averageలు దాచే pauses, chat windowలో స్పష్టంగా కనిపిస్తాయి.

నేను OLLAMA_NUM_PARALLELను పెంచాలా లేదా vLLMకు మారాలా?

ముందుగా parallel countను పెంచండి. దీనికి అదనపు ఖర్చు లేదు. ఒక drop-in fileతో ఇది పూర్తవుతుంది. ఒక దీర్ఘమైన answer వెనుక నలుగురు queueలో వేచి ఉండే సాధారణ సమస్యను ఇది పరిష్కరిస్తుంది. Memory పరిమితి అవుతుంది. Parallel requests మీరు memoryలో ఉంచాల్సిన context పరిమాణాన్ని గుణిస్తాయి. అందువల్ల layers CPUకు spill అవుతున్నాయా అని గమనించండి. మీకు అదనపు VRAM ఉన్న GPU ఉండి, నిజంగా నాలుగు కంటే ఎక్కువ requests ఒకేసారి in flightలో ఉంటే vLLMకు మారండి. ఆ స్థాయి వద్ద paged cache మరియు per-token scheduling వాటి overhead కంటే ఎక్కువ ప్రయోజనం ఇస్తాయి.

నెమ్మదిగా ఉన్న LLM serverను మరిన్ని CPU cores పరిష్కరిస్తాయా?

వినియోగదారులు ఎక్కువగా గమనించే భాగానికి కాదు. ప్రతి token కోసం decode మొత్తం modelను memory నుంచి చదువుతుంది. అందువల్ల అది RAM bandwidthపై ఆధారపడుతుంది. Bandwidth పూర్తిగా వినియోగమైన తర్వాత అదనపు cores సహాయపడవు. Prefill మాత్రం coresతో scale అవుతుంది. కాబట్టి ఎక్కువ cores long promptsలో time to first tokenను తగ్గిస్తాయి. 4 నుంచి 8 GB VPSలో ప్రధాన పరిమితి సాధారణంగా memory capacity. అందువల్ల మరిన్ని vCPUs కంటే చిన్న model లేదా తక్కువ context ఉపయోగించడం సమర్థవంతమైన పరిష్కారం.