mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
feat: kill all silent fallbacks — fail clearly, never degrade silently
Remove 9 silent fallback chains in the Python sidecar: - upscale: RealESRGAN→Lanczos (now errors with install guidance) - upscale: GFPGAN skip (now errors with install guidance) - gpu: GPU→CPU (now reports device in response, never silent) - remove_bg: alpha matting fallback (now errors with retry guidance) - remove_bg: GPU→CPU session (now reports device) - colorize: DDColor→OpenCV (now errors with install guidance) - enhance_faces: CodeFormer→GFPGAN (now errors with install guidance) - ocr: quality cascade (now errors at requested level) - bridge: dispatcher crash retry (now reports retry in stderr) Also: raise red_eye max_faces 10→50, face_landmarks max_num_faces configurable, restore.py min face size 48→24px.
This commit is contained in:
@@ -1,10 +1,16 @@
|
||||
"""Runtime GPU/CUDA detection utility."""
|
||||
import functools
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
def emit_info(msg):
|
||||
"""Emit an informational JSON message to stderr for the bridge to capture."""
|
||||
print(json.dumps({"info": msg}), file=sys.stderr, flush=True)
|
||||
|
||||
|
||||
@functools.lru_cache(maxsize=1)
|
||||
def gpu_available():
|
||||
"""Return True if a usable CUDA GPU is present at runtime."""
|
||||
@@ -51,24 +57,34 @@ def gpu_available():
|
||||
|
||||
|
||||
def onnx_providers():
|
||||
"""Return ONNX Runtime execution providers in priority order."""
|
||||
"""Return (providers, device) tuple.
|
||||
|
||||
providers: ONNX Runtime execution providers in priority order.
|
||||
device: "cuda" or "cpu" — reflects which hardware will actually be used.
|
||||
"""
|
||||
if gpu_available():
|
||||
return ["CUDAExecutionProvider", "CPUExecutionProvider"]
|
||||
return ["CPUExecutionProvider"]
|
||||
return (["CUDAExecutionProvider", "CPUExecutionProvider"], "cuda")
|
||||
emit_info("No GPU detected, processing on CPU")
|
||||
return (["CPUExecutionProvider"], "cpu")
|
||||
|
||||
|
||||
def safe_onnx_session(model_path, providers=None):
|
||||
"""Create an ONNX Runtime InferenceSession with graceful CUDA EP fallback."""
|
||||
"""Create an ONNX Runtime InferenceSession with graceful CUDA EP fallback.
|
||||
|
||||
Returns (session, device) where device is "cuda" or "cpu".
|
||||
"""
|
||||
import onnxruntime as ort
|
||||
|
||||
device = "cpu"
|
||||
if providers is None:
|
||||
providers = onnx_providers()
|
||||
providers, device = onnx_providers()
|
||||
|
||||
try:
|
||||
return ort.InferenceSession(model_path, providers=providers)
|
||||
session = ort.InferenceSession(model_path, providers=providers)
|
||||
return session, device
|
||||
except Exception as e:
|
||||
if "CUDAExecutionProvider" in providers:
|
||||
print(f"[gpu] CUDA EP init failed ({e}), falling back to CPU",
|
||||
file=sys.stderr, flush=True)
|
||||
return ort.InferenceSession(model_path, providers=["CPUExecutionProvider"])
|
||||
emit_info(f"CUDA init failed ({e}), falling back to CPU")
|
||||
session = ort.InferenceSession(model_path, providers=["CPUExecutionProvider"])
|
||||
return session, "cpu"
|
||||
raise
|
||||
|
||||
Reference in New Issue
Block a user