SSD Nodes Learn 🎉 VPS $5.50/महिन्यापासून
मार्गदर्शक Matt Connorद्वारे Matt Connor · अपडेटेड 2026-08-13

LiteLLM म्हणजे काय आणि ते स्वतः कसे host करावे?

LiteLLM वापरून सर्व LLM साठी एकच OpenAI-compatible endpoint तयार करा. VPS वर हे gateway सेट करून virtual keys, बजेट मर्यादा आणि स्वयंचलित fallbacks कसे मिळवायचे ते शिका.

Self-hosted LLM gateway काय करते

LiteLLM हे एक open source LLM gateway आहे जे तुम्ही स्वतः host करता: हे एक HTTP endpoint आहे ज्याला तुमची सर्व ॲप्लिकेशन्स कॉल करतात, आणि ते प्रत्येक विनंती योग्य provider कडे पाठवते. LLM म्हणजे large language model. हे gateway OpenAI chat completions API (application programming interface) वापरते, त्यामुळे ज्या client library आधीच OpenAI शी संवाद साधतात, त्या दोन बदल केल्यानंतर यावर काम करतात: base URL आणि key.

हा एक अतिरिक्त स्तर असणे हाच याचा मुख्य उद्देश आहे. तुमच्या ॲप्लिकेशन्सना provider चे credentials साठवून ठेवण्याची गरज उरत नाही. एखादा model बदलणे म्हणजे पाच वेगवेगळ्या सर्व्हिसेसमधील कोड बदलण्याऐवजी सर्व्हरवरील एका config फाईलमधील एक ओळ बदलणे इतके सोपे होते. आणि प्रत्येक कॉल एकाच प्रक्रियेतून जात असल्याने, तुमच्याकडे बजेट ठरवण्यासाठी आणि खर्चाची नोंद ठेवण्यासाठी एक मध्यवर्ती जागा उपलब्ध होते.

एकदा हे सुरू झाले की तुम्हाला खालील गोष्टी मिळतात:

  • एक endpoint. ॲप्लिकेशन्स https://gateway.example.com/v1 ला लक्ष्य करतात आणि तुम्ही ठरवलेल्या model चे नाव विचारतात, जसे की bulk किंवा strong.
  • Virtual keys. प्रत्येक ॲप्लिकेशनला स्वतःची key मिळते, ज्यामध्ये स्वतःची model allowlist आणि खर्चाची मर्यादा (spend ceiling) असते. तुम्ही इतरांना धक्का न लावता एक key रद्द करू शकता.
  • Fallbacks. एखादा कॉल अयशस्वी झाल्यास किंवा prompt खूप मोठा असल्यास, तो आपोआप दुसऱ्या model वर पुन्हा प्रयत्न (retry) केला जातो.
  • नोंदवलेला रेकॉर्ड. प्रत्येक विनंतीचा खर्च एका ओळीत लिहिला जातो, त्यामुळे "कोणत्या ॲपने तो खर्च केला" याचे उत्तर मिळते.

गेटवे स्वतः का चालवावा

मॅनेज्ड राउटरचा आकार सारखाच असतो, परंतु प्रत्येक विनंतीच्या मध्यभागी दुसऱ्या कोणाची तरी प्रक्रिया कार्यरत असते. स्वतः गेटवे चालवल्यामुळे तुमचे प्रोव्हायडर कीज (provider keys) आणि प्रॉम्प्ट मजकूर तुम्ही नियंत्रित करत असलेल्या सर्व्हरवर राहतात. याची किंमत मोजावी लागते: आता तुम्ही अशा घटकाचे संचालन करत आहात ज्यावर प्रत्येक ॲप्लिकेशन अवलंबून आहे. या मार्गदर्शिकेचा शेवटचा विभाग याच खर्चाबद्दल आहे, कारण बहुतेक लेख या महत्त्वाच्या भागाकडे दुर्लक्ष करतात.

आवश्यक गोष्टी

  • Ubuntu 24.04 वर चालणारा एक VPS (virtual private server), ज्यावर Docker आणि Compose प्लगइन इन्स्टॉल केलेले असावे.
  • जर बाहेरील यंत्रे TLS (transport layer security) द्वारे गेटवेपर्यंत पोहोचणार असतील, तर त्याकडे निर्देशित करणारे एक domain name.
  • किमान एक provider API key.

