Skip to content

Commit 1ea6f18

Browse files
committed
Version 4.25.6
Fix ChatterBox optional perth import crashing model load on Python 3.13 Technical details: - Move perth import behind lazy watermark initialization - Prevent module load from touching fragile librosa resample path by default - Keep watermarking available only when explicitly enabled
1 parent 5185a16 commit 1ea6f18

7 files changed

Lines changed: 72 additions & 71 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [4.25.6] - 2026-04-10
9+
10+
### Fixed
11+
12+
- Fix ChatterBox model loading failure on some Python 3.13 setups
13+
- Fix ChatterBox crashing before generation when optional watermark dependency imports a fragile librosa path
14+
- Improve compatibility by loading watermark support only when it is actually used
815
## [4.25.5] - 2026-04-08
916

1017
### Added

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
[![Dynamic TOML Badge][version-shield]][version-url]
88
[![Ko-Fi](https://img.shields.io/badge/Ko--fi-F16061?style=for-the-badge&logo=ko-fi&logoColor=white)](https://ko-fi.com/diogogo)
99

10-
# TTS Audio Suite v4.25.5
10+
# TTS Audio Suite v4.25.6
1111

1212
[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/diogogo)
1313

engines/chatterbox/perth_loader.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import warnings
2+
3+
4+
def create_perth_watermarker():
5+
"""
6+
Lazily import perth only when watermarking is actually requested.
7+
8+
Watermarking is disabled by default, so Chatterbox should not fail model load
9+
just because perth drags in a fragile librosa import path on some envs.
10+
"""
11+
with warnings.catch_warnings():
12+
warnings.simplefilter("ignore")
13+
import perth
14+
15+
watermarker_cls = getattr(perth, "PerthImplicitWatermarker", None)
16+
if watermarker_cls is None:
17+
raise AttributeError("PerthImplicitWatermarker not available in perth module")
18+
19+
watermarker = watermarker_cls()
20+
if watermarker is None:
21+
raise ValueError("PerthImplicitWatermarker returned None")
22+
23+
return watermarker

engines/chatterbox/tts.py

Lines changed: 21 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,33 +4,24 @@
44

55
import torch
66
import torch.nn.functional as F
7-
from huggingface_hub import hf_hub_download
8-
import warnings
9-
10-
# Use librosa fallback for Python 3.13 compatibility
11-
from utils.audio.librosa_fallback import safe_load, safe_resample
12-
# Import safetensors for multilanguage model support
13-
from safetensors.torch import load_file
7+
from huggingface_hub import hf_hub_download
8+
import warnings
9+
10+
# Use librosa fallback for Python 3.13 compatibility
11+
from utils.audio.librosa_fallback import safe_load, safe_resample
12+
from .perth_loader import create_perth_watermarker
13+
# Import safetensors for multilanguage model support
14+
from safetensors.torch import load_file
1415

1516
# Import folder_paths for model directory detection
1617
try:
1718
import folder_paths
1819
except ImportError:
1920
folder_paths = None
2021

21-
# Import perth with warnings disabled and graceful fallback
22-
try:
23-
with warnings.catch_warnings():
24-
warnings.simplefilter("ignore")
25-
import perth
26-
PERTH_AVAILABLE = True
27-
except ImportError:
28-
perth = None
29-
PERTH_AVAILABLE = False
30-
31-
from .models.t3 import T3
32-
from .models.s3tokenizer import S3_SR, drop_invalid_tokens
33-
from .models.s3gen import S3GEN_SR, S3Gen
22+
from .models.t3 import T3
23+
from .models.s3tokenizer import S3_SR, drop_invalid_tokens
24+
from .models.s3gen import S3GEN_SR, S3Gen
3425
from .models.tokenizers import EnTokenizer
3526
from .models.voice_encoder import VoiceEncoder
3627
from .models.t3.modules.cond_enc import T3Cond
@@ -197,20 +188,16 @@ def to(self, device):
197188

198189
return self
199190

200-
def _init_watermarker_if_needed(self):
201-
"""Initialize watermarker on first use if enabled"""
202-
if self.enable_watermarking and not self._watermarker_init_attempted:
203-
self._watermarker_init_attempted = True
204-
try:
205-
with warnings.catch_warnings():
206-
warnings.simplefilter("ignore")
207-
self.watermarker = perth.PerthImplicitWatermarker()
208-
if self.watermarker is None:
209-
raise ValueError("PerthImplicitWatermarker returned None")
210-
except Exception as e:
211-
print(f"❌ Failed to initialize watermarker: {e}")
212-
self.watermarker = None
213-
self.enable_watermarking = False
191+
def _init_watermarker_if_needed(self):
192+
"""Initialize watermarker on first use if enabled"""
193+
if self.enable_watermarking and not self._watermarker_init_attempted:
194+
self._watermarker_init_attempted = True
195+
try:
196+
self.watermarker = create_perth_watermarker()
197+
except Exception as e:
198+
print(f"❌ Failed to initialize watermarker: {e}")
199+
self.watermarker = None
200+
self.enable_watermarking = False
214201

215202
@classmethod
216203
def from_local(cls, ckpt_dir, device, language=None) -> 'ChatterboxTTS':

engines/chatterbox/vc.py

Lines changed: 18 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,21 @@
22
import os
33

44
import torch
5-
import warnings
6-
from huggingface_hub import hf_hub_download
7-
8-
# Use librosa fallback for Python 3.13 compatibility
9-
from utils.audio.librosa_fallback import safe_load
5+
import warnings
6+
from huggingface_hub import hf_hub_download
7+
8+
# Use librosa fallback for Python 3.13 compatibility
9+
from utils.audio.librosa_fallback import safe_load
10+
from .perth_loader import create_perth_watermarker
1011

1112
# Import folder_paths for model directory detection
1213
try:
1314
import folder_paths
1415
except ImportError:
1516
folder_paths = None
1617

17-
# Import perth with warnings disabled and graceful fallback
18-
try:
19-
with warnings.catch_warnings():
20-
warnings.simplefilter("ignore")
21-
import perth
22-
PERTH_AVAILABLE = True
23-
except ImportError:
24-
perth = None
25-
PERTH_AVAILABLE = False
26-
27-
# Import safetensors for multilanguage model support
28-
from safetensors.torch import load_file
18+
# Import safetensors for multilanguage model support
19+
from safetensors.torch import load_file
2920

3021
from .models.s3tokenizer import S3_SR
3122
from .models.s3gen import S3GEN_SR, S3Gen
@@ -82,23 +73,16 @@ def to(self, device):
8273

8374
return self
8475

85-
def _init_watermarker_if_needed(self):
86-
"""Initialize watermarker on first use if enabled"""
87-
if self.enable_watermarking and not self._watermarker_init_attempted:
88-
self._watermarker_init_attempted = True
89-
try:
90-
if PERTH_AVAILABLE and hasattr(perth, 'PerthImplicitWatermarker'):
91-
with warnings.catch_warnings():
92-
warnings.simplefilter("ignore")
93-
self.watermarker = perth.PerthImplicitWatermarker()
94-
if self.watermarker is None:
95-
raise ValueError("PerthImplicitWatermarker returned None")
96-
else:
97-
raise AttributeError("PerthImplicitWatermarker not available in perth module")
98-
except Exception as e:
99-
print(f"❌ Failed to initialize watermarker: {e}")
100-
self.watermarker = None
101-
self.enable_watermarking = False
76+
def _init_watermarker_if_needed(self):
77+
"""Initialize watermarker on first use if enabled"""
78+
if self.enable_watermarking and not self._watermarker_init_attempted:
79+
self._watermarker_init_attempted = True
80+
try:
81+
self.watermarker = create_perth_watermarker()
82+
except Exception as e:
83+
print(f"❌ Failed to initialize watermarker: {e}")
84+
self.watermarker = None
85+
self.enable_watermarking = False
10286

10387
@classmethod
10488
def from_local(cls, ckpt_dir, device) -> 'ChatterboxVC':

nodes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
pass
1212

1313
# Version and constants
14-
VERSION = "4.25.5"
14+
VERSION = "4.25.6"
1515
IS_DEV = False # Set to False for release builds
1616
VERSION_DISPLAY = f"v{VERSION}" + (" (dev)" if IS_DEV else "")
1717
SEPARATOR = "=" * 70

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[project]
22
name = "tts_audio_suite"
33
description = "TTS Audio Suite - Universal multi-engine TTS extension for ComfyUI with unified architecture supporting IndexTTS-2, ChatterBox, Chatterbox Multilingual TTS (Official 23-Lang), F5-TTS, Higgs Audio 2, VibeVoice, and RVC engines. It has character voice management, SRT subtitle TTS support, and audio processing capabilities."
4-
version = "4.25.5"
4+
version = "4.25.6"
55
license = {file = "LICENSE"}
66

77
[project.urls]

0 commit comments

Comments
 (0)