{"record":{"id":"5e55cc0399781b28","repo":"RVC-Boss/GPT-SoVITS","slug":"sovits-v3-4","errorCode":null,"errorMessage":"SoVits V3/4模型不支持流式推理模式","messagePattern":"SoVits V3/4模型不支持流式推理模式","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"GPT_SoVITS/TTS_infer_pack/TTS.py","lineNumber":1442,"sourceCode":"                            # token_padding_length = int(phones.shape[-1]*2)-_semantic_tokens.shape[-1]\n                            # if token_padding_length>0:\n                            #     _semantic_tokens = F.pad(_semantic_tokens, (0, token_padding_length), \"constant\", 486)\n                            # else:\n                            #     token_padding_length = 0\n\n                            audio_chunk, latent, latent_mask = self.vits_model.decode_streaming(\n                                                    _semantic_tokens.unsqueeze(0), \n                                                    phones, refer_audio_spec, \n                                                    speed=speed_factor,\n                                                    sv_emb=sv_emb,\n                                                    result_length=semantic_tokens.shape[-1]+overlap_len if not is_first_chunk else None,\n                                                    overlap_frames=last_latent[:,:,-overlap_len*(2 if self.vits_model.semantic_frame_rate == \"25hz\" else 1):] \\\n                                                    if last_latent is not None else None,\n                                                    padding_length=token_padding_length\n                                                )\n                            audio_chunk=audio_chunk.detach()[0, 0, :]\n                        else:\n                            raise RuntimeError(i18n(\"SoVits V3/4模型不支持流式推理模式\"))\n                        \n                        if overlap_len>overlap_length:\n                            audio_chunk=audio_chunk[-int((overlap_length+semantic_tokens.shape[-1])*upsample_rate):]\n\n                        audio_chunk_ = audio_chunk\n                        if is_first_chunk and not is_final:\n                            is_first_chunk = False\n                            audio_chunk_ = audio_chunk_[:-overlap_size]\n                        elif is_first_chunk and is_final: \n                            is_first_chunk = False\n                        elif not is_first_chunk and not is_final:\n                            audio_chunk_ = self.sola_algorithm([last_audio_chunk, audio_chunk_], overlap_size)\n                            audio_chunk_ = (\n                                audio_chunk_[last_audio_chunk.shape[0]-overlap_size:-overlap_size] if not is_final \\\n                                    else audio_chunk_[last_audio_chunk.shape[0]-overlap_size:]\n                                    )\n\n                        last_latent = latent","sourceCodeStart":1424,"sourceCodeEnd":1460,"githubUrl":"https://github.com/RVC-Boss/GPT-SoVITS/blob/d523079fc05d9a8028d6085bffe4a2757c32abb6/GPT_SoVITS/TTS_infer_pack/TTS.py#L1424-L1460","documentation":"RuntimeError raised in the streaming decode branch when the loaded vits_model has no decode_streaming capability but streaming was requested. SoVITS v3/v4 use a different vocoder architecture whose decoder cannot do chunked streaming generation, so only v1/v2 (25hz/non-25hz classic) models support streaming; requesting it with v3/v4 hits the else-branch and raises.","triggerScenarios":"Calling the streaming inference API (stream=True / the generator variant of run) while a SoVITS v3 or v4 model is loaded — the code calls self.vits_model.decode_streaming only when the attribute exists, otherwise raises RuntimeError with this message.","commonSituations":"API server configured for streaming responses but user switched the sovits checkpoint to a v3/v4 lora or full model; new deployment copies a streaming example config while shipping v4 weights; client demands realtime chunked audio but the model cannot provide it.","solutions":["Switch to a v1 or v2 SoVITS model if streaming/realtime output is a hard requirement.","Or disable streaming (return_finished_audio=True / stream=False) so inference falls back to full-clip generation even with v3/v4.","If you build a client, probe model capability (check model_version or hasattr(model, 'decode_streaming')) before requesting streaming, and fall back to non-streaming automatically."],"exampleFix":"# before\nfor chunk in handler.run(..., stream=True):  # RuntimeError: SoVits V3/4模型不支持流式推理模式\n    play(chunk)\n\n# after\nstreaming_ok = getattr(handler.vits_model, \"decode_streaming\", None) is not None\nif streaming_ok:\n    for chunk in handler.run(..., stream=True):\n        play(chunk)\nelse:\n    play(handler.run(..., return_finished_audio=True))","handlingStrategy":"type-guard","validationCode":"streaming_supported = getattr(handler.vits_model, \"decode_streaming\", None) is not None\nif stream_requested and not streaming_supported:\n    stream_requested = False  # fall back to full-clip generation","typeGuard":"def model_supports_streaming(handler) -> bool:\n    \"\"\"v1/v2 sovits expose decode_streaming; v3/v4 do not.\"\"\"\n    return getattr(handler.vits_model, \"decode_streaming\", None) is not None","tryCatchPattern":"try:\n    yield from handler.run(..., stream=True)\nexcept RuntimeError as e:\n    if \"不支持流式\" in str(e):\n        yield handler.run(..., return_finished_audio=True)\n    else:\n        raise","preventionTips":["Advertise streaming capability from the server based on the loaded model, and gate client requests on it.","Keep a v1/v2 checkpoint available if realtime streaming is a product requirement.","Test streaming immediately after every model switch."],"tags":["streaming","sovits","v3","v4","model-capability"],"backgroundTag":null,"analyzedSha":"d523079fc05d9a8028d6085bffe4a2757c32abb6","analyzedAt":"2026-08-15T01:06:46.402Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}