SSD Nodes Learn 🎉 VPS $5.50/నెల నుండి
మార్గదర్శకాలు Matt Connorద్వారా Matt Connor · అప్‌డేట్ చేయబడింది 2026-08-13

Self-hosted LLM 5 మంది వద్ద ఎందుకు నెమ్మదిస్తుంది?

ఒక user వద్ద సరిగ్గా పనిచేసి, ఐదుగురి వద్ద ఎందుకు నెమ్మదిస్తుందో తెలుసుకోండి: batching, KV cache, prefill, queue depth మీ LLM server సామర్థ్యాన్ని ఎలా నిర్ణయిస్తాయో చూడండి.

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

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

దీనికి పరిష్కారం సాధారణంగా మరింత శక్తివంతమైన server కాదు. ఒకే forward pass లో అనేక requests ను model ద్వారా process చేసే serving engine అవసరం. అదే సమయంలో అందరి conversation లను ఉంచడానికి తగినంత spare 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 ను జోడిస్తే engine అదే 5 GB ను ఒక్కసారి చదివి, దాని ఆధారంగా రెండు tokens ను గణిస్తుంది. రెండో user కోసం అదనపు సమయం దాదాపు ఉండదు. Requests ను ఖచ్చితంగా ఒకదాని తర్వాత ఒకటి అందించడం వల్ల ఈ ప్రయోజనం కోల్పోతాం.

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

నెమ్మదైన సమాధానం పూర్తయ్యే వరకు static batching అందరినీ వేచి ఉండేలా చేస్తుంది

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

ఒక user 1,200 token summary అడిగితే, batch లోని నాలుగు one-line answers కూడా అందులోనే lock అయి ఉంటాయి. ఎందుకంటే batch లోని అత్యంత నెమ్మదైన request పూర్తయ్యే వరకు batch ఏ slot ను విడుదల చేయదు.

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

ప్రతి token వద్ద continuous batching requests ను స్వీకరించి, పూర్తిచేసిన requests ను తొలగిస్తుంది

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

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

ప్రచురితమైన 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 పొడవుగా ఉంటే, తెరిచి ఉన్న ప్రతి window లో ఇది స్పష్టమైన pause గా కనిపిస్తుంది. మరొకరు send నొక్కినప్పుడల్లా server hiccup అవుతోందని చెప్పినప్పుడు ఉద్దేశించేది ఇదే stutter.

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

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

ముందుగా అయిపోయేది KV cache మెమరీ

ప్రతి active conversation లోని ప్రతి 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 గల ఒక conversation కు సుమారు 1.2 GB cache అవసరం. ఇలాంటి ఐదు conversations కు 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 అవసరం." Required 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 fraction". Weights కేటాయించిన తర్వాత మిగిలిన memory paged KV pool గా మారుతుంది. ఆ pool లో స్థలం తగ్గితే scheduler request ను విఫలంగా గుర్తించదు; దాని బదులుగా request ను 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 తొలగిపోతుంది. Request ను మళ్లీ అనుమతించినప్పుడు దాని prefill మళ్లీ జరుగుతుంది. అదే పని రెండుసార్లు చేయాల్సి వస్తుంది. "preemption మరియు recomputation వల్ల end-to-end latency ప్రతికూలంగా ప్రభావితమవుతుంది" అని documentation హెచ్చరిస్తుంది. Average latency సాధారణంగానే కనిపించినప్పటికీ, ఒక user అందరికంటే చాలా ఎక్కువసేపు ఎందుకు వేచి ఉండాల్సి వచ్చిందో వివరించడానికి ఈ log line అత్యంత ఉపయోగకరంగా ఉంటుంది. cumulative 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లో ఇది ఉచితం కాదు. రెండు streamలు అదే కొద్దిమంది vCPUలు మరియు అదే RAM bandwidthను పంచుకుంటాయి. అందువల్ల ప్రతి వినియోగదారుకు tokens per second సుమారు సగానికి తగ్గుతుంది. చాలా తక్కువ cache పరిమితికి రెండింతల cache అవసరం ఏర్పడుతుంది.

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

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

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