गेटवे कोणतीही inference प्रक्रिया करत नाही. तो विनंत्या पुढे पाठवतो आणि उत्तरे स्ट्रीम करतो, त्यामुळे त्याचा CPU लोड हा मॉडेलच्या आकारापेक्षा विनंत्यांच्या संख्येवर अवलंबून असतो. 1 vCPU असलेला सर्व्हर कोणत्याही तक्रारीशिवाय काही अंतर्गत ॲप्लिकेशन्स हाताळू शकतो. डेटाबेसचा आकार वाढत जातो, कारण गेटवे प्रत्येक विनंतीसाठी खर्चाची एक नोंद (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
  allowed_fails: 3
  cooldown_time: 30
  json_logs: true
  set_verbose: false

router_settings:
  fallbacks: [{"bulk": ["strong"]}]
  context_window_fallbacks: [{"bulk": ["strong"]}]

general_settings:
  background_health_checks: true
  health_check_interval: 300

model_name हे नाव तुमचे क्लायंट पाठवतात. litellm_params.model हे प्रत्यक्ष मॉडेल आहे, जे provider/model म्हणून लिहिले जाते. तुमच्या मॉडेल्सना व्हेंडरच्या नावानुसार नाव देण्याऐवजी त्यांच्या कामाच्या स्वरूपानुसार नाव द्या. जे ॲप्लिकेशन bulk ची मागणी करते, ते पुढच्या महिन्यात तुम्ही bulk हे वेगळे मॉडेल निवडले तरीही काम करत राहते.

api_key: os.environ/ANTHROPIC_API_KEY हे LiteLLM ला रन-टाइमला तो व्हेरिएबल वाचण्यास सांगते. प्रत्यक्ष की (key) कधीही फाईलमध्ये दिसत नाही, जे महत्त्वाचे आहे कारण config.yaml ही फाईल तुम्ही कमिट करता.

दोन एन्ट्रीज मुद्दाम strong हे नाव शेअर करतात. जेव्हा एकापेक्षा जास्त डिप्लॉयमेंटचे model_name समान असते, तेव्हा राउटर त्यांना एकमेकांना बदलण्यायोग्य मानतो आणि पहिले अपयशी ठरल्यास दुसऱ्याचा प्रयत्न करतो. अशा प्रकारे strong एखाद्या प्रोव्हायडरच्या खराब वेळेतही टिकून राहते.

num_retries: 2 हे त्रुटी आढळल्यास त्याच डिप्लॉयमेंटचा पुन्हा प्रयत्न करते. फॉलबॅक (fallback) फक्त तेव्हाच सक्रिय होतो जेव्हा सर्व प्रयत्न संपतात. allowed_fails: 3 सह cooldown_time: 30 वापरल्यास, 3 वेळा अपयशी ठरल्यानंतर डिप्लॉयमेंटला 30 सेकंदांसाठी रोटेशनमधून बाहेर काढले जाते, जेणेकरून 500 एरर देणाऱ्या प्रोव्हायडरला प्रत्येक विनंतीवर पुन्हा प्रयत्न केले जाणार नाहीत.

fallbacks आणि context_window_fallbacks चे ट्रिगर्स वेगळे आहेत आणि दुसरे ट्रिगर अधिक उपयुक्त असूनही अनेकदा दुर्लक्षित केले जाते.

  • fallbacks हे प्राथमिक कॉल अपयशी ठरल्यावर सक्रिय होते.
  • context_window_fallbacks हे तेव्हा सक्रिय होते जेव्हा प्रोव्हायडर विनंती नाकारतो कारण ती मॉडेलच्या कॉन्टेक्स्ट विंडोपेक्षा मोठी असते. यामुळे, मोठी प्रॉम्प्ट एरर देण्याऐवजी अशा मॉडेलकडे पाठवली जाते जिथे त्यासाठी पुरेशी जागा आहे.

येथे content_policy_fallbacks देखील आहे, जे कंटेंट पॉलिसीच्या कारणास्तव प्रोव्हायडरने विनंती नाकारल्यास वापरले जाते. हे फक्त तेव्हाच सेट करा जेव्हा तुमच्याकडे अशा कॉल्सना पाठवण्यासाठी योग्य जागा असेल.

Docker Compose वापरून VPS वर LiteLLM डिप्लॉय करा

तीन फाइल्स साठवण्यासाठी एक डिरेक्टरी तयार करा: 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 ला बगल देऊन कंटेनर पोर्ट कसे प्रकाशित करते हे पहा. बाहेरून येणारी ट्रॅफिक त्याऐवजी रिव्हर्स प्रॉक्सीद्वारे येते.

प्रोव्हायडर कीज (keys) इमेजच्या बाहेर ठेवा

.env फाईलमध्ये सर्व सिक्रेट्स असतात. रन-टाइमला ती एनवायरमेंट व्हेरिएबल म्हणून पास केली जाते, त्यामुळे ती कधीही इमेजमध्ये समाविष्ट (bake) केली जात नाही आणि ती कधीही कमिट केली जात नाही.

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 कीज खऱ्या रँडमनेससह जनरेट करा आणि त्यानंतर फाईल लॉक करा:

printf 'sk-%s\n' "$(openssl rand -hex 32)"
chmod 600 .env

LITELLM_MASTER_KEY हे ॲडमिन क्रेडेंशियल आहे. हे मॅनेजमेंट API ला ऑथेंटिकेट करते आणि /ui वरील ॲडमिन UI साठी हा पासवर्ड आहे. कोणत्याही ॲप्लिकेशनकडे हे कधीही नसावे.

LITELLM_SALT_KEY डेटाबेसमध्ये साठवलेल्या प्रोव्हायडर क्रेडेंशियल्सना एनक्रिप्ट करते. हे एकदा सेट करा आणि तसेच राहू द्या. जर तुम्ही ते नंतर बदलले, तर आधी साठवलेली क्रेडेंशियल्स डिक्रिप्ट करता येणार नाहीत. परिणामी, गेटवे सामान्यपणे सुरू होईल, परंतु त्यानंतर त्या प्रोव्हायडर्सना केलेली प्रत्येक कॉल ऑथेंटिकेशनमध्ये अपयशी ठरेल.

STORE_MODEL_IN_DB=True तुम्हाला config.yaml ला स्पर्श न करता ॲडमिन UI वरून मॉडेल्स जोडण्याची आणि संपादित करण्याची सुविधा देते. हे सोयीचे आहे, परंतु यामुळे तुमची माहितीचे स्रोत (source of truth) दोन भागात विभागले जातात. यापैकी अधिकृत स्रोत कोणता हे ठरवा आणि तो निर्णय config च्या शेजारी लिहून ठेवा.

ज्या तर्कामुळे कीज कॉन्फिग फाईलच्या बाहेर ठेवल्या जातात, त्याच तर्कामुळे त्या तुम्ही एजंटला दिलेल्या टूल्सच्या बाहेरही ठेवल्या पाहिजेत. प्रोव्हायडर सिक्रेट्सना AI एजंट्सपासून दूर ठेवणे या पॅटर्नबद्दल माहिती देते, आणि Docker Compose मधील env फाईल्स आणि सिक्रेट्स त्याची कार्यपद्धती स्पष्ट करते.

सर्व्हिस सुरू करा आणि पहिल्या बूटवर लक्ष ठेवा:

docker compose up -d
docker compose logs -f litellm

ते प्रत्यक्षात काम करत असल्याची खात्री करा

येथे दोन अनधिकृत (unauthenticated) प्रोब्स आणि एक अधिकृत (authenticated) प्रोब आहे, आणि ते वेगवेगळ्या कारणांमुळे अयशस्वी होतात.

curl -s http://127.0.0.1:4000/health/liveliness
curl -s http://127.0.0.1:4000/health/readiness

/health/liveliness ला कोणत्याही ऑथेंटिकेशनची गरज नसते आणि प्रक्रिया सुरू असताना ते "I'm alive!" असे उत्तर देते. /health/readiness ला देखील कोणत्याही ऑथेंटिकेशनची गरज नसते. ते "status": "healthy" आणि db फील्ड असलेला JSON ऑब्जेक्ट परत करते, किंवा डेटाबेस पोहोचण्यायोग्य नसल्यास 503 एरर देते. तुमची मॉनिटरिंग सिस्टिम readiness वर सेट करा, कारण liveliness अशा गेटवेवरही 'green' राहते जो एखादी व्हर्च्युअल की शोधू शकत नाही.

अधिकृत चेक तो आहे जो प्रोव्हायडर्सशी संवाद साधतो:

curl -s http://127.0.0.1:4000/health \
  -H "Authorization: Bearer $LITELLM_MASTER_KEY"

ते healthy_endpoints आणि unhealthy_endpoints ॲरेसह उत्तर देते. unhealthy_endpoints मध्ये असलेला मॉडेल जर ऑथेंटिकेशन एरर दाखवत असेल, तर याचा अर्थ .env मधील प्रोव्हायडर की चुकीची आहे किंवा गहाळ आहे, आणि हीच ती त्रुटी आहे जी तुम्हाला आता शोधायची आहे. background_health_checks: true सेट केलेले असल्यामुळे, प्रॉक्सी स्वतःहून दर health_check_interval सेकंदांनी हे प्रोब्स चालवते आणि /health शेवटचा निकाल परत करते, त्यामुळे वारंवार पोलिंग केल्याने प्रत्येक वेळी तुमच्या प्रोव्हायडर्सना टेस्ट रिक्वेस्ट पाठवली जात नाही.

व्हर्च्युअल कीज आणि प्रति-की बजेट

प्रत्येक ॲप्लिकेशनला मास्टर कीच्या आधारे तयार केलेली स्वतःची स्वतंत्र की मिळते.

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
  }'

प्रतिसादामध्ये key फील्ड असते, जे sk- ने सुरू होते. ही स्ट्रिंग म्हणजे ॲप्लिकेशनला मिळणारी एकमेव गोष्ट आहे आणि ॲप्लिकेशनला फक्त इतकीच माहिती मिळते.

  • models ही एक अलाउलिस्ट आहे, जी ही की काय विनंती करू शकते हे ठरवते. वरील की फक्त bulk साठी विनंती करू शकते, त्याव्यतिरिक्त इतर कशासाठीही नाही.
  • max_budget: 5 सह budget_duration: "30d" म्हणजे दर 30 दिवसांच्या कालावधीसाठी पाच अमेरिकन डॉलर्सचे बजेट; त्यानंतर की काम करणे थांबवते.
  • rpm_limit आणि tpm_limit या की साठी प्रति मिनिट विनंत्या आणि प्रति मिनिट टोकन्सची मर्यादा निश्चित करतात.
  • key_alias हे नाव तुम्ही सहा आठवड्यांनंतर स्पेंड लॉगमध्ये ओळखू शकाल. हे नेहमी सेट करा.

जेव्हा बजेट संपते, तेव्हा कॉल HTTP 401 एररसह अपयशी ठरतो आणि त्याचा फॉरमॅट खालीलप्रमाणे असतो:

