# CosyVoice 3.0 部署文档

## 概览

| 项目 | 值 |
|------|------|
| 模型 | Fun-CosyVoice3-0.5B-2512 (0.5B 参数) |
| 端口 | 8010 |
| GPU | 0 (CUDA_VISIBLE_DEVICES=0) |
| 推理精度 | FP16 (自动混合精度) |
| PM2 名称 | vigent2-cosyvoice |
| Conda 环境 | cosyvoice (Python 3.10) |
| 启动脚本 | `run_cosyvoice.sh` |
| 服务脚本 | `models/CosyVoice/cosyvoice_server.py` |
| 模型加载时间 | ~22-34 秒 |
| 显存占用 | ~3-5 GB |

## 支持语言

中文、英文、日语、韩语、德语、西班牙语、法语、意大利语、俄语，18+ 中国方言

## 目录结构

```
models/CosyVoice/
├── cosyvoice_server.py              # FastAPI 服务 (端口 8010)
├── cosyvoice/                        # CosyVoice 源码
│   └── cli/cosyvoice.py             # AutoModel 入口
├── third_party/Matcha-TTS/          # 子模块依赖
├── pretrained_models/
│   ├── Fun-CosyVoice3-0.5B/        # 模型文件 (~8.2GB)
│   │   ├── llm.pt                   # LLM 模型 (1.9GB)
│   │   ├── llm.rl.pt               # RL 模型 (1.9GB, 备用)
│   │   ├── flow.pt                  # Flow 模型 (1.3GB)
│   │   ├── hift.pt                  # HiFT 声码器 (80MB)
│   │   ├── campplus.onnx            # 说话人嵌入 (27MB)
│   │   ├── speech_tokenizer_v3.onnx # 语音分词器 (925MB)
│   │   ├── cosyvoice3.yaml          # 模型配置
│   │   └── CosyVoice-BlankEN/      # Qwen tokenizer
│   └── CosyVoice-ttsfrd/           # 文本正则化资源
│       ├── resource/                # 解压后的 ttsfrd 资源
│       └── resource.zip
run_cosyvoice.sh                      # PM2 启动脚本
```

## API 接口

### GET /health

健康检查，返回：
```json
{
  "service": "CosyVoice 3.0 Voice Clone",
  "model": "Fun-CosyVoice3-0.5B",
  "ready": true,
  "gpu_id": 0
}
```

### POST /generate

声音克隆生成。

**参数 (multipart/form-data)：**

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| ref_audio | File | 是 | 参考音频 (WAV) |
| text | string | 是 | 要合成的文本 |
| ref_text | string | 是 | 参考音频的转写文字 |
| language | string | 否 | 语言 (默认 "Chinese"，CosyVoice 自动检测) |
| speed | float | 否 | 语速 (默认 1.0，范围 0.5-2.0，建议 0.8-1.2) |
| instruct_text | string | 否 | 语气指令 (默认 ""，非空时切换为 `inference_instruct2` 模式) |

**推理模式分支：**
- `instruct_text` 为空 → `inference_zero_shot(text, prompt_text, ref_audio)` — 纯声音克隆
- `instruct_text` 非空 → `inference_instruct2(text, instruct_text, ref_audio)` — 带语气/情绪控制的声音克隆

**支持的语气指令示例：**
```
"You are a helpful assistant. 请非常开心地说一句话。<|endofprompt|>"
"You are a helpful assistant. 请非常伤心地说一句话。<|endofprompt|>"
"You are a helpful assistant. 请非常生气地说一句话。<|endofprompt|>"
```

**返回：** WAV 音频文件

**状态码：**
- 200: 成功
- 429: GPU 忙，请重试
- 500: 生成失败/超时
- 503: 模型未加载/服务中毒

## 安全机制

1. **GPU 推理锁** (`asyncio.Lock`): 防止并发推理导致 GPU 状态损坏
2. **429 拒绝**: 锁被占用时立即返回 429，客户端重试
3. **超时保护**: `60 + len(text) * 2` 秒，上限 300 秒
4. **Poisoned 标记**: 超时后标记服务为中毒状态，健康检查返回 `ready: false`
5. **强制退出**: 超时后 1.5 秒强制 `os._exit(1)`，PM2 自动重启
6. **启动自检**: 启动时用短文本做一次真实推理，验证 GPU 推理链路可用；失败则 `_model_loaded = False`，健康检查返回 `ready: false`，避免假阳性
7. **参考音频自动截取**: 参考音频超过 10 秒时自动截取前 10 秒（CosyVoice 建议 3-10 秒），避免采样异常

## 运维命令

```bash
# 启动
pm2 start run_cosyvoice.sh --name vigent2-cosyvoice

# 重启
pm2 restart vigent2-cosyvoice

# 查看日志
pm2 logs vigent2-cosyvoice --lines 50

# 健康检查
curl http://localhost:8010/health

# 停止
pm2 stop vigent2-cosyvoice
```

