Fix Seed-VC integration: use SeedVCWrapper instead of non-existent load_model

- Replace broken import from inference import load_model with SeedVCWrapper
- SeedVCWrapper properly loads all models (DiT, Whisper, BigVGAN, CAMPPlus, RMVPE)
- Add support for F0 conditioning and voice conversion parameters
- Implement proper voice conversion using wrapper.convert_voice()
- Keep fallback to passthrough mode if wrapper fails to load

Fixes: Could not import Seed-VC modules: cannot import name 'load_model' from 'inference'
This commit is contained in:
Azimkin
2026-04-08 13:52:05 +02:00
parent 69cb910eb9
commit 7ecb9941e9

View File

@@ -17,7 +17,7 @@ class SeedVCService:
def __init__(self, model_name: str = "seed-uvit-whisper-small-wavenet", repo_path: str = "./Seed-VC"):
self.model_name = model_name
self.repo_path = repo_path
self.model = None
self.wrapper = None
self.device = None
self.initialized = False
@@ -49,29 +49,34 @@ class SeedVCService:
self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
logger.info(f"Using device: {self.device}")
# Import Seed-VC modules
# Import Seed-VC wrapper
try:
from inference import load_model, inference
self.inference_fn = inference
self.model = load_model(self.model_name, self.device)
logger.info(f"Model {self.model_name} loaded successfully")
from seed_vc_wrapper import SeedVCWrapper
self.wrapper = SeedVCWrapper(device=self.device)
logger.info("Seed-VC wrapper loaded successfully")
except ImportError as e:
logger.warning(f"Could not import Seed-VC modules: {e}")
logger.warning(f"Could not import SeedVCWrapper: {e}")
logger.warning("Voice conversion will use passthrough mode")
self.model = None
self.wrapper = None
self.initialized = True
except Exception as e:
logger.error(f"Failed to initialize Seed-VC: {e}")
self.initialized = True # Mark as initialized to avoid retry
self.model = None
self.wrapper = None
def convert_voice(
self,
source_audio_path: str,
reference_audio_path: str,
output_path: str
output_path: str,
diffusion_steps: int = 10,
length_adjust: float = 1.0,
inference_cfg_rate: float = 0.7,
f0_condition: bool = False,
auto_f0_adjust: bool = True,
pitch_shift: int = 0
) -> str:
"""
Convert voice from source to match reference voice.
@@ -80,6 +85,12 @@ class SeedVCService:
source_audio_path: Path to source audio (TTS output)
reference_audio_path: Path to reference voice audio
output_path: Path to save converted audio
diffusion_steps: Number of diffusion steps (default: 10)
length_adjust: Length adjustment factor (default: 1.0)
inference_cfg_rate: Inference CFG rate (default: 0.7)
f0_condition: Whether to use F0 conditioning (default: False)
auto_f0_adjust: Whether to automatically adjust F0 (default: True)
pitch_shift: Pitch shift in semitones (default: 0)
Returns:
Path to converted audio file
@@ -89,32 +100,39 @@ class SeedVCService:
logger.info(f"Converting voice: {source_audio_path} -> {output_path}")
logger.info(f"Using reference: {reference_audio_path}")
if self.model is None:
if self.wrapper is None:
# Fallback: convert MP3 to WAV
logger.warning("Seed-VC not available, using passthrough mode")
return self._passthrough_convert(source_audio_path, output_path)
try:
# Load audio files
source_audio, sr = librosa.load(source_audio_path, sr=22050)
reference_audio, _ = librosa.load(reference_audio_path, sr=22050)
# Perform voice conversion
converted_audio = self.inference_fn(
self.model,
source_audio,
reference_audio,
sr=22050
# Perform voice conversion using the wrapper
# Returns numpy array of audio samples
audio_array = self.wrapper.convert_voice(
source=source_audio_path,
target=reference_audio_path,
diffusion_steps=diffusion_steps,
length_adjust=length_adjust,
inference_cfg_rate=inference_cfg_rate,
f0_condition=f0_condition,
auto_f0_adjust=auto_f0_adjust,
pitch_shift=pitch_shift,
stream_output=False # We want the full audio array, not streaming
)
# Determine sample rate based on f0_condition
sr = 44100 if f0_condition else 22050
# Save output
sf.write(output_path, converted_audio, 22050)
sf.write(output_path, audio_array, sr)
logger.info(f"Voice conversion complete: {output_path}")
return output_path
except Exception as e:
logger.error(f"Voice conversion failed: {e}")
import traceback
logger.error(traceback.format_exc())
# Fallback: convert MP3 to WAV
logger.warning("Fallback to MP3-to-WAV conversion")
return self._passthrough_convert(source_audio_path, output_path)