#!/bin/bash # IndexTTS 环境安装部署脚本 # 基于 https://github.com/index-tts/index-tts 官方文档 # 更新时间:2025-09-02 set -e # 遇到错误立即退出 # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # 日志函数 log_info() { echo -e "${BLUE}[INFO]${NC} $1" } log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } # 检查系统要求 check_requirements() { log_info "检查系统要求..." # 检查操作系统 if [[ "$OSTYPE" == "darwin"* ]]; then OS="macos" log_info "检测到 macOS 系统" elif [[ "$OSTYPE" == "linux-gnu"* ]]; then OS="linux" log_info "检测到 Linux 系统" else log_error "不支持的操作系统: $OSTYPE" exit 1 fi # 检查 Homebrew (macOS) 或包管理器 if [[ "$OS" == "macos" ]]; then if ! command -v brew &> /dev/null; then log_error "Homebrew 未安装,请先安装 Homebrew" exit 1 fi fi # 检查 Python 版本 if ! command -v python3.10 &> /dev/null; then log_warning "Python 3.10 未安装,正在安装..." if [[ "$OS" == "macos" ]]; then brew install python@3.10 else log_error "请手动安装 Python 3.10" exit 1 fi fi # 验证 Python 版本 PYTHON_VERSION=$(python3.10 --version 2>&1 | cut -d' ' -f2) if [[ ! "$PYTHON_VERSION" =~ ^3\.10\. ]]; then log_error "Python 版本必须是 3.10.x,当前版本: $PYTHON_VERSION" exit 1 fi # 检查 Git if ! command -v git &> /dev/null; then log_error "Git 未安装" exit 1 fi # 检查 FFmpeg if ! command -v ffmpeg &> /dev/null; then log_warning "FFmpeg 未安装,正在安装..." if [[ "$OS" == "macos" ]]; then brew install ffmpeg else sudo apt-get update && sudo apt-get install -y ffmpeg fi fi log_success "系统要求检查完成" } # 安装 Python 包管理器 install_package_managers() { log_info "安装包管理器..." # 安装 uv if ! command -v uv &> /dev/null; then log_info "安装 uv 包管理器..." curl -LsSf https://astral.sh/uv/install.sh | sh export PATH="$HOME/.local/bin:$PATH" log_success "uv 安装完成" else log_info "uv 已安装" fi # 验证 uv 安装 if command -v uv &> /dev/null; then UV_VERSION=$(uv --version) log_info "uv 版本: $UV_VERSION" fi log_success "包管理器安装完成" } # 创建虚拟环境 create_virtualenv() { log_info "创建 Python 3.10 虚拟环境..." # 删除现有虚拟环境(如果存在) if [[ -d ".venv" ]]; then log_warning "删除现有虚拟环境" rm -rf .venv fi # 创建新虚拟环境 python3.10 -m venv .venv source .venv/bin/activate log_success "虚拟环境创建完成" } # 初始化 uv 项目 init_uv_project() { log_info "初始化 uv 项目..." source .venv/bin/activate # 创建 pyproject.toml cat > pyproject.toml << 'EOF' [project] name = "voice-cli-tts" version = "0.1.0" description = "TTS dependencies for voice-cli" requires-python = ">=3.10,<3.11" dependencies = [ "torch>=2.8", "torchaudio>=2.8", "numpy>=1.19.0,<2.0.0", "soundfile>=0.12", "huggingface-hub>=0.34.4", ] [tool.uv] dev-dependencies = [] [build-system] requires = ["hatchling"] build-backend = "hatchling.build" EOF # 同步依赖 uv sync log_success "uv 项目初始化完成" } # 安装 PyTorch install_pytorch() { log_info "安装 PyTorch..." source .venv/bin/activate # 使用 uv 安装 PyTorch uv add torch torchaudio --index-url https://download.pytorch.org/whl/cpu log_success "PyTorch 安装完成" } # 安装 IndexTTS install_indextts() { log_info "安装 IndexTTS..." source .venv/bin/activate # 克隆 IndexTTS 仓库 if [[ -d "/tmp/index-tts" ]]; then rm -rf /tmp/index-tts fi log_info "克隆 IndexTTS 仓库..." git clone https://github.com/index-tts/index-tts.git /tmp/index-tts # 安装 IndexTTS log_info "安装 IndexTTS 包..." cd /tmp/index-tts pip install -e . # 处理可能的 pynini 问题 if pip install pynini 2>/dev/null; then log_info "pynini 安装成功" else log_warning "pynini 安装失败,尝试通过 conda 安装..." # 如果 conda 可用,尝试使用 conda if command -v conda &> /dev/null; then conda install -c conda-forge pynini==2.1.6 pip install WeTextProcessing --no-deps else log_warning "conda 不可用,跳过 pynini 安装" fi fi cd - > /dev/null log_success "IndexTTS 安装完成" } # 下载模型 download_models() { log_info "下载 IndexTTS 模型..." source .venv/bin/activate # 确保已安装 huggingface-hub uv add huggingface-hub # 创建 checkpoints 目录 mkdir -p checkpoints # 下载模型文件 log_info "正在下载 IndexTTS-1.5 模型文件..." # 先尝试下载小文件 python -c " from huggingface_hub import hf_hub_download import os files_to_download = [ 'config.yaml', 'bpe.model', 'unigram_12000.vocab', 'README.md', '.gitattributes' ] for file in files_to_download: try: hf_hub_download( repo_id='IndexTeam/IndexTTS-1.5', filename=file, local_dir='checkpoints' ) print(f'✓ {file} 下载完成') except Exception as e: print(f'✗ {file} 下载失败: {e}') " # 下载大模型文件 log_info "下载大模型文件(可能需要较长时间)..." python -c " from huggingface_hub import hf_hub_download import os large_files = [ 'gpt.pth', 'bigvgan_generator.pth', 'dvae.pth' ] for file in large_files: try: print(f'正在下载 {file}...') hf_hub_download( repo_id='IndexTeam/IndexTTS-1.5', filename=file, local_dir='checkpoints' ) print(f'✓ {file} 下载完成') except Exception as e: print(f'✗ {file} 下载失败: {e}') print(f'请手动下载: https://huggingface.co/IndexTeam/IndexTTS-1.5/blob/main/{file}') " # 验证关键文件 log_info "验证模型文件..." required_files = ['config.yaml', 'gpt.pth', 'bigvgan_generator.pth'] missing_files = [] for file in required_files; do if [[ ! -f "checkpoints/$file" ]]; then missing_files+=("$file") fi done if [[ ${#missing_files[@]} -gt 0 ]]; then log_warning "以下文件缺失: ${missing_files[*]}" log_warning "请手动下载这些文件到 checkpoints 目录" log_warning "下载地址: https://huggingface.co/IndexTeam/IndexTTS-1.5" else log_success "所有必需模型文件都已下载" fi log_success "模型下载完成" } # 创建参考语音文件 create_reference_voice() { log_info "创建参考语音文件..." # 创建参考语音文件(如果没有的话) if [[ ! -f "reference_voice.wav" ]]; then log_info "创建参考语音文件..." # 使用 say 命令创建语音文件 (macOS) if [[ "$OS" == "macos" ]]; then say -v "Alex" "This is a reference voice for IndexTTS" -o reference_voice.aiff ffmpeg -y -i reference_voice.aiff reference_voice.wav 2>/dev/null || true rm -f reference_voice.aiff if [[ -f "reference_voice.wav" ]]; then log_success "参考语音文件创建成功: reference_voice.wav" else log_warning "参考语音文件创建失败" fi else log_warning "无法自动创建语音文件,请手动提供 reference_voice.wav" log_info "您可以使用以下方式创建参考语音文件:" log_info "1. 使用录音工具录制 3-30 秒的语音" log_info "2. 确保格式为 WAV" log_info "3. 保存为 reference_voice.wav" fi else log_info "参考语音文件已存在: reference_voice.wav" fi } # 测试安装 test_installation() { log_info "测试 IndexTTS 安装..." source .venv/bin/activate # 测试导入 log_info "测试 IndexTTS 导入..." if python -c "import indextts; print('IndexTTS 导入成功')" 2>/dev/null; then log_success "IndexTTS 导入测试通过" else log_error "IndexTTS 导入失败" return 1 fi # 测试 CLI log_info "测试 IndexTTS CLI..." if indextts --help > /dev/null 2>&1; then log_success "IndexTTS CLI 测试通过" else log_error "IndexTTS CLI 测试失败" return 1 fi log_success "安装测试完成" } # 创建测试脚本 create_test_script() { log_info "创建测试脚本..." cat > test_indextts.py << 'EOF' #!/usr/bin/env python3 """ IndexTTS 测试脚本 """ import os import sys import subprocess def test_indextts(): print("开始测试 IndexTTS...") # 检查模型文件 required_files = ['checkpoints/config.yaml', 'checkpoints/gpt.pth'] for file in required_files: if not os.path.exists(file): print(f"错误: 缺少模型文件 {file}") return False # 检查参考语音文件 if not os.path.exists('reference_voice.wav'): print("错误: 缺少参考语音文件 reference_voice.wav") return False try: # 测试合成 test_text = "你好,这是一个测试。" output_file = "test_output.wav" cmd = [ 'indextts', test_text, '--voice', 'reference_voice.wav', '--output_path', output_file, '--model_dir', 'checkpoints', '--config', 'checkpoints/config.yaml', '--force' ] print(f"执行命令: {' '.join(cmd)}") result = subprocess.run(cmd, capture_output=True, text=True) if result.returncode == 0 and os.path.exists(output_file): print(f"测试成功! 输出文件: {output_file}") print(f"文件大小: {os.path.getsize(output_file)} bytes") return True else: print(f"测试失败") print(f"返回码: {result.returncode}") print(f"输出: {result.stdout}") print(f"错误: {result.stderr}") return False except Exception as e: print(f"测试异常: {e}") return False if __name__ == "__main__": success = test_indextts() sys.exit(0 if success else 1) EOF chmod +x test_indextts.py log_success "测试脚本创建完成" } # 显示使用说明 show_usage() { echo echo "==========================================" echo " 使用说明" echo "==========================================" echo echo "1. 激活虚拟环境:" echo " source .venv/bin/activate" echo echo "2. 运行测试:" echo " python test_indextts.py" echo echo "3. 使用 IndexTTS CLI:" echo " indextts --help" echo echo "4. 启动 voice-cli 服务器:" echo " voice-cli server run" echo echo "5. 测试 TTS 接口:" echo " curl -X POST 'http://127.0.0.1:8087/tts/sync' \\" echo " -H 'Content-Type: application/json' \\" echo " -d '{\"text\": \"你好世界\"}' --max-time 60" echo echo "==========================================" echo } # 主函数 main() { echo "==========================================" echo " IndexTTS 环境安装部署脚本" echo "==========================================" echo # 检查是否在正确的目录 if [[ ! -f "tts_service.py" ]]; then log_error "请在包含 tts_service.py 的目录中运行此脚本" exit 1 fi # 执行安装步骤 log_info "开始安装 IndexTTS 环境..." echo check_requirements install_package_managers create_virtualenv init_uv_project install_pytorch install_indextts download_models create_reference_voice test_installation create_test_script echo echo "==========================================" log_success "IndexTTS 环境安装完成!" echo "==========================================" echo show_usage echo "注意事项:" echo "- 确保 checkpoints 目录中有模型文件" echo "- 确保 reference_voice.wav 文件存在" echo "- 如果遇到问题,请检查日志输出" echo "- IndexTTS 处理时间通常为 15-30 秒" echo } # 运行主函数 main "$@"