feat: GPU acceleration support for ONNX Runtime inference

Centralize execution provider selection in providers.py with
auto-detection and graceful fallback. All ONNX sessions (embedder,
detector, face processor, recognizer) now use the configured providers.

- New VISION_EXECUTION_PROVIDERS env var: "auto" for GPU auto-detect,
  or explicit "CUDAExecutionProvider,CPUExecutionProvider"
- Provider priority: CUDA > ROCm > OpenVINO > CPU (when set to "auto")
- docker-compose.yml includes commented-out NVIDIA GPU deploy section
- Supports onnxruntime-gpu as a drop-in replacement for onnxruntime

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-12 22:12:21 +02:00
parent 94c07b1d0d
commit bbb8e4850c
7 changed files with 138 additions and 20 deletions

View File

@@ -67,15 +67,15 @@ class OpenCLIPEmbedder(Embedder):
visual_path = model_dir / "visual.onnx"
textual_path = model_dir / "textual.onnx"
opts = ort.SessionOptions()
opts.inter_op_num_threads = 2
opts.intra_op_num_threads = 2
from app.services.vision.providers import create_session
from app.config import settings as app_settings
providers = app_settings.vision.execution_providers
logger.info("Loading OpenCLIP visual encoder from %s", visual_path)
self._visual = ort.InferenceSession(str(visual_path), opts, providers=["CPUExecutionProvider"])
self._visual = create_session(str(visual_path), configured_providers=providers)
logger.info("Loading OpenCLIP textual encoder from %s", textual_path)
self._textual = ort.InferenceSession(str(textual_path), opts, providers=["CPUExecutionProvider"])
self._textual = create_session(str(textual_path), configured_providers=providers)
def embed_image(self, image: np.ndarray) -> np.ndarray:
inp = _preprocess_image(image, _OPENCLIP_SIZE, _OPENCLIP_MEAN, _OPENCLIP_STD)
@@ -110,15 +110,15 @@ class SigLIP2Embedder(Embedder):
visual_path = model_dir / "visual.onnx"
textual_path = model_dir / "textual.onnx"
opts = ort.SessionOptions()
opts.inter_op_num_threads = 2
opts.intra_op_num_threads = 2
from app.services.vision.providers import create_session
from app.config import settings as app_settings
providers = app_settings.vision.execution_providers
logger.info("Loading SigLIP2 visual encoder from %s", visual_path)
self._visual = ort.InferenceSession(str(visual_path), opts, providers=["CPUExecutionProvider"])
self._visual = create_session(str(visual_path), configured_providers=providers)
logger.info("Loading SigLIP2 textual encoder from %s", textual_path)
self._textual = ort.InferenceSession(str(textual_path), opts, providers=["CPUExecutionProvider"])
self._textual = create_session(str(textual_path), configured_providers=providers)
def embed_image(self, image: np.ndarray) -> np.ndarray:
inp = _preprocess_image(image, _SIGLIP2_SIZE, _SIGLIP2_MEAN, _SIGLIP2_STD)