fix(ai): increase timeout to 60s, keep model resident in RAM for 24h, and warm up on startup

This commit is contained in:
Antigravity committed 2026-10-07 09:57:38 +03:00
1 parent dee9b8d10b
commit 915d2784a2
3 files changed
+26 -4

No files matched your search

+23 -2
View File
@@ -223,6 +223,7 @@ async def translate_sentence_ai(
"prompt": prompt, "prompt": prompt,
"stream": False, "stream": False,
"format": "json", "format": "json",
"keep_alive": "24h",
"options": { "options": {
"temperature": 0.2, "temperature": 0.2,
"num_predict": 300, "num_predict": 300,
@@ -234,7 +235,7 @@ async def translate_sentence_ai(
source = f"ollama:{config.OLLAMA_MODEL}" source = f"ollama:{config.OLLAMA_MODEL}"
try: try:
async with httpx.AsyncClient(timeout=35.0) as client: async with httpx.AsyncClient(timeout=60.0) as client:
resp = await client.post(f"{config.OLLAMA_BASE_URL}/api/generate", json=payload) resp = await client.post(f"{config.OLLAMA_BASE_URL}/api/generate", json=payload)
if resp.status_code == 200: if resp.status_code == 200:
data = resp.json() data = resp.json()
@@ -282,7 +283,8 @@ async def translate_sentence_ai(
else: else:
logger.warning(f"Ollama returned HTTP {resp.status_code}: {resp.text}") logger.warning(f"Ollama returned HTTP {resp.status_code}: {resp.text}")
except Exception as e: except Exception as e:
logger.warning(f"Ollama connection error: {e}") err_msg = f"{type(e).__name__}: {e}" if str(e) else type(e).__name__
logger.warning(f"Ollama connection error ({err_msg})")
# 4. Graceful Fallback if Ollama is unreachable # 4. Graceful Fallback if Ollama is unreachable
if not sentence_ru: if not sentence_ru:
@@ -329,3 +331,22 @@ async def get_ollama_status() -> Dict[str, Any]:
"models": [], "models": [],
"active_model": config.OLLAMA_MODEL, "active_model": config.OLLAMA_MODEL,
} }
async def warmup_ollama_model() -> bool:
"""Preloads the configured Ollama model into RAM with keep_alive to eliminate cold-start latency."""
try:
async with httpx.AsyncClient(timeout=60.0) as client:
resp = await client.post(
f"{config.OLLAMA_BASE_URL}/api/generate",
json={"model": config.OLLAMA_MODEL, "keep_alive": "24h"},
)
if resp.status_code == 200:
logger.info(f"Ollama model '{config.OLLAMA_MODEL}' warmed up successfully (keep_alive=24h).")
return True
else:
logger.warning(f"Ollama warmup returned HTTP {resp.status_code}: {resp.text}")
except Exception as e:
err_msg = f"{type(e).__name__}: {e}" if str(e) else type(e).__name__
logger.warning(f"Ollama warmup deferred ({err_msg})")
return False
+2 -1
View File
@@ -35,7 +35,7 @@ from app.reader import (
fetch_and_parse_rfc, parse_rfc_text, fetch_and_parse_wikipedia, fetch_and_parse_rfc, parse_rfc_text, fetch_and_parse_wikipedia,
extract_wikipedia_title_and_lang extract_wikipedia_title_and_lang
) )
from app.ai import translate_sentence_ai, get_ollama_status from app.ai import translate_sentence_ai, get_ollama_status, warmup_ollama_model
from app.phrasal import detect_phrasal_verb from app.phrasal import detect_phrasal_verb
from app.cefr import ( from app.cefr import (
get_cefr_level_summaries, get_cefr_level_summaries,
@@ -68,6 +68,7 @@ from app.miner import run_mining_task_background
async def lifespan(app: FastAPI): async def lifespan(app: FastAPI):
init_db() init_db()
ensure_admin_user() ensure_admin_user()
asyncio.create_task(warmup_ollama_model())
yield yield
await close_http_client() await close_http_client()
+1 -1
View File
@@ -29,4 +29,4 @@ services:
volumes: volumes:
- ./data/ollama:/root/.ollama - ./data/ollama:/root/.ollama
environment: environment:
- OLLAMA_KEEP_ALIVE=5m - OLLAMA_KEEP_ALIVE=24h