-
Notifications
You must be signed in to change notification settings - Fork 5
feat(matte): 抠图 provider 加选择开关,让已合入的 BiRefNet 不再是死代码 #823
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
johnnyzhang-eng
wants to merge
4
commits into
main
Choose a base branch
from
feat/matte-provider-switch
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
4dc0fe0
feat(matte): 抠图 provider 加选择开关,让已合入的 BiRefNet 不再是死代码
johnnyzhang-eng 3f52b16
fix(matte): 给 BiRefNet 补 warmup,否则共享接线静默失效
johnnyzhang-eng fb2fe14
docs(env): .env.example 补上 WINDUP_MATTE_PROVIDER
johnnyzhang-eng 46679b9
test(env): 把 WINDUP_MATTE_PROVIDER 登记进豁免名单
johnnyzhang-eng File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
42 changes: 42 additions & 0 deletions
42
backend/packages/framework/src/windup_framework/providers/matte_factory.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| """按配置选抠图 provider。 | ||
|
|
||
| 为什么要这个开关:BiRefNet 在同一帧上把主体内部非实心从 5,541 px 降到 106 px(-98%), | ||
| 但单帧峰值 6.85GB —— 生产 worker 容器上限 5GiB、宿主总共 7.7GB,**跑不了**,而组员 | ||
| 本机 16GB 跑得很轻松。同一份代码两种装配,好过为它开一条分支:分支一定会漂,而漂出来 | ||
| 的"更好的管线"产出的素材,产品复现不出来。 | ||
|
|
||
| 默认必须是 u2net:忘配等于用得起的那个,而不是忘配就把生产打 OOM。 | ||
| """ | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| import logging | ||
| import os | ||
|
|
||
| from .interfaces import MatteProvider | ||
|
|
||
| logger = logging.getLogger("windup.matte.factory") | ||
|
|
||
| #: 环境变量名。取值 ``u2net``(默认) / ``birefnet``。 | ||
| ENV = "WINDUP_MATTE_PROVIDER" | ||
|
xiaocheny214 marked this conversation as resolved.
|
||
| _U2NET = "u2net" | ||
| _BIREFNET = "birefnet" | ||
|
|
||
|
|
||
| def make_matte_provider(name: str | None = None) -> MatteProvider: | ||
| """按名字造 provider;不认识的名字回落 u2net 并留一条 WARNING。 | ||
|
|
||
| 不认识就抛错的话,一个拼错的环境变量会让整个 worker 起不来;而回落是安全方向 —— | ||
| u2net 在任何机器上都跑得起来,坏处只是抠图差一点,且这条 WARNING 说明了原因。 | ||
| """ | ||
| choice = (name or os.environ.get(ENV) or _U2NET).strip().lower() | ||
| if choice == _BIREFNET: | ||
| from .matte_birefnet import BiRefNetMatteProvider | ||
|
|
||
| logger.info("抠图用 BiRefNet(与 u2net 取并集);单帧峰值约 6.85GB,别在小内存机器上开") | ||
| return BiRefNetMatteProvider() | ||
| if choice != _U2NET: | ||
| logger.warning("%s=%r 不认识,回落 u2net;可选:%s / %s", ENV, choice, _U2NET, _BIREFNET) | ||
| from .matte import OnnxU2NetMatteProvider | ||
|
|
||
| return OnnxU2NetMatteProvider() | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| """抠图 provider 的选择开关。 | ||
|
|
||
| 这个开关存在的理由:BiRefNet 单帧峰值 6.85GB,生产 worker 上限 5GiB —— 开错方向的代价 | ||
| 不是"抠图差一点",是把 worker 打 OOM。所以默认值与回落方向都要有用例钉住。 | ||
| """ | ||
| from __future__ import annotations | ||
|
|
||
| import pytest | ||
|
|
||
| from windup_framework.providers import make_matte_provider | ||
| from windup_framework.providers.matte import OnnxU2NetMatteProvider | ||
| from windup_framework.providers.matte_factory import ENV | ||
|
|
||
|
|
||
| def test_default_is_u2net_so_a_missing_env_cannot_oom_the_worker(monkeypatch): | ||
| """拦的坏例:默认值给成 BiRefNet。 | ||
|
|
||
| 忘配就该拿到跑得起来的那个。反过来的话,一台没设这个变量的机器会在第一帧抠图时 | ||
| 被 OOM kill,而表现是 worker 无声重启、任务卡在 RUNNING。 | ||
| """ | ||
| monkeypatch.delenv(ENV, raising=False) | ||
| assert isinstance(make_matte_provider(), OnnxU2NetMatteProvider) | ||
|
|
||
|
|
||
| def test_an_unknown_value_falls_back_instead_of_killing_the_worker(monkeypatch): | ||
| """拦的坏例:不认识的值直接抛错。 | ||
|
|
||
| 一个拼错的环境变量(``bierfnet``)会让整个 worker 起不来,而回落只是抠图差一点。 | ||
| 两个方向的代价不对称。 | ||
| """ | ||
| monkeypatch.setenv(ENV, "bierfnet") | ||
| assert isinstance(make_matte_provider(), OnnxU2NetMatteProvider) | ||
|
|
||
|
|
||
| def test_explicit_argument_beats_the_environment(monkeypatch): | ||
| """显式传参优先于环境变量 —— 否则测试与本地脚本没法覆盖部署的设置。""" | ||
| monkeypatch.setenv(ENV, "birefnet") | ||
| assert isinstance(make_matte_provider("u2net"), OnnxU2NetMatteProvider) | ||
|
|
||
|
|
||
| def test_birefnet_is_reachable_by_name_not_dead_code(monkeypatch): | ||
| """拦的坏例:provider 合进仓里却没有任何路径能选到它(#686 就是这么变成死代码的)。 | ||
|
|
||
| 只断言"造出来的是那个类",不真跑推理:权重 224MB,CI 上不该下载,而这条要证明的是 | ||
| **接线通了**,不是模型好不好。 | ||
| """ | ||
| pytest.importorskip("onnxruntime") | ||
| from windup_framework.providers.matte_birefnet import BiRefNetMatteProvider | ||
|
|
||
| monkeypatch.setenv(ENV, "birefnet") | ||
| assert isinstance(make_matte_provider(), BiRefNetMatteProvider) | ||
|
|
||
|
|
||
| def test_every_selectable_provider_survives_the_bootstrap_warmup_call(monkeypatch): | ||
| """拦的坏例:某个 provider 缺 ``warmup``,整条共享接线静默失效。 | ||
|
|
||
| ``bootstrap.worker`` 是 ``matte.warmup()`` 然后 ``bind_matte(matte)``,两句包在同一个 | ||
| ``except Exception`` 里。缺 ``warmup`` 时第一句抛 AttributeError,``bind_matte`` | ||
| **就到不了** —— 三个 executor 各自惰性 new 一份,而 BiRefNet 默认与 u2net 取并集, | ||
| 每份内部再 new 一个 u2net,进程里 6 个 ONNX 会话。生产 worker 上限 5GiB, | ||
| BiRefNet 单帧峰值 6.85GB。表面上只有一条 "ONNX 预热失败" 的 WARNING。 | ||
| (FennoAI 式审查在 #823 上指出;本用例把它钉住。) | ||
|
|
||
| 断言的是**协议齐全**,不真跑推理:权重 224MB + 176MB,CI 上不该下载。 | ||
| """ | ||
| from windup_framework.providers import make_matte_provider | ||
| from windup_framework.providers.matte_factory import ENV, _BIREFNET, _U2NET | ||
|
|
||
| for choice in (_U2NET, _BIREFNET): | ||
| monkeypatch.setenv(ENV, choice) | ||
| provider = make_matte_provider() | ||
| assert callable(getattr(provider, "warmup", None)), ( | ||
| f"{type(provider).__name__} 缺 warmup —— bind_matte 会被跳过," | ||
| "共享实例失效,进程里会装多份 ONNX 会话" | ||
| ) | ||
| assert callable(getattr(provider, "cutout", None)) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.