mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
fix: resolve ONNX CUDA fallback, Docker e2e infrastructure, and all test failures
- Add safe_onnx_session() to gpu.py with graceful CUDA EP → CPU fallback - Replace bare ort.InferenceSession() calls across colorize, restore, inpaint, remove_bg - Add libcublas-12-6 to production Dockerfile for ONNX Runtime CUDA EP - Add skipIfFeatureNotInstalled guards to remove-bg, blur-faces, smart-crop, ocr, noise-removal e2e specs - Add AI tool install prompt detection in tools-all.spec.ts - Add smart-crop to PYTHON_SIDECAR_TOOLS so frontend shows install prompt correctly - Create Dockerfile.test.dockerignore to include tests/ in test image builds - Add libheif-examples and exiftool to Dockerfile.test for HEIC and metadata tests - Regenerate visual regression baselines for Docker/Linux and skip on non-Docker platforms
This commit is contained in:
@@ -46,19 +46,11 @@ OPENCV_POINTS_PATH = os.environ.get(
|
||||
|
||||
def colorize_ddcolor(img_bgr, intensity):
|
||||
"""Colorize using DDColor ONNX model."""
|
||||
import onnxruntime as ort
|
||||
from gpu import safe_onnx_session
|
||||
|
||||
emit_progress(15, "Loading DDColor model")
|
||||
|
||||
providers = ["CUDAExecutionProvider", "CPUExecutionProvider"]
|
||||
try:
|
||||
from gpu import gpu_available
|
||||
if not gpu_available():
|
||||
providers = ["CPUExecutionProvider"]
|
||||
except ImportError:
|
||||
providers = ["CPUExecutionProvider"]
|
||||
|
||||
session = ort.InferenceSession(DDCOLOR_MODEL_PATH, providers=providers)
|
||||
session = safe_onnx_session(DDCOLOR_MODEL_PATH)
|
||||
input_name = session.get_inputs()[0].name
|
||||
input_shape = session.get_inputs()[0].shape
|
||||
# Dynamic dims are strings ('w', 'h'), so default to 512 if not int
|
||||
|
||||
@@ -55,3 +55,20 @@ def onnx_providers():
|
||||
if gpu_available():
|
||||
return ["CUDAExecutionProvider", "CPUExecutionProvider"]
|
||||
return ["CPUExecutionProvider"]
|
||||
|
||||
|
||||
def safe_onnx_session(model_path, providers=None):
|
||||
"""Create an ONNX Runtime InferenceSession with graceful CUDA EP fallback."""
|
||||
import onnxruntime as ort
|
||||
|
||||
if providers is None:
|
||||
providers = onnx_providers()
|
||||
|
||||
try:
|
||||
return ort.InferenceSession(model_path, providers=providers)
|
||||
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"])
|
||||
raise
|
||||
|
||||
@@ -99,7 +99,7 @@ def main():
|
||||
|
||||
try:
|
||||
import cv2
|
||||
import onnxruntime as ort
|
||||
import onnxruntime
|
||||
except ImportError as e:
|
||||
print(json.dumps({
|
||||
"success": False,
|
||||
@@ -110,11 +110,8 @@ def main():
|
||||
emit_progress(10, "Loading model")
|
||||
model_path = _get_model_path()
|
||||
|
||||
# Configure ONNX Runtime session
|
||||
from gpu import onnx_providers
|
||||
providers = onnx_providers()
|
||||
|
||||
session = ort.InferenceSession(model_path, providers=providers)
|
||||
from gpu import safe_onnx_session
|
||||
session = safe_onnx_session(model_path)
|
||||
|
||||
emit_progress(20, "Loading images")
|
||||
img = Image.open(input_path).convert("RGB")
|
||||
|
||||
@@ -76,7 +76,16 @@ def main():
|
||||
|
||||
emit_progress(10, "Loading model")
|
||||
|
||||
session = new_session(model, providers=onnx_providers())
|
||||
providers = onnx_providers()
|
||||
try:
|
||||
session = new_session(model, providers=providers)
|
||||
except Exception as e:
|
||||
if "CUDAExecutionProvider" in providers:
|
||||
print(f"[remove-bg] GPU session failed ({e}), falling back to CPU",
|
||||
file=sys.stderr, flush=True)
|
||||
session = new_session(model, providers=["CPUExecutionProvider"])
|
||||
else:
|
||||
raise
|
||||
|
||||
emit_progress(25, "Model loaded")
|
||||
|
||||
|
||||
@@ -152,14 +152,10 @@ def inpaint_damage(img_bgr, mask):
|
||||
Returns:
|
||||
Restored BGR image with damage inpainted.
|
||||
"""
|
||||
import onnxruntime as ort
|
||||
from gpu import safe_onnx_session
|
||||
|
||||
model_path = _get_lama_path()
|
||||
providers = ["CPUExecutionProvider"]
|
||||
if "CUDAExecutionProvider" in ort.get_available_providers():
|
||||
providers.insert(0, "CUDAExecutionProvider")
|
||||
|
||||
session = ort.InferenceSession(model_path, providers=providers)
|
||||
session = safe_onnx_session(model_path)
|
||||
|
||||
orig_h, orig_w = img_bgr.shape[:2]
|
||||
img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)
|
||||
@@ -261,7 +257,7 @@ def enhance_faces(img_bgr, fidelity=0.7):
|
||||
Tuple of (enhanced BGR image, number of faces found).
|
||||
"""
|
||||
import mediapipe as mp
|
||||
import onnxruntime as ort
|
||||
from gpu import safe_onnx_session
|
||||
|
||||
# Detect faces
|
||||
img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)
|
||||
@@ -321,11 +317,7 @@ def enhance_faces(img_bgr, fidelity=0.7):
|
||||
|
||||
# Load CodeFormer model
|
||||
model_path = _get_codeformer_path()
|
||||
providers = ["CPUExecutionProvider"]
|
||||
if "CUDAExecutionProvider" in ort.get_available_providers():
|
||||
providers.insert(0, "CUDAExecutionProvider")
|
||||
|
||||
session = ort.InferenceSession(model_path, providers=providers)
|
||||
session = safe_onnx_session(model_path)
|
||||
input_names = [inp.name for inp in session.get_inputs()]
|
||||
|
||||
result = img_bgr.copy()
|
||||
@@ -476,20 +468,12 @@ def colorize_bw(img_bgr, intensity=0.85):
|
||||
|
||||
Reuses the DDColor model that the colorize tool already downloads.
|
||||
"""
|
||||
import onnxruntime as ort
|
||||
from gpu import safe_onnx_session
|
||||
|
||||
if not os.path.exists(DDCOLOR_MODEL_PATH):
|
||||
return img_bgr, False
|
||||
|
||||
providers = ["CPUExecutionProvider"]
|
||||
try:
|
||||
from gpu import gpu_available
|
||||
if gpu_available():
|
||||
providers.insert(0, "CUDAExecutionProvider")
|
||||
except ImportError as e:
|
||||
print(f"[restore] GPU detection unavailable: {e}", file=sys.stderr, flush=True)
|
||||
|
||||
session = ort.InferenceSession(DDCOLOR_MODEL_PATH, providers=providers)
|
||||
session = safe_onnx_session(DDCOLOR_MODEL_PATH)
|
||||
input_name = session.get_inputs()[0].name
|
||||
input_shape = session.get_inputs()[0].shape
|
||||
model_size = (
|
||||
|
||||
Reference in New Issue
Block a user