Implement BiRefNet and HAT Sharper models with background removal capabilities

- Added validation documentation for AI model tiers.
- Introduced `background.py` for background removal logic, including inference functions for alpha and foreground extraction.
- Created `onnx_birefnet.py` to handle BiRefNet model sessions and alpha inference.
- Developed tests for background models, ensuring proper dispatch and session reuse.
- Added tests for BiRefNet ONNX model to validate alpha output and error handling for invalid values.
- Implemented model export scripts for BiRefNet and HAT Sharper, ensuring proper weight compression and licensing.
- Created `deform_sampling.py` for deformable convolution operations used in BiRefNet.
- Added utility functions for compressing ONNX weights without altering graph arithmetic.
- Introduced a reference plane node for depth field adjustments in geometry processing.
This commit is contained in:
2026-09-10 20:50:44 +08:00
parent 8ae3c1d5b7
commit e8129fe495
70 changed files with 1890 additions and 1208 deletions

View File

@@ -50,10 +50,10 @@ def test_valid_model_cache_skips_all_preparation():
@pytest.mark.parametrize("valid", [True, False])
def test_pisa_export_validates_all_outputs_before_replacing(tmp_path, valid):
def test_isolated_export_validates_all_outputs_before_replacing(tmp_path, valid):
module = load_sync_models()
digest = module.hashlib.sha256(b"new").hexdigest()
models = tuple(module.ModelFile("PISA_SR", "pisa-sr", name, 3, digest) for name in ("a.onnx", "b.onnx"))
models = tuple(module.ModelFile("HAT_GAN_X4_SHARPER", "hat-gan-x4-sharper", name, 3, digest) for name in ("a.onnx", "b.onnx"))
def export(command, **kwargs):
destination = Path(command[-1])
@@ -71,7 +71,7 @@ def test_pisa_export_validates_all_outputs_before_replacing(tmp_path, valid):
module.prepare_model(models[0])
assert not models[0].destination.exists()
assert models[1].destination.read_bytes() == b"old"
assert not list(tmp_path.glob(".pisa-sr-*"))
assert not list(tmp_path.glob(".hat-gan-x4-sharper-*"))
def test_local_export_failure_cleans_temporary_output(tmp_path):
@@ -120,7 +120,7 @@ class SyncModelsTests(unittest.TestCase):
builds = self.sync.MODEL_BUILDS
self.assertEqual(
set(builds),
{"REALESRGAN_GENERAL_WDN_X4V3", "SAFMN_REAL_X4"},
{"REALESRGAN_GENERAL_WDN_X4V3"},
)
for build in builds.values():
self.assertTrue(build.source_url.startswith("https://github.com/"))