From 11c591e5b5e28f1af1dba5caa58dab03a8b5aa99 Mon Sep 17 00:00:00 2001 From: lingh Date: Sat, 4 Jul 2026 20:57:39 +0800 Subject: [PATCH] Default the HTTP service to cross-check OFF (opt in via BGFILTER_CROSS_CHECK) The cross-model veto adds one extra large-model inference per request (measured ~35 s/image on CPU: 14.4 s -> 49.1 s), which is too slow as a service default. The service now disables it regardless of the config default; BGFILTER_CROSS_CHECK=1 re-enables it (GPU or quality-first deployments). CLI behaviour is unchanged (still on by default). Startup log and /healthz report the effective state. Co-Authored-By: Claude Fable 5 --- README.md | 5 +++++ app.py | 9 ++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8dce818..3ca2b22 100644 --- a/README.md +++ b/README.md @@ -173,6 +173,11 @@ Config comes from `BGFILTER_CONFIG` (defaults to `configs/default.yaml` when pre caps input size (default ~4MP → `413`); `BGFILTER_PRELOAD=1` loads the default models at startup. Run a single worker (`--workers 1`) — each worker loads its own copy of the models. +Unlike the CLI, the service defaults the **cross-model veto to off** — it adds one +extra large-model inference (~35 s/image on CPU, 14 s → 49 s total). Opt in with +`BGFILTER_CROSS_CHECK=1` (worth it on GPU or when hair-gap residue matters more than +latency); `/healthz` reports the effective state as `crossCheck`. + ## Quality Check The quality checker measures alpha validity and edge spill on semi-transparent edge diff --git a/app.py b/app.py index 500e8c7..9130d80 100644 --- a/app.py +++ b/app.py @@ -62,6 +62,12 @@ def _build_settings(): if device: # Covers both settings.model.device and settings.segmentation.device. settings = override_settings(settings, device=device) + # The cross-model veto adds one extra large-model inference (~35 s/image on + # CPU), so the service defaults it OFF regardless of the config default; + # opt back in with BGFILTER_CROSS_CHECK=1. Other cross_check params (model, + # thresholds) still come from the config. + cross_check = os.environ.get("BGFILTER_CROSS_CHECK", "0").strip().lower() in ("1", "true", "yes", "on") + settings = override_settings(settings, cross_check=cross_check) return settings @@ -71,9 +77,10 @@ async def lifespan(app: FastAPI): settings = _build_settings() preload = os.environ.get("BGFILTER_PRELOAD", "1").strip().lower() not in ("0", "false", "no", "") logger.info( - "starting bgfilter service: device=%s default_seg=%s preload=%s max_pixels=%d", + "starting bgfilter service: device=%s default_seg=%s cross_check=%s preload=%s max_pixels=%d", settings.model.device, settings.segmentation.backend, + settings.cross_check.enabled, preload, MAX_IMAGE_PIXELS, )