ChenfengDX
ChenfengDX
发布于 2026-01-12 / 23 阅读
0
0

WSL2 环境下 IndexTTS 与 VideoLingo 的深度集成指南

1. 背景与痛点

在 WSL2 (Windows Subsystem for Linux) 环境下开发 AI 项目时,我们经常会遇到一个棘手的网络问题:为了下载 HuggingFace 模型,我们通常会配置全局代理(如 Clash),但这会导致本地进程间的通信(127.0.0.1)也被代理拦截,从而引发 502 Bad Gateway 错误。

本文将分享如何将 IndexTTS 封装为 API 服务,并成功集成到 VideoLingo 中,同时彻底解决 WSL2 下的代理冲突问题。


2. 核心集成方案

我们的目标是让 VideoLingo 能够通过 HTTP 请求调用 IndexTTS 的语音合成功能。

2.1 IndexTTS API 服务端配置

/root/index-tts/ 目录下创建 api_server.py

关键点

  • 使用 FastAPI 框架。
  • 确保路径正确指向 IndexTTS 的根目录。
  • 监听一个冷门端口(如 9999)以避开常用端口冲突。
import os
import sys
import torch
import uvicorn
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import Optional

# 路径配置:确保能找到 IndexTTS 源码
INDEX_TTS_ROOT = "/root/index-tts"
if INDEX_TTS_ROOT not in sys.path:
    sys.path.append(INDEX_TTS_ROOT)

from indextts.infer_v2 import IndexTTS2

app = FastAPI()

class TTSRequest(BaseModel):
    text: str
    spk_audio_path: str
    output_path: str
    emo_audio_path: Optional[str] = None

tts_model = None

def get_model():
    global tts_model
    if tts_model is None:
        print(">>> [API] 正在加载模型 (首次调用需联网下载组件)...")
        tts_model = IndexTTS2(
            cfg_path=os.path.join(INDEX_TTS_ROOT, "checkpoints/config.yaml"),
            model_dir=os.path.join(INDEX_TTS_ROOT, "checkpoints"),
            use_fp16=torch.cuda.is_available(),
            device="cuda" if torch.cuda.is_available() else "cpu"
        )
        print(">>> [API] 模型加载成功!")
    return tts_model

@app.post("/tts")
async def generate_tts(request: TTSRequest):
    print(f"\n>>> [API] 收到请求: {request.text[:20]}...")
    try:
        model = get_model()
        os.makedirs(os.path.dirname(request.output_path), exist_ok=True)
        
        # IndexTTS2.infer 是生成器,必须迭代才能触发保存
        inference_gen = model.infer(
            spk_audio_prompt=request.spk_audio_path,
            text=request.text,
            output_path=request.output_path,
            emo_audio_prompt=request.emo_audio_path,
            verbose=False
        )
        for _ in inference_gen: pass
        
        print(f">>> [API] 合成成功: {request.output_path}")
        return {"status": "success", "audio_path": request.output_path}
    except Exception as e:
        print(f">>> [API] 错误: {e}")
        raise HTTPException(status_code=500, detail=str(e))

if __name__ == "__main__":
    uvicorn.run(app, host="127.0.0.1", port=9999)

2.2 VideoLingo 调用端配置

修改 /root/VideoLingo/core/tts_backend/custom_tts.py

关键点

  • 强制禁用代理:通过 proxies={"http": None, "https": None} 确保请求直连本地 API,不经过 Clash。
import requests
import os

def custom_tts(text, save_path):
    API_URL = "http://127.0.0.1:9999/tts"
    # 默认音色路径
    DEFAULT_SPK = "/root/index-tts/examples/voice_01.wav"
    
    payload = {
        "text": text,
        "spk_audio_path": DEFAULT_SPK,
        "output_path": os.path.abspath(save_path)
    }
    
    try:
        print(f"[Client] 正在发送请求 (强制直连 API)...")
        # 核心修复:强制跳过系统代理
        response = requests.post(
            API_URL, 
            json=payload, 
            timeout=600, 
            proxies={"http": None, "https": None} 
        )
        
        if response.status_code == 200:
            print(f"[Client] 成功生成配音!")
        else:
            raise Exception(f"API 错误: {response.text}")
            
    except Exception as e:
        print(f"[Client] 调用失败: {e}")
        raise e

if __name__ == "__main__":
    # 连通性测试
    custom_tts("测试配音,正在加载模型并合成。", "test.wav")

3. 运行与跑通

第一步:启动 API 服务

为了让 API 既能连上本地,又能通过代理下载模型,启动时需指定 no_proxy

cd /root/index-tts
export no_proxy=localhost,127.0.0.1 && uv run python api_server.py

第二步:运行连通性测试

在另一个终端运行:

cd /root/VideoLingo/core/tts_backend/
python3 custom_tts.py

第三步:连通性测试之端口占用清除

# 查看哪个进程在使用9999端口
sudo lsof -i :9999

# 或者使用 netstat
sudo netstat -tlnp | grep :9999

# 找到PID后,停止该进程
pkill -f "api_server.py"

第四步:修复500 Internal Server Error错误

主要是参考音频没给,改下请求端的默认音频即可


4. 经验总结

  1. 代理冲突:WSL2 下的 502 Bad Gateway 通常是代理拦截了本地回环地址。在代码中显式设置 proxies={...} 是最稳妥的解决办法。
  2. 模型加载:IndexTTS 首次调用会下载 w2v-bert-2.0 等组件,请确保服务端启动时代理配置正确(使用 no_proxy 排除本地地址)。
  3. 生成器机制:IndexTTS 的推理函数是生成器,调用时必须完整迭代才能完成文件保存。

5. 进阶操作:后台启动与音色切换

为了让集成方案更具实用性,以下是两个必备的进阶操作。

5.1 API 服务后台静默启动

在实际使用中,我们不希望 API 服务占用一个终端窗口。可以使用 nohup 命令让服务在后台持续运行,并将日志记录到文件中。

后台启动命令

cd /root/index-tts
export no_proxy=localhost,127.0.0.1
nohup uv run python api_server.py > tts_api.log 2>&1 &

相关管理操作

  • 查看运行日志tail -f tts_api.log(实时查看合成进度和报错)。
  • 查看服务进程ps -ef | grep api_server.py
  • 关闭后台服务fuser -k 9999/tcp(强制关闭占用 9999 端口的进程)。

5.2 快速切换配音音色

IndexTTS 的核心优势是音色克隆。要更换 VideoLingo 的配音音色,您无需修改 API 服务端,只需修改调用端 custom_tts.py 中的一个路径即可。

操作步骤

  1. 将您喜欢的 .wav 格式参考音频放入 /root/index-tts/examples/ 目录下(例如 my_voice.wav)。
  2. 修改 /root/VideoLingo/core/tts_backend/custom_tts.py 中的 DEFAULT_SPK 变量:
def custom_tts(text, save_path):
    # --- 修改这里即可更换音色 ---
    DEFAULT_SPK = "/root/index-tts/examples/my_voice.wav" 
    # --------------------------
    # ... 其余代码保持不变 ...

提示:IndexTTS 对参考音频的要求不高,通常 5-10 秒清晰的干声(无背景音乐)即可达到非常好的克隆效果。

希望这篇指南能帮助你在 WSL2 环境下顺利集成 IndexTTS!


评论