diff --git a/DEPLOY.md b/DEPLOY.md index 6a17e6f..cb6a882 100644 --- a/DEPLOY.md +++ b/DEPLOY.md @@ -53,15 +53,34 @@ provided by the AutoDL image, python at `/root/miniconda3`. has no systemd / boot hook, so the autostart lives in `~/.bashrc` and only fires when you open an **interactive shell (SSH / JupyterLab terminal)**. -Talking to supervisord (socket at `~/bgfilter-supervisor.sock`, config at -`~/supervisord.conf`): +**Managing the service** (supervisorctl lives next to python; socket +`~/bgfilter-supervisor.sock`, supervisord config `~/supervisord.conf`): ```bash -/root/miniconda3/bin/supervisorctl -c ~/supervisord.conf status bgfilter # status -/root/miniconda3/bin/supervisorctl -c ~/supervisord.conf restart bgfilter # restart -tail -f ~/autodl-tmp/bgfilter.log # logs (default ~/autodl-tmp) +S="/root/miniconda3/bin/supervisorctl -c $HOME/supervisord.conf" +$S status bgfilter # state + uptime +$S restart bgfilter # restart (e.g. after editing configs/*.yaml) +$S stop bgfilter # stop the service (supervisord keeps running) +$S start bgfilter # start it again +$S shutdown # stop everything, incl. supervisord itself + +tail -f ~/autodl-tmp/bgfilter.log # service log (dir set by --log-dir) +tail -f ~/supervisord.log # supervisord's own log (when the service won't start) ``` +If supervisord itself is not running — fresh container restart with no shell +opened yet, or a stale-socket error — start it the same way the `~/.bashrc` +autostart does: + +```bash +rm -f ~/bgfilter-supervisor.sock ~/supervisord.pid +/root/miniconda3/bin/supervisord -c ~/supervisord.conf +``` + +Changes to `~/supervisord.conf` itself (port, log path, …) are applied by +re-running the deploy script — it regenerates the file and does +`reread + update + restart`. + > After editing `configs/*.yaml` (e.g. enabling `cross_check.reuse_as_seg`), run > the `restart bgfilter` above so the service reloads config — config is read only > at startup; there is no per-request switch for it. @@ -218,39 +237,26 @@ Override the base directory with `BGFILTER_WEIGHTS_DIR`. `models/` is gitignored ### Cross-check veto (on by default) -The pipeline runs a second, high-resolution matting model -(`ZhengPeng7/BiRefNet_HR-matting`, ~425 MB) as a "second opinion" that clears -background residue trapped between hair strands. It is **ON by default** (both CLI -and HTTP service). **You must provision this model** (Option A or B above): +The pipeline runs a second matting model (`ZhengPeng7/BiRefNet_HR-matting`, +~425 MB) as an independent "second opinion" — what it does and why is in +[README.md](README.md) → *Pipelines*. Deploy-side facts: -- ⚠️ **On an offline server (`HF_HUB_OFFLINE=1`) it must be present before the - first request** — otherwise every default request fails, since it cannot - download the model at runtime. -- Turn it off service-wide with `BGFILTER_CROSS_CHECK=0`, or override per request - with the `cross_check` form field (`true`/`false`). -- The service preloads it at startup with the rest of the warm set. -- Optional: `cross_check.reuse_as_seg: true` in the config (default **off**) makes - that same forward double as the segmentation mask on the birefnet backend — - replacing the primary seg model instead of adding to it (~20 s/image faster on - CPU, ~1 GB less VRAM; the redundant primary segmenter is then skipped at - startup). Off by default so the veto stays an independent signal. +- It is **ON by default** (CLI and HTTP service), so **provision this model** + (Option A or B above). ⚠️ On an offline server (`HF_HUB_OFFLINE=1`) it must be + present before the first request — otherwise every default request fails. +- Turn it off service-wide with `BGFILTER_CROSS_CHECK=0`, or per request with the + `cross_check` form field; the service preloads it at startup when enabled. +- `cross_check.reuse_as_seg: true` in the config (default **off**) makes that + forward double as the segmentation mask: one less model loaded, ~20 s/image + faster on CPU, ~1 GB less VRAM. Config-only — restart to change it. ### Background mode (flat vs complex) -The `/remove-background` `background_mode` form field selects the pipeline: - -- `flat` (**default**, also when omitted): the colour-keyed pipeline for a solid - flat background — unchanged behaviour. -- `complex`: non-flat / scene background. No colour key: segmentation alone drives - the trimap and the colour-keyed stages (background auto-detect, hue split, chroma - suppression, despill) are bypassed. `screen_color` is ignored; expect flat - backgrounds to stay stronger on hair-level detail. - -No extra weights: `complex` reuses the already-provisioned BiRefNet segmenter + -ViTMatte. The cross-check veto still works in `complex` (via a hue-free gate) but -**defaults off** there — pass `cross_check=on` to enable it. The response echoes the -mode used in the `X-BGFilter-Background-Mode: flat|complex` header. Full field/header -reference is in `README.md` → *HTTP service*. +`background_mode=complex` (non-flat / scene backgrounds) needs **no extra +weights** — it reuses the already-provisioned BiRefNet segmenter + ViTMatte and +bypasses the colour-keyed stages. The cross-check veto **defaults off** in +complex mode (pass `cross_check=on` to enable it). Field semantics and response +headers: [README.md](README.md) → *HTTP service*. ### Downloading behind a firewall (CN networks) @@ -434,6 +440,21 @@ curl -H "X-Genarrative-Image-Token: " \ ViTMatte + one BiRefNet@1024, chunked attention). The **default lane** is slower — the cross-check adds a second HR-matting@2048 forward. Requests are serialized by the global lock, so plan for a handful of images/min per instance. +- **Default lane, workstation CPU reference (Ryzen 9700X, native bf16, 32 GB; + cross-check on with `reuse_as_seg`, chunked attention):** + + | input | precision | warm / image | peak memory | + |---|---|---|---| + | 1024×1536 | fp32 | ~45 s | — | + | 1024×1536 | bf16 | ~33 s | — | + | 2048×2048 | bf16 | ~53 s | 11.4 GB (batch), 8.1 GB (single image) | + + Without `reuse_as_seg` add the primary BiRefNet@1024 forward (~+20 s/image). + The memory ceiling is the cross-check HR forward (fixed `input_size` 2048 + regardless of image size). Before chunked attention the same 2048² bf16 run + peaked at 25.2 GB; fully un-optimized fp32 would need an estimated 55–60 GB. + CPUs without native bf16 (e.g. Zen 2) auto-fall back to fp32 — prefer + `--no-cross-check` there if memory or latency is tight. - For throughput: use a GPU (`BGFILTER_DEVICE=cuda`, install a CUDA torch build) — roughly an order of magnitude faster — and/or run multiple instances behind a load balancer (each with `--workers 1`). diff --git a/DEPLOY_ZH.md b/DEPLOY_ZH.md index c67ce46..922ca01 100644 --- a/DEPLOY_ZH.md +++ b/DEPLOY_ZH.md @@ -45,14 +45,32 @@ python 在 `/root/miniconda3`。 - **容器重启后**服务不会自动起来——AutoDL 没有 systemd / 开机钩子,自启写在 `~/.bashrc` 里, 需要**开一个交互式 shell(SSH / JupyterLab 终端)** 才会触发拉起。 -与 supervisord 打交道(socket 在 `~/bgfilter-supervisor.sock`,配置在 `~/supervisord.conf`): +**服务管理**(supervisorctl 与 python 同目录;socket 在 `~/bgfilter-supervisor.sock`, +supervisord 配置在 `~/supervisord.conf`): ```bash -/root/miniconda3/bin/supervisorctl -c ~/supervisord.conf status bgfilter # 状态 -/root/miniconda3/bin/supervisorctl -c ~/supervisord.conf restart bgfilter # 重启 -tail -f ~/autodl-tmp/bgfilter.log # 日志(默认 ~/autodl-tmp) +S="/root/miniconda3/bin/supervisorctl -c $HOME/supervisord.conf" +$S status bgfilter # 状态 + 运行时长 +$S restart bgfilter # 重启(如改了 configs/*.yaml 之后) +$S stop bgfilter # 停服务(supervisord 本身继续跑) +$S start bgfilter # 再启动 +$S shutdown # 全部停掉,包括 supervisord 自己 + +tail -f ~/autodl-tmp/bgfilter.log # 服务日志(目录由 --log-dir 决定) +tail -f ~/supervisord.log # supervisord 自己的日志(服务起不来时看这个) ``` +若 supervisord 本身没在跑——容器刚重启还没开过 shell,或报 socket 残留错误——照 +`~/.bashrc` 自启的方式手动拉起: + +```bash +rm -f ~/bgfilter-supervisor.sock ~/supervisord.pid +/root/miniconda3/bin/supervisord -c ~/supervisord.conf +``` + +改 `~/supervisord.conf` 本身(端口、日志路径等)的方式是重跑部署脚本——它会重新生成 +该文件并做 `reread + update + restart`。 + > 改了 `configs/*.yaml`(比如开 `cross_check.reuse_as_seg`)后,用上面的 `restart bgfilter` > 让服务重新加载配置——配置只在启动时读入,没有请求级开关。 @@ -201,32 +219,22 @@ hf download ZhengPeng7/BiRefNet_HR-matting --local-dir models/BiRefNet_HR- ### cross-check 否决(默认开启) -管线会再跑一个高分辨率 matting 模型(`ZhengPeng7/BiRefNet_HR-matting`,约 425 MB) -作为"第二意见",清理发丝间残留的背景色。**CLI 和 HTTP 服务都默认开启**,因此**必须 -备好这个模型**(上面方案 A 或 B): +管线会再跑一个 matting 模型(`ZhengPeng7/BiRefNet_HR-matting`,约 425 MB)作为独立的 +"第二意见"——它做什么、为什么,见 [README_ZH.md](README_ZH.md) → *管线*。部署侧要点: -- ⚠️ **离线服务器(`HF_HUB_OFFLINE=1`)必须在第一个请求前就备好它**,否则每个默认请求都会 - 失败——运行时它无法联网下载模型。 -- 服务级关闭:`BGFILTER_CROSS_CHECK=0`;或按请求覆盖:表单字段 `cross_check`(`true`/`false`)。 -- 服务启动时会随暖机集一起预载它。 -- 可选:配置里 `cross_check.reuse_as_seg: true`(默认**关**)可让这次前向在 birefnet - 后端兼作分割掩码——**替换**而非叠加 primary 分割模型(CPU 快约 20 秒/张、GPU 省约 - 1 GB 显存;此时冗余的 primary 分割模型在启动时会被跳过)。默认关闭是为了让否决 - 保持为独立信号。 +- **CLI 和 HTTP 服务都默认开启**,因此**必须备好这个模型**(上面方案 A 或 B)。 + ⚠️ 离线服务器(`HF_HUB_OFFLINE=1`)必须在第一个请求前就备好它,否则每个默认请求都失败。 +- 服务级关闭:`BGFILTER_CROSS_CHECK=0`;按请求覆盖:表单字段 `cross_check`。 + 开启时服务启动即预载。 +- 配置里 `cross_check.reuse_as_seg: true`(默认**关**)让这次前向兼作分割掩码: + 少载一个模型、CPU 快约 20 秒/张、GPU 省约 1 GB 显存。仅配置文件可设——改动需重启。 ### 背景模式(flat vs complex) -`/remove-background` 的 `background_mode` 表单字段选择管线: - -- `flat`(**默认**,不传时也是它):纯色背景的色键管线——行为不变。 -- `complex`:非纯色/实景背景。无色键:完全由分割器驱动 trimap,色键相关阶段(背景 - 自动探测、色相劈分、chroma 抑制、despill)全部跳过。`screen_color` 被忽略;发丝 - 级细节通常弱于纯色模式。 - -不需要额外权重:`complex` 复用已部署的 BiRefNet 分割器 + ViTMatte。cross-check 否决 -在 `complex` 下仍可用(走无色相门控),但**默认关闭**——传 `cross_check=on` 才启用。 -响应头 `X-BGFilter-Background-Mode: flat|complex` 回显本次实际模式。完整的字段/响应头 -参考见 `README_ZH.md` → *HTTP 服务*。 +`background_mode=complex`(非纯色/实景背景)**不需要额外权重**——复用已部署的 +BiRefNet 分割器 + ViTMatte,跳过色键相关阶段。cross-check 否决在 complex 模式下 +**默认关闭**(传 `cross_check=on` 启用)。字段语义与响应头见 +[README_ZH.md](README_ZH.md) → *HTTP 服务*。 ### 墙内下载(国内网络) @@ -395,6 +403,20 @@ curl -H "X-Genarrative-Image-Token: " \ - CPU 吞吐:**`cpu-fast` lane** 约 **14–15 秒/张(1.5 MP)**(base ViTMatte + 一个 BiRefNet@1024,分块注意力)。**默认 lane** 更慢——cross-check 会多跑一次 HR-matting@2048 前向。请求被全局锁串行,单实例按每分钟几张估算。 +- **默认 lane,工作站 CPU 参考(Ryzen 9700X,原生 bf16,32 GB;cross-check 开且 + `reuse_as_seg` 开,分块注意力):** + + | 输入 | 精度 | warm / 每图 | 峰值内存 | + |---|---|---|---| + | 1024×1536 | fp32 | ~45 s | — | + | 1024×1536 | bf16 | ~33 s | — | + | 2048×2048 | bf16 | ~53 s | 11.4 GB(批处理)、8.1 GB(单图) | + + 不开 `reuse_as_seg` 要加上主 BiRefNet@1024 前向(每图约 +20 s)。内存上限来自 + cross-check 的 HR 前向(无论图多大都固定 `input_size` 2048)。分块注意力之前, + 同一个 2048² bf16 run 峰值 25.2 GB;完全未优化的 fp32 估计要 55–60 GB。无原生 + bf16 的 CPU(如 Zen 2)自动回落 fp32——这类机器上内存或延迟紧张时优先 + `--no-cross-check`。 - 要提吞吐:上 GPU(`BGFILTER_DEVICE=cuda`,装 CUDA 版 torch),大约快一个数量级; 和/或多实例 + 负载均衡(每个都 `--workers 1`)。 - **GPU 部署(实测,RTX 5070 Ti 16 GB,完整管线——cross-check 开,bf16):** diff --git a/README.md b/README.md index 408775e..5d1209f 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ frame — detection **fails with an error**; pass `--screen-color` explicitly in To set it yourself, give a hex prior: -```powershell +```bash ... --screen-color "#CFEFFF" ``` @@ -76,26 +76,24 @@ auto-detected colour is used directly.) ## Environment -Use the conda environment `lightML`. +Any Python 3.11–3.13 environment (venv or conda) works: -```powershell -conda activate lightML +```bash pip install -r requirements.txt +python -m bgfilter.cli --help ``` -If the shell is not activated, call the environment Python directly: - -```powershell -D:\MiniConda\envs\lightML\python.exe -m bgfilter.cli --help -``` +For a server install — CPU-wheel torch, offline weights, systemd — follow +[DEPLOY.md](DEPLOY.md) instead; it covers the same dependencies with the +production choices spelled out. ## Single Image -```powershell -D:\MiniConda\envs\lightML\python.exe -m bgfilter.cli ` - --input Samples\TestImage.png ` - --output Outputs\TestImage_rgba.png ` - --debug-dir Outputs\TestImage_debug +```bash +python -m bgfilter.cli \ + --input Samples/TestImage.png \ + --output Outputs/TestImage_rgba.png \ + --debug-dir Outputs/TestImage_debug ``` No `--config` is needed — the built-in defaults are identical to @@ -112,34 +110,19 @@ auto-detect the flat background), and `--trimap-mode`. ## Batch -```powershell -D:\MiniConda\envs\lightML\python.exe -m bgfilter.cli ` - --input-dir Samples ` - --output-dir Outputs ` - --debug-dir Outputs\debug +```bash +python -m bgfilter.cli \ + --input-dir Samples \ + --output-dir Outputs \ + --debug-dir Outputs/debug ``` -## Performance (CPU reference numbers) +## Performance -Measured on a Ryzen 9700X (Zen 5, native bf16), 32 GB RAM, with cross-check on, -**`--cross-check-as-seg` enabled** and chunked global attention on. (Reuse is -off by default on this branch; without it, add the primary BiRefNet@1024 -forward — roughly +20 s/image at these sizes.) - -| input | precision | warm / image | peak memory | -|---|---|---|---| -| 1024x1536 | fp32 | ~45 s | — | -| 1024x1536 | bf16 | ~33 s | — | -| 2048x2048 | bf16 | ~53 s | 11.4 GB (batch), 8.1 GB (single image) | - -The memory ceiling is the cross-check BiRefNet_HR forward (fixed -`input_size` 2048 regardless of the image size) — genuine live activations -of a full-resolution dense prediction net. Before chunked attention and the -mimalloc fix, the same 2048x2048 bf16 run peaked at 25.2 GB; a fully -un-optimized fp32 run would need an estimated 55-60 GB (ViTMatte's un-chunked -N^2 attention alone ~39 GB). CPUs without native bf16 (e.g. Zen 2) auto-fall -back to fp32 — on such machines prefer `--no-cross-check` if memory or -latency is tight. +Rough orders of magnitude: **~33–53 s/image** on a fast desktop CPU (bf16, +cross-check on), **~1–2 s/image** on a modern GPU. All measured numbers — CPU +lanes, GPU VRAM footprints, memory ceilings and the knobs that move them — live +in [DEPLOY.md](DEPLOY.md) §11 (*Capacity & performance*). ## Chroma-alpha debug mode @@ -147,12 +130,12 @@ latency is tight. alpha seed. Useful for fast inspection of chroma confidence, trimap, and despill. (Distinct from the chroma-only *pipeline* above, which still runs ViTMatte.) -```powershell -D:\MiniConda\envs\lightML\python.exe -m bgfilter.cli ` - --input-dir Samples ` - --output-dir Outputs\chroma ` - --debug-dir Outputs\chroma_debug ` - --matting-method chroma ` +```bash +python -m bgfilter.cli \ + --input-dir Samples \ + --output-dir Outputs/chroma \ + --debug-dir Outputs/chroma_debug \ + --matting-method chroma \ --device cpu ``` @@ -267,39 +250,36 @@ curl -sS \ http://127.0.0.1:18083/remove-background -o output.png ``` -Config comes from `BGFILTER_CONFIG` (defaults to `configs/default.yaml` when present); -`BGFILTER_DEVICE` overrides both model and segmentation device; `BGFILTER_MAX_IMAGE_PIXELS` -caps input size (default ~4MP → `413`); `BGFILTER_PRELOAD=1` loads the default models at -startup; `BGFILTER_AUTH_TOKEN` gates the endpoint (see Authentication above). +Runtime configuration (config file, device, size caps, preload, auth token, +pipelining workers) is all via `BGFILTER_*` environment variables — the full table +is [DEPLOY.md](DEPLOY.md) §6. -Like the CLI, the service runs the **cross-model veto by default** (config -default: on); its HR-matting model is preloaded with the rest of the warm set. -Set `BGFILTER_CROSS_CHECK=0` to turn it off service-wide, or use the per-request -`cross_check` form field to override either way; `/healthz` reports the default -as `crossCheck`. With `cross_check.reuse_as_seg: true` in the config (off by -default) the HR-matting forward replaces the primary seg forward instead of -adding to it, and the then-redundant primary segmenter is skipped at startup. +Like the CLI, the service runs the **cross-model veto by default**; `/healthz` +reports the effective default as `crossCheck` and the per-request `cross_check` +field overrides it either way (service-wide kill switch: `BGFILTER_CROSS_CHECK=0`). +`cross_check.reuse_as_seg` (config-only, default off — see *Pipelines* above) has +no per-request switch; changing it means editing the config and restarting. ## Quality Check The quality checker measures alpha validity and edge spill on semi-transparent edge pixels. -```powershell -D:\MiniConda\envs\lightML\python.exe -m bgfilter.quality_cli ` - Outputs\TestImage_rgba.png ` +```bash +python -m bgfilter.quality_cli \ + Outputs/TestImage_rgba.png \ --max-edge-green-excess-p95 0.30 ``` Run the bundled sample smoke check: -```powershell -D:\MiniConda\envs\lightML\python.exe scripts\smoke_samples.py ` - --samples-dir Samples ` - --output-dir Outputs\smoke_samples ` - --config configs\default.yaml ` - --device cpu ` - --fallback-to-chroma-alpha ` +```bash +python scripts/smoke_samples.py \ + --samples-dir Samples \ + --output-dir Outputs/smoke_samples \ + --config configs/default.yaml \ + --device cpu \ + --fallback-to-chroma-alpha \ --max-edge-green-excess-p95 0.30 ``` @@ -310,26 +290,9 @@ D:\MiniConda\envs\lightML\python.exe scripts\smoke_samples.py ` `anime-seg` (`skytnt/anime-seg`) is a plain ONNX download; `birefnet` (`ZhengPeng7/BiRefNet`) ships custom modelling code so it needs `trust_remote_code=True` plus `timm` / `einops` / `kornia`. -- Downloading the weights behind a firewall — the reliable combination is the - `hf-mirror.com` mirror **with the local proxy bypassed** and **Xet disabled**: - ```powershell - $env:HF_ENDPOINT = "https://hf-mirror.com" # domestic mirror - $env:NO_PROXY = "*" # bypass the proxy; the mirror is direct - $env:HF_HUB_DISABLE_XET = "1" # these repos are Xet-backed; force classic HTTP - ``` - Two gotchas this avoids: (1) mirror + an overseas proxy makes the mirror's `resolve` - bounce back to `huggingface.co`, which recent `huggingface_hub` rejects with - `FileMetadataError`; (2) with `hf-xet` installed the Xet download path fails instantly. - Once the weights are cached, run offline with `HF_HUB_OFFLINE=1 TRANSFORMERS_OFFLINE=1` - (as the service does in production). -- Bundling weights in the project — instead of the HF cache, drop each model into a - plain folder named after the repo basename under `models/`: - `models/vitmatte-base-composition-1k`, `models/BiRefNet`, `models/anime-seg`, - `models/BiRefNet_HR-matting` (cross-check second opinion, default on). The loader - prefers a matching local folder and falls back to the HF repo id / cache when absent, so - it is opt-in. Populate them with e.g. `hf download ZhengPeng7/BiRefNet --local-dir - models/BiRefNet`. Override the base directory with `BGFILTER_WEIGHTS_DIR`. `models/` is - gitignored. +- **Provisioning weights** — offline HF cache, plain `models/` folders + (`BGFILTER_WEIGHTS_DIR`), the `scripts/fetch_weights.py` one-shot downloader, + and the CN-network mirror workaround — is covered in [DEPLOY.md](DEPLOY.md) §5. - Foreground colour estimation uses pymatting's `estimate_foreground_ml` to propagate clean foreground colour into semi-transparent edges before de-spill. Set `foreground.method: unmix` to fall back to the legacy heuristic. diff --git a/README_ZH.md b/README_ZH.md index 57f2099..236ae7f 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -54,7 +54,7 @@ RGB 输入 要自己指定,给一个十六进制先验: -```powershell +```bash ... --screen-color "#CFEFFF" ``` @@ -64,26 +64,23 @@ RGB 输入 ## 环境 -使用 conda 环境 `lightML`。 +任意 Python 3.11–3.13 环境(venv 或 conda)均可: -```powershell -conda activate lightML +```bash pip install -r requirements.txt +python -m bgfilter.cli --help ``` -若未激活 shell,直接调用该环境的 Python: - -```powershell -D:\MiniConda\envs\lightML\python.exe -m bgfilter.cli --help -``` +服务器安装(CPU wheel 版 torch、离线权重、systemd)请直接按 [DEPLOY_ZH.md](DEPLOY_ZH.md) +走——同样的依赖,但把生产环境的取舍都写明了。 ## 单张图 -```powershell -D:\MiniConda\envs\lightML\python.exe -m bgfilter.cli ` - --input Samples\TestImage.png ` - --output Outputs\TestImage_rgba.png ` - --debug-dir Outputs\TestImage_debug +```bash +python -m bgfilter.cli \ + --input Samples/TestImage.png \ + --output Outputs/TestImage_rgba.png \ + --debug-dir Outputs/TestImage_debug ``` 无需 `--config`——内置默认值与 `configs/default.yaml` 完全一致。只有当你编辑了该文件 @@ -97,42 +94,30 @@ fp32;大输入还会默认对 ViTMatte 全局注意力按 query 分块——精 ## 批量 -```powershell -D:\MiniConda\envs\lightML\python.exe -m bgfilter.cli ` - --input-dir Samples ` - --output-dir Outputs ` - --debug-dir Outputs\debug +```bash +python -m bgfilter.cli \ + --input-dir Samples \ + --output-dir Outputs \ + --debug-dir Outputs/debug ``` -## 性能(CPU 参考数据) +## 性能 -在 Ryzen 9700X(Zen 5,原生 bf16)、32 GB 内存上实测,cross-check 开启、 -**`--cross-check-as-seg` 开启**、分块全局注意力开启。(本分支默认关闭复用;不开的话要 -加上主 BiRefNet@1024 前向——在这些尺寸下每图约 +20 s。) - -| 输入 | 精度 | warm / 每图 | 峰值内存 | -|---|---|---|---| -| 1024x1536 | fp32 | ~45 s | — | -| 1024x1536 | bf16 | ~33 s | — | -| 2048x2048 | bf16 | ~53 s | 11.4 GB(批处理)、8.1 GB(单图) | - -内存上限来自 cross-check 的 BiRefNet_HR 前向(无论图多大都固定 `input_size` 2048)—— -一个全分辨率密集预测网络的真实活跃激活。在分块注意力和 mimalloc 修复之前,同一个 -2048x2048 bf16 run 峰值 25.2 GB;完全未优化的 fp32 run 估计要 55-60 GB(单是 ViTMatte -未分块的 N^2 注意力就 ~39 GB)。无原生 bf16 的 CPU(如 Zen 2)会自动回落 fp32——这类 -机器上若内存或延迟紧张,优先 `--no-cross-check`。 +量级参考:快速桌面 CPU(bf16、cross-check 开)约 **33–53 s/图**,现代 GPU 约 +**1–2 s/图**。全部实测数据——CPU 各 lane、GPU 显存占用、内存上限及相关旋钮—— +见 [DEPLOY_ZH.md](DEPLOY_ZH.md) §11(容量与性能)。 ## Chroma-alpha 调试模式 `--matting-method chroma` 跳过 ViTMatte,直接用 chroma 置信度作为 alpha 种子。适合快速 检查 chroma 置信度、trimap 和 despill。(不同于上面的仅 Chroma *管线*,后者仍跑 ViTMatte。) -```powershell -D:\MiniConda\envs\lightML\python.exe -m bgfilter.cli ` - --input-dir Samples ` - --output-dir Outputs\chroma ` - --debug-dir Outputs\chroma_debug ` - --matting-method chroma ` +```bash +python -m bgfilter.cli \ + --input-dir Samples \ + --output-dir Outputs/chroma \ + --debug-dir Outputs/chroma_debug \ + --matting-method chroma \ --device cpu ``` @@ -209,9 +194,9 @@ python -m uvicorn app:app --host 127.0.0.1 --port 18083 --workers 1 | 码 | 何时 | | --- | --- | | `200` | 成功——响应体是 RGBA PNG。 | -| `400` | 输入有误:图片无法解码,`screen_color`/`seg_model`/`cross_check`/`background_mode` 非法,或自动探测失败(请传 `screen_color`)。 | +| `400` | 输入有误:图片无法解码,`file`/`image_url` 不是恰好其一,`image_url` 非法/fetch 失败,`screen_color`/`seg_model`/`cross_check`/`background_mode` 非法,或自动探测失败(请传 `screen_color`)。 | | `401` | 鉴权已开且 token 缺失或错误。 | -| `413` | 图片超过 `BGFILTER_MAX_IMAGE_PIXELS`(默认约 4 MP)。 | +| `413` | 图片超过 `BGFILTER_MAX_IMAGE_PIXELS`(默认约 4 MP),或 `image_url` 响应体超过 `BGFILTER_FETCH_MAX_BYTES`(默认约 25 MB)。 | | `500` | 推理失败。 | | `503` | 服务仍在加载模型(未就绪)。 | @@ -237,38 +222,42 @@ curl -sS \ -F "file=@scene.jpg" \ -F "background_mode=complex" \ http://127.0.0.1:18083/remove-background -o output.png + +# 用 URL 代替上传(服务端自行 fetch;image_url 与 file 二选一,不可同时给) +curl -sS \ + -F "image_url=https://example.com/input.png" \ + -F "screen_color=#CFEFFF" \ + -H "X-Genarrative-Image-Token: " \ + http://127.0.0.1:18083/remove-background -o output.png ``` -配置来自 `BGFILTER_CONFIG`(存在时默认 `configs/default.yaml`);`BGFILTER_DEVICE` 同时 -覆盖 model 和 segmentation 的 device;`BGFILTER_MAX_IMAGE_PIXELS` 限制输入尺寸 -(默认约 4MP → `413`);`BGFILTER_PRELOAD=1` 启动时预加载默认模型;`BGFILTER_AUTH_TOKEN` -控制端点鉴权(见上方"鉴权")。 +运行时配置(配置文件、device、尺寸上限、预加载、鉴权 token、流水线 worker 数)全部 +通过 `BGFILTER_*` 环境变量——完整表格见 [DEPLOY_ZH.md](DEPLOY_ZH.md) §6。 -与 CLI 一样,服务**默认开启交叉模型否决**(配置默认:on);其 HR-matting 模型随暖机集 -一起预加载。用 `BGFILTER_CROSS_CHECK=0` 全服务关闭,或用按请求的 `cross_check` 表单 -字段任意覆盖;`/healthz` 以 `crossCheck` 报告默认值。若配置里 `cross_check.reuse_as_seg: -true`(默认关闭),HR-matting 前向会替代主分割前向而非叠加,那个冗余的主分割器会在启动 -时跳过。 +与 CLI 一样,服务**默认开启交叉模型否决**;`/healthz` 以 `crossCheck` 报告生效的默认值, +按请求的 `cross_check` 表单字段可任意覆盖(全服务关闭用 `BGFILTER_CROSS_CHECK=0`)。 +`cross_check.reuse_as_seg`(仅配置文件可设,默认关——见上方"管线")没有请求级开关; +改它意味着改配置并重启服务。 ## 质量检查 质量检查器在半透明边缘像素上度量 alpha 有效性和边缘溢色。 -```powershell -D:\MiniConda\envs\lightML\python.exe -m bgfilter.quality_cli ` - Outputs\TestImage_rgba.png ` +```bash +python -m bgfilter.quality_cli \ + Outputs/TestImage_rgba.png \ --max-edge-green-excess-p95 0.30 ``` 跑内置样本冒烟检查: -```powershell -D:\MiniConda\envs\lightML\python.exe scripts\smoke_samples.py ` - --samples-dir Samples ` - --output-dir Outputs\smoke_samples ` - --config configs\default.yaml ` - --device cpu ` - --fallback-to-chroma-alpha ` +```bash +python scripts/smoke_samples.py \ + --samples-dir Samples \ + --output-dir Outputs/smoke_samples \ + --config configs/default.yaml \ + --device cpu \ + --fallback-to-chroma-alpha \ --max-edge-green-excess-p95 0.30 ``` @@ -278,22 +267,9 @@ D:\MiniConda\envs\lightML\python.exe scripts\smoke_samples.py ` - ViTMatte 和分割权重在首次使用时从 Hugging Face 加载。`anime-seg` (`skytnt/anime-seg`)是普通 ONNX 下载;`birefnet`(`ZhengPeng7/BiRefNet`)自带 自定义建模代码,故需 `trust_remote_code=True` 外加 `timm` / `einops` / `kornia`。 -- 防火墙后下载权重——可靠组合是 `hf-mirror.com` 镜像 **+ 绕过本地代理** **+ 禁用 Xet**: - ```powershell - $env:HF_ENDPOINT = "https://hf-mirror.com" # 国内镜像 - $env:NO_PROXY = "*" # 绕过代理;镜像是直连 - $env:HF_HUB_DISABLE_XET = "1" # 这些仓库是 Xet 后端;强制走经典 HTTP - ``` - 规避两个坑:(1) 镜像 + 海外代理会让镜像的 `resolve` 弹回 `huggingface.co`,新版 - `huggingface_hub` 会以 `FileMetadataError` 拒绝;(2) 装了 `hf-xet` 时 Xet 下载路径会 - 立即失败。权重缓存好后,用 `HF_HUB_OFFLINE=1 TRANSFORMERS_OFFLINE=1` 离线运行 - (生产环境即如此)。 -- 把权重打包进项目——不走 HF 缓存,而是把每个模型放进 `models/` 下、以仓库 basename - 命名的纯文件夹:`models/vitmatte-base-composition-1k`、`models/BiRefNet`、 - `models/anime-seg`、`models/BiRefNet_HR-matting`(交叉否决第二意见,默认开启)。加载器 - 优先匹配本地文件夹,缺失时回落到 HF 仓库 id / 缓存,故为可选。用例如 - `hf download ZhengPeng7/BiRefNet --local-dir models/BiRefNet` 填充。用 - `BGFILTER_WEIGHTS_DIR` 改基目录。`models/` 已被 gitignore。 +- **权重准备**——离线 HF 缓存、`models/` 纯文件夹(`BGFILTER_WEIGHTS_DIR`)、一键下载 + 脚本 `scripts/fetch_weights.py`、以及国内网络的镜像 workaround——见 + [DEPLOY_ZH.md](DEPLOY_ZH.md) §5。 - 前景颜色估计用 pymatting 的 `estimate_foreground_ml`,在 de-spill 前把干净前景色 传播进半透明边缘。设 `foreground.method: unmix` 回落到旧的启发式方法。 - `docs/green_screen_matting_workflow.md` 是最初的第一阶段绿幕规格;本 README 反映当前