Commit ·
4bd5dc7
1
Parent(s): 2fe3d02
Use NVIDIA hosted Mistral fallback
Browse files- mp1/pluto/dispatcher.py +68 -35
mp1/pluto/dispatcher.py
CHANGED
|
@@ -23,6 +23,7 @@ from pluto.tracer import Tracer
|
|
| 23 |
load_dotenv()
|
| 24 |
|
| 25 |
NVIDIA_CHAT_URL = "https://integrate.api.nvidia.com/v1/chat/completions"
|
|
|
|
| 26 |
NVIDIA_RERANK_URLS = (
|
| 27 |
"https://ai.api.nvidia.com/v1/retrieval/nvidia/llama-nemotron-rerank-1b-v2/reranking",
|
| 28 |
"https://ai.api.nvidia.com/v1/retrieval/nvidia/reranking",
|
|
@@ -113,42 +114,9 @@ def dispatch(
|
|
| 113 |
print(f" [WARNING] {cfg.provider} failed: {e}")
|
| 114 |
|
| 115 |
if cfg.provider == "groq":
|
| 116 |
-
|
| 117 |
-
fb = ModeConfig(
|
| 118 |
-
mode_name=cfg.mode_name,
|
| 119 |
-
model_id="mistral-small-latest",
|
| 120 |
-
temperature=cfg.temperature,
|
| 121 |
-
max_tokens=cfg.max_tokens,
|
| 122 |
-
compute_profile="fallback",
|
| 123 |
-
provider="mistral",
|
| 124 |
-
)
|
| 125 |
-
text = _call_mistral(fb, prompt)
|
| 126 |
else:
|
| 127 |
-
|
| 128 |
-
if groq_key:
|
| 129 |
-
print(" [FALLBACK] Trying Groq...")
|
| 130 |
-
fb = ModeConfig(
|
| 131 |
-
mode_name=cfg.mode_name,
|
| 132 |
-
model_id="llama-3.1-8b-instant",
|
| 133 |
-
temperature=cfg.temperature,
|
| 134 |
-
max_tokens=cfg.max_tokens,
|
| 135 |
-
compute_profile="fallback",
|
| 136 |
-
provider="groq",
|
| 137 |
-
)
|
| 138 |
-
text = _call_groq(fb, prompt)
|
| 139 |
-
elif os.getenv("MISTRAL_API_KEY", ""):
|
| 140 |
-
print(" [FALLBACK] Trying Mistral...")
|
| 141 |
-
fb = ModeConfig(
|
| 142 |
-
mode_name=cfg.mode_name,
|
| 143 |
-
model_id="mistral-small-latest",
|
| 144 |
-
temperature=cfg.temperature,
|
| 145 |
-
max_tokens=cfg.max_tokens,
|
| 146 |
-
compute_profile="fallback",
|
| 147 |
-
provider="mistral",
|
| 148 |
-
)
|
| 149 |
-
text = _call_mistral(fb, prompt)
|
| 150 |
-
else:
|
| 151 |
-
raise
|
| 152 |
|
| 153 |
elapsed = time.perf_counter() - t0
|
| 154 |
if tracer:
|
|
@@ -163,6 +131,48 @@ def dispatch(
|
|
| 163 |
return text
|
| 164 |
|
| 165 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 166 |
def _call_groq(cfg: ModeConfig, prompt: str) -> str:
|
| 167 |
"""Call Groq with smart retry and rate-limit backoff."""
|
| 168 |
groq_max_retries = 8
|
|
@@ -306,6 +316,29 @@ def _call_nvidia(cfg: ModeConfig, prompt: str) -> str:
|
|
| 306 |
return ""
|
| 307 |
|
| 308 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 309 |
def rerank(query: str, passages: list[str]) -> list[float]:
|
| 310 |
"""
|
| 311 |
Score each passage for relevance to the query using the NVIDIA reranker.
|
|
|
|
| 23 |
load_dotenv()
|
| 24 |
|
| 25 |
NVIDIA_CHAT_URL = "https://integrate.api.nvidia.com/v1/chat/completions"
|
| 26 |
+
NVIDIA_MISTRAL_FALLBACK_MODEL = "mistralai/mistral-medium-3.5-128b"
|
| 27 |
NVIDIA_RERANK_URLS = (
|
| 28 |
"https://ai.api.nvidia.com/v1/retrieval/nvidia/llama-nemotron-rerank-1b-v2/reranking",
|
| 29 |
"https://ai.api.nvidia.com/v1/retrieval/nvidia/reranking",
|
|
|
|
| 114 |
print(f" [WARNING] {cfg.provider} failed: {e}")
|
| 115 |
|
| 116 |
if cfg.provider == "groq":
|
| 117 |
+
text = _call_best_fallback(cfg, prompt, allow_groq=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 118 |
else:
|
| 119 |
+
text = _call_best_fallback(cfg, prompt, allow_groq=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 120 |
|
| 121 |
elapsed = time.perf_counter() - t0
|
| 122 |
if tracer:
|
|
|
|
| 131 |
return text
|
| 132 |
|
| 133 |
|
| 134 |
+
def _call_best_fallback(cfg: ModeConfig, prompt: str, allow_groq: bool) -> str:
|
| 135 |
+
"""Try the configured fallback providers without confusing NVIDIA and Mistral keys."""
|
| 136 |
+
groq_key = os.getenv("GROQ_API_KEY", "").strip()
|
| 137 |
+
if allow_groq and groq_key:
|
| 138 |
+
print(" [FALLBACK] Trying Groq...")
|
| 139 |
+
fb = ModeConfig(
|
| 140 |
+
mode_name=cfg.mode_name,
|
| 141 |
+
model_id="llama-3.1-8b-instant",
|
| 142 |
+
temperature=cfg.temperature,
|
| 143 |
+
max_tokens=cfg.max_tokens,
|
| 144 |
+
compute_profile="fallback",
|
| 145 |
+
provider="groq",
|
| 146 |
+
)
|
| 147 |
+
return _call_groq(fb, prompt)
|
| 148 |
+
|
| 149 |
+
mistral_key = os.getenv("MISTRAL_API_KEY", "").strip()
|
| 150 |
+
if mistral_key and not _looks_like_nvidia_key(mistral_key):
|
| 151 |
+
print(" [FALLBACK] Trying Mistral...")
|
| 152 |
+
fb = ModeConfig(
|
| 153 |
+
mode_name=cfg.mode_name,
|
| 154 |
+
model_id="mistral-small-latest",
|
| 155 |
+
temperature=cfg.temperature,
|
| 156 |
+
max_tokens=cfg.max_tokens,
|
| 157 |
+
compute_profile="fallback",
|
| 158 |
+
provider="mistral",
|
| 159 |
+
)
|
| 160 |
+
return _call_mistral(fb, prompt)
|
| 161 |
+
|
| 162 |
+
nvidia_key = os.getenv("NVIDIA_API_KEY", "").strip()
|
| 163 |
+
if nvidia_key:
|
| 164 |
+
print(" [FALLBACK] Trying NVIDIA-hosted Mistral...")
|
| 165 |
+
return _call_nvidia_hosted_mistral(cfg, prompt, nvidia_key)
|
| 166 |
+
|
| 167 |
+
if mistral_key:
|
| 168 |
+
raise ValueError("MISTRAL_API_KEY appears to be an NVIDIA nvapi key. Put it in NVIDIA_API_KEY instead.")
|
| 169 |
+
raise ValueError("No fallback provider is configured.")
|
| 170 |
+
|
| 171 |
+
|
| 172 |
+
def _looks_like_nvidia_key(api_key: str) -> bool:
|
| 173 |
+
return api_key.strip().startswith("nvapi-")
|
| 174 |
+
|
| 175 |
+
|
| 176 |
def _call_groq(cfg: ModeConfig, prompt: str) -> str:
|
| 177 |
"""Call Groq with smart retry and rate-limit backoff."""
|
| 178 |
groq_max_retries = 8
|
|
|
|
| 316 |
return ""
|
| 317 |
|
| 318 |
|
| 319 |
+
def _call_nvidia_hosted_mistral(cfg: ModeConfig, prompt: str, api_key: str) -> str:
|
| 320 |
+
"""Call Mistral served through NVIDIA NIM using NVIDIA credentials."""
|
| 321 |
+
payload = {
|
| 322 |
+
"model": NVIDIA_MISTRAL_FALLBACK_MODEL,
|
| 323 |
+
"messages": [{"role": "user", "content": prompt}],
|
| 324 |
+
"temperature": cfg.temperature,
|
| 325 |
+
"max_tokens": cfg.max_tokens,
|
| 326 |
+
}
|
| 327 |
+
response = requests.post(
|
| 328 |
+
NVIDIA_CHAT_URL,
|
| 329 |
+
headers={
|
| 330 |
+
"Authorization": f"Bearer {api_key}",
|
| 331 |
+
"Content-Type": "application/json",
|
| 332 |
+
},
|
| 333 |
+
json=payload,
|
| 334 |
+
timeout=NVIDIA_TIMEOUT_WITH_FALLBACK,
|
| 335 |
+
)
|
| 336 |
+
if response.status_code != 200:
|
| 337 |
+
raise RuntimeError(f"NVIDIA-hosted Mistral {response.status_code}: {response.text[:300]}")
|
| 338 |
+
data = response.json()
|
| 339 |
+
return data["choices"][0]["message"]["content"]
|
| 340 |
+
|
| 341 |
+
|
| 342 |
def rerank(query: str, passages: list[str]) -> list[float]:
|
| 343 |
"""
|
| 344 |
Score each passage for relevance to the query using the NVIDIA reranker.
|