update svc inference and webui

This commit is contained in:
jlqian98
2026-03-12 16:49:53 +08:00
parent dc6dedd677
commit ca3b600c07
3 changed files with 47 additions and 12 deletions
+1 -1
View File
@@ -6,7 +6,7 @@ root_dir=$(dirname "$script_dir")
cd $root_dir || exit
export PYTHONPATH=$root_dir:$PYTHONPATH
model_path=pretrained_models/SoulX-Singer-SVC/model.pt
model_path=pretrained_models/SoulX-Singer/model-svc.pt
config=soulxsinger/config/soulxsinger.yaml
prompt_wav_path=example/audio/zh_prompt.mp3
target_wav_path=example/audio/music.mp3
+20 -4
View File
@@ -212,6 +212,20 @@ class SoulXSingerSVC(nn.Module):
else:
pitch_shift = pitch_shift
# if target audio is less than 30 seconds, infer the whole audio
if gt_wav.shape[-1] < 30 * self.audio_cfg.sample_rate:
generated_audio = self.infer_segment(
pt_wav=pt_wav,
gt_wav=gt_wav,
pt_f0=pt_f0,
gt_f0=gt_f0,
pitch_shift=pitch_shift,
n_steps=n_steps,
cfg=cfg,
)
return generated_audio, pitch_shift
# if target audio is longer than 30 seconds, build vocal segments and infer each segment
generated_audio = []
f0_rate = self.audio_cfg.sample_rate // self.audio_cfg.hop_size
@@ -264,7 +278,8 @@ class SoulXSingerSVC(nn.Module):
def infer_segment(self, pt_wav, gt_wav, pt_f0, gt_f0, pitch_shift=0, n_steps=32, cfg=3):
pt_mel = self.mel(pt_wav)
len_prompt_mel = pt_f0.shape[1]
len_prompt_mel = pt_mel.shape[1]
pt_f0 = F.pad(pt_f0, (0, 0, 0, max(0, len_prompt_mel - pt_f0.shape[1])))[:, :len_prompt_mel]
f0_course_pt = self.f0_to_coarse(pt_f0)
f0_course_gt = self.f0_to_coarse(gt_f0, f0_shift=pitch_shift * 5)
@@ -272,12 +287,13 @@ class SoulXSingerSVC(nn.Module):
pt_content_feat = self.whisper_encoder.encode(pt_wav, sr=self.audio_cfg.sample_rate)
gt_content_feat = self.whisper_encoder.encode(gt_wav, sr=self.audio_cfg.sample_rate)
t_pt, t_gt = f0_course_pt.shape[1], f0_course_gt.shape[1]
pt_content_feat = F.pad(pt_content_feat, (0, 0, 0, max(0, t_pt - pt_content_feat.shape[1])))[:, :t_pt, :]
gt_content_feat = F.pad(gt_content_feat, (0, 0, 0, max(0, t_gt - gt_content_feat.shape[1])))[:, :t_gt, :]
content_feat = torch.cat([pt_content_feat, gt_content_feat], 1)
f0_feat = self.f0_encoder(f0_course)
min_len = min(content_feat.shape[1], f0_feat.shape[1])
content_feat = content_feat[:, :min_len, :]
f0_feat = f0_feat[:, :min_len, :]
features = content_feat + f0_feat
gt_decoder_inp = features[:, len_prompt_mel:, :]
+26 -7
View File
@@ -60,7 +60,7 @@ _I18N = dict(
zh="上传 Prompt 与 Target 音频,并配置相关参数",
),
instruction_p2=dict(
en="Click the button to start singing voice conversion.",
en="Click「🎤Singing Voice Conversion」to start singing voice conversion.",
zh="点击「🎤歌声转换」开始最终生成。",
),
tips_title=dict(en="Tips", zh="提示"),
@@ -145,7 +145,7 @@ class AppState:
self.svc_config = load_config("soulxsinger/config/soulxsinger.yaml")
self.svc_model = build_svc_model(
model_path="pretrained_models/SoulX-Singer-SVC/model.pt",
model_path="pretrained_models/SoulX-Singer/model-svc.pt",
config=self.svc_config,
device=self.device,
)
@@ -194,8 +194,6 @@ class AppState:
args = Args()
args.device = self.device
args.model_path = "soulx-singer-svc.pt"
args.config = "soulxsinger/config/soulxsinger.yaml"
args.prompt_wav_path = str(prompt_wav_path)
args.target_wav_path = str(target_wav_path)
args.prompt_f0_path = str(prompt_f0_path)
@@ -305,7 +303,30 @@ def _start_svc(prompt_audio, target_audio, prompt_vocal_sep, target_vocal_sep, a
def render_interface() -> gr.Blocks:
with gr.Blocks(title="SoulX-Singer SVC Demo", theme=gr.themes.Default()) as page:
with gr.Blocks(title="SoulX-Singer-SVC Demo", theme=gr.themes.Default()) as page:
gr.HTML(
'<div style="'
'text-align: center; '
'padding: 1.25rem 0 1.5rem; '
'margin-bottom: 0.5rem;'
'">'
'<div style="'
'display: inline-block; '
'font-size: 1.75rem; '
'font-weight: 700; '
'letter-spacing: 0.02em; '
'color: #1a1a2e; '
'line-height: 1.3;'
'">SoulX-Singer-SVC</div>'
'<div style="'
'width: 80px; '
'height: 3px; '
'margin: 1rem auto 0; '
'background: linear-gradient(90deg, transparent, #6366f1, transparent); '
'border-radius: 2px;'
'"></div>'
'</div>'
)
with gr.Row(equal_height=True):
lang_choice = gr.Radio(
choices=["中文", "English"],
@@ -315,7 +336,6 @@ def render_interface() -> gr.Blocks:
interactive=True,
)
title_md = gr.Markdown(_i18n("title"))
usage_md = gr.Markdown(_usage_md())
with gr.Row(equal_height=True):
@@ -402,7 +422,6 @@ def render_interface() -> gr.Blocks:
inputs=[lang_choice],
outputs=[
lang_choice,
title_md,
usage_md,
prompt_audio,
target_audio,