feat: improve BRIA RMBG 2.0 transformers compatibility and error handling
This commit is contained in:
+1
-1
@@ -4,7 +4,7 @@ description = "Photoshop-like layered canvas editor to your ComfyUI workflow. Th
|
||||
version = "1.5.13"
|
||||
license = { text = "MIT License" }
|
||||
requires-python = ">=3.10"
|
||||
dependencies = ["torch", "torchvision", "huggingface_hub", "aiohttp", "numpy", "tqdm", "Pillow", "transformers>=4.50.3", "kornia"]
|
||||
dependencies = ["torch", "torchvision", "huggingface_hub", "aiohttp", "numpy", "tqdm", "Pillow", "transformers", "kornia"]
|
||||
|
||||
[project.urls]
|
||||
Repository = "https://github.com/Azornes/Comfyui-LayerForge"
|
||||
|
||||
@@ -22,6 +22,8 @@ from .backends.rmbg import (
|
||||
_find_existing_rmbg_model,
|
||||
_find_local_rmbg_model,
|
||||
_get_rmbg_model_loader,
|
||||
_get_rmbg_model_status_message,
|
||||
_get_rmbg_transformers_status,
|
||||
_get_rmbg_remote_model,
|
||||
_is_rmbg_model_directory,
|
||||
)
|
||||
@@ -79,6 +81,8 @@ __all__ = [
|
||||
"_get_comfy_birefnet_loader",
|
||||
"_get_rmbg_model_directory",
|
||||
"_get_rmbg_model_loader",
|
||||
"_get_rmbg_model_status_message",
|
||||
"_get_rmbg_transformers_status",
|
||||
"_get_rmbg_remote_model",
|
||||
"_is_native_birefnet_checkpoint",
|
||||
"_is_rmbg_model_directory",
|
||||
|
||||
@@ -17,6 +17,7 @@ from .backends.rmbg import (
|
||||
_find_existing_rmbg_model,
|
||||
_find_local_rmbg_model,
|
||||
_get_rmbg_model_loader,
|
||||
_get_rmbg_model_status_message,
|
||||
_get_rmbg_remote_model,
|
||||
)
|
||||
from .options import _get_birefnet_model_options
|
||||
@@ -62,7 +63,7 @@ async def check_matting_model(request):
|
||||
return _matting_status_response(
|
||||
False,
|
||||
"unsupported_rmbg",
|
||||
"BRIA RMBG 2.0 requires the 'transformers' package in the active ComfyUI environment.",
|
||||
_get_rmbg_model_status_message(),
|
||||
model_path=requested_model,
|
||||
models=model_options,
|
||||
)
|
||||
|
||||
@@ -12,15 +12,72 @@ from ..catalog import _RMBG_MODEL_CATALOG, _RMBG_REMOTE_PREFIX
|
||||
from ..paths import _get_rmbg_model_directory
|
||||
|
||||
|
||||
def _get_rmbg_transformers_status():
|
||||
"""Inspect the installed Transformers API without changing the environment."""
|
||||
try:
|
||||
import transformers
|
||||
except ModuleNotFoundError as error:
|
||||
if error.name == "transformers":
|
||||
return {
|
||||
"loader": None,
|
||||
"message": (
|
||||
"BRIA RMBG 2.0 requires the 'transformers' package in the active ComfyUI environment. "
|
||||
"Install or update it manually if you want to use this model."
|
||||
),
|
||||
}
|
||||
return {
|
||||
"loader": None,
|
||||
"message": (
|
||||
"The installed Transformers package could not be loaded for BRIA RMBG 2.0: "
|
||||
f"{error}. Check the active ComfyUI environment and update Transformers manually if needed."
|
||||
),
|
||||
}
|
||||
except Exception as error:
|
||||
return {
|
||||
"loader": None,
|
||||
"message": (
|
||||
"The installed Transformers package could not be loaded for BRIA RMBG 2.0: "
|
||||
f"{error}. Update Transformers manually if needed."
|
||||
),
|
||||
}
|
||||
|
||||
version = getattr(transformers, "__version__", "unknown")
|
||||
try:
|
||||
loader = getattr(transformers, "AutoModelForImageSegmentation", None)
|
||||
from_pretrained = getattr(loader, "from_pretrained", None)
|
||||
except Exception as error:
|
||||
return {
|
||||
"loader": None,
|
||||
"message": (
|
||||
f"Installed Transformers version {version} is not supported for BRIA RMBG 2.0: {error}. "
|
||||
"Update Transformers manually if you want to use this model."
|
||||
),
|
||||
}
|
||||
|
||||
if not callable(loader) or not callable(from_pretrained):
|
||||
return {
|
||||
"loader": None,
|
||||
"message": (
|
||||
f"Installed Transformers version {version} is not supported for BRIA RMBG 2.0. "
|
||||
"It does not provide the required AutoModelForImageSegmentation API. "
|
||||
"Update Transformers manually if you want to use this model."
|
||||
),
|
||||
}
|
||||
|
||||
return {"loader": loader, "message": None, "version": version}
|
||||
|
||||
|
||||
def _get_rmbg_model_loader():
|
||||
"""Return the Transformers loader used by BRIA RMBG 2.0, when installed."""
|
||||
try:
|
||||
from transformers import AutoModelForImageSegmentation
|
||||
status = _get_rmbg_transformers_status()
|
||||
if status["loader"] is None:
|
||||
log.debug(status["message"])
|
||||
return status["loader"]
|
||||
|
||||
return AutoModelForImageSegmentation
|
||||
except Exception as error:
|
||||
log.debug(f"BRIA RMBG 2.0 Transformers loader is unavailable: {error}")
|
||||
return None
|
||||
|
||||
def _get_rmbg_model_status_message():
|
||||
"""Return an actionable message for a missing or incompatible Transformers install."""
|
||||
return _get_rmbg_transformers_status()["message"]
|
||||
|
||||
|
||||
def _is_rmbg_model_directory(path):
|
||||
@@ -142,23 +199,29 @@ class RMBG2Model:
|
||||
|
||||
@classmethod
|
||||
def load(cls, model_directory):
|
||||
loader = _get_rmbg_model_loader()
|
||||
status = _get_rmbg_transformers_status()
|
||||
loader = status["loader"]
|
||||
if loader is None:
|
||||
raise RuntimeError(
|
||||
"BRIA RMBG 2.0 requires the 'transformers' package. "
|
||||
"Install the LayerForge requirements in the ComfyUI environment."
|
||||
)
|
||||
raise RuntimeError(status["message"])
|
||||
|
||||
cache_key = os.path.normcase(os.path.normpath(os.path.abspath(model_directory)))
|
||||
with cls._model_cache_lock:
|
||||
if cache_key not in cls._model_cache:
|
||||
device = _get_rmbg_device()
|
||||
log.info(f"Loading BRIA RMBG 2.0 from {model_directory} on {device}")
|
||||
model = loader.from_pretrained(
|
||||
model_directory,
|
||||
trust_remote_code=True,
|
||||
local_files_only=True,
|
||||
)
|
||||
try:
|
||||
model = loader.from_pretrained(
|
||||
model_directory,
|
||||
trust_remote_code=True,
|
||||
local_files_only=True,
|
||||
)
|
||||
except Exception as error:
|
||||
version = status.get("version", "unknown")
|
||||
raise RuntimeError(
|
||||
f"BRIA RMBG 2.0 could not be loaded with installed Transformers version {version}. "
|
||||
"This version may not support the model's remote code; update Transformers manually "
|
||||
f"if needed. Original error: {error}"
|
||||
) from error
|
||||
model.eval().to(device)
|
||||
cls._model_cache[cache_key] = cls(model, device)
|
||||
else:
|
||||
@@ -230,6 +293,8 @@ __all__ = [
|
||||
"_find_existing_rmbg_model",
|
||||
"_find_local_rmbg_model",
|
||||
"_get_rmbg_model_loader",
|
||||
"_get_rmbg_model_status_message",
|
||||
"_get_rmbg_transformers_status",
|
||||
"_get_rmbg_remote_model",
|
||||
"_is_rmbg_model_directory",
|
||||
]
|
||||
|
||||
@@ -16,6 +16,7 @@ from .backends.rmbg import (
|
||||
_ensure_rmbg_model,
|
||||
_find_local_rmbg_model,
|
||||
_get_rmbg_model_loader,
|
||||
_get_rmbg_model_status_message,
|
||||
_get_rmbg_remote_model,
|
||||
)
|
||||
|
||||
@@ -39,10 +40,7 @@ class BiRefNetMatting:
|
||||
|
||||
if rmbg_model or local_rmbg_path:
|
||||
if _get_rmbg_model_loader() is None:
|
||||
raise RuntimeError(
|
||||
"BRIA RMBG 2.0 requires the 'transformers' package. "
|
||||
"Install the LayerForge requirements in the active ComfyUI environment."
|
||||
)
|
||||
raise RuntimeError(_get_rmbg_model_status_message())
|
||||
model_directory = _ensure_rmbg_model(model_path)
|
||||
self.model = RMBG2Model.load(model_directory)
|
||||
self.model_path = model_directory
|
||||
|
||||
+1
-1
@@ -5,5 +5,5 @@ aiohttp
|
||||
numpy
|
||||
tqdm
|
||||
Pillow
|
||||
transformers>=4.50.3
|
||||
transformers
|
||||
kornia
|
||||
|
||||
@@ -826,6 +826,10 @@ async function createCanvasWidget(node: ComfyNode, widget: any, app: ComfyApp):
|
||||
case 'unsupported_comfyui':
|
||||
showErrorNotification(modelStatus.message, 8000);
|
||||
return;
|
||||
|
||||
case 'unsupported_rmbg':
|
||||
showErrorNotification(modelStatus.message, 8000);
|
||||
return;
|
||||
|
||||
case 'not_downloaded':
|
||||
showWarningNotification(modelStatus.message || "The selected background-removal model will be downloaded automatically.", 7000);
|
||||
|
||||
@@ -745,6 +745,21 @@ def test_rmbg_model_status_does_not_require_native_birefnet_loader(layerforge_ru
|
||||
assert status.payload["model_path"] == "remote:rmbg_2_0"
|
||||
|
||||
|
||||
def test_rmbg_reports_an_unsupported_transformers_api(layerforge_runtime, monkeypatch):
|
||||
rmbg_module = layerforge_runtime.matting_rmbg
|
||||
transformers = ModuleType("transformers")
|
||||
transformers.__version__ = "0.0-test"
|
||||
monkeypatch.setitem(sys.modules, "transformers", transformers)
|
||||
|
||||
status = rmbg_module._get_rmbg_transformers_status()
|
||||
|
||||
assert status["loader"] is None
|
||||
assert "0.0-test" in status["message"]
|
||||
assert "not supported" in status["message"]
|
||||
assert "AutoModelForImageSegmentation" in status["message"]
|
||||
assert rmbg_module._get_rmbg_model_loader() is None
|
||||
|
||||
|
||||
def test_legacy_automatic_checkpoint_is_not_migrated(layerforge_runtime, monkeypatch, tmp_path):
|
||||
birefnet_module = layerforge_runtime.matting_birefnet
|
||||
model_dir = Path(tmp_path) / "models" / "background_removal"
|
||||
|
||||
Reference in New Issue
Block a user