Make the pipelining knobs config-file settable (server: section)
CPU_WORKERS / GPU_CONCURRENCY were env-only. Add a `server:` config section (server.cpu_workers, server.gpu_concurrency) so a lane's concurrency lives in its yaml alongside device/precision, matching how model.device already works. Precedence mirrors BGFILTER_DEVICE: config is the default, the env var overrides per box. The pool + admission semaphore now build in lifespan (after the config loads) instead of at import, and PipelineManager reads gpu_concurrency from the settings. configs/gpu.yaml ships 8 / 2 (its target is the 32 GB GPU boxes) with an inline VRAM caveat: gpu_concurrency>1 must fit weights + N × forward, so keep it 1 on ≤16 GB cards. Verified on a 4080 SUPER: startup logs cpu_workers=8 gpu_concurrency=2 from gpu.yaml with no env set, request returns a valid RGBA. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+4
-1
@@ -13,6 +13,7 @@ from .settings import (
|
||||
ModelSettings,
|
||||
PipelineSettings,
|
||||
SegmentationSettings,
|
||||
ServerSettings,
|
||||
TrimapSettings,
|
||||
)
|
||||
|
||||
@@ -49,7 +50,7 @@ def _update_dataclass(instance: T, values: dict[str, Any] | None) -> T:
|
||||
def settings_from_dict(data: dict[str, Any]) -> PipelineSettings:
|
||||
data = dict(data)
|
||||
screen_color = data.pop("screen_color", None)
|
||||
allowed_sections = {"chroma", "trimap", "alpha_post", "cross_check", "foreground", "despill", "model", "segmentation"}
|
||||
allowed_sections = {"chroma", "trimap", "alpha_post", "cross_check", "foreground", "despill", "model", "segmentation", "server"}
|
||||
unknown_sections = sorted(set(data) - allowed_sections)
|
||||
if unknown_sections:
|
||||
raise ValueError(f"Unknown config section(s): {', '.join(unknown_sections)}")
|
||||
@@ -63,6 +64,7 @@ def settings_from_dict(data: dict[str, Any]) -> PipelineSettings:
|
||||
despill=_update_dataclass(DespillSettings(), data.get("despill")),
|
||||
model=_update_dataclass(ModelSettings(), data.get("model")),
|
||||
segmentation=_update_dataclass(SegmentationSettings(), data.get("segmentation")),
|
||||
server=_update_dataclass(ServerSettings(), data.get("server")),
|
||||
screen_color=screen_color,
|
||||
)
|
||||
|
||||
@@ -141,5 +143,6 @@ def override_settings(settings: PipelineSettings, **overrides: Any) -> PipelineS
|
||||
despill=_update_dataclass(despill, despill_updates),
|
||||
model=_update_dataclass(model, model_updates),
|
||||
segmentation=_update_dataclass(segmentation, seg_updates),
|
||||
server=settings.server,
|
||||
screen_color=screen_color,
|
||||
)
|
||||
|
||||
+3
-2
@@ -43,8 +43,9 @@ class PipelineManager:
|
||||
# pipeline this manager builds. =1 (default) makes the device strictly
|
||||
# single-stream; >1 lets that many forwards overlap so batch-1 kernels that
|
||||
# underfill the SMs can co-schedule (higher GPU-bound throughput, but the
|
||||
# concurrent activations multiply GPU memory). Uncontended when CPU_WORKERS=1.
|
||||
gpu_conc = max(1, int(os.environ.get("BGFILTER_GPU_CONCURRENCY", "1")))
|
||||
# concurrent activations multiply GPU memory). Config value
|
||||
# (``server.gpu_concurrency``) is the default; the env var overrides it.
|
||||
gpu_conc = max(1, int(os.environ.get("BGFILTER_GPU_CONCURRENCY", base_settings.server.gpu_concurrency)))
|
||||
self._gpu_lock = threading.Lock() if gpu_conc == 1 else threading.BoundedSemaphore(gpu_conc)
|
||||
if preload:
|
||||
if base_settings.model.matting_method == "vitmatte":
|
||||
|
||||
@@ -196,6 +196,22 @@ class SegmentationSettings:
|
||||
precision: str = "fp32"
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ServerSettings:
|
||||
"""HTTP-service request concurrency (ignored by the CLI).
|
||||
|
||||
``cpu_workers`` is the thread-pool size for request pipelining: >1 lets that
|
||||
many requests run concurrently, overlapping their CPU stages while the GPU
|
||||
forwards stay serialized. ``gpu_concurrency`` caps how many forwards may
|
||||
co-schedule on the device at once (>1 fills the SMs that batch-1 underuses,
|
||||
but multiplies GPU activation memory -- size it to the VRAM). Both env vars
|
||||
``BGFILTER_CPU_WORKERS`` / ``BGFILTER_GPU_CONCURRENCY`` override these.
|
||||
"""
|
||||
|
||||
cpu_workers: int = 1
|
||||
gpu_concurrency: int = 1
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class PipelineSettings:
|
||||
chroma: ChromaSettings = ChromaSettings()
|
||||
@@ -206,6 +222,7 @@ class PipelineSettings:
|
||||
despill: DespillSettings = DespillSettings()
|
||||
model: ModelSettings = ModelSettings()
|
||||
segmentation: SegmentationSettings = SegmentationSettings()
|
||||
server: ServerSettings = ServerSettings()
|
||||
# Background-colour prior. None = auto-detect the flat background colour from the
|
||||
# image border (raises if there is no clean flat background). A hex string like
|
||||
# "#CFEFFF" sets it explicitly.
|
||||
|
||||
Reference in New Issue
Block a user