## 从零部署步骤

### 1. 克隆仓库

```bash
cd /home/rongye/ProgramFiles/ViGent2/models
git clone --recursive https://github.com/FunAudioLLM/CosyVoice.git
cd CosyVoice
git submodule update --init --recursive
```

### 2. 创建 Conda 环境

```bash
conda create -n cosyvoice -y python=3.10
conda activate cosyvoice
```

### 3. 安装依赖

注意：不能直接 `pip install -r requirements.txt`，有版本冲突需要处理。

```bash
# 安装 PyTorch 2.3.1 (CUDA 12.1) — 必须先装，版本严格要求
pip install torch==2.3.1 torchaudio==2.3.1 --index-url https://download.pytorch.org/whl/cu121

# 核心推理依赖
pip install conformer==0.3.2 HyperPyYAML==1.2.2 inflect==7.3.1 \
  librosa==0.10.2 lightning==2.2.4 modelscope==1.20.0 omegaconf==2.3.0 \
  pydantic==2.7.0 soundfile==0.12.1 fastapi==0.115.6 uvicorn==0.30.0 \
  transformers==4.51.3 protobuf==4.25 hydra-core==1.3.2 \
  rich==13.7.1 diffusers==0.29.0 x-transformers==2.11.24 wetext==0.0.4

# onnxruntime-gpu
pip install onnxruntime-gpu==1.18.0 \
  --extra-index-url https://aiinfra.pkgs.visualstudio.com/PublicPackages/_packaging/onnxruntime-cuda-12/pypi/simple/

# 其他必要依赖
pip install gdown matplotlib pyarrow wget onnx python-multipart httpx

# openai-whisper 需要 setuptools < 71（提供 pkg_resources）
pip install "setuptools<71"
pip install --no-build-isolation openai-whisper==20231117

# pyworld 需要 g++ 和 Cython
pip install Cython
PATH="/usr/bin:$PATH" pip install pyworld==0.3.4

# 关键版本修复
pip install "numpy<2"               # onnxruntime-gpu 不兼容 numpy 2.x
pip install "ruamel.yaml<0.18"      # hyperpyyaml 不兼容 ruamel.yaml 0.19+
```

> **重要**: CosyVoice 要求 torch==2.3.1。torch 2.10+ 会导致 CUBLAS_STATUS_INVALID_VALUE 错误。
> torch 2.3.1+cu121 自带 nvidia-cudnn-cu12，onnxruntime CUDAExecutionProvider 可正常使用。

### 4. 下载模型

```bash
# 使用 huggingface_hub (国内用 hf-mirror.com)
HF_ENDPOINT=https://hf-mirror.com python -c "
from huggingface_hub import snapshot_download
snapshot_download('FunAudioLLM/Fun-CosyVoice3-0.5B-2512', local_dir='pretrained_models/Fun-CosyVoice3-0.5B')
snapshot_download('FunAudioLLM/CosyVoice-ttsfrd', local_dir='pretrained_models/CosyVoice-ttsfrd')
"
```

### 5. 安装 ttsfrd (可选，提升文本正则化质量)

```bash
cd pretrained_models/CosyVoice-ttsfrd/
unzip resource.zip -d .
pip install ttsfrd_dependency-0.1-py3-none-any.whl
pip install ttsfrd-0.4.2-cp310-cp310-linux_x86_64.whl
```

### 6. 注册 PM2

```bash
pm2 start run_cosyvoice.sh --name vigent2-cosyvoice
pm2 save
```

## 已知问题

1. **ttsfrd "prepare tts engine failed"**: ttsfrd C 库内部日志，Python 层初始化成功，不影响使用
2. **Sliding Window Attention 警告**: transformers 库提示，不影响推理结果
3. **onnxruntime Memcpy 性能提示**: `Memcpy nodes are not supported by the CUDA EP`，仅为性能建议日志，不影响功能

> 注：libcudnn.so.8 问题在 torch 2.3.1+cu121 环境下已解决（自带 nvidia-cudnn-cu12），onnxruntime CUDAExecutionProvider 可正常加载。

## 与 Qwen3-TTS 对比

| 特性 | Qwen3-TTS (已停用) | CosyVoice 3.0 (当前) |
|------|-----------|----------------|
| 端口 | 8009 | 8010 |
| 模型大小 | 0.6B | 0.5B |
| 语言 | 中/英/日/韩 | 9 语言 + 18 方言 |
| 克隆方式 | ref_audio + ref_text | ref_audio + ref_text |
| prompt 格式 | 直接传 ref_text | `You are a helpful assistant.<\|endofprompt\|>` + ref_text |
| 内置分段 | 无，需客户端分段 | 内置 text_normalize 自动分段 |
| 状态 | 已停用 (PM2 stopped) | 生产使用中 |