ExceededBudget: Current spend for token: 7.2e-05; Max Budget for Token: 2e-07

यातील स्टेटस कोड गोंधळात टाकणारा असतो. क्लायंट लायब्ररी 401 ला ऑथेंटिकेशन समस्या म्हणून दर्शवते, त्यामुळे स्टॅक ट्रेस वाचणारा डेव्हलपर की वैध आहे की नाही हे तपासू लागतो. स्टेटस कोडच्या शेजारी रिस्पॉन्स बॉडी लॉग करा, अन्यथा बजेट संपल्याची समस्या प्रत्येक वेळी खराब क्रेडेंशियल असल्यासारखीच वाटेल.

त्याच मॅनेजमेंट API द्वारे की तपासा आणि ॲडजस्ट करा:

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}'

गेटवेवर लागू केलेले बजेट तेव्हाही प्रभावी ठरते जेव्हा एजंटमध्येच काही बिघाड झालेला असतो, म्हणूनच हे VPS वरील AI एजंटसाठी खर्च नियंत्रण या प्रक्रियेचा कणा आहे.

स्वस्त मॉडेलकडे बल्क काम पाठवणे

क्लायंटला गेटवेकडे निर्देशित करा. बेस URL, की, मॉडेलचे नाव:

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 ला व्हर्च्युअल की वर सेट करा.

config.yaml मधील राउटिंग धोरण आता कॉलरला माहिती नसतानाही लागू होते. bulk साठीची विनंती स्वस्त मॉडेलकडे जाते. जर ती कॉल रिट्राय (retries) नंतरही अयशस्वी झाली, तर विनंती strong विरुद्ध पुन्हा प्रयत्न केली जाते. जर प्रॉम्प्ट bulk साठी खूप मोठा असेल, तर context_window_fallbacks त्रुटी देण्याऐवजी तो strong कडे पाठवते. क्लासिफिकेशन पास किंवा समरायझिंग बॅकलॉगसारखी बल्क कामे डीफॉल्टनुसार स्वस्त दरात चालतात आणि फक्त कठीण विनंत्यांसाठी जास्त खर्च येतो.

