LiteLLM journey: drop_params ทำไมต้อง recreate
สารบัญ
"ทุกอย่างดูเหมือนตั้งค่าถูกต้องใน DB แต่ logs ก็ยังโยน error 400 ออกมา — แล้วผมก็นั่งงงอยู่สิบนาทีกว่าจะรู้ว่า 'ค่านี้' apply ตอน start container เท่านั้น"
ผมเปลี่ยน drop_params จาก false เป็น true เพื่อให้ LiteLLM drop reasoning_effort แบบเงียบๆ — pattern ที่ docs แนะนำ และ community ใน r/LocalLLaMA ก็เห็นด้วย
แต่ error ก็ยังเด้งออกมาหลังจากนั้นสองชั่วโมง
ลอง trace ดูกันว่าเกิดอะไรขึ้น และ lesson คืออะไร
TL;DR
- DB auto-reload ของ LiteLLM ครอบคลุมบางค่าเท่านั้น —
drop_paramsไม่อยู่ในนั้น - เปลี่ยน
drop_paramsผ่าน DB อย่างเดียว → ไม่ apply จนกว่าจะ restart container - Decision matrix ตอนนี้ชัดเจน: drop_params / routing_strategy / image upgrade → ต้อง
docker compose up -d --force-recreate
Context: ระบบที่ผมใช้งาน
- Stack: LiteLLM proxy (v1.102.0-rc.2) + postgres 18 + redis 7 บน homelab ที่
litellm-gateway.lan - Models: MiniMax-M3 + qwen3.8-27b (self-host vLLM) — ลูกค้าจริงคือ Hermes client ที่ส่ง
reasoning_effortมาทุก request - Config: 3-way sync —
config.yaml↔ DB (LiteLLM_Config) ↔ UI - Auto-reload: 60s ผ่าน
proxy_config_reload_interval_seconds
ที่ผม assume คือ "ถ้า DB UPDATE ค่า → รอ 65 วินาที → LiteLLM apply อัตโนมัติ" — มัน work กับ credentials, models, num_retries, cache หลายๆ ครั้ง
แต่ไม่ใช่ทุกค่า
เหตุการณ์จริง (timeline)
02:50 — UPDATE LiteLLM_Config JSONB เปลี่ยน drop_params จาก false เป็น true (per community consensus)
02:50 - 04:30 — assume "รอ auto-reload" แล้วใช้งานต่อ
06:19:15 — log:
litellm.UnsupportedParamsError: minimax does not support parameters:
['reasoning_effort'], for model=MiniMax-M3. To drop these, set
`litellm.drop_params=True` or for proxy:
litellm_settings:
drop_params: true
06:23:37 — log ซ้ำอีก request
06:30 — ลอง curl ทดสอบเอง ก็ยัง HTTP 400
ทุกอย่างใน DB ถูกต้องหมด — แต่ LiteLLM ก็ยังไม่ apply
Root Cause: scope ของ periodic reload
ผมไปอ่าน source ของ LiteLLM พบว่า proxy_config_reload_interval_seconds job ทำ 3 อย่างเท่านั้น:
proxy_config.check_periodic_reloads— model cost map, anthropic beta headersproxy_config.get_credentials— DB credentialsproxy_config.add_deployment— models จากLiteLLM_ProxyModelTable
drop_params อยู่ใน LiteLLM_Config.litellm_settings — มันถูก load ตอน container start และ cache ไว้ใน memory จนกว่า container จะ restart ใหม่
นั่นหมายความว่า DB อัปเดต 100 ครั้ง ก็ไม่มีผล ถ้าไม่ recreate container
ทำไมถึงออกแบบแบบนี้? ผมเดาว่าเพื่อ deterministic behavior — admin เปลี่ยน flag ร้ายแรง (เช่น disable drop_params เพื่อ audit) แล้วอยากให้ apply ทันที + drop request ที่ค้าง pipeline ไว้ ไม่ใช่ silently bypass
ซึ่งก็สมเหตุสมผล — แต่ docs ไม่ได้บอกชัดเจน
Fix: recreate container
docker compose up -d --force-recreate litellm
ใช้เวลาประมาณ 30 วินาที จากนั้น verify:
curl http://localhost:4000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $MASTER" \
-d '{"model":"MiniMax-M3","messages":[{"role":"user","content":"ping"}],
"reasoning_effort":"medium","max_tokens":10}'
Response:
{
"id": "06fa590a...",
"model": "MiniMax-M3",
"object": "chat.completion",
"choices": [{"finish_reason": "length", "message": {"role": "assistant", "content": "\n\n"}}]
}
HTTP 200 — reasoning_effort ถูก drop เงียบๆ ตามที่คาดไว้
Decision Matrix: เมื่อไหร่ต้อง Recreate
ตอนนี้ผมแยกชัดเจนระหว่าง "DB update พอ" กับ "ต้อง recreate":
| Setting | Auto-reload 60s | Recreate required |
|---|---|---|
rpm, tpm (rate limits) | ใช่ | ไม่ |
max_input_tokens, max_output_tokens | ใช่ | ไม่ |
success_callback, failure_callback | ใช่ | ไม่ |
cache, cache_params | ใช่ | ไม่ |
num_retries, allowed_fails (router) | ใช่ | ไม่ |
maximum_spend_logs_retention_period | ใช่ | ไม่ |
drop_params | ไม่ | ใช่ |
routing_strategy | ไม่ | ใช่ |
| Critical callbacks (rate limiter) | ไม่ | ใช่ |
| Image upgrade (pin digest) | ไม่ | ใช่ |
Rule of thumb: ถ้าค่านั้นส่งผลต่อ "behavior ของ LiteLLM runtime" ไม่ใช่แค่ "data of model config" → มักต้อง recreate
สรุป
- DB auto-reload (60s) apply เฉพาะ model/credentials/callbacks — ไม่ใช่ flag ของ runtime behavior
- ถ้าจะเปลี่ยน
drop_params,routing_strategy, image → backup compose.yaml + recreate container - ตรวจ logs ก่อน assume ว่า "DB update = apply"
ไม่ใช่ทุกอย่างที่ตั้งใน DB จะเริ่มทำงานทันที — และนี่เป็นหนึ่งใน classic gotcha ของ LiteLLM ที่ docs ไม่ได้เขียนให้อ่านง่าย
อ้างอิง
- LiteLLM — drop_params docs — official docs ที่ระบุ
drop_params: true - LiteLLM — proxy_config_reload_interval_seconds — ตัวที่ควบคุม periodic reload
- LiteLLM PR #29431 — discussion เรื่อง stream_options + response API param leak ที่ fix ใน v1.102.0-rc.2
- r/LocalLLaMA — drop_params pattern — community consensus ที่ confirm ว่า
drop_params: trueเป็น default practice - LiteLLM release v1.102.0-rc.2 — version ที่รันตอน debug
เนื้อหานี้มีประโยชน์ไหม? ช่วยสนับสนุนค่ากาแฟให้ผู้เขียนสักแก้ว
Buy Me a Coffee