#2829·GPT-SoVITS

inference_cli.py never loads the SoVITS model: change_sovits_weights is a generator and is called without being iterated

Author: itasYangCreated Aug 25, 2026Updated Aug 25, 2026

Summary

GPT_SoVITS/inference_cli.py calls change_sovits_weights() as a plain statement, but that function is a generator function. The call therefore creates a generator object and returns immediately — the function body never runs, and the SoVITS weights are never loaded.

Inference still produces audio, because inference_webui already loaded a SoVITS model at import time. So --sovits_model is silently ignored: you get output, no error, and no indication that a different model than the one you asked for was used.

change_gpt_weights() is a normal function, so --gpt_model works. The asymmetry is what makes this easy to miss.

Evidence

1. Static

On current main:

  • GPT_SoVITS/inference_webui.py L261 def change_sovits_weights(...), with yield at L295 and L377 → generator function.
  • GPT_SoVITS/inference_cli.py:
L30:  change_gpt_weights(gpt_path=GPT_model_path)
L31:  change_sovits_weights(sovits_path=SoVITS_model_path)

L31 is never iterated.

python
>>> inspect.isgeneratorfunction(change_sovits_weights)
True
>>> inspect.isgeneratorfunction(change_gpt_weights)
False

2. Dynamic

Same process, same weight path, two calling styles, comparing a SHA256 fingerprint of the loaded model's parameters:

initial state       : 4a17cbb61d7d79da  version=v2Pro  class=SynthesizerTrn
after plain call    : 4a17cbb61d7d79da  version=v2Pro  class=SynthesizerTrn   <-- unchanged
  (returned object  : generator)
after consuming     : 63d735ba8b62f4f0  version=v3     class=SynthesizerTrnV3 <-- changed

The plain call leaves the parameters bit-identical and does not even change the model class.

3. Behavioural

Requesting v3 and v4 weights through the CLI-style call produced 32000 Hz output for both — the sample rate of the already-loaded v2Pro model. After consuming the generator, the same requests produced 24000 Hz (v3) and 48000 Hz (v4), the correct rates for those vocoders.

Reproduce

python
import inspect, hashlib
import GPT_SoVITS.inference_webui as iw

def fp():
    h = hashlib.sha256(); n = 0
    for p in iw.vq_model.parameters():
        h.update(p.detach().float().cpu().numpy().tobytes())
        n += p.numel()
        if n > 5_000_000: break
    return h.hexdigest()[:16], iw.model_version, type(iw.vq_model).__name__

print(inspect.isgeneratorfunction(iw.change_sovits_weights))   # True
print("before        :", fp())

iw.change_sovits_weights("GPT_SoVITS/pretrained_models/s2Gv3.pth",
                         prompt_language="日文", text_language="日文")
print("after plain   :", fp())                                  # identical

for _ in iw.change_sovits_weights("GPT_SoVITS/pretrained_models/s2Gv3.pth",
                                  prompt_language="日文", text_language="日文"):
    pass
print("after consume :", fp())                                  # changed

Why this went unnoticed

inference_webui auto-loads a SoVITS model at import time, picking one from the weights directory. If that happens to be the model you wanted, everything appears to work. The bug only shows up when you try to switch — and even then it fails silently with plausible audio, so it is easy to attribute the wrong-sounding result to the model or the data rather than to the loader.

Note also that passing prompt_language=None / text_language=None (the defaults) raises UnboundLocalError: local variable 'prompt_text_update' referenced before assignment once the generator is consumed, because the branch that assigns those locals is skipped. So a naive fix of just wrapping the existing call in a loop is not enough — the language arguments have to be passed as well.

Suggested fix

In inference_cli.py:

python
for _ in change_sovits_weights(sovits_path=SoVITS_model_path,
                               prompt_language=ref_language,
                               text_language=target_language):
    pass

A more robust alternative would be to split the weight-loading logic out of the Gradio-facing generator into a plain function that both the WebUI and the CLI call, so this class of mistake cannot recur.

Environment

Windows 11, GPT-SoVITS-v2pro-20250604 integrated package, but the two source files above are unchanged on current main, so the issue is in the repository rather than in the packaging.