Compare commits

...
23 Commits
Author SHA1 Message Date
Dr.Lt.Data 50c7b71a6a fixed: removed the torch_whitelist related logic and updated the ultralytics dependency to version 8.3.162 or higher
https://github.com/ltdrdata/ComfyUI-Impact-Subpack/issues/69
2025-07-22 12:43:06 +09:00
Dr.Lt.Data 5b4e55058a fixed: ruff check 2025-07-03 12:15:47 +09:00
Dr.Lt.Data 45cb4dfe59 fixed: UltralyticsDetectorProvider - cannot find model path properly if ultralytics dir is mismatched
https://github.com/ltdrdata/ComfyUI-Impact-Subpack/issues/37
2025-07-03 12:14:03 +09:00
Dr.Lt.Data 1365a5d377 fixed: update_model_paths - proper log messages
https://github.com/ltdrdata/ComfyUI-Impact-Subpack/issues/57
2025-06-17 22:30:27 +09:00
Dr.Lt.Data 122a1fffa1 modified: requirements.txt - remove version pinning the numpy to <2 2025-05-19 05:31:20 +09:00
Dr.Lt.Data 0e2638b699 hotfix: Instead of forcibly setting weights_only to True when it is not provided, apply it as the default state. 2025-04-29 18:39:12 +09:00
Dr.Lt.Data f10e457c30 modified: move user directory from user/default/ComfyUI-Impact-Pack to /user/default/ComfyUI-Impact-Subpack 2025-04-28 12:48:36 +09:00
Dr.Lt.Data f69aab1460 update README.md 2025-04-28 12:44:50 +09:00
Dr.Lt.Data ef1053fbb9 bump version 2025-04-28 12:36:14 +09:00
Dr.Lt.Data 1a3bf8c90c Merge pull request #41 from RedsAnalysis/weights_only-workaround
changed the torch_wrapper to include weights_only =false for [getattr]
2025-04-28 12:34:52 +09:00
Reddy Arambhumi b67bdff24a removed the upward dir search to find user dir and assuming the module folder_paths always returns a user dir 2025-04-26 03:45:35 -04:00
Reddy Arambhumi 4b36344be6 Modify torch_wrapper to re-read model-whitelist.txt when a safe load fails for a model not currently cached. Allows whitelist updates without restarting ComfyUI 2025-04-24 02:02:28 -04:00
Red af3543d6cb Merge branch 'ltdrdata:main' into weights_only-workaround 2025-04-24 00:48:28 -04:00
Reddy Arambhumi 54066cb848 Prioritizes ComfyUI's to find the user directory for the whitelist file. Falls back to the previous directory search method if needed. 2025-04-24 00:44:25 -04:00
Dr.Lt.Data f5c9e24148 modified: release pinning ultralytics version
fixed: ruff check
2025-04-22 00:40:08 +09:00
Reddy Arambhumi f8a2591c65 Fix: Add secure whitelist fallback for legacy .pt model loading 2025-04-16 19:10:41 -04:00
Red eaa7d4a0b8 Merge branch 'ltdrdata:main' into weights_only-workaround 2025-04-16 17:08:52 -04:00
Dr.Lt.Data 5809fcdcb9 Merge pull request #40 from ComfyNodePRs/update-publish-yaml
Update Github Action for Publishing to Comfy Registry
2025-04-13 11:32:08 +09:00
Arambhumi Reddy 40a3ba4d41 changed the torch_wrapper to include weights_only =false for cases where [getattr] is raised in the error log 2025-04-07 13:17:22 -04:00
Dr.Lt.Data 74db20c95e update README.md 2025-01-26 18:54:15 +09:00
Dr.Lt.Data 6dfb6e1acd update DB 2025-01-26 18:50:50 +09:00
snomiao 7ba0e2760c chore(publish): update GitHub Actions workflow for node publishing
- Add permissions for issue writing
- Update action version to v1 for publish-node-action
- Add condition to run job only for 'ltdrdata' repository owner
2025-01-25 17:25:20 +00:00
Dr.Lt.Data 2074152852 fixed: specific python version doesn't support this f-string.
https://github.com/ltdrdata/ComfyUI-Impact-Pack/issues/893
2025-01-25 16:07:08 +09:00
9 changed files with 272 additions and 108 deletions
+6 -2
View File
@@ -7,15 +7,19 @@ on:
paths:
- "pyproject.toml"
permissions:
issues: write
jobs:
publish-node:
name: Publish Custom Node to registry
runs-on: ubuntu-latest
if: ${{ github.repository_owner == 'ltdrdata' }}
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Publish Custom Node
uses: Comfy-Org/publish-node-action@main
uses: Comfy-Org/publish-node-action@v1
with:
## Add your own personal access token to your Github Repository secrets and reference it here.
personal_access_token: ${{ secrets.REGISTRY_ACCESS_TOKEN }}
personal_access_token: ${{ secrets.REGISTRY_ACCESS_TOKEN }}
+13
View File
@@ -15,6 +15,19 @@ This node pack provides nodes that complement the [ComfyUI Impact Pack](https://
* civitai/[adetailer](https://civitai.com/search/models?sortBy=models_v5&query=adetailer) - You can download various types detection models....Many models are associated with NSFW content.
## Paths
* In `extra_model_paths.yaml`, you can add the following entries:
- `ultralytics_bbox` - Specifies the paths for bbox YOLO models.
- `ultralytics_segm` - Specifies the paths for segm YOLO models.
- `ultralytics` - Allows the presence of `bbox/` and `segm/` subdirectories.
## Model loading configuration related to `weights_only`
* Loading model files can involve executing code, so if malicious code is embedded in a model, it can pose a security risk. For this reason, PyTorch 2.6 and later have introduced features for safer model loading. The issue is that older model files, which were created without such safe loading (weights_only) restrictions, may occasionally fail to load properly.
* By listing the paths of models deemed safe in `<user_directory>/default/ComfyUI-Impact-Subpack/model-whitelist.txt`, those specific models will have weights_only disabled, allowing them to be loaded without restriction.
* `<user_directory>`: typically located at ComfyUI/user.
## How To Install?
### Install via ComfyUI-Manager (Recommended)
+1 -1
View File
@@ -8,7 +8,7 @@
import importlib
import logging
version_code = [1, 2, 8]
version_code = [1, 3, 5]
version_str = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '')
logging.info(f"### Loading: ComfyUI-Impact-Subpack ({version_str})")
+5 -4
View File
@@ -1,21 +1,22 @@
import os
import sys
from torchvision.datasets.utils import download_url
import logging
subpack_path = os.path.join(os.path.dirname(__file__))
comfy_path = os.environ.get('COMFYUI_PATH')
if comfy_path is None:
comfy_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
print(f"\nWARN: The `COMFYUI_PATH` environment variable is not set. Assuming `{comfy_path}` as the ComfyUI path.", file=sys.stderr)
logging.warning(f"\nWARN: The `COMFYUI_PATH` environment variable is not set. Assuming `{comfy_path}` as the ComfyUI path.")
sys.path.append(comfy_path)
model_path = os.environ.get('COMFYUI_MODEL_PATH')
if model_path is None:
model_path = os.path.abspath(os.path.join(comfy_path, 'models'))
print(f"\nWARN: The `COMFYUI_MODEL_PATH` environment variable is not set. Assuming `{model_path}` as the ComfyUI path.", file=sys.stderr)
logging.warning(f"\nWARN: The `COMFYUI_MODEL_PATH` environment variable is not set. Assuming `{model_path}` as the ComfyUI path.")
ultralytics_bbox_path = os.path.join(model_path, "ultralytics", "bbox")
ultralytics_segm_path = os.path.join(model_path, "ultralytics", "segm")
+231 -92
View File
@@ -7,6 +7,10 @@ from collections import namedtuple
from . import utils
import inspect
import logging
import os
import pickle
import folder_paths
orig_torch_load = torch.load
@@ -17,6 +21,99 @@ SEG = namedtuple("SEG",
defaults=[None])
# --- Whitelist Configuration ---
WHITELIST_DIR = None
WHITELIST_FILE_PATH = None
try:
# --- Attempting: Use ComfyUI's folder_paths (Preferred Method) ---
user_dir = folder_paths.get_user_directory()
if user_dir and os.path.isdir(user_dir):
WHITELIST_DIR = os.path.join(user_dir, "default", "ComfyUI-Impact-Subpack")
WHITELIST_FILE_PATH = os.path.join(WHITELIST_DIR, "model-whitelist.txt")
logging.info(f"[Impact Pack/Subpack] Using folder_paths to determine whitelist path: {WHITELIST_FILE_PATH}")
else:
logging.warning(f"[Impact Pack/Subpack] folder_paths.get_user_directory() returned invalid path: {user_dir}.")
# --- Ensure directory exists---
if WHITELIST_FILE_PATH: # Check if any method succeeded in setting the path
try:
# Crucially, create the DIRECTORY first
# Use the WHITELIST_DIR determined by one of the methods above
os.makedirs(WHITELIST_DIR, exist_ok=True)
logging.info(f"[Impact Pack/Subpack] Ensured whitelist directory exists: {WHITELIST_DIR}")
except OSError as e:
logging.error(f"[Impact Pack/Subpack] Failed to create whitelist directory {WHITELIST_DIR}: {e}. Whitelisting may not function.")
WHITELIST_FILE_PATH = None # Indicate failure / disable whitelisting
except Exception as e:
logging.error(f"[Impact Pack/Subpack] Unexpected error creating whitelist directory: {e}", exc_info=True)
WHITELIST_FILE_PATH = None # Indicate failure / disable whitelisting
else:
# Handle case where path determination failed via all methods
logging.error("[Impact Pack/Subpack] Whitelist path determination failed using all methods. Whitelisting disabled.")
# WHITELIST_FILE_PATH is already None
except Exception as e:
# Catch errors during the whole setup process (e.g., inspect failing)
logging.error(f"[Impact Pack/Subpack] Critical error during whitelist path setup: {e}", exc_info=True)
WHITELIST_FILE_PATH = None # Disable whitelisting on critical setup error
logging.error("[Impact Pack/Subpack] Whitelisting disabled due to critical setup error.")
def load_whitelist(filepath):
"""
Loads filenames from the whitelist file.
Attempts to create the file with instructions if it doesn't exist.
Returns a set of approved base filenames.
"""
approved_files = set()
# Check again if filepath is valid before proceeding
if filepath is None or not isinstance(filepath, str):
# Log was already done if None during setup, avoid duplicate messages
# logging.error("[Impact Pack/Subpack] Whitelist file path is invalid. Whitelisting disabled.")
return approved_files # Return empty set
try:
# Try reading the existing file
with open(filepath, 'r') as f:
for line in f:
line = line.strip()
# Store only the base filename for easier matching
if line and not line.startswith('#'):
approved_files.add(os.path.basename(line))
logging.info(f"[Impact Pack/Subpack] Loaded {len(approved_files)} model(s) from whitelist: {filepath}")
except FileNotFoundError:
# This block now runs only if the directory was created successfully but the file is missing
logging.warning(f"[Impact Pack/Subpack] Model whitelist file not found at: {filepath}. ")
logging.warning(" >> An empty whitelist file will be created.")
logging.warning(" >> To allow unsafe loading for specific trusted legacy models (e.g., older .pt),")
logging.warning(" >> add their base filenames (one per line) to this file.")
try:
# Attempt to create the file with comments since it wasn't found
# This should now succeed because os.makedirs created the directory
with open(filepath, 'w') as f:
f.write("# Add base filenames of trusted models (e.g., my_old_yolo.pt) here, one per line.\n")
f.write("# This allows loading them with `weights_only=False` if they fail safe loading\n")
f.write("# due to errors like 'restricted getattr' in newer PyTorch versions.\n")
f.write("# WARNING: Only add files you absolutely trust, as this bypasses a security feature.\n")
f.write("# Prefer using .safetensors files whenever possible.\n")
logging.info(f"[Impact Pack/Subpack] Created empty whitelist file: {filepath}")
except Exception as create_e:
# Log error if creating the file fails even after creating the directory
logging.error(f"[Impact Pack/Subpack] Failed to create empty whitelist file at {filepath}: {create_e}", exc_info=True)
except Exception as e:
logging.error(f"[Impact Pack/Subpack] Error loading model whitelist from {filepath}: {e}", exc_info=True)
return approved_files
# Now call the function using the dynamically determined (or None) path
_MODEL_WHITELIST = load_whitelist(WHITELIST_FILE_PATH)
# ---------- End of Whitelist Management ----------
class NO_BBOX_DETECTOR:
pass
@@ -42,7 +139,7 @@ def restricted_getattr(obj, name, *args):
if name != "forward":
logging.error(f"Access to potentially dangerous attribute '{obj.__module__}.{obj.__name__}.{name}' is blocked.\nIf you believe the use of this code is genuinely safe, please report it.\nhttps://github.com/ltdrdata/ComfyUI-Impact-Subpack/issues")
raise RuntimeError(f"Access to potentially dangerous attribute '{obj.__module__}.{obj.__name__}.{name}' is blocked.")
return getattr(obj, name, *args)
restricted_getattr.__module__ = 'builtins'
@@ -65,70 +162,12 @@ try:
from numpy import dtype
from numpy.dtypes import Float64DType
except:
logging.error("[Impact Subpack] installed 'numpy' is outdated. Please update 'numpy' to 1.26.4")
raise Exception("[Impact Subpack] installed 'numpy' is outdated. Please update 'numpy' to 1.26.4")
logging.error("[Impact Subpack] installed 'numpy' is outdated. Please update 'numpy>=1.26.4'")
raise Exception("[Impact Subpack] installed 'numpy' is outdated. Please update 'numpy>=1.26.4'")
torch_whitelist = []
# https://github.com/comfyanonymous/ComfyUI/issues/5516#issuecomment-2466152838
def build_torch_whitelist():
"""
For security, only a limited set of namespaces is allowed during loading.
Since the same module may be identified by different namespaces depending on the model,
some modules are additionally registered with aliases to ensure backward compatibility.
"""
global torch_whitelist
for name, obj in inspect.getmembers(modules):
if inspect.isclass(obj) and obj.__module__.startswith("ultralytics.nn.modules"):
aliasObj = type(name, (obj,), {})
aliasObj.__module__ = "ultralytics.nn.modules"
torch_whitelist.append(obj)
torch_whitelist.append(aliasObj)
for name, obj in inspect.getmembers(block_modules):
if inspect.isclass(obj) and obj.__module__.startswith("ultralytics.nn.modules"):
aliasObj = type(name, (obj,), {})
aliasObj.__module__ = "ultralytics.nn.modules.block"
torch_whitelist.append(obj)
torch_whitelist.append(aliasObj)
for name, obj in inspect.getmembers(loss_modules):
if inspect.isclass(obj) and obj.__module__.startswith("ultralytics.utils.loss"):
aliasObj = type(name, (obj,), {})
aliasObj.__module__ = "ultralytics.yolo.utils.loss"
torch_whitelist.append(obj)
torch_whitelist.append(aliasObj)
for name, obj in inspect.getmembers(torch_modules):
if inspect.isclass(obj) and obj.__module__.startswith("torch.nn.modules"):
torch_whitelist.append(obj)
aliasIterableSimpleNamespace = type("IterableSimpleNamespace", (IterableSimpleNamespace,), {})
aliasIterableSimpleNamespace.__module__ = "ultralytics.yolo.utils"
aliasTaskAlignedAssigner = type("TaskAlignedAssigner", (TaskAlignedAssigner,), {})
aliasTaskAlignedAssigner.__module__ = "ultralytics.yolo.utils.tal"
aliasYOLOv10DetectionModel = type("YOLOv10DetectionModel", (DetectionModel,), {})
aliasYOLOv10DetectionModel.__module__ = "ultralytics.nn.tasks"
aliasYOLOv10DetectionModel.__name__ = "YOLOv10DetectionModel"
aliasv10DetectLoss = type("v10DetectLoss", (loss_modules.E2EDetectLoss,), {})
aliasv10DetectLoss.__name__ = "v10DetectLoss"
aliasv10DetectLoss.__module__ = "ultralytics.utils.loss"
torch_whitelist += [DetectionModel, aliasYOLOv10DetectionModel, SegmentationModel, IterableSimpleNamespace,
aliasIterableSimpleNamespace, TaskAlignedAssigner, aliasTaskAlignedAssigner, aliasv10DetectLoss,
restricted_getattr, dill._dill._load_type, scalar, dtype, Float64DType]
build_torch_whitelist()
except Exception as e:
logging.error(e)
logging.error("\n!!!!!\n\n[ComfyUI-Impact-Subpack] If this error occurs, please check the following link:\n\thttps://github.com/ltdrdata/ComfyUI-Impact-Pack/blob/Main/troubleshooting/TROUBLESHOOTING.md\n\n!!!!!\n")
@@ -136,47 +175,147 @@ except Exception as e:
# HOTFIX: https://github.com/ltdrdata/ComfyUI-Impact-Pack/issues/754
# importing YOLO breaking original torch.load capabilities
# --- Start: REPLACE the existing torch_wrapper function ---
def torch_wrapper(*args, **kwargs):
# NOTE: A trick to support code based on `'weights_only' in torch.load.__code__.co_varnames`.
if 'weights_only' in kwargs:
weights_only = kwargs.pop('weights_only')
else:
weights_only = None
"""
Wrapper for torch.load that attempts safe loading (weights_only=True) first.
If a specific UnpicklingError related to disallowed globals (like 'getattr')
occurs, it checks a user-defined whitelist (_MODEL_WHITELIST). If the file
is whitelisted, it retries with weights_only=False. Otherwise, it blocks
the unsafe load and raises the error.
"""
# Use the globally saved original torch.load reference from the top of the file
# Check if weights_only was explicitly passed by the caller
# Explicitly declare modification of global scope is intended
global _MODEL_WHITELIST
weights_only_explicit = kwargs.get('weights_only', None) # Read value without popping yet
# Try to get the filename being loaded (usually the first arg if it's a path)
filename = None
filename_arg_source = "[unknown source]"
if args and isinstance(args[0], str):
filename = os.path.basename(args[0]) # Get just the filename part
filename_arg_source = args[0]
elif 'f' in kwargs and isinstance(kwargs['f'], str):
filename = os.path.basename(kwargs['f']) # Get just the filename part
filename_arg_source = kwargs['f']
# Note: filename might remain None if loading from a file-like object
# Check if using newer PyTorch with safe_globals attribute (indicates >= 2.6 behavior likely)
if hasattr(torch.serialization, 'safe_globals'):
if weights_only is not None:
kwargs['weights_only'] = weights_only
return orig_torch_load(*args, **kwargs) # NOTE: This code simply delegates the call to torch.load, and any errors that occur here are not the responsibility of Subpack.
# Determine the effective weights_only setting for the FIRST attempt
load_kwargs = kwargs.copy()
try:
# --- Attempt 1: Default Load ---
# Try loading with the determined weights_only setting (usually True)
logging.debug(f"[Impact Pack/Subpack] Attempting safe load (weights_only=True) for: {filename_arg_source}")
return orig_torch_load(*args, **load_kwargs)
except pickle.UnpicklingError as e:
# --- Handle Specific Load Failure ---
# Check if the error is the specific one caused by disallowed globals
# like 'getattr' AND we were attempting a safe load (weights_only=True)
# Using 'getattr' because it was the specific error reported.
is_disallowed_global_error = 'getattr' in str(e)
if is_disallowed_global_error:
# Check the whitelist
if filename and filename in _MODEL_WHITELIST:
# --- Fallback: Whitelisted Unsafe Load ---
logging.warning("##############################################################################")
logging.warning(f"[Impact Pack/Subpack] WARNING: Safe load failed for '{filename}' (Reason: {e}).")
logging.warning(f" >> FILE IS IN THE WHITELIST: {WHITELIST_FILE_PATH}")
logging.warning(" >> This model likely uses legacy Python features blocked by default for security.")
logging.warning(" >> RETRYING WITH 'weights_only=False' because it's whitelisted.")
logging.warning(" >> SECURITY RISK: Ensure you added this file to the whitelist consciously")
logging.warning(f" >> and trust its source: {filename_arg_source}")
logging.warning(" >> Prefer using .safetensors files whenever available.")
logging.warning("##############################################################################")
retry_kwargs = kwargs.copy()
retry_kwargs['weights_only'] = False
# Call the original function again, now unsafely (because whitelisted)
return orig_torch_load(*args, **retry_kwargs)
else:
# --- File not in current whitelist, try reloading ---
logging.warning(f"[Impact Pack/Subpack] File '{filename}' not found in current whitelist cache.")
whitelist_path_msg = WHITELIST_FILE_PATH if WHITELIST_FILE_PATH else "[Path not determined]"
logging.info(f"[Impact Pack/Subpack] Attempting to reload whitelist from: {whitelist_path_msg}")
try:
# Reload the whitelist from the file
_MODEL_WHITELIST = load_whitelist(WHITELIST_FILE_PATH)
logging.info(f"[Impact Pack/Subpack] Whitelist reloaded. Now contains {len(_MODEL_WHITELIST)} entries.")
# --- Re-check Whitelist After Reload ---
if filename and filename in _MODEL_WHITELIST:
logging.warning("##############################################################################")
logging.warning(f"[Impact Pack/Subpack] SUCCESS: File '{filename}' FOUND in reloaded whitelist.")
logging.warning(" >> Proceeding with whitelisted unsafe load (weights_only=False).")
logging.warning(f" >> Ensure you recently added this file to: {whitelist_path_msg}")
logging.warning(" >> SECURITY RISK: Ensure you trust its source.")
logging.warning("##############################################################################")
retry_kwargs = kwargs.copy()
retry_kwargs['weights_only'] = False
return orig_torch_load(*args, **retry_kwargs)
else:
# File still not found after reload, proceed with blocking
logging.error("[Impact Pack/Subpack] File still not found in whitelist after reload.")
# Fall through to the original blocking logic below
except Exception as reload_e:
logging.error(f"[Impact Pack/Subpack] Error occurred during whitelist reload attempt: {reload_e}", exc_info=True)
# Fall through to the original blocking logic below if reload fails
# --- Blocked: Not Whitelisted (Original Logic - runs if reload failed or file still not found) ---
logging.error("##############################################################################")
logging.error(f"[Impact Pack/Subpack] ERROR: Safe load failed for '{filename_arg_source}' (Reason: {e}).")
logging.error(" >> This model likely uses legacy Python features blocked by default for security.")
# Updated log message here:
logging.error(f" >> UNSAFE LOAD BLOCKED because the file ('{filename or 'unknown'}') is NOT in the whitelist (even after reload attempt).")
logging.error(f" >> Whitelist path: {whitelist_path_msg}")
if filename:
logging.error(" >> To allow loading this specific file (IF YOU TRUST IT), ensure its base name")
logging.error(f" >> ('{filename}') is correctly added to the whitelist file (one name per line) and saved.")
else:
logging.error(" >> Cannot determine filename to check against whitelist.")
logging.error(" >> SECURITY RISK: Only whitelist files from sources you absolutely trust.")
logging.error(" >> Prefer using .safetensors files whenever available.")
logging.error("##############################################################################")
raise e # Re-raise the original security-related error
else:
# If it's a different UnpicklingError, re-raise it. Don't attempt unsafe load.
logging.error(f"[Impact Pack/Subpack] UnpicklingError during safe load (not 'getattr' related): {e}. Re-raising.")
raise e # Re-raise other UnpicklingErrors
else:
if weights_only is not None:
kwargs['weights_only'] = weights_only
else:
logging.warning("[Impact Subpack] Your torch version is outdated, and security features cannot be applied properly.")
kwargs['weights_only'] = False
# --- Handle Older PyTorch Versions (no safe_globals) ---
# Behavior here respects the caller's explicit request or defaults to False
load_kwargs = kwargs.copy()
effective_weights_only = weights_only_explicit if weights_only_explicit is not None else False # Default False for old torch
load_kwargs['weights_only'] = effective_weights_only
return orig_torch_load(*args, **kwargs)
if not effective_weights_only:
logging.warning(f"[Impact Pack/Subpack] Older PyTorch version detected. Proceeding with potentially unsafe load (weights_only=False) for: {filename_arg_source}")
else:
logging.debug(f"[Impact Pack/Subpack] Older PyTorch version detected. Proceeding with explicit weights_only=True for: {filename_arg_source}")
# Call the original torch.load directly with the determined settings for older PyTorch
return orig_torch_load(*args, **load_kwargs)
# --- End: Replacement block for the torch_wrapper function ---
torch.load = torch_wrapper
def load_yolo(model_path: str):
# https://github.com/comfyanonymous/ComfyUI/issues/5516#issuecomment-2466152838
if hasattr(torch.serialization, 'safe_globals'):
with torch.serialization.safe_globals(torch_whitelist):
try:
return YOLO(model_path)
except ModuleNotFoundError:
# https://github.com/ultralytics/ultralytics/issues/3856
YOLO("yolov8n.pt")
return YOLO(model_path)
else:
try:
return YOLO(model_path)
except ModuleNotFoundError:
YOLO("yolov8n.pt")
return YOLO(model_path)
return YOLO(model_path)
def inference_bbox(
model,
@@ -385,4 +524,4 @@ class UltraSegmDetector:
return utils.combine_masks(segmasks)
def setAux(self, x):
pass
pass
+11 -4
View File
@@ -9,8 +9,8 @@ def update_model_paths(model_path):
utils.add_folder_path_and_extensions("ultralytics_bbox", [os.path.join(model_path, "ultralytics", "bbox")], folder_paths.supported_pt_extensions)
utils.add_folder_path_and_extensions("ultralytics_segm", [os.path.join(model_path, "ultralytics", "segm")], folder_paths.supported_pt_extensions)
utils.add_folder_path_and_extensions("ultralytics", [os.path.join(model_path, "ultralytics")], folder_paths.supported_pt_extensions)
logging.info(f'[Impact Subpack] ultralytics_bbox: {os.path.join(model_path, "ultralytics", "bbox")}')
logging.info(f'[Impact Subpack] ultralytics_segm: {os.path.join(model_path, "ultralytics", "segm")}')
logging.info(f'[Impact Subpack] ultralytics_bbox: {", ".join(folder_paths.folder_names_and_paths["ultralytics_bbox"][0])}')
logging.info(f'[Impact Subpack] ultralytics_segm: {", ".join(folder_paths.folder_names_and_paths["ultralytics_segm"][0])}')
update_model_paths(folder_paths.models_dir)
if 'download_model_base' in folder_paths.folder_names_and_paths:
@@ -32,7 +32,13 @@ class UltralyticsDetectorProvider:
model_path = folder_paths.get_full_path("ultralytics", model_name)
if model_path is None:
print(f"[Impact Subpack] model file '{model_name}' is not found in one of the following directories:")
if model_name.startswith('bbox/'):
model_path = folder_paths.get_full_path("ultralytics_bbox", model_name[5:])
elif model_name.startswith('segm/'):
model_path = folder_paths.get_full_path("ultralytics_segm", model_name[5:])
if model_path is None:
logging.error(f"[Impact Subpack] model file '{model_name}' is not found in one of the following directories:")
cands = []
cands.extend(folder_paths.get_folder_paths("ultralytics"))
@@ -41,7 +47,8 @@ class UltralyticsDetectorProvider:
elif model_name.startswith('segm/'):
cands.extend(folder_paths.get_folder_paths("ultralytics_segm"))
print(f'\t{"\n\t".join(cands)}\n')
formatted_cands = "\n\t".join(cands)
logging.error(f'\t{formatted_cands}\n')
raise ValueError(f"[Impact Subpack] model file '{model_name}' is not found.")
+1 -1
View File
@@ -133,7 +133,7 @@ def crop_ndarray2(npimg, crop_region):
return cropped
def crop_ndarray4(npimg, crop_region):
x1 = crop_region[0]
y1 = crop_region[1]
+2 -2
View File
@@ -1,9 +1,9 @@
[project]
name = "comfyui-impact-subpack"
description = "This node pack provides nodes that complement the Impact Pack, such as the UltralyticsDetectorProvider."
version = "1.2.8"
version = "1.3.5"
license = { file = "LICENSE.txt" }
dependencies = ["matplotlib", "ultralytics==8.3.40"]
dependencies = ["matplotlib", "ultralytics"]
[project.urls]
Repository = "https://github.com/ltdrdata/ComfyUI-Impact-Subpack"
+2 -2
View File
@@ -1,5 +1,5 @@
matplotlib
ultralytics==8.3.40
numpy==1.26.4
ultralytics>=8.3.162
numpy
opencv-python-headless
dill