ఏదైనా పరిమాణాన్ని నిర్ణయించే ముందు ప్రస్తుతం ప్రాసెస్‌లో ఉన్న requests సంఖ్యను లెక్కించండి. లెక్కింపు సాధారణమే: ప్రాసెస్‌లో ఉన్న requests = users × ప్రతి turn ను రూపొందించడానికి పట్టే seconds ÷ turns మధ్య ఉన్న seconds.

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

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

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 తరువాత weights మాత్రమే ఉన్న పరిమాణం కంటే పెద్ద పరిమాణంతో loaded model ను చూపుతుంది. కారణం, 8,192 tokens ఉన్న నాలుగు slots వాటి పక్కన 32,768 tokens cache ను reserve చేస్తాయి. మొత్తం model GPUలోనే ఉండాలని మీరు ఆశించినప్పుడు PROCESSOR column modelలో కొంత భాగం CPUలో ఉందని చూపితే, GPUలో మిగిలిన స్థలం కంటే ఎక్కువ cache ను మీరు కోరారు. ఆ రెండు సంఖ్యల్లో ఒకదాన్ని తగ్గించండి.

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

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

తగిన serving engine ఎప్పుడు ఉపయోగకరంగా మారుతుంది

GPUలో headroom ఉండి, దాదాపు నాలుగు కంటే ఎక్కువ అభ్యర్థనలు వాస్తవంగా ఒకేసారి process అవుతున్నప్పుడు 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లో ఎక్కువ భాగాన్ని claim చేస్తుంది. 4 నుంచి 8 GB VPSలో ఇది సరైన trade-off కాదు. అలాంటి సందర్భంలో చిన్న model, తక్కువ context, మరియు మీరు నియంత్రించే queue ఉపయోగించడం మంచిది. Ollama మరియు vLLM serving enginesగా ఎలా భిన్నంగా ఉంటాయి ఈ ఎంపికను పూర్తిగా వివరిస్తుంది. VPSలో Qwen 3 8Bను నడపడం అదనపు userను చేర్చే ముందు mid-sized modelకు అవసరమయ్యే వనరులను చూపిస్తుంది.

పురాణం దాచే సమతుల్యత

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

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

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

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

మందగించినప్పుడు ఏమి తనిఖీ చేయాలి

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

Ollama నుంచి HTTP 503 వస్తోంది. Queue నిండిపోయింది. Server నిజంగా తన సామర్థ్య పరిమితికి చేరి ఉండవచ్చు. లేదా 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 పరిమితిని మించి ఉపయోగించబడుతోందని దీని అర్థం.

Server idle గా ఉన్నప్పటికీ TTFT అధ్వానంగా ఉంది. ఇది concurrency సమస్య కాదు; ఇది prefill సమస్య. మొదటి token కనిపించే ముందు long prompts కు గణనీయమైన సమయం పడుతుంది. అందువల్ల hardware ను పరిశీలించే ముందు prompt size మరియు prefix caching ను తనిఖీ చేయండి.

FAQ

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

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

ఒక చిన్న GPU ఏకకాలంలో ఎంతమంది వినియోగదారులకు సేవలందించగలదు?

వినియోగదారుల సంఖ్యను కాదు, memoryని లెక్కించండి. ముందుగా model weights, తరువాత KV cacheను పరిగణించండి. ప్రతి active conversationలో ప్రతి tokenకు దీని ఖర్చు 2 times layers times key/value heads times head dimension times bytes. సాధారణ 8B modelలో 36 layers, 8 key/value heads, head dimension 128 ఉంటే 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కు అదనపు పనిని జోడిస్తుంది. కొత్త request రావడం వల్ల streaming users కోసం ఒక stepలో కొంత సమయం తగ్గుతుంది. Preempt అయిన requestకు prefill రెండుసార్లు చేయాలి. Averageను కాకుండా p95 inter-token latencyని కొలవండి. Averageలు దాచే pauses chat windowలో స్పష్టంగా కనిపిస్తాయి.

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

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

ఎక్కువ CPU cores slow LLM serverను పరిష్కరిస్తాయా?

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