Spaces:
Running on Zero
Running on Zero
sync: from ael backend/space/
Browse files- rerank.py +25 -1
- searx_bridge.py +11 -1
rerank.py
CHANGED
|
@@ -85,6 +85,7 @@ RECENT = deque(maxlen=int(os.environ.get("AEL_RERANK_LOG", "200")))
|
|
| 85 |
_router = None
|
| 86 |
_router_lock = threading.Lock()
|
| 87 |
_load_error = None
|
|
|
|
| 88 |
|
| 89 |
|
| 90 |
def _get_router():
|
|
@@ -94,7 +95,7 @@ def _get_router():
|
|
| 94 |
serves search, and the route needs to be able to ask "any opinion?"
|
| 95 |
without handling an exception.
|
| 96 |
"""
|
| 97 |
-
global _router, _load_error
|
| 98 |
if _router is not None or _load_error is not None:
|
| 99 |
return _router
|
| 100 |
with _router_lock:
|
|
@@ -108,10 +109,32 @@ def _get_router():
|
|
| 108 |
_router.preload([MODEL])
|
| 109 |
except Exception as e: # noqa: BLE001 - reported, never raised
|
| 110 |
_load_error = f"{type(e).__name__}"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 111 |
print(f"[rerank] disabled: cannot load laya ({_load_error}): {e}", flush=True)
|
| 112 |
return _router
|
| 113 |
|
| 114 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 115 |
def status():
|
| 116 |
"""For the /status route: is this thing actually working right now."""
|
| 117 |
router = _get_router()
|
|
@@ -178,6 +201,7 @@ def rerank(query, results, budget_ms=800):
|
|
| 178 |
"dropped": 0,
|
| 179 |
"starved": False,
|
| 180 |
"scores": [],
|
|
|
|
| 181 |
}
|
| 182 |
if not ENABLED or not results:
|
| 183 |
return out
|
|
|
|
| 85 |
_router = None
|
| 86 |
_router_lock = threading.Lock()
|
| 87 |
_load_error = None
|
| 88 |
+
_load_message = None
|
| 89 |
|
| 90 |
|
| 91 |
def _get_router():
|
|
|
|
| 95 |
serves search, and the route needs to be able to ask "any opinion?"
|
| 96 |
without handling an exception.
|
| 97 |
"""
|
| 98 |
+
global _router, _load_error, _load_message
|
| 99 |
if _router is not None or _load_error is not None:
|
| 100 |
return _router
|
| 101 |
with _router_lock:
|
|
|
|
| 109 |
_router.preload([MODEL])
|
| 110 |
except Exception as e: # noqa: BLE001 - reported, never raised
|
| 111 |
_load_error = f"{type(e).__name__}"
|
| 112 |
+
# The message matters and nothing else about this exception does:
|
| 113 |
+
# "the reranker is off" is a decision, "the reranker broke because
|
| 114 |
+
# <this>" is a bug report. The caller redacts before logging it.
|
| 115 |
+
_load_message = f"{type(e).__name__}: {e}"[:300]
|
| 116 |
print(f"[rerank] disabled: cannot load laya ({_load_error}): {e}", flush=True)
|
| 117 |
return _router
|
| 118 |
|
| 119 |
|
| 120 |
+
def _no_opinion():
|
| 121 |
+
"""Why this module has nothing to say, for the caller.
|
| 122 |
+
|
| 123 |
+
A reranker that is silently disabled is the worst outcome available: the
|
| 124 |
+
route's fail-open path cannot tell "the model declined" from "the model is
|
| 125 |
+
not installed", and both look like a working search that quietly does not
|
| 126 |
+
rerank. The first version of this stage returned `ok: false` and nothing
|
| 127 |
+
else, and that ambiguity cost a full session of debugging the Space's
|
| 128 |
+
build when the Space had been fine the whole time — the app simply had the
|
| 129 |
+
URL wrong and never asked.
|
| 130 |
+
"""
|
| 131 |
+
if not ENABLED:
|
| 132 |
+
return "disabled by config"
|
| 133 |
+
if _load_error:
|
| 134 |
+
return _load_message or _load_error
|
| 135 |
+
return None
|
| 136 |
+
|
| 137 |
+
|
| 138 |
def status():
|
| 139 |
"""For the /status route: is this thing actually working right now."""
|
| 140 |
router = _get_router()
|
|
|
|
| 201 |
"dropped": 0,
|
| 202 |
"starved": False,
|
| 203 |
"scores": [],
|
| 204 |
+
"no_opinion": _no_opinion(),
|
| 205 |
}
|
| 206 |
if not ENABLED or not results:
|
| 207 |
return out
|
searx_bridge.py
CHANGED
|
@@ -76,7 +76,17 @@ def register_routes(fa_app):
|
|
| 76 |
try:
|
| 77 |
out = await asyncio.to_thread(rerank.rerank, q, results, budget_ms)
|
| 78 |
except Exception as e: # noqa: BLE001
|
| 79 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 80 |
return JSONResponse(out)
|
| 81 |
|
| 82 |
@fa_app.get("/respite/v2/searx/rerank/recent")
|
|
|
|
| 76 |
try:
|
| 77 |
out = await asyncio.to_thread(rerank.rerank, q, results, budget_ms)
|
| 78 |
except Exception as e: # noqa: BLE001
|
| 79 |
+
# `no_opinion` as well as `error`: the client reports the former, so
|
| 80 |
+
# a crash that never reached rerank() must not read as "the model
|
| 81 |
+
# had nothing to say about your query".
|
| 82 |
+
return JSONResponse(
|
| 83 |
+
{
|
| 84 |
+
"ok": False,
|
| 85 |
+
"error": f"rerank failed: {e}",
|
| 86 |
+
"no_opinion": f"{type(e).__name__}: {e}"[:300],
|
| 87 |
+
"results": results,
|
| 88 |
+
}
|
| 89 |
+
)
|
| 90 |
return JSONResponse(out)
|
| 91 |
|
| 92 |
@fa_app.get("/respite/v2/searx/rerank/recent")
|