येथेच गेटवे टूल-वापरणाऱ्या एजंट्ससाठी उपयुक्त ठरतो. एकाच VPS वरील MCP (model context protocol) सर्व्हर आणि तो चालवणारा एजंट हे दोघेही एकाच एंडपॉईंटकडे निर्देशित करू शकतात, त्यामुळे त्यामागील मॉडेल पुन्हा डिप्लॉय न करता बदलता येते.

फॉलबॅक (fallback) झाला आहे हे कसे ओळखावे?

ही एक अशी बिघाड स्थिती (failure mode) आहे ज्यामध्ये आर्थिक नुकसान होते, कारण वरकरणी सर्व काही व्यवस्थित चालल्यासारखे वाटते. यशस्वी फॉलबॅक HTTP 200 स्टेटस आणि सामान्य रिस्पॉन्स बॉडी देतो. तुमचे स्वस्त मॉडेल दिवसभर बंद असू शकते आणि प्रत्येक कॉल शांतपणे महागड्या मॉडेलद्वारे पूर्ण केला जाऊ शकतो; अशा वेळी बिलाची पावती हाच पहिला पुरावा ठरतो.

याचा पुरावा रिस्पॉन्स हेडर्समध्ये उपलब्ध असतो. ते तपासण्यासाठी खालीलप्रमाणे विनंती करा:

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 हे क्लायंटने विचारलेले मॉडेल आहे. x-litellm-model-id हे त्या मॉडेलचे डिप्लॉयमेंट आहे ज्याने उत्तर दिले आहे. जेव्हा हे दोन्ही भिन्न असतात, तेव्हा फॉलबॅक झाला आहे असे समजावे.
  • x-litellm-attempted-fallbacks आणि x-litellm-attempted-retries हे फॉलबॅकची संख्या मोजतात. सुरळीत चालणाऱ्या कॉलमध्ये दोन्हीची किंमत 0 असते.
  • x-litellm-response-cost ही त्या एका विशिष्ट कॉलची अमेरिकन डॉलर्समधील किंमत आहे.
  • x-litellm-call-id हा तो आयडेंटिफायर आहे ज्याचा वापर करून तुम्ही तुमच्या लॉग्समध्ये तोच कॉल शोधू शकता.

प्रत्येक विनंतीवर x-litellm-attempted-fallbacks नोंदवा आणि जेव्हा त्याची किंमत 0 च्या वर जाईल तेव्हा अलर्ट सेट करा. हा एकच आकडा 'कार्यरत राउटिंग पॉलिसी' आणि 'शांतपणे महागड्या मॉडेलवर स्विच झालेली राउटिंग पॉलिसी' यांमधील फरक स्पष्ट करतो.

याची पूर्ण आवृत्ती म्हणजे ट्रेसिंग (tracing), ज्यासाठी स्वतंत्र सेटअप आवश्यक आहे: एजंट कॉल्सच्या ट्रेसिंगसाठी self-hosted Langfuse. LiteLLM मध्ये कॉलबॅक इन-बिल्ट असतो, त्यामुळे तो जोडण्यासाठी फक्त दोन ओळींचा कोड आणि क्रेडेंशियल्स लागतात.

litellm_settings:
  success_callback: ["langfuse"]
  failure_callback: ["langfuse"]
LANGFUSE_PUBLIC_KEY=pk-lf-...
LANGFUSE_SECRET_KEY=sk-lf-...
LANGFUSE_HOST=https://langfuse.example.com

failure_callback आणि success_callback दोन्ही सेट करा. हे न केल्यास, तुमच्याकडे फक्त अशाच ट्रेसची नोंद राहील जिथे काहीही बिघडलेले नाही. याव्यतिरिक्त, LiteLLM प्रत्येक विनंतीसाठी Postgres मध्ये खर्चाची एक ओळ (spend row) लिहिते आणि /ui वरील Admin UI त्या टेबलमधील माहिती वाचते. ट्रॅफिकनुसार हे टेबल वाढत जाते, त्यामुळे लहान डिस्कवर लक्ष ठेवा.

गेटवेला रिव्हर्स प्रॉक्सीच्या मागे ठेवा

बॉक्सच्या बाहेरील कोणत्याही गोष्टीने पोर्ट 4000 वर पोहोचू नये. nginx किंवा Caddy मध्ये TLS टर्मिनेट करा आणि विनंत्या loopback ॲड्रेसवर फॉरवर्ड करा.

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 महत्त्वाचे आहे कारण स्ट्रीमिंग पूर्ण होणे ही server-sent events ची मालिका असते. जर बफरिंग सुरू असेल, तर nginx प्रतिसाद संपेपर्यंत सर्व चंक्स (chunks) स्वतःकडे रोखून धरते, त्यामुळे क्लायंटला काहीही मिळत नाही आणि शेवटी सर्व डेटा एकदम मिळतो. proxy_read_timeout 600s महत्त्वाचे आहे कारण दीर्घकाळ चालणारी जनरेशन प्रक्रिया nginx च्या 60 सेकंदांच्या डीफॉल्ट वेळेपेक्षा जास्त वेळ घेते. जेव्हा असे घडते, तेव्हा क्लायंटला 504 एरर मिळतो आणि एरर लॉगमध्ये upstream timed out (110: Connection timed out) while reading response header from upstream नोंदवले जाते.

प्रमाणपत्रासाठी, nginx वर Let's Encrypt सह Certbot हा सर्वात सोपा मार्ग आहे. जर बॉक्सवर आधीच अनेक कंटेनर्स चालत असतील, तर अनेक Compose ॲप्सच्या समोर Traefik वापरल्याने राउटिंग आणि प्रमाणपत्रे एकाच ठिकाणी व्यवस्थापित होतात.

गेटवे आता अपयशाचा एकमेव बिंदू (single point of failure) बनला आहे

तुम्ही काय तयार केले आहे त्याबद्दल प्रामाणिक राहा. तुमच्या मालकीचे प्रत्येक ॲप्लिकेशन आता एका VPS वरील एका कंटेनरवर अवलंबून आहे. तो बंद असताना, कोणतीही सेवा कोणत्याही मॉडेलला कॉल करू शकत नाही, अगदी त्या प्रोव्हाइडर्सना सुद्धा जे पूर्णपणे व्यवस्थित काम करत आहेत. यातून चार गोष्टी स्पष्ट होतात.

  • चुकीच्या कॉन्फिगरेशनमुळे सर्व काही एकाच वेळी बंद पडू शकते. restart: unless-stopped क्रॅश झाल्यावर पुन्हा सुरू होतो, आणि तो अशा कंटेनरला पुन्हा सुरू करतो जो config.yaml पार्स करू शकत नाही, हे वारंवार घडते. प्रत्येक कॉन्फिगरेशन बदलानंतर docker compose logs litellm वाचा, आणि कॉन्फिगरेशनमध्ये बदल तेव्हाच करा जेव्हा ते तपासण्यासाठी तुमच्याकडे वेळ असेल.
  • Postgres विनंतीच्या मार्गामध्ये (request path) आहे. व्हर्च्युअल की लुकअप आणि खर्चाची नोंदणी या दोन्हीसाठी याचा वापर होतो. /health/readiness कडून 503 एरर मिळणे ही तुमची चेतावणी आहे की गेटवे चालू आहे, पण तो यापैकी काहीही करू शकत नाही.
  • एका इंस्टन्सला मोठे करण्याऐवजी नवीन इंस्टन्स जोडून स्केलिंग करा. प्रकल्पाचे स्वतःचे मार्गदर्शन असे आहे की प्रति इंस्टन्स एक वर्कर (--num_workers 1) असावा आणि अनेक इंस्टन्सनी एकाच डेटाबेसचा वापर करावा. लोड बॅलन्सरच्या मागे दोन छोटे गेटवे ठेवल्यास एका कंटेनरवर अवलंबून राहण्याची समस्या दूर होते. मात्र, यामुळे डेटाबेसची समस्या दूर होत नाही.
  • जे तुम्ही पुन्हा तयार करू शकत नाही त्याचा बॅकअप घ्या. यामध्ये config.yaml आणि .env, तसेच डेटाबेसचा pg_dump समाविष्ट आहे. LITELLM_SALT_KEY गमावल्यास त्या डंपमधील एनक्रिप्टेड प्रोव्हाइडर क्रेडेंशियल्स निरुपयोगी ठरतात, म्हणून env फाईल आणि डंप एकाच बॅकअप जॉबमध्ये असणे आवश्यक आहे: restic द्वारे ऑफ-बॉक्स स्टोरेजवर बॅकअप.

