From 1d32170c2edb13c890a178b6309a4666e6aa4d4e Mon Sep 17 00:00:00 2001 From: James Pine Date: Fri, 13 Mar 2026 04:15:20 -0700 Subject: [PATCH] fix: cast librosa float64 audio to float32 for Chatterbox voice encoder The upstream VoiceEncoder's melspectrogram only casts to float32 when hp.normalized_mels is True (it defaults to False), so librosa's float64 output flows through as double tensors into float32 model weights, causing 'expected m1 and m2 to have the same dtype, but got: float != double'. Fix by monkey-patching prepare_conditionals in both Chatterbox and Chatterbox Turbo backends to ensure librosa.load returns float32. --- backend/backends/chatterbox_backend.py | 24 ++++++++++++++++++++ backend/backends/chatterbox_turbo_backend.py | 24 ++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/backend/backends/chatterbox_backend.py b/backend/backends/chatterbox_backend.py index 88f87d4e..8d716df7 100644 --- a/backend/backends/chatterbox_backend.py +++ b/backend/backends/chatterbox_backend.py @@ -178,6 +178,30 @@ class ChatterboxTTSBackend: progress_manager.mark_complete(model_name) task_manager.complete_download(model_name) + # Monkey-patch prepare_conditionals to cast librosa's float64 + # audio to float32 before it reaches the voice encoder. The + # upstream VoiceEncoder's melspectrogram only casts to float32 + # when hp.normalized_mels is True (it defaults to False), so + # float64 mels hit float32 model weights → dtype mismatch. + _orig_prepare = self.model.prepare_conditionals + + def _f32_prepare(wav_fpath, **kwargs): + import librosa as _librosa + + _orig_librosa_load = _librosa.load + + def _load_f32(*a, **kw): + wav, sr = _orig_librosa_load(*a, **kw) + return wav.astype(np.float32), sr + + _librosa.load = _load_f32 + try: + return _orig_prepare(wav_fpath, **kwargs) + finally: + _librosa.load = _orig_librosa_load + + self.model.prepare_conditionals = _f32_prepare + logger.info("Chatterbox Multilingual TTS loaded successfully") except ImportError as e: diff --git a/backend/backends/chatterbox_turbo_backend.py b/backend/backends/chatterbox_turbo_backend.py index 16bb5d70..44606cf3 100644 --- a/backend/backends/chatterbox_turbo_backend.py +++ b/backend/backends/chatterbox_turbo_backend.py @@ -178,6 +178,30 @@ class ChatterboxTurboTTSBackend: progress_manager.mark_complete(model_name) task_manager.complete_download(model_name) + # Monkey-patch prepare_conditionals to cast librosa's float64 + # audio to float32 before it reaches the voice encoder. The + # upstream VoiceEncoder's melspectrogram only casts to float32 + # when hp.normalized_mels is True (it defaults to False), so + # float64 mels hit float32 model weights → dtype mismatch. + _orig_prepare = self.model.prepare_conditionals + + def _f32_prepare(wav_fpath, **kwargs): + import librosa as _librosa + + _orig_librosa_load = _librosa.load + + def _load_f32(*a, **kw): + wav, sr = _orig_librosa_load(*a, **kw) + return wav.astype(np.float32), sr + + _librosa.load = _load_f32 + try: + return _orig_prepare(wav_fpath, **kwargs) + finally: + _librosa.load = _orig_librosa_load + + self.model.prepare_conditionals = _f32_prepare + logger.info("Chatterbox Turbo TTS loaded successfully") except ImportError as e: