LiteLLM को अपने सर्वर पर कैसे host करें
LiteLLM का उपयोग करके एक ही OpenAI compatible endpoint से सभी LLM providers को मैनेज करें। इस गाइड में VPS पर virtual keys, बजट लिमिट और fallbacks सेट करने की पूरी प्रक्रिया दी गई है।
Self-hosted LLM gateway क्या करता है
LiteLLM एक open source LLM gateway है जिसे आप स्वयं host करते हैं: यह एक ऐसा HTTP endpoint है जिसे आपके सभी applications call करते हैं, और यह प्रत्येक request को उस provider के पास भेज देता है जिसे उसे पूरा करना चाहिए। LLM का अर्थ large language model है। यह gateway OpenAI chat completions API (application programming interface) का उपयोग करता है, इसलिए कोई भी client library जो पहले से OpenAI के साथ काम करती है, वह दो बदलावों के बाद इसके साथ काम करने लगती है: base URL और key।
यह indirection की एक परत ही इसका मुख्य उद्देश्य है। आपके applications को अब provider credentials रखने की आवश्यकता नहीं होती। किसी model को बदलना अब कोड में पांच अलग-अलग services को बदलने के बजाय सर्वर पर config file में केवल एक line का बदलाव रह जाता है। और चूंकि हर call एक ही process से होकर गुजरती है, इसलिए आपके पास budget निर्धारित करने और खर्च का रिकॉर्ड रखने के लिए एक केंद्रीय स्थान होता है।
इसे run करने के बाद आपको ये सुविधाएं मिलती हैं:
- एक endpoint. Applications
https://gateway.example.com/v1को target करती हैं और आपके द्वारा बनाए गए model name, जैसेbulkयाstrong, के लिए request भेजती हैं। - Virtual keys. प्रत्येक application को अपनी key मिलती है, जिसकी अपनी model allowlist और अपना spend ceiling होता है। आप दूसरों को प्रभावित किए बिना एक key को revoke कर सकते हैं।
- Fallbacks. कोई failed call या बहुत बड़ा prompt स्वचालित रूप से किसी दूसरे model पर retry किया जाता है।
- एक logged record. प्रत्येक request अपनी लागत के साथ एक row लिखती है, जिससे यह पता चल जाता है कि "किस app ने कितना खर्च किया"।
गेटवे को स्वयं क्यों चलाएं
एक managed router का आकार वही होता है, लेकिन हर request के बीच में किसी और की process काम कर रही होती है। इसे स्वयं चलाने से आपके provider keys और prompt text उस box पर सुरक्षित रहते हैं जिसे आप नियंत्रित करते हैं। इसकी वास्तविक लागत यह है: अब आप उस component का संचालन करते हैं जिस पर हर application निर्भर करती है। इस guide का अंतिम भाग इसी लागत के बारे में है, क्योंकि यह वह हिस्सा है जिसे अधिकांश लेख छोड़ देते हैं।
आवश्यकताएँ
- Ubuntu 24.04 पर चलने वाला एक VPS (virtual private server), जिसमें Docker और Compose plugin इंस्टॉल हो।
- यदि मशीन के बाहर से TLS (transport layer security) के माध्यम से gateway तक पहुँचना है, तो एक domain name जो उस VPS को point करता हो।
- कम से कम एक provider API key।
Gateway कोई inference नहीं करता है। यह केवल requests को forward करता है और answers को stream करता है, इसलिए इसका CPU load model size के बजाय request volume पर निर्भर करता है। 1 vCPU वाला box बिना किसी समस्या के कई internal applications को संभाल सकता है। जो चीज़ बढ़ती है वह database है, क्योंकि gateway प्रत्येक request के लिए एक spend row लिखता है।
सबसे पहले config.yaml लिखें
config फ़ाइल यह निर्धारित करती है कि क्लाइंट किन मॉडल्स के लिए अनुरोध कर सकता है। इसमें चार मुख्य सेक्शन महत्वपूर्ण हैं: model_list, litellm_settings, router_settings और general_settings।
model_list:
- model_name: bulk
litellm_params:
model: anthropic/claude-haiku-4-5
api_key: os.environ/ANTHROPIC_API_KEY
- model_name: strong
litellm_params:
model: anthropic/claude-sonnet-5
api_key: os.environ/ANTHROPIC_API_KEY
- model_name: strong
litellm_params:
model: openai/gpt-5.5
api_key: os.environ/OPENAI_API_KEY
litellm_settings:
num_retries: 2
request_timeout: 120
json_logs: true
set_verbose: false
router_settings:
allowed_fails: 3
cooldown_time: 30
fallbacks: [{"bulk": ["strong"]}]
context_window_fallbacks: [{"bulk": ["strong"]}]
general_settings:
background_health_checks: true
health_check_interval: 300model_name वह नाम है जिसे आपके क्लाइंट भेजते हैं। litellm_params.model वास्तविक मॉडल है, जिसे provider/model के रूप में लिखा जाता है। अपने मॉडल्स का नाम वेंडर के बजाय उनके कार्य (job) के आधार पर रखें। जो एप्लिकेशन bulk के लिए अनुरोध करती है, वह तब भी काम करती रहती है जब आप अगले महीने यह तय करते हैं कि bulk एक अलग मॉडल होना चाहिए।
api_key: os.environ/ANTHROPIC_API_KEY LiteLLM को रन टाइम पर उस वेरिएबल को पढ़ने के लिए कहता है। लिटरल की (literal key) कभी भी फ़ाइल में दिखाई नहीं देती है, जो महत्वपूर्ण है क्योंकि config.yaml वह फ़ाइल है जिसे आप कमिट (commit) करते हैं।
दो एंट्रीज़ जानबूझकर strong नाम साझा करती हैं। जब एक से अधिक डिप्लॉयमेंट में समान model_name होता है, तो राउटर उन्हें एक-दूसरे के स्थान पर उपयोग करने योग्य (interchangeable) मानता है और उस नाम के लिए अनुरोधों को उनके बीच वितरित करता है। इस तरह strong किसी एक प्रोवाइडर के खराब प्रदर्शन के दौरान भी काम करता रहता है: एक बार जब कोई डिप्लॉयमेंट कूलडाउन (नीचे देखें) में चला जाता है, तो strong के लिए नए अनुरोध दूसरे डिप्लॉयमेंट पर चले जाते हैं।
num_retries: 2 एक retryable त्रुटि को दो बार तक पुनः प्रयास (retry) करता है। वे पुनः प्रयास उसी मॉडल ग्रुप में किसी अन्य उपलब्ध डिप्लॉयमेंट का चयन कर सकते हैं: LiteLLM के आर्किटेक्चर दस्तावेज़, जिन्हें 2026-10-29 को जाँचा गया था, ग्रुप के भीतर पुनः प्रयासों और क्रॉस-ग्रुप फॉलबैक को अलग-अलग चरणों के रूप में वर्णित करते हैं। इसलिए, strong के लिए एक पुनः प्रयास वेटेड फेलओवर (weighted failover) को सक्षम किए बिना दूसरे प्रोवाइडर पर जा सकता है। फॉलबैक केवल तभी सक्रिय होता है जब वे पुनः प्रयास समाप्त हो जाते हैं।
allowed_fails और cooldown_time राउटर विकल्प हैं, इसलिए वे router_settings के अंतर्गत आते हैं। प्रॉक्सी उस सेक्शन से अपना राउटर बनाता है, और v1.95.0 पर litellm_settings के अंतर्गत लिखा गया cooldown_time उस तक कभी नहीं पहुँचता है, इसलिए कूलडाउन चुपचाप 5 सेकंड के डिफ़ॉल्ट पर बने रहते हैं। cooldown_time: 30 यह निर्धारित करता है कि कूलडाउन होने के बाद कोई डिप्लॉयमेंट कितने समय तक रोटेशन से बाहर रहता है। कॉन्फ़िगरेशन संदर्भ allowed_fails को उस विफलता गणना (failure count) के रूप में वर्णित करता है जिसे कूलडाउन होने से पहले cooldown_time के भीतर पार करना आवश्यक है। v1.95.0 सोर्स में, allowed_fails: 3 डिफ़ॉल्ट है, और अपने डिफ़ॉल्ट पर राउटर उन इन-बिल्ट ट्रिगर्स का पालन करता है; विफलता गणना केवल तब प्रभावी होती है जब आप एक अलग संख्या सेट करते हैं। इन ट्रिगर्स में एक से अधिक डिप्लॉयमेंट वाले ग्रुप के लिए 429 रिस्पॉन्स पर तत्काल कूलडाउन, ऐसे ग्रुप के लिए कम से कम 5 अनुरोधों के बाद वर्तमान मिनट में 50% से अधिक विफलताएं, और ऐसी त्रुटियां शामिल हैं जिन्हें राउटर पुनः प्रयास नहीं करेगा, जैसे कि गलत की (key) से 401 त्रुटि। एक अलग ट्रिगर तब भी एक डिप्लॉयमेंट को कूलडाउन करता है जब वर्तमान मिनट में सभी अनुरोध विफल हो जाते हैं और ट्रैफ़िक SINGLE_DEPLOYMENT_TRAFFIC_FAILURE_THRESHOLD तक पहुँच जाता है, जो डिफ़ॉल्ट रूप से 1000 अनुरोध है। एक प्रोवाइडर जो अचानक 500 त्रुटियां देता है, उसे हर अनुरोध पर आज़माना बंद कर दिया जाता है, जबकि हर कुछ मिनटों में आने वाली एक छिटपुट 500 त्रुटि कभी भी कूलडाउन को ट्रिगर नहीं करती है।
fallbacks और context_window_fallbacks के अलग-अलग ट्रिगर हैं, और दूसरा वाला वह उपयोगी ट्रिगर है जिसे लोग छोड़ देते हैं।
fallbacksतब सक्रिय होता है जब प्राथमिक कॉल विफल हो जाती है।context_window_fallbacksतब सक्रिय होता है जब प्रोवाइडर अनुरोध को उस मॉडल की कॉन्टेक्स्ट विंडो से बड़ा होने के कारण अस्वीकार कर देता है, ताकि एक बड़ा प्रॉम्प्ट कॉलर को त्रुटि वापस करने के बजाय उस मॉडल के पास जाए जिसमें उसके लिए जगह हो।
इसके अलावा content_policy_fallbacks भी है, जो कंटेंट पॉलिसी के आधार पर मना करने वाले प्रोवाइडर के लिए है। इसे केवल तभी सेट करें यदि आपके पास उन कॉल्स को भेजने के लिए कोई उचित स्थान हो।
VPS पर Docker Compose के साथ LiteLLM को Deploy करना
तीन फाइलों वाली एक डायरेक्टरी बनाएँ: config.yaml, docker-compose.yml और .env। अपस्ट्रीम क्विकस्टार्ट latest टैग को पुल करता है। इसके बजाय एक रिलीज टैग को पिन करें, ताकि अगले महीने docker compose up -d करने पर आपको वही गेटवे मिले जो आज मिला है, और रोलबैक केवल एक लाइन का काम हो।
services:
litellm:
image: ghcr.io/berriai/litellm:v1.95.0
restart: unless-stopped
command: ["--config", "/app/config.yaml", "--num_workers", "1"]
ports:
- "127.0.0.1:4000:4000"
volumes:
- ./config.yaml:/app/config.yaml:ro
env_file: .env
depends_on:
db:
condition: service_healthy
db:
image: postgres:16
restart: unless-stopped
environment:
POSTGRES_USER: litellm
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?set POSTGRES_PASSWORD in .env}
POSTGRES_DB: litellm
healthcheck:
test: ["CMD-SHELL", "pg_isready -U litellm"]
interval: 5s
timeout: 5s
retries: 10
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:Compose यहाँ .env को दो बार पढ़ता है। एक बार compose फाइल के अंदर ${POSTGRES_PASSWORD} को सब्स्टिट्यूट करने के लिए, और दूसरी बार env_file के माध्यम से हर वेरिएबल को कंटेनर में पास करने के लिए।
अगस्त 2026 में v1.95.0 वर्तमान रिलीज थी। प्रोजेक्ट के रिलीज पेज को देखें और डिप्लॉयमेंट के समय जो भी वर्तमान हो उसे पिन करें। प्रत्येक रिलीज एक सिग्नेचर पब्लिश करती है, इसलिए आप इमेज पर भरोसा करने से पहले उसे चेक कर सकते हैं:
cosign verify --key https://raw.githubusercontent.com/BerriAI/litellm/v1.95.0/cosign.pub ghcr.io/berriai/litellm:v1.95.0पोर्ट लाइन 127.0.0.1:4000:4000 है, जो पोर्ट को केवल लूपबैक इंटरफेस पर पब्लिश करती है। इसके बजाय 4000:4000 लिखें और आपका गेटवे पूरे इंटरनेट से एक्सेस किया जा सकेगा, क्योंकि Docker iptables FORWARD चेन में अपने नियम जोड़ता है और वे ufw से पहले इवैल्यूएट होते हैं, इसलिए ufw deny 4000 इसे नहीं रोकता है। यह सबसे आम तरीका है जिससे एक सेल्फ-होस्टेड गेटवे अनचाहे रूप से ओपन हो जाता है: देखें Docker ufw के ऊपर से कंटेनर पोर्ट को कैसे पब्लिश करता है। बाहर से आने वाला ट्रैफिक इसके बजाय रिवर्स प्रॉक्सी के माध्यम से आता है।
Provider keys को image से बाहर रखें
.env फ़ाइल में सभी secrets होते हैं। इसे run time पर environment के रूप में pass किया जाता है, इसलिए इसे कभी भी image में bake नहीं किया जाता है और न ही कभी commit किया जाता है।
LITELLM_MASTER_KEY=sk-REPLACE_ME
LITELLM_SALT_KEY=sk-REPLACE_ME_TOO
POSTGRES_PASSWORD=REPLACE_ME_AS_WELL
DATABASE_URL=postgresql://litellm:REPLACE_ME_AS_WELL@db:5432/litellm
STORE_MODEL_IN_DB=True
LITELLM_MODE=PRODUCTION
LITELLM_LOG=ERROR
ANTHROPIC_API_KEY=sk-ant-...
OPENAI_API_KEY=sk-proj-...दो LiteLLM keys को वास्तविक randomness के साथ generate करें, फिर फ़ाइल को lock करें:
printf 'sk-%s\n' "$(openssl rand -hex 32)"
chmod 600 .envLITELLM_MASTER_KEY एडमिन क्रेडेंशियल है। यह management API को authenticate करता है और /ui पर Admin UI के लिए पासवर्ड है। किसी भी application के पास इसे कभी नहीं होना चाहिए।
LITELLM_SALT_KEY डेटाबेस में संग्रहीत provider क्रेडेंशियल्स को encrypt करता है। इसे एक बार सेट करें और छोड़ दें। यदि आप इसे बाद में बदलते हैं, तो पहले से संग्रहीत क्रेडेंशियल्स को decrypt नहीं किया जा सकेगा। इसके परिणामस्वरूप gateway सामान्य रूप से start तो हो जाएगा, लेकिन उन providers को की जाने वाली हर call authentication पर विफल हो जाएगी।
STORE_MODEL_IN_DB=True आपको config.yaml को छुए बिना Admin UI से models को जोड़ने और edit करने की सुविधा देता है। यह सुविधाजनक है, लेकिन यह आपके source of truth को दो भागों में विभाजित कर देता है। तय करें कि कौन सा authoritative है और उस निर्णय को config के पास लिख लें।
जो तर्क keys को config फ़ाइल से बाहर रखता है, वही तर्क उन्हें उन tools से भी बाहर रखता है जो आप किसी agent को देते हैं। Provider secrets को AI agents से बाहर रखना उस pattern को कवर करता है, और Docker Compose में env फ़ाइलें और secrets इसकी कार्यप्रणाली को कवर करता है।
इसे start करें और पहली boot प्रक्रिया को monitor करें:
docker compose up -d
docker compose logs -f litellmजाँचें कि यह वास्तव में काम कर रहा है
यहाँ दो unauthenticated probes और एक authenticated probe है, और वे अलग-अलग कारणों से विफल होते हैं।
curl -s http://127.0.0.1:4000/health/liveliness
curl -s http://127.0.0.1:4000/health/readiness/health/liveliness को किसी authentication की आवश्यकता नहीं होती है और जब process चल रही होती है तो यह "I'm alive!" का उत्तर देता है। /health/readiness को भी किसी authentication की आवश्यकता नहीं होती है। यह "status": "healthy" और db field के साथ एक JSON object लौटाता है, या जब database तक नहीं पहुँचा जा सकता है तो 503 error देता है। अपनी monitoring को readiness पर point करें, क्योंकि liveliness उस gateway पर भी green रहती है जो एक भी virtual key को look up नहीं कर सकता है।
Authenticated check वह है जो providers से बात करता है:
curl -s http://127.0.0.1:4000/health \
-H "Authorization: Bearer $LITELLM_MASTER_KEY"यह healthy_endpoints और unhealthy_endpoints arrays के साथ उत्तर देता है। unhealthy_endpoints में authentication error के साथ बैठा एक model यह दर्शाता है कि .env में provider key गलत है या गायब है, जो कि वह विफलता है जिसे आप अभी ढूँढना चाहते हैं। चूँकि background_health_checks: true set है, proxy इन probes को हर health_check_interval seconds में अपने आप चलाता है और /health अंतिम परिणाम लौटाता है, इसलिए इसे poll करने पर हर बार आपके providers को test request नहीं भेजी जाती है।
Virtual keys और per-key budgets
प्रत्येक application को अपनी एक key मिलती है, जिसे master key के आधार पर तैयार किया जाता है।
curl -s http://127.0.0.1:4000/key/generate \
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
-H 'Content-Type: application/json' \
-d '{
"key_alias": "nightly-summariser",
"models": ["bulk"],
"max_budget": 5,
"budget_duration": "30d",
"rpm_limit": 60,
"tpm_limit": 200000
}'Response में key field होता है जो sk- से शुरू होता है। यह string ही वह एकमात्र चीज़ है जो application को प्राप्त होती है।
modelsउन requests की allowlist है जिन्हें यह key कर सकती है। ऊपर दी गई key केवलbulkके लिए request कर सकती है और किसी अन्य चीज़ के लिए नहीं।max_budget: 5के साथbudget_duration: "30d"का अर्थ है पांच अमेरिकी डॉलर प्रति कैलेंडर माह। LiteLLM हर महीने की 1 तारीख को आधी रात को (UTC में, जब तक कि आपlitellm_settingsके अंतर्गतtimezoneसेट न करें)30dबजट को reset कर देता है, न कि 30 दिनों के rolling cycle पर। इसलिए, एक बार जब key पांच डॉलर खर्च कर लेती है, तो यह अगली 1 तारीख तक काम करना बंद कर देती है।rpm_limitऔरtpm_limitकेवल इस key के लिए प्रति मिनट requests और प्रति मिनट tokens की सीमा तय करते हैं।key_aliasवह नाम है जिसे आप छह सप्ताह बाद spend log में पहचान पाएंगे। इसे हमेशा सेट करें।
जब बजट समाप्त हो जाता है, तो call budget_exceeded प्रकार की error और इस प्रारूप के संदेश के साथ विफल हो जाती है:
Budget has been exceeded! Key=<key> Current cost: <spend>, Max budget: <max_budget>Status code release पर निर्भर करता है। Pinned v1.95.0 पर यह HTTP 429 है। v1.104.0 से default HTTP 422 है, और litellm_settings के अंतर्गत budget_exceeded_status_code: 429 सेट करने से पुराना code वापस आ जाता है। वास्तविक rpm_limit और tpm_limit hits दोनों ही releases पर 429 return करते हैं। प्रत्येक upgrade के बाद जाँचें कि आपको कौन सा code मिल रहा है।
Status code इसे भ्रमित करने वाला बनाता है, क्योंकि कोई भी code "budget" नहीं दर्शाता है। Client library 429 को rate limit के रूप में report करती है और ऐसे बजट के खिलाफ backoff के साथ retry कर सकती है जो reset होने तक वापस नहीं आएगा, और यह 422 को ऐसी request के रूप में report करती है जिसे process नहीं किया जा सका। Status code के साथ response body को log करें, अन्यथा बजट समाप्त होने की स्थिति हर बार कुछ और ही प्रतीत होगी।
उसी management API के माध्यम से keys का निरीक्षण और समायोजन करें:
curl -s "http://127.0.0.1:4000/key/info?key=sk-..." \
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
curl -s -X POST http://127.0.0.1:4000/key/update \
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
-H 'Content-Type: application/json' \
-d '{"key": "sk-...", "max_budget": 25}'Gateway पर लागू किया गया बजट तब भी प्रभावी रहता है जब समस्या स्वयं agent में हो, इसीलिए यह VPS पर AI agents के लिए लागत नियंत्रण की आधारशिला है।
बल्क वर्क को सस्ते मॉडल पर भेजें
क्लाइंट को गेटवे की ओर पॉइंट करें। बेस URL, की (key), और मॉडल का नाम सेट करें:
curl -s http://127.0.0.1:4000/v1/chat/completions \
-H "Authorization: Bearer sk-<the virtual key>" \
-H 'Content-Type: application/json' \
-d '{
"model": "bulk",
"messages": [{"role": "user", "content": "Say hello in five words."}]
}'कोई भी OpenAI क्लाइंट लाइब्रेरी एक ही तरह से काम करती है: base_url को https://gateway.example.com/v1 पर सेट करें और api_key को वर्चुअल की (key) पर सेट करें।
config.yaml की राउटिंग पॉलिसी अब कॉलर को पता चले बिना लागू हो जाती है। bulk के लिए किया गया अनुरोध सस्ते मॉडल पर जाता है। यदि वह कॉल अपने रिट्राय (retries) के बाद विफल हो जाती है, तो अनुरोध को strong के विरुद्ध फिर से प्रयास किया जाता है। यदि प्रॉम्प्ट bulk के लिए बहुत लंबा है, तो context_window_fallbacks इसे त्रुटि देने के बजाय strong पर भेज देता है। बल्क वर्क जैसे कि क्लासिफिकेशन पास या समराइजिंग बैकलॉग डिफ़ॉल्ट रूप से सस्ते में चलते हैं, और केवल कठिन अनुरोधों पर ही अधिक खर्च आता है।
यहीं पर एक गेटवे टूल-उपयोग करने वाले एजेंट्स के साथ अपनी उपयोगिता साबित करता है। एक उसी VPS पर MCP (model context protocol) सर्वर और उसे चलाने वाला एजेंट दोनों एक ही एंडपॉइंट की ओर पॉइंट कर सकते हैं, जिससे उनके पीछे का मॉडल किसी को भी फिर से डिप्लॉय किए बिना बदल जाता है।
आपको कैसे पता चलेगा कि fallback हुआ है?
यह विफलता का वह प्रकार है जिसमें पैसे का नुकसान होता है, क्योंकि कुछ भी टूटा हुआ नहीं दिखता। एक सफल fallback HTTP 200 और सामान्य response body के साथ आता है। आपका सस्ता model एक दिन के लिए down हो सकता है, हर call चुपचाप महंगे model द्वारा पूरी की जा सकती है, और इसका पहला प्रमाण आपका invoice होता है।
इसके प्रमाण response headers में मौजूद होते हैं। उन्हें जाँचें:
curl -s -D - -o /dev/null http://127.0.0.1:4000/v1/chat/completions \
-H "Authorization: Bearer sk-<the virtual key>" \
-H 'Content-Type: application/json' \
-d '{"model":"bulk","messages":[{"role":"user","content":"ping"}]}' \
| grep -i '^x-litellm'x-litellm-model-groupवह model नाम है जिसके तहत request route की गई थी, जैसे किbulk।x-litellm-model-idउस deployment की ID है जिसने उत्तर दिया, जिसे आप/v1/model/info?litellm_model_id=...के साथ देख सकते हैं। जब वह ID आपकेbulkdeployments में से एक नहीं होती है, तो fallback हुआ होता है।x-litellm-attempted-fallbacksऔरx-litellm-attempted-retriesइनकी गणना करते हैं। एक सामान्य call पर इनमें से किसी का भी count 0 से ऊपर नहीं होता है।x-litellm-response-costअमेरिकी डॉलर में उस एक call की लागत है।x-litellm-call-idवह identifier है जिसका उपयोग आप अपने logs में उसी call को खोजने के लिए करते हैं।
हर request पर x-litellm-attempted-fallbacks को record करें और जब भी यह 0 से ऊपर हो तो alert सेट करें। वह एक संख्या ही एक ऐसी routing policy जो काम करती है, और एक ऐसी routing policy जो चुपचाप "हमेशा महंगे model का उपयोग करें" में बदल गई है, के बीच का अंतर है।
इसका पूर्ण संस्करण tracing है, और इसके लिए अलग setup की आवश्यकता होती है: tracing agent calls के लिए self-hosted Langfuse। LiteLLM में callback शामिल है, इसलिए इसे जोड़ना केवल दो लाइनों और credentials का काम है।
litellm_settings:
success_callback: ["langfuse"]
failure_callback: ["langfuse"]LANGFUSE_PUBLIC_KEY=pk-lf-...
LANGFUSE_SECRET_KEY=sk-lf-...
LANGFUSE_HOST=https://langfuse.example.comLangfuse v3 और उसके बाद के संस्करणों के लिए, LiteLLM का Langfuse पेज अब इसके langfuse_otel preset की अनुशंसा करता है; ऊपर दिया गया langfuse callback अभी भी प्रलेखित है। failure_callback के साथ-साथ success_callback भी सेट करें। यदि आप इसे छोड़ देते हैं, तो आप केवल उन्हीं traces को रखेंगे जहाँ कुछ भी गलत नहीं हुआ। इसके अलावा, LiteLLM हर request के लिए Postgres में एक spend row लिखता है और /ui पर स्थित Admin UI उस table को पढ़ता है। यह traffic के साथ बढ़ता है, इसलिए इसे एक छोटी disk पर monitor करें।
Gateway को reverse proxy के पीछे रखें
बॉक्स के बाहर की किसी भी चीज़ को port 4000 तक नहीं पहुँचना चाहिए। Nginx या Caddy में TLS termination करें और traffic को loopback address पर forward करें।
location / {
proxy_pass http://127.0.0.1:4000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_read_timeout 600s;
}इनमें से दो पंक्तियाँ ऐसी हैं जिन्हें लोग अक्सर छोड़ देते हैं। proxy_buffering off महत्वपूर्ण है क्योंकि streaming completion वास्तव में server-sent events की एक श्रृंखला है। Nginx पर buffering चालू रहने से वह chunks को buffers में इकट्ठा करता है और फिर उन्हें forward करता है, जिससे client तक delivery में देरी होती है। proxy_read_timeout 600s महत्वपूर्ण है क्योंकि Nginx का 60 second का default timeout gateway से दो reads के बीच का अधिकतम समय है, न कि पूरी response की समय सीमा। एक non-streamed completion generation पूरा होने तक कुछ भी नहीं भेजता है, इसलिए यदि generation लंबी है तो 60 seconds से अधिक समय बीत जाता है और client को 504 error मिलता है, जबकि error log में upstream timed out (110: Connection timed out) while reading response header from upstream दर्ज हो जाता है। एक streamed completion जो लगातार chunks भेजता रहता है, वह 60 seconds से अधिक समय तक चल सकता है; यह timeout केवल तभी होता है जब model इतने समय तक शांत रहे।
Certificate के लिए, nginx पर Let's Encrypt के साथ Certbot सबसे छोटा रास्ता है। यदि बॉक्स पहले से ही कई containers को serve कर रहा है, तो कई Compose apps के सामने Traefik routing और certificates को एक ही स्थान पर manage करता है।
गेटवे अब विफलता का एक एकल बिंदु (single point of failure) है
आपने जो बनाया है उसके बारे में स्पष्ट रहें। आपके स्वामित्व वाले सभी एप्लिकेशन अब एक VPS पर एक कंटेनर पर निर्भर हैं। जब तक यह डाउन है, कोई भी मॉडल को कॉल नहीं कर सकता, उन प्रदाताओं (providers) को भी नहीं जो पूरी तरह से ठीक काम कर रहे हैं। इसके चार परिणाम होते हैं।
- एक गलत कॉन्फ़िगरेशन सब कुछ एक साथ बंद कर देता है।
restart: unless-stoppedक्रैश को रीस्टार्ट करता है, और यह उस कंटेनर को बार-बार रीस्टार्ट करता है जो config.yaml को पार्स नहीं कर सकता। हर कॉन्फ़िगरेशन बदलाव के बादdocker compose logs litellmपढ़ें, और कॉन्फ़िगरेशन में बदलाव तब करें जब आपके पास उन्हें देखने का समय हो। - कैश मिस (cache miss) होने पर Postgres रिक्वेस्ट पाथ में रहता है। वर्चुअल की लुकअप इसका उपयोग तब करता है जब की (key) कैश नहीं होती है; रिस्पॉन्स के बाद स्पेंड रिकॉर्डिंग एसिंक्रोनस रूप से चलती है।
/health/readinessका 503 एरर देना आपकी चेतावनी है कि गेटवे चल तो रहा है लेकिन इनमें से कोई भी काम नहीं कर पा रहा है। - पहले कोर का उपयोग करें, फिर इंस्टेंस जोड़ें। प्रोजेक्ट की प्रोडक्शन गाइडेंस में प्रति इंस्टेंस एक वर्कर (
--num_workers 1) की सलाह Kubernetes या किसी अन्य पॉड ऑटोस्केलर के लिए है जो आपके लिए इंस्टेंस जोड़ता है। एक सिंगल VM या इस तरह के बेयर कंटेनर के लिए यह इसके विपरीत कहता है: वर्कर की संख्या को मशीन के vCPU काउंट पर सेट करें। ऊपर दिए गए 1 vCPU बॉक्स पर यह अभी भी--num_workers 1है; बड़े बॉक्स पर इसे बढ़ाएं, और याद रखें कि प्रत्येक वर्कर की अपनी मेमोरी होती है। लोड बैलेंसर के पीछे एक दूसरा गेटवे सिंगल कंटेनर की समस्या को हटा देता है। यह डेटाबेस को नहीं हटाता है। - उसका बैकअप लें जिसे आप दोबारा उत्पन्न (regenerate) नहीं कर सकते। वह
config.yamlऔर.envहै, साथ ही डेटाबेस काpg_dumpभी।LITELLM_SALT_KEYखोने का मतलब है कि उस डंप के अंदर मौजूद एन्क्रिप्टेड प्रदाता क्रेडेंशियल्स बेकार हो जाएंगे, इसलिए env फ़ाइल और डंप एक ही बैकअप जॉब का हिस्सा होने चाहिए: restic का ऑफ-बॉक्स स्टोरेज पर बैकअप।
अपग्रेड करने का मतलब है इमेज टैग को एडिट करना और docker compose up -d चलाना। LiteLLM डिफ़ॉल्ट रूप से स्टार्टअप पर prisma migrate deploy चलाता है, इसलिए नया कंटेनर अपने पहले बूट पर डेटाबेस स्कीमा को माइग्रेट कर देता है। टैग बदलने से पहले डंप ले लें, क्योंकि पुरानी इमेज को वापस लाने से वह माइग्रेशन अनडू (undo) नहीं होता जो पहले ही चल चुका है।
उन सभी वर्ज़न के रिलीज़ नोट्स पढ़ें जिन्हें आप छोड़ रहे हैं, न कि केवल उस वर्ज़न के जिस पर आप पहुँच रहे हैं। v1.95.0 से v1.104.0 या बाद के वर्ज़न पर जाने में कई बड़े बदलाव (breaking changes) शामिल हैं: ऊपर दिया गया बजट स्टेटस कोड, एक प्रॉक्सी जो अनसेट, खाली या सार्वजनिक रूप से ज्ञात मास्टर की के साथ शुरू होने से इनकार कर देता है, और एक प्रॉक्सी जो स्टार्टअप पर डेटाबेस सेटअप विफल होने पर बंद हो जाता है, जो restart: unless-stopped के तहत रीस्टार्ट लूप के रूप में दिखाई देता है। v1.102.x या उससे पुराने वर्ज़न से आने पर, v1.104.0 के नोट्स आपसे दो LiteLLM_SpendLogs इंडेक्स खुद बनाने के लिए भी कहते हैं।
FAQ
क्या LiteLLM हर कॉल में ध्यान देने योग्य latency जोड़ता है?
अक्टूबर 2026 में इसके README के अनुसार, यह प्रोजेक्ट 1000 requests प्रति सेकंड पर 95th percentile पर 8 ms latency का दावा करता है। इसे एक vendor figure मानें। जो संख्या वास्तव में आपकी latency को प्रभावित करती है, वह आपके applications और gateway के बीच की network दूरी है, क्योंकि आपने हर कॉल में एक round trip जोड़ दिया है। Gateway को उसी region में चलाएं जहाँ applications चल रहे हैं, और फिर वास्तविक response पर x-litellm-overhead-duration-ms header के साथ अपने overhead को मापें।
nginx को सामने रखने के बाद streaming काम करना क्यों बंद कर देती है?
क्योंकि nginx डिफ़ॉल्ट रूप से upstream responses को buffer करता है और streaming completion असल में server-sent events की एक श्रृंखला होती है। proxy_buffering ऑन होने पर, nginx chunks को आगे भेजने से पहले buffers में इकट्ठा करता है, जिससे client तक delivery में देरी होती है। Location block में proxy_buffering off; सेट करें। उसी block में proxy_read_timeout को भी बढ़ाएं। डिफ़ॉल्ट रूप से, gateway से डेटा न मिलने पर nginx 60 सेकंड बाद हार मान लेता है, जिस तक एक लंबी non-streamed generation आसानी से पहुँच जाती है, और client को 504 error मिलता है।
जब virtual key का बजट खत्म हो जाता है तो क्या होता है?
कॉल budget_exceeded प्रकार की error और Budget has been exceeded! Key=<key> Current cost: <spend>, Max budget: <max_budget> के रूप में एक message के साथ विफल हो जाती है। Pinned v1.95.0 पर status HTTP 429 होता है; v1.104.0 से डिफ़ॉल्ट HTTP 422 है। कोई भी code बजट के बारे में नहीं बताता, यही इसमें फँसाव है: एक client library 429 को rate limit के रूप में रिपोर्ट करती है और उसे retry कर सकती है, इसलिए लोग message पढ़ने के बजाय throttling को ठीक करने में लग जाते हैं। Status code के साथ response body को log करें। Master key के विरुद्ध /key/info?key=sk-... के साथ key की वास्तविक स्थिति की पुष्टि करें, और यदि बजट बहुत कम सेट किया गया था तो /key/update के साथ सीमा बढ़ाएं।
क्या gateway hosted models के साथ-साथ local model को भी route कर सकता है?
हाँ, और यह model_list में एक और entry है। api_base के साथ ollama_chat/ prefix का उपयोग करें, उदाहरण के लिए api_base: http://ollama:11434 के साथ model: ollama_chat/llama3.1। Compose की डिफ़ॉल्ट networking पर, container के अंदर localhost का मतलब वही container होता है, इसलिए Compose service name या Docker network पर host के address का उपयोग करें, कभी भी 127.0.0.1 का नहीं। Host networking, जहाँ container host के network stack को साझा करता है, इसका अपवाद है। Local model को खड़ा करना एक अलग काम है: देखें Ollama के साथ VPS पर LLM को self-host करना।