अपग्रेड करण्यासाठी इमेज टॅग एडिट करा आणि docker compose up -d रन करा. LiteLLM डीफॉल्टनुसार स्टार्टअपवर prisma migrate deploy रन करते, त्यामुळे नवीन कंटेनर पहिल्यांदा बूट होताना डेटाबेस स्कीमा मायग्रेट करतो. टॅग बदलण्यापूर्वी डंप घ्या, कारण जुनी इमेज परत टाकल्याने आधीच झालेली मायग्रेशन प्रक्रिया पूर्ववत होत नाही.

FAQ

LiteLLM मुळे प्रत्येक कॉलमध्ये लक्षणीय विलंब (latency) येतो का?

ऑगस्ट 2026 च्या README नुसार, हा प्रकल्प प्रति सेकंद 1000 विनंत्यांवर 95 व्या पर्सेंटाइलला 8 ms विलंब दर्शवतो. याकडे केवळ विक्रेत्याने दिलेली आकडेवारी म्हणून पहा. तुमच्या लॅटन्सीवर परिणाम करणारी मुख्य गोष्ट म्हणजे तुमच्या ॲप्लिकेशन्स आणि गेटवेमधील नेटवर्क अंतर, कारण तुम्ही प्रत्येक कॉलमध्ये एक अतिरिक्त राऊंड ट्रिप वाढवली आहे. गेटवे त्याच रिजनमध्ये चालवा जिथे तुमचे ॲप्लिकेशन्स आहेत आणि त्यानंतर प्रत्यक्ष प्रतिसादावर x-litellm-overhead-duration-ms हेडर वापरून तुमचा ओव्हरहेड मोजा.

nginx समोर ठेवल्यानंतर स्ट्रीमिंग काम करणे का थांबले?

कारण nginx डीफॉल्टनुसार अपस्ट्रीम प्रतिसाद बफर करते आणि स्ट्रीमिंग पूर्ण होणे ही 'server-sent events' ची मालिका असते. proxy_buffering चालू असताना, nginx सर्व चंक्स गोळा करते आणि प्रतिसाद पूर्ण झाल्यावरच ते पाठवते, त्यामुळे क्लायंट शांत राहतो आणि शेवटी पूर्ण उत्तर एकदाच मिळते. लोकेशन ब्लॉक मध्ये proxy_buffering off; सेट करा. त्याच ब्लॉक मध्ये proxy_read_timeout वाढवा, कारण अन्यथा दीर्घ जनरेशन nginx च्या 60 सेकंदांच्या डीफॉल्ट मर्यादेला ओलांडते आणि क्लायंटला 504 एरर मिळतो.

व्हर्च्युअल की चे बजेट संपल्यावर काय होते?

कॉल HTTP 401 एररसह अपयशी ठरतो आणि त्याचा बॉडी भाग ExceededBudget: Current spend for token: 7.2e-05; Max Budget for Token: 2e-07 स्वरूपात असतो. 401 हा एक सापळा आहे: क्लायंट लायब्ररी याला ऑथेंटिकेशन फेल्युअर म्हणून रिपोर्ट करते, त्यामुळे लोक मेसेज वाचण्याऐवजी की वैध आहे का हे तपासू लागतात. स्टेटस कोडसोबत रिस्पॉन्स बॉडी लॉग करा. मास्टर की च्या तुलनेत /key/info?key=sk-... वापरून की ची खरी स्थिती तपासा आणि जर बजेट खूप कमी सेट केले असेल तर /key/update वापरून मर्यादा वाढवा.

गेटवे होस्ट केलेल्या मॉडेल्ससोबतच स्थानिक (local) मॉडेलकडेही ट्रॅफिक वळवू शकतो का?

हो, आणि हे model_list मधील आणखी एक एन्ट्री आहे. api_base सह ollama_chat/ प्रीफिक्स वापरा, उदाहरणार्थ api_base: http://ollama:11434 सोबत model: ollama_chat/llama3.1. कंटेनरच्या आतून, localhost म्हणजे तो कंटेनर स्वतः, म्हणून Docker नेटवर्कवर Compose सर्व्हिसचे नाव किंवा होस्टचा पत्ता वापरा, कधीही 127.0.0.1 वापरू नका. स्थानिक मॉडेल सुरू करणे हे एक वेगळे काम आहे: VPS वर Ollama सह LLM सेल्फ-होस्ट करणे पहा.