127 lines
4.7 KiB
Python
127 lines
4.7 KiB
Python
"""
|
|
ComfyUI custom node install script — run automatically by ComfyUI Manager
|
|
on node install/update, and can also be run manually:
|
|
|
|
python install.py
|
|
|
|
Installs optional heavy dependencies that can't go in requirements.txt
|
|
without breaking other packages:
|
|
- VibeVoice TTS (from FushionHub/VibeVoice fork, --no-deps to prevent downgrades)
|
|
"""
|
|
|
|
import sys
|
|
import subprocess
|
|
import importlib.util
|
|
|
|
|
|
def _pkg_installed(name: str) -> bool:
|
|
return importlib.util.find_spec(name) is not None
|
|
|
|
|
|
def _pip(*args, ignore_errors=False) -> bool:
|
|
cmd = [sys.executable, "-m", "pip", *args]
|
|
print(f"[install] Running: {' '.join(cmd)}")
|
|
result = subprocess.run(cmd, capture_output=False)
|
|
ok = result.returncode == 0
|
|
if not ok and not ignore_errors:
|
|
print(f"[install] WARNING: command failed (exit {result.returncode})")
|
|
return ok
|
|
|
|
|
|
def install_vibevoice():
|
|
print("\n[install] === VibeVoice TTS ===")
|
|
|
|
if _pkg_installed("vibevoice"):
|
|
print("[install] vibevoice already installed — skipping.")
|
|
return
|
|
|
|
# ── Pre-install safe dependencies first (without --no-deps) ──────────
|
|
# These are vibevoice's deps that are safe to install normally.
|
|
# We do this before --no-deps so they land at a compatible version.
|
|
safe_deps = [
|
|
"av", # PyAV — audio/video I/O (may fail on some platforms, that's ok)
|
|
"aiortc", # WebRTC support
|
|
"pyee", # Event emitter
|
|
"dnspython", # DNS toolkit
|
|
"ifaddr", # Network interface addresses
|
|
"pylibsrtp", # SRTP
|
|
"pyopenssl", # OpenSSL bindings
|
|
]
|
|
for dep in safe_deps:
|
|
pkg = dep.split("[")[0].replace("-", "_") # normalise for find_spec
|
|
if _pkg_installed(pkg):
|
|
print(f"[install] {dep}: already installed")
|
|
continue
|
|
print(f"[install] Installing {dep}...")
|
|
_pip("install", dep, ignore_errors=True)
|
|
|
|
# ── Install vibevoice itself with --no-deps ────────────────────────────
|
|
# We use --no-deps to avoid downgrading transformers or other packages
|
|
# that are already installed at a version other projects depend on.
|
|
# The FushionHub fork is a maintained mirror of the original Microsoft
|
|
# repo (which was taken down). It has an identical API.
|
|
print("[install] Installing vibevoice (--no-deps to prevent downgrades)...")
|
|
ok = _pip(
|
|
"install",
|
|
"git+https://github.com/FushionHub/VibeVoice.git",
|
|
"--no-deps",
|
|
ignore_errors=True,
|
|
)
|
|
if ok:
|
|
print("[install] vibevoice installed successfully.")
|
|
else:
|
|
print("[install] WARNING: vibevoice install failed.")
|
|
print("[install] VibeVoice TTS will not be available.")
|
|
print("[install] To install manually:")
|
|
print("[install] pip install git+https://github.com/FushionHub/VibeVoice.git --no-deps")
|
|
print("[install] Also install its deps manually if needed:")
|
|
print("[install] pip install av aiortc pyee dnspython ifaddr pylibsrtp pyopenssl")
|
|
|
|
|
|
def install_vv_deps():
|
|
"""Install isolated transformers 4.51.3 + friends into vv_deps/ for subprocess."""
|
|
import os
|
|
deps_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "vv_deps")
|
|
marker = os.path.join(deps_dir, ".installed")
|
|
if os.path.exists(marker):
|
|
print("[install] vv_deps already installed — skipping.")
|
|
return
|
|
|
|
print("\n[install] === VibeVoice Subprocess Dependencies (vv_deps/) ===")
|
|
os.makedirs(deps_dir, exist_ok=True)
|
|
|
|
# VibeVoice requires transformers 4.51.3, but ComfyUI ships transformers 5.x.
|
|
# We install the old versions into an isolated directory so the subprocess can
|
|
# use them without conflicting with the main process.
|
|
packages = [
|
|
"transformers==4.51.3",
|
|
"accelerate==1.6.0",
|
|
"tokenizers==0.21.0", # transformers 4.51.3 requires tokenizers<0.22
|
|
"huggingface-hub==0.30.2", # transformers 4.51.3 requires huggingface-hub<1.0
|
|
]
|
|
|
|
ok = True
|
|
for pkg in packages:
|
|
print(f"[install] Installing {pkg} into vv_deps/...")
|
|
if not _pip("install", "--target", deps_dir, pkg, "--no-deps", ignore_errors=True):
|
|
ok = False
|
|
|
|
if ok:
|
|
with open(marker, "w") as f:
|
|
f.write(" ".join(packages))
|
|
print("[install] vv_deps installed successfully.")
|
|
else:
|
|
print("[install] WARNING: Some vv_deps packages failed to install.")
|
|
print("[install] VibeVoice TTS subprocess may not work correctly.")
|
|
|
|
|
|
def main():
|
|
print("[install] comfyui-llm-tools — running install script")
|
|
install_vibevoice()
|
|
install_vv_deps()
|
|
print("[install] Done.")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|