fix: cold-start timeouts, keepalives, vLLM probe, fast-Ollama-fallback
#1
by msradam - opened
- app/llm.py +16 -7
app/llm.py
CHANGED
|
@@ -92,6 +92,15 @@ def _build_router() -> Router:
|
|
| 92 |
fallbacks: list[dict[str, list[str]]] = []
|
| 93 |
use_vllm = _PRIMARY == "vllm" and bool(_VLLM_BASE)
|
| 94 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 95 |
for alias, (vllm_name, ollama_tag) in _LOGICAL.items():
|
| 96 |
if use_vllm:
|
| 97 |
model_list.append({
|
|
@@ -100,8 +109,8 @@ def _build_router() -> Router:
|
|
| 100 |
"model": f"openai/{vllm_name}",
|
| 101 |
"api_base": _VLLM_BASE,
|
| 102 |
"api_key": _VLLM_KEY,
|
| 103 |
-
"timeout":
|
| 104 |
-
"stream_timeout":
|
| 105 |
},
|
| 106 |
})
|
| 107 |
if _FALLBACK == "ollama":
|
|
@@ -111,8 +120,8 @@ def _build_router() -> Router:
|
|
| 111 |
"litellm_params": {
|
| 112 |
"model": f"ollama_chat/{ollama_tag}",
|
| 113 |
"api_base": _OLLAMA_BASE,
|
| 114 |
-
"timeout":
|
| 115 |
-
"stream_timeout":
|
| 116 |
},
|
| 117 |
})
|
| 118 |
fallbacks.append({alias: [fb_alias]})
|
|
@@ -122,8 +131,8 @@ def _build_router() -> Router:
|
|
| 122 |
"litellm_params": {
|
| 123 |
"model": f"ollama_chat/{ollama_tag}",
|
| 124 |
"api_base": _OLLAMA_BASE,
|
| 125 |
-
"timeout":
|
| 126 |
-
"stream_timeout":
|
| 127 |
},
|
| 128 |
})
|
| 129 |
|
|
@@ -135,7 +144,7 @@ def _build_router() -> Router:
|
|
| 135 |
fallbacks=fallbacks,
|
| 136 |
num_retries=0, # Router fallback handles the failover; no point
|
| 137 |
# burning seconds re-hitting a dead endpoint.
|
| 138 |
-
timeout=
|
| 139 |
)
|
| 140 |
|
| 141 |
|
|
|
|
| 92 |
fallbacks: list[dict[str, list[str]]] = []
|
| 93 |
use_vllm = _PRIMARY == "vllm" and bool(_VLLM_BASE)
|
| 94 |
|
| 95 |
+
# vLLM on RunPod can take 250+ seconds to cold-start (container boot +
|
| 96 |
+
# model load into GPU VRAM). The first-token timeout must exceed that.
|
| 97 |
+
# stream_timeout (per-chunk) stays tight since subsequent tokens are fast.
|
| 98 |
+
_vllm_first_token_timeout = int(
|
| 99 |
+
os.environ.get("RIPRAP_LITELLM_TIMEOUT_S", "360"))
|
| 100 |
+
# 5s: fail fast so callers (mellea probe loop) aren't blocked waiting
|
| 101 |
+
# for an Ollama that doesn't exist in the vLLM-primary HF Space.
|
| 102 |
+
_ollama_timeout = 5
|
| 103 |
+
|
| 104 |
for alias, (vllm_name, ollama_tag) in _LOGICAL.items():
|
| 105 |
if use_vllm:
|
| 106 |
model_list.append({
|
|
|
|
| 109 |
"model": f"openai/{vllm_name}",
|
| 110 |
"api_base": _VLLM_BASE,
|
| 111 |
"api_key": _VLLM_KEY,
|
| 112 |
+
"timeout": _vllm_first_token_timeout,
|
| 113 |
+
"stream_timeout": 60,
|
| 114 |
},
|
| 115 |
})
|
| 116 |
if _FALLBACK == "ollama":
|
|
|
|
| 120 |
"litellm_params": {
|
| 121 |
"model": f"ollama_chat/{ollama_tag}",
|
| 122 |
"api_base": _OLLAMA_BASE,
|
| 123 |
+
"timeout": _ollama_timeout,
|
| 124 |
+
"stream_timeout": _ollama_timeout,
|
| 125 |
},
|
| 126 |
})
|
| 127 |
fallbacks.append({alias: [fb_alias]})
|
|
|
|
| 131 |
"litellm_params": {
|
| 132 |
"model": f"ollama_chat/{ollama_tag}",
|
| 133 |
"api_base": _OLLAMA_BASE,
|
| 134 |
+
"timeout": _ollama_timeout,
|
| 135 |
+
"stream_timeout": _ollama_timeout,
|
| 136 |
},
|
| 137 |
})
|
| 138 |
|
|
|
|
| 144 |
fallbacks=fallbacks,
|
| 145 |
num_retries=0, # Router fallback handles the failover; no point
|
| 146 |
# burning seconds re-hitting a dead endpoint.
|
| 147 |
+
timeout=_vllm_first_token_timeout if use_vllm else _ollama_timeout,
|
| 148 |
)
|
| 149 |
|
| 150 |
|