Add files via upload

This commit is contained in:
AI Lab
2025-08-27 10:07:41 -07:00
committed by GitHub
parent e973d1ef4a
commit 5c8fc7d1b3
3 changed files with 104 additions and 74 deletions
+8 -5
View File
@@ -9,11 +9,15 @@ import json
import gc
import sys
import io
import warnings
from pathlib import Path
os.environ['TRANSFORMERS_VERBOSITY'] = 'error'
os.environ['TOKENIZERS_PARALLELISM'] = 'false'
# Suppress transformers FutureWarnings for better user experience
warnings.filterwarnings("ignore", category=FutureWarning, module="transformers")
if torch.cuda.is_available():
torch.backends.cudnn.benchmark = True
if hasattr(torch.backends, 'cuda'):
@@ -45,12 +49,11 @@ class MiniCPM_Transformers_Models:
self.model_checkpoint = prompt_generator_dir / Path(model_id).name
if not self.model_checkpoint.exists():
print(f"Downloading model: {model_id}")
print(f"Downloading model: {model_id} (this may take several minutes...)")
from huggingface_hub import snapshot_download
snapshot_download(
repo_id=model_id,
local_dir=str(self.model_checkpoint),
local_dir_use_symlinks=False,
local_dir=str(self.model_checkpoint)
)
self.device = torch.device("cuda" if processing_mode == "GPU" and torch.cuda.is_available() else "cpu")
@@ -244,7 +247,7 @@ class AILab_MiniCPM_4_V(MiniCPM_Transformers_Base):
RETURN_TYPES = ("STRING",)
RETURN_NAMES = ("STRING",)
FUNCTION = "generate"
CATEGORY = "🧪AILab/MiniCPM"
CATEGORY = "🧪AILab/📝MiniCPM"
def generate(self, image=None, video=None, model=None, preset_prompt="Describe", custom_prompt="", device="Auto", memory_management="Keep in Memory", seed=-1):
try:
@@ -322,7 +325,7 @@ class AILab_MiniCPM_4_V_Advanced(MiniCPM_Transformers_Base):
RETURN_TYPES = ("STRING", "STRING")
RETURN_NAMES = ("PROMPT", "STRING")
FUNCTION = "generate"
CATEGORY = "🧪AILab/MiniCPM"
CATEGORY = "🧪AILab/📝MiniCPM"
def generate(self, image=None, video=None, model=None, preset_prompt="Describe", custom_prompt="", system_prompt="", max_new_tokens=None, temperature=None, top_p=None, top_k=None, repetition_penalty=None, video_max_num_frames=64, video_max_slice_nums=2, device="Auto", memory_management="Keep in Memory", seed=-1):
try:
+80 -44
View File
@@ -59,27 +59,56 @@ class MiniCPM_GGUF_Models:
raise ValueError("Invalid model path")
repo_path, filename = model.rsplit("/", 1)
model_path = llm_models_dir / filename
if not model_path.exists():
print(f"Downloading model: {filename}")
model_path = Path(hf_hub_download(
repo_id=repo_path,
filename=filename,
local_dir=str(llm_models_dir),
local_dir_use_symlinks=False
)).resolve()
model_config = None
model_key = None
for key, config in GGUF_MODELS.items():
if config["name"] == model:
model_config = config
model_key = key
break
if not model_config:
raise ValueError(f"Model configuration not found for: {model}")
mmproj_filename = GGUF_MODELS.get("MiniCPM-V-4 (Q4_0)", {}).get("mmproj", "openbmb/MiniCPM-V-4-gguf/mmproj-model-f16.gguf")
mmproj_local = llm_models_dir / Path(mmproj_filename).name
if "download_path" in model_config:
download_subdir = llm_models_dir / model_config["download_path"]
else:
download_subdir = llm_models_dir
download_subdir.mkdir(parents=True, exist_ok=True)
model_path = download_subdir / filename
if not model_path.exists():
print(f"Downloading GGUF model: {filename} (large file, please wait...)")
try:
model_path = Path(hf_hub_download(
repo_id=repo_path,
filename=filename,
local_dir=str(download_subdir)
)).resolve()
except Exception as e:
print(f"GGUF model download failed: {e}")
raise
mmproj_filename = model_config.get("mmproj")
if not mmproj_filename:
if "MiniCPM-V-4.5" in model_key or "4_5" in model:
mmproj_filename = "openbmb/MiniCPM-V-4_5-gguf/mmproj-model-f16.gguf"
else:
mmproj_filename = "openbmb/MiniCPM-V-4-gguf/mmproj-model-f16.gguf"
mmproj_local = download_subdir / Path(mmproj_filename).name
if not mmproj_local.exists():
print(f"Downloading mmproj: {Path(mmproj_filename).name}")
print(f"Downloading vision model: {Path(mmproj_filename).name}...")
repo_path, filename = mmproj_filename.rsplit("/", 1)
mmproj_local = Path(hf_hub_download(
repo_id=repo_path,
filename=filename,
local_dir=str(llm_models_dir),
local_dir_use_symlinks=False
)).resolve()
try:
mmproj_local = Path(hf_hub_download(
repo_id=repo_path,
filename=filename,
local_dir=str(download_subdir)
)).resolve()
except Exception as e:
print(f"Vision model download failed: {e}")
raise
n_ctx = MODEL_SETTINGS["context_window"]
n_batch = 2048
@@ -107,16 +136,37 @@ class MiniCPM_GGUF_Models:
)
except Exception as model_error:
error_msg = str(model_error).lower()
if "unknown minicpmv version" in error_msg:
raise RuntimeError(
f"MiniCPM version compatibility issue detected.\n"
f"Your llama-cpp-python version doesn't support this model.\n"
f"Try:\n"
f"1. Update llama-cpp-python: pip install --upgrade llama-cpp-python\n"
f"2. Try different llama-cpp-python version: pip install llama-cpp-python==0.2.90\n"
f"3. Or use the original MiniCPM transformers node instead\n"
f"Original error: {model_error}"
)
if "unknown minicpmv version" in error_msg or "unsupported minicpmv version" in error_msg:
# Check if this is a V4.5 model
is_v45_model = any([
"4.5" in model.lower(),
"4_5" in model.lower(),
"v4.5" in model.lower()
])
if is_v45_model:
raise RuntimeError(
f"MiniCPM-V-4.5 compatibility issue detected.\n"
f"MiniCPM-V-4.5 support was just added to llama.cpp on Aug 26, 2025 (PR #15575).\n"
f"Your llama-cpp-python 0.3.16 was compiled before this update.\n\n"
f"Solutions:\n"
f"1. 🔄 Wait for new llama-cpp-python release (recommended - should be available soon)\n"
f"2. 🔨 Compile from source: pip uninstall llama-cpp-python && pip install llama-cpp-python --force-reinstall --no-cache-dir\n"
f"3. 🎯 Use MiniCPM-V-4.5 Transformers node instead (works perfectly)\n"
f"4. 🔙 Use MiniCPM-V-4.0 GGUF models (fully supported)\n\n"
f"Background: MiniCPM-V-4.5 GGUF support requires the latest llama.cpp code.\n"
f"Original error: {model_error}"
)
else:
raise RuntimeError(
f"MiniCPM version compatibility issue detected.\n"
f"Your llama-cpp-python version doesn't support this model.\n\n"
f"Try:\n"
f"1. Update llama-cpp-python: pip install --upgrade llama-cpp-python\n"
f"2. Try different version: pip install llama-cpp-python==0.2.90\n"
f"3. Use the MiniCPM transformers node instead\n\n"
f"Original error: {model_error}"
)
else:
raise model_error
@@ -222,19 +272,6 @@ class MiniCPM_GGUF_Models:
return f"Generation error: {str(e)}"
finally:
gc.collect()
# def _clean_output(self, text: str) -> str:
# if not text:
# return text
# text = re.sub(r'^[\s\-•*]+', '', text)
# text = re.sub(r'^(?!1\.)\d+[\.\)\s\-]+', '', text)
# # text = re.sub(r'^\d+[\.\)\s\-]+', '', text)
# text = re.sub(r'^(Assistant|User|MiniCPM|AI):\s*', '', text, flags=re.IGNORECASE)
# text = re.sub(r'^[A-Z][a-z]+:\s*', '', text)
# text = text.strip()
# if not text:
# return "Unable to generate description."
# return text
def _clean_output(self, text: str) -> str:
if not text:
@@ -352,7 +389,6 @@ class MiniCPM_GGUF_Base:
frames = [ToPILImage()(v.permute([2, 0, 1])).convert("RGB") for v in frames]
return frames
class AILab_MiniCPM_4_V_GGUF(MiniCPM_GGUF_Base):
@classmethod
def INPUT_TYPES(cls):
@@ -374,7 +410,7 @@ class AILab_MiniCPM_4_V_GGUF(MiniCPM_GGUF_Base):
RETURN_TYPES = ("STRING",)
RETURN_NAMES = ("STRING",)
FUNCTION = "generate"
CATEGORY = "🧪AILab/MiniCPM"
CATEGORY = "🧪AILab/📝MiniCPM"
def generate(self, image=None, video=None, model=None, preset_prompt="Describe", custom_prompt="", device="Auto", memory_management="Keep in Memory", seed=-1):
try:
@@ -444,7 +480,7 @@ class AILab_MiniCPM_4_V_GGUF_Advanced(MiniCPM_GGUF_Base):
RETURN_TYPES = ("STRING", "STRING")
RETURN_NAMES = ("PROMPT", "STRING")
FUNCTION = "generate"
CATEGORY = "🧪AILab/MiniCPM"
CATEGORY = "🧪AILab/📝MiniCPM"
def generate(self, image=None, video=None, model=None, preset_prompt="Describe", custom_prompt="", system_prompt="", max_new_tokens=None, temperature=None, top_p=None, top_k=None, repetition_penalty=None, video_max_num_frames=64, video_max_slice_nums=2, device="Auto", memory_management="Keep in Memory", seed=-1):
try:
+16 -25
View File
@@ -20,27 +20,16 @@ try:
import llama_cpp
GGUF_AVAILABLE = True
except ImportError:
# Use Windows color codes for better visibility
print("\n" + "=" * 80)
print("\033[91mWARNING: llama-cpp-python library not found, GGUF functionality is not available\033[0m")
print("\033[93mTo use GGUF features, install additional dependencies:\033[0m")
print("\033[96mpip install llama-cpp-python\033[0m")
# Check if installation guide exists and provide link
install_guide = current_dir / "llama_cpp_install.md"
if install_guide.exists():
print("\033[93mFor detailed installation instructions with CUDA support, please see:\033[0m")
print(f"\033[96m{install_guide}\033[0m")
print("\033[92mBasic MiniCPM functionality is still available\033[0m")
print("=" * 80 + "\n")
print("\033[93m⚠️ GGUF functionality unavailable - install llama-cpp-python for GGUF support\033[0m")
print("\033[96m📖 Installation guide: https://github.com/1038lab/ComfyUI-MiniCPM/tree/main/llama_cpp_install\033[0m")
except Exception as e:
print("\n" + "=" * 80)
print(f"\033[91mError loading GGUF dependencies: {str(e)}\033[0m")
print("\033[92mBasic MiniCPM functionality is still available\033[0m")
print("=" * 80 + "\n")
print(f"\033[91m❌ GGUF loading error: {str(e)}\033[0m")
print("\033[96m📖 Installation guide: https://github.com/1038lab/ComfyUI-MiniCPM/tree/main/llama_cpp_install\033[0m")
# Process all Python files in the directory (auto-registration functionality)
loaded_modules = []
skipped_modules = []
for file in current_dir.glob('*.py'):
if file.name not in EXCLUDE_FILES:
try:
@@ -51,24 +40,26 @@ for file in current_dir.glob('*.py'):
# Skip GGUF module if llama-cpp-python is not available
if not GGUF_AVAILABLE and 'GGUF' in module_name:
print(f"\033[93mSkipping {module_name} - GGUF functionality not available\033[0m")
skipped_modules.append(module_name)
continue
spec.loader.exec_module(module)
if hasattr(module, 'NODE_CLASS_MAPPINGS'):
NODE_CLASS_MAPPINGS.update(module.NODE_CLASS_MAPPINGS)
print(f"\033[92mLoaded {module_name} nodes: {list(module.NODE_CLASS_MAPPINGS.keys())}\033[0m")
loaded_modules.append(module_name)
if hasattr(module, 'NODE_DISPLAY_NAME_MAPPINGS'):
NODE_DISPLAY_NAME_MAPPINGS.update(module.NODE_DISPLAY_NAME_MAPPINGS)
except Exception as e:
print(f"\033[91mError loading module {module_name}: {str(e)}\033[0m")
if 'GGUF' not in module_name: # Only show warning for non-GGUF modules
print(f"\033[93mWarning: Failed to load {module_name} module\033[0m")
print(f"\033[91m❌ Failed to load {module_name}: {str(e)}\033[0m")
skipped_modules.append(module_name)
print(f"\n\033[92mMiniCPM nodes loaded: {list(NODE_CLASS_MAPPINGS.keys())}\033[0m")
print(f"\033[92mTotal nodes registered: {len(NODE_CLASS_MAPPINGS)}\033[0m")
# Summary output
if loaded_modules:
print(f"\033[92m✅ MiniCPM loaded: {len(NODE_CLASS_MAPPINGS)} nodes from {len(loaded_modules)} modules\033[0m")
if skipped_modules:
print(f"\033[93m⏭️ Skipped: {', '.join(skipped_modules)}\033[0m")
__all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS']