@memef1f1y/dsh-plugin-tts 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/test.yml +33 -0
- package/ANALYSIS.md +205 -0
- package/LICENSE +21 -0
- package/PR-REVIEW.md +75 -0
- package/README.md +297 -0
- package/README.zh.md +263 -0
- package/Snipaste_2026-08-16_13-28-10.png +0 -0
- package/Snipaste_2026-08-16_13-28-23.png +0 -0
- package/Snipaste_2026-08-16_13-28-37.png +0 -0
- package/Snipaste_2026-08-16_13-29-01.png +0 -0
- package/Snipaste_2026-08-16_13-29-11.png +0 -0
- package/TODO.md +23 -0
- package/cordis.patch.yml +4 -0
- package/docs/CLOUD-GUIDE.md +216 -0
- package/docs/COSYVOICE-GUIDE.md +216 -0
- package/docs/EDGE-GUIDE.md +166 -0
- package/docs/HOST-CONTRACT.md +36 -0
- package/docs/INDEX-TTS2-GUIDE.md +208 -0
- package/docs/RVC-GUIDE.md +390 -0
- package/docs/USER-GUIDE.md +334 -0
- package/docs/acceptance-checklist.md +148 -0
- package/docs/adaptive-chunked-playback.md +194 -0
- package/docs/macos-test-prompt.md +230 -0
- package/docs/windows-gpu-verify-prompt.md +151 -0
- package/lib/client.js +7036 -0
- package/lib/index.mjs +3288 -0
- package/logo.png +0 -0
- package/package.json +52 -0
- package/pnpm-workspace.yaml +7 -0
- package/rvc-server.py +564 -0
- package/tests/README.md +45 -0
- package/tests/client-load.mjs +393 -0
- package/tests/e2e-compact-index.mjs +86 -0
- package/tests/e2e-index-ab.mjs +138 -0
- package/tests/e2e-real-rvc.mjs +122 -0
- package/tests/i18n-keys.mjs +82 -0
- package/tests/mock-registry.mjs +50 -0
- package/tests/package-runtime-patch.mjs +88 -0
- package/tests/rvc-server-live.mjs +230 -0
- package/tests/smoke.mjs +1107 -0
- package/tools/gen-ui-preview.mjs +174 -0
- package/tools/mac-verify.sh +158 -0
- package/tools/make-pack.mjs +155 -0
- package/tools/package-runtime.py +214 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# 自适应分块渐进播放方案(Adaptive Chunked Progressive Playback)
|
|
2
|
+
|
|
3
|
+
> RVC 长文本朗读的"先全部转换、后整体播放"改造成"边转换、边播放"的设计与实现说明。
|
|
4
|
+
> 核心思想:**性能开销摊在用户本机**,不同机器自动校准块大小与预热数量,做到"即点即听、长文不卡顿"。
|
|
5
|
+
|
|
6
|
+
## 1. 问题
|
|
7
|
+
|
|
8
|
+
RVC 是**变声**而非 TTS:输入音频长度 = 输出音频长度,所以"长文本朗读"必须
|
|
9
|
+
先把整段文本用 Edge TTS 合成底噪,再交给 RVC 转换。旧链路是:
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
整段文本 → Edge 合成整段底噪 → RVC 整段转换 → 返回 → 播放
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
对短句(≤12 秒音频)这是最优解;但对长回复(数百字、几分钟音频)会变成:
|
|
16
|
+
|
|
17
|
+
- 用户点击后**干等**:合成 + 转换整段(几十秒甚至几分钟)完成才出声;
|
|
18
|
+
- 期间没有任何反馈,体验像"卡死";
|
|
19
|
+
- 内存峰值高(整段音频一次性进出 RVC)。
|
|
20
|
+
|
|
21
|
+
曾考虑"只读前 20 字"来缩短等待 —— 但这会**丢掉正文内容**,被否决。
|
|
22
|
+
正确方向是:内容一字不丢,但**让第一块尽快出声,其余在播放的同时后台合成**。
|
|
23
|
+
|
|
24
|
+
## 2. 方案总览
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
Edge 合成整段底噪? 不 —— 改成:
|
|
28
|
+
1) 文本按句切块(每块 ≈ 10-20 秒音频)
|
|
29
|
+
2) 先转换预热块(2-4 块)→ 立即返回给前端开始播放
|
|
30
|
+
3) 播放第 n 块的同时,后台转换第 n+1、n+2 块(转换/播放重叠)
|
|
31
|
+
4) 前端队列快见底时向 Host 拉取下一块,无缝续播
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
关键比率:**速度比 ratio = 转换耗时 / 音频时长**。
|
|
35
|
+
|
|
36
|
+
- GPU(RTX 5070 实测):15 秒音频 ≈ 3-4 秒转换 → ratio ≈ 0.25
|
|
37
|
+
→ 转换永远追得上播放,队列不会饿死,**天然无缝**。
|
|
38
|
+
- CPU 用户:ratio 可能 > 1 → 必须缩小块、加大预热,把"卡顿点"压到最少。
|
|
39
|
+
|
|
40
|
+
## 3. 自适应校准(probe + 分档)
|
|
41
|
+
|
|
42
|
+
首次使用长文本 RVC 时,Host 做一次 **5 秒探测**:
|
|
43
|
+
|
|
44
|
+
1. Edge 合成一段固定探测文本(≈3.6 秒音频);
|
|
45
|
+
2. 本机 RVC 转换,测出 `ratio = 转换耗时 / 音频秒数`(含每块 Edge 合成耗时,
|
|
46
|
+
与真实分块流水线口径一致,偏保守);
|
|
47
|
+
3. 按分档表决定 `chunkSec`(每块音频秒数)与 `prewarm`(先转换几块再开播);
|
|
48
|
+
4. 结果按配置指纹持久化到 `~/.dsh/tts-rvc/calibration.json`:
|
|
49
|
+
- **7 天有效**,dsh 重启后直接复用,连那一次 ~7s 探测都省掉;
|
|
50
|
+
- 同时记录 `device`(RVC 服务 `/health` 上报的 GPU 名);换显卡/切 CPU 时
|
|
51
|
+
自动重新探测,不会拿旧的 GPU 数据给 CPU 用;
|
|
52
|
+
- 探测失败不覆盖磁盘上的旧有效条目(会话内 2 分钟用保守档兜底)。
|
|
53
|
+
|
|
54
|
+
| ratio | 块大小 | 预热块数 | 适用 |
|
|
55
|
+
|---|---|---|---|
|
|
56
|
+
| ≤ 0.4 | 20 秒 | 2 | 强 GPU,几乎无缝 |
|
|
57
|
+
| 0.4 – 0.6 | 15 秒 | 2 | 中端 GPU |
|
|
58
|
+
| 0.6 – 0.9 | 10 秒 | 3 | 入门 GPU / 快 CPU |
|
|
59
|
+
| > 0.9 | 6 秒 | 4 | CPU,尽量平滑 |
|
|
60
|
+
| 探测失败 | 10 秒 | 3 | 保守兜底(60 秒内不重复探测) |
|
|
61
|
+
|
|
62
|
+
块大小换算:中文 ≈ 3.6 字/秒 → `maxChars ≈ chunkSec × 3.6`(拉丁文本按 12 字/秒)。
|
|
63
|
+
|
|
64
|
+
### 为什么分档而不是固定值?
|
|
65
|
+
|
|
66
|
+
同一套代码要在"4090 用户"和"核显用户"上都成立。固定大块在 CPU 上会频繁断流,
|
|
67
|
+
固定小块在 GPU 上是浪费。**按本机实测速度自适应**才是"即选即用"的根基。
|
|
68
|
+
|
|
69
|
+
## 4. 文本切块
|
|
70
|
+
|
|
71
|
+
`splitText(text, maxChars)`:
|
|
72
|
+
|
|
73
|
+
1. 按句号/感叹/问号/分号(含中英文)切句;
|
|
74
|
+
2. 超长句再按逗号/顿号切段;
|
|
75
|
+
3. 仍超长的硬切(每段 ≤ maxChars);
|
|
76
|
+
4. 尽量让每块落在语义边界,避免在句中切断导致听感断裂。
|
|
77
|
+
5. **原子 token 保护**:URL / 邮箱 / 小数 / 版本号(如 `3.14`、`v2.0.1`)先换成无标点
|
|
78
|
+
placeholder 再切分——句子级切分不会把小数里的 `.` 误当句号拆开;硬切(`safeEnd`)会
|
|
79
|
+
滑到最近空白/标点边界,且绝不切断 placeholder(长 URL 保持整段读出)。
|
|
80
|
+
6. **孤儿块合并**:末尾不足 8 字的极短句并入前一块(合并后 ≤ maxChars),避免"结巴"听感。
|
|
81
|
+
|
|
82
|
+
## 5. 协议:任务队列(Host 侧)
|
|
83
|
+
|
|
84
|
+
`POST /dsh-tts-api/speak`(RVC + Edge 底噪 + 预估 > 12 秒时):
|
|
85
|
+
|
|
86
|
+
```jsonc
|
|
87
|
+
// 请求不变;响应变为:
|
|
88
|
+
{ "jobId": "j1", "chunks": ["/dsh-tts-audio/c1", "/dsh-tts-audio/c2"], "total": 6,
|
|
89
|
+
"ratio": 0.24, "chunkSec": 20 }
|
|
90
|
+
// chunks 只含"预热块";总块数在 total
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
`GET /dsh-tts-api/rvc-next?job=j1`(前端逐块拉取):
|
|
94
|
+
|
|
95
|
+
```jsonc
|
|
96
|
+
{ "url": "/dsh-tts-audio/c3", "more": true } // 还有后续
|
|
97
|
+
{ "done": true } // 已到末尾
|
|
98
|
+
{ "error": "后续段落合成失败:..." } // 某块失败
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Host 内部:
|
|
102
|
+
|
|
103
|
+
- 每 job 一个**串行转换链**(`job.tail`),并发拉取自动排队,RVC 服务不被并发打爆;
|
|
104
|
+
- 每块 = Edge 合成该块文本 → RVC 转换 → 临时 wav → 音频路由 URL;
|
|
105
|
+
- job 惰性回收:完成 2 分钟后 / 创建 10 分钟后清理,上限 50 个;
|
|
106
|
+
- 单块失败不影响已缓冲的块,只把错误带给前端,前端提示后停止。
|
|
107
|
+
|
|
108
|
+
## 6. 前端渐进播放(无感衔接)
|
|
109
|
+
|
|
110
|
+
`playChunks(jobId, chunks, total, token)` 使用 **Web Audio 精确调度**:
|
|
111
|
+
|
|
112
|
+
- 每个块 `fetch → decodeAudioData` 成 AudioBuffer(保持 2 块解码余量),
|
|
113
|
+
按采样时钟**首尾相接调度**:`src.start(prevEnd)`(prevEnd 由已调度缓冲时长累加),
|
|
114
|
+
块间零事件抖动、零重载延迟;
|
|
115
|
+
- **服务端裁剪每块边缘填充静音**(rvc-server `/convert` 输出前 `trim_edges`):
|
|
116
|
+
实测每块头 138ms / 尾 538ms 纯静音(Edge TTS + RVC 填充),裁掉并各保留
|
|
117
|
+
20ms / 120ms 自然气息,块间不再有 ~680ms 死寂;
|
|
118
|
+
- 停止/打断:`speakToken` 全局令牌 + 源列表 `stop()`(waCleanup),立即静音;
|
|
119
|
+
- **进度可见**:`shared.chunkProgress = { index, total }` 随块播放更新——朗读按钮
|
|
120
|
+
tooltip 与试听面板显示「第 x/y 段 · 边播边合成」(绝不静默丢内容);
|
|
121
|
+
- 失败:某块合成失败 → 红字提示并停止;无 Web Audio 环境降级为双 `<audio>` ping-pong。
|
|
122
|
+
|
|
123
|
+
> 备注:`vc_single` 返回 **int16**,`trim_edges` 先归一化为 float [-1,1] 再处理,
|
|
124
|
+
> 否则 `sf.write` 会把 int16 样本值当 [-1,1] 幅值整体削波(曾导致输出 99% 满幅失真)。
|
|
125
|
+
|
|
126
|
+
## 7. RVC 服务端配套
|
|
127
|
+
|
|
128
|
+
`rvc-server.py` 本次新增:
|
|
129
|
+
|
|
130
|
+
1. **`/health` 上报 `gpu_name` / `vram_gb`** —— 校准持久化的设备指纹来源;
|
|
131
|
+
2. **faiss 索引缓存**:RVC pipeline 每次转换都会 `faiss.read_index` 重新读一遍
|
|
132
|
+
~400MB 索引文件(每块一次,代价可观)。现在按路径缓存加载好的 Index 对象,
|
|
133
|
+
`/load` 时清空 —— 分块模式下每块省掉一次 400MB 磁盘读。
|
|
134
|
+
|
|
135
|
+
## 8. 边界与回退
|
|
136
|
+
|
|
137
|
+
| 情况 | 行为 |
|
|
138
|
+
|---|---|
|
|
139
|
+
| 短文本(≤12 秒) | 不进队列,走原来的单 URL 链路(零额外开销) |
|
|
140
|
+
| 探测失败 | 保守档(10 秒 / 预热 3),会话内 2 分钟不重复探测 |
|
|
141
|
+
| 某块转换失败 | 已缓冲的继续播,后续报错并停止 |
|
|
142
|
+
| 停止 / 换消息 / 切会话 | 令牌失效,队列立即退出,无残留播放 |
|
|
143
|
+
| 刷新页面 | 队列随页面消失;Host job 按时回收 |
|
|
144
|
+
|
|
145
|
+
## 10. 实测(RTX 5070 + azusa-test)
|
|
146
|
+
|
|
147
|
+
| 场景 | 结果 |
|
|
148
|
+
|---|---|
|
|
149
|
+
| 短句链路 | ~4.6-5.4s(含 Edge 合成) |
|
|
150
|
+
| 长文本首响 | 探测 + 预热 2 块 ≈ 6-7s(**此后 7 天内从 calibration.json 直接复用,不再探测**) |
|
|
151
|
+
| 长文本全链 | 6/6 块取完,迟到块 RIFF 476KB;块间无感知停顿 |
|
|
152
|
+
| 索引缓存收益 | ratio 0.62 → 0.48(省掉每块 400MB 索引重读),档位 10s/3 → 15s/2 |
|
|
153
|
+
|
|
154
|
+
## 11. Phase 2 预留
|
|
155
|
+
|
|
156
|
+
- 音色包注册表 + 下载 UI(版权干净音色)→ 已包含在下方"已完成"(含私有仓库 rvc-for-tts 示例);
|
|
157
|
+
- 便携运行时打包 → **已完成(v1)**:`tools/package-runtime.py` 复制已验证环境 + 可选
|
|
158
|
+
torch cu128 升级(RTX 50 系提速,官方 CDN 慢时用国内镜像);本机实测转换正常。
|
|
159
|
+
|
|
160
|
+
> 已完成:
|
|
161
|
+
> - `calibration.json` 落盘(`~/.dsh/tts-rvc/`,7 天有效 + 设备指纹,跨会话复用探测结果);
|
|
162
|
+
> - **紧凑索引生成工具**(设置面板「索引路径」旁「压缩」按钮):408MB 原索引
|
|
163
|
+
> 子采样重建为**与源同度量**的精确 flat 索引(RVC 训练默认 L2,pipeline 的
|
|
164
|
+
> `square(1/score)` 加权即按 L2 设计),2k→5.9MB(-98.5%)、10k→29.3MB(-92.5%),
|
|
165
|
+
> RVC 管线零改动兼容,实测转换正常;音色包分发不再受索引体积阻碍;
|
|
166
|
+
> - **音色包注册表 + 下载 UI**:清单格式(schema 2:模型 + indexes 变体数组 + sha256 +
|
|
167
|
+
> 版权/作者/版本,url 支持相对路径),Host 代理清单与下载(规避 CORS)、sha256 逐一校验后
|
|
168
|
+
> 安装到 `~/.dsh/tts-rvc/packs/<id>/`,自动填入模型/索引并应用底噪/f0/index_rate 默认值;
|
|
169
|
+
> 失败自动清理残留;mock 仓库 `tests/mock-registry.mjs` 供本地测试;私有音色仓库
|
|
170
|
+
> `github.com/1624318455/rvc-for-tts`(azusa-test 模型 + 2k/10k/20k 紧凑索引);
|
|
171
|
+
> - **便携运行时打包 v1**:`tools/package-runtime.py`(--skip-torch 零下载即可用;
|
|
172
|
+
> 可选 cu128 升级适配 Blackwell,官方 CDN 慢时用 aliyun 镜像)。
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## English summary
|
|
177
|
+
|
|
178
|
+
RVC is voice **conversion** (input length == output length), not TTS, so a long
|
|
179
|
+
read must first synthesize the whole base audio with Edge TTS. Instead of
|
|
180
|
+
converting everything before playing (long silent wait), the plugin now:
|
|
181
|
+
|
|
182
|
+
1. **Probes** the local machine once (convert a ~3.6s clip, measure
|
|
183
|
+
`ratio = convert_time / audio_seconds`); results persist to
|
|
184
|
+
`~/.dsh/tts-rvc/calibration.json` (7-day validity, GPU-name fingerprint,
|
|
185
|
+
re-probes on device change), so the probe is paid only once per config;
|
|
186
|
+
2. Picks **chunk size (6–20s) and prewarm count (2–4)** from a ratio tier table;
|
|
187
|
+
3. Splits the text into sentence-aligned chunks, converts the prewarm chunks,
|
|
188
|
+
and returns a **job queue** immediately;
|
|
189
|
+
4. The client **plays while prefetching**: each next chunk is converted during
|
|
190
|
+
the current chunk's playback (`GET /rvc-next`), so long reads stream
|
|
191
|
+
seamlessly on GPU and degrade gracefully on CPU (smaller chunks, more
|
|
192
|
+
prewarm);
|
|
193
|
+
5. The RVC server reports GPU name/VRAM in `/health` and **caches the faiss
|
|
194
|
+
index** so each chunk no longer re-reads the ~400MB index file.
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
# macOS 跨平台实测 Prompt(粘贴给 Mac 上的 LLM)
|
|
2
|
+
|
|
3
|
+
> 用法:把本文全文(从「# 任务」到文末)粘贴给 Mac 上的 LLM(或放入其工作目录让它读取)。
|
|
4
|
+
> 它是自包含的:Mac 上的 LLM 看不到 Windows 这边的对话,一切信息都在下面。
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# 任务
|
|
9
|
+
|
|
10
|
+
你是运行在一台 **macOS 电脑** 上的 AI 助手。你的任务是**在真实 macOS 环境里验证一个开源语音插件的 RVC 变声服务能否跨平台运行**,并如实报告结果(包括失败)。这个插件叫 `dsh-plugin-tts`,Windows 上已完整验证通过(RTX 5070 GPU),但 **macOS 从未实测**——本次就是要补上这个测试,发现任何问题都算有价值的产出。
|
|
11
|
+
|
|
12
|
+
# 背景:被测对象是什么
|
|
13
|
+
|
|
14
|
+
`dsh-plugin-tts` 是一个文本转语音插件,其中「自定义音色(RVC)」模式的工作方式是:
|
|
15
|
+
|
|
16
|
+
1. 一个本地 HTTP 服务 `rvc-server.py` 包装 RVC 的推理核心(一个叫 `infer/` 的代码目录);
|
|
17
|
+
2. 插件把文字先用微软 Edge TTS 读成原声,再把原声音频 POST 给这个服务做音色转换;
|
|
18
|
+
3. 服务把转换后的音频返回给插件播放。
|
|
19
|
+
|
|
20
|
+
`rvc-server.py` 的 HTTP 协议(JSON + base64,无其他依赖):
|
|
21
|
+
|
|
22
|
+
- `GET /health` — 服务状态、设备、已加载模型
|
|
23
|
+
- `GET /files?kind=pth|index` — 扫描本机模型/索引文件
|
|
24
|
+
- `POST /load {"model": "<绝对路径>", "index": "<绝对路径或空>"}` — 加载音色模型
|
|
25
|
+
- `POST /convert {"audio_base64": "<wav 的 base64>", "params": {...}}` — 转换(`f0_method` 默认 `rmvpe`)
|
|
26
|
+
- `POST /compact-index {"index": "<.index 路径>", "target_vectors": 2000}` — 把大索引压缩成小索引
|
|
27
|
+
|
|
28
|
+
macOS 上设备会自动选 **CPU**(`device=cpu, is_half=false`),转换比 Windows GPU 慢是**正常现象**,不算失败。
|
|
29
|
+
|
|
30
|
+
# 本机已验证的环境组合(Windows,务必尽量复刻)
|
|
31
|
+
|
|
32
|
+
| 组件 | 版本 |
|
|
33
|
+
|---|---|
|
|
34
|
+
| Python | 3.9.13 |
|
|
35
|
+
| torch / torchaudio | 2.0.0 / 2.0.1 |
|
|
36
|
+
| fairseq | 0.12.2(PyPI 官方版) |
|
|
37
|
+
| numpy / numba / llvmlite | 1.23.5 / 0.56.4 / 0.39.1 |
|
|
38
|
+
| librosa / scipy | 0.9.1 / 1.9.3 |
|
|
39
|
+
| soundfile / pyworld / resampy | 0.11.0+ / 0.3.2 / 0.4.2 |
|
|
40
|
+
| fastapi / uvicorn | 0.88.0 / 0.20.0 |
|
|
41
|
+
| faiss | faiss-cpu |
|
|
42
|
+
|
|
43
|
+
> 这组版本已被证实与 `rvc-server.py` + 这套 `infer/` 代码兼容。macOS 上**优先按这个表装**;个别包在 macOS 装不上时,见「常见坑」。
|
|
44
|
+
|
|
45
|
+
# 前置条件检查
|
|
46
|
+
|
|
47
|
+
1. macOS 12 或更新(Apple Silicon 或 Intel 均可,推荐 ≥16GB 内存、≥10GB 空闲磁盘);
|
|
48
|
+
2. 已安装:`git`、`ffmpeg`(`brew install ffmpeg`)、Xcode Command Line Tools(`xcode-select --install`);
|
|
49
|
+
3. Python 3.9:推荐用 pyenv(`brew install pyenv && pyenv install 3.9.18 && pyenv local 3.9.18`)。系统自带的 python3 版本若 ≥3.10 也可以先试,但依赖装不上时必须回到 3.9。
|
|
50
|
+
|
|
51
|
+
# 步骤 1:准备 RVC 推理核心 `infer/`
|
|
52
|
+
|
|
53
|
+
`rvc-server.py` 要求旁边有一个 `infer/` 目录(RVC 的推理核心,纯 Python 代码,约 0.7MB)。二选一:
|
|
54
|
+
|
|
55
|
+
- **方案 A(推荐,与已验证代码完全一致)**:用户会从 Windows 机器把 `infer/` 目录和 `requirements.txt` 拷给你(会放在某个约定路径,比如 `~/rvc-transfer/infer/`)。如果没找到,先问用户。
|
|
56
|
+
- **方案 B(拿不到 Windows 文件时)**:
|
|
57
|
+
```bash
|
|
58
|
+
git clone --depth 1 https://github.com/RVC-Project/Retrieval-based-Voice-Conversion-WebUI.git rvc-src
|
|
59
|
+
cp -r rvc-src/infer ~/rvc-work/infer
|
|
60
|
+
cp rvc-src/requirements.txt ~/rvc-work/requirements.txt
|
|
61
|
+
```
|
|
62
|
+
注意:**新版 RVC 仓库(当前 HEAD)的 `infer/` 已经整体重构,不能直接用**——布局从
|
|
63
|
+
`infer/modules/vc/ + infer/lib/infer_pack/` 变成了 `infer/vc/ + infer/module/`,
|
|
64
|
+
hubert 也改成了 HuggingFace Transformers 格式,与 `rvc-server.py` 期望的旧版结构
|
|
65
|
+
(`from infer.modules.vc.modules import VC` 等)完全不兼容,连 `infer/modules` 目录都不存在。
|
|
66
|
+
实测请改用**旧版 tag**(与其锁定依赖匹配):
|
|
67
|
+
```bash
|
|
68
|
+
git clone --depth 1 https://github.com/RVC-Project/Retrieval-based-Voice-Conversion-WebUI.git rvc-src
|
|
69
|
+
cd rvc-src && git fetch --depth 1 origin tag 2.2.231006
|
|
70
|
+
git archive 2.2.231006 infer/ | tar -x -C ../rvc-work/
|
|
71
|
+
git show 2.2.231006:requirements.txt > ../rvc-work/requirements.txt
|
|
72
|
+
```
|
|
73
|
+
若坚持用新布局,`rvc-server.py` 会直接 `ModuleNotFoundError`(没有 `infer/modules`)。
|
|
74
|
+
|
|
75
|
+
另外无论哪种 infer:**手装依赖时,除锁定版本清单外还需** `av`、`praat-parselmouth`、
|
|
76
|
+
`torchcrepe`;`faiss-cpu` 用 `==1.7.3`(最新 1.13 要求 numpy≥1.25);装 `fairseq==0.12.2`
|
|
77
|
+
前把 pip 降到 **<24.1**;保持 `setuptools<81`(否则缺 `pkg_resources`)。
|
|
78
|
+
|
|
79
|
+
# 步骤 2:搭工作目录和模型资产
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
mkdir -p ~/rvc-work/assets/hubert ~/rvc-work/assets/rmvpe ~/rvc-work/assets/weights
|
|
83
|
+
cd ~/rvc-work
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
下载 RVC 必需的两个推理模型(共约 360MB;HuggingFace 在国内可能慢,用 `hf-mirror.com` 镜像):
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
# hubert 特征提取模型(约 181MB)——路径必须与 infer/ 代码引用一致(本套代码是 assets/hubert/hubert_base.pt)
|
|
90
|
+
curl -L -o assets/hubert/hubert_base.pt \
|
|
91
|
+
https://huggingface.co/lj1995/VoiceConversionWebUI/resolve/main/hubert_base.pt
|
|
92
|
+
# 若上面失败/太慢:
|
|
93
|
+
# https://hf-mirror.com/lj1995/VoiceConversionWebUI/resolve/main/hubert_base.pt
|
|
94
|
+
|
|
95
|
+
# rmvpe 音高提取模型(约 173MB)
|
|
96
|
+
curl -L -o assets/rmvpe/rmvpe.pt \
|
|
97
|
+
https://huggingface.co/lj1995/VoiceConversionWebUI/resolve/main/rmvpe.pt
|
|
98
|
+
# 镜像:https://hf-mirror.com/lj1995/VoiceConversionWebUI/resolve/main/rmvpe.pt
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
下载测试音色包(公开仓库 `1624318455/rvc-for-tts`,作者自己训练的音色,许可见仓库 manifest):
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
curl -L -o assets/weights/model.pth \
|
|
105
|
+
https://raw.githubusercontent.com/1624318455/rvc-for-tts/main/packs/guanguanV1/model.pth # 52.5MB
|
|
106
|
+
curl -L -o assets/weights/guanguanV1.index \
|
|
107
|
+
https://raw.githubusercontent.com/1624318455/rvc-for-tts/main/packs/guanguanV1/guanguanV1.index # 32MB(可选)
|
|
108
|
+
# raw.githubusercontent 慢/失败时可用 ghproxy 类镜像,或请用户从 Windows 机器拷
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
# 步骤 3:建 Python 环境(锁定已验证版本)
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
cd ~/rvc-work
|
|
115
|
+
python3.9 -m venv venv # 或 pyenv 的 3.9
|
|
116
|
+
source venv/bin/activate
|
|
117
|
+
pip install -U pip setuptools wheel Cython
|
|
118
|
+
|
|
119
|
+
pip install \
|
|
120
|
+
torch==2.0.0 torchaudio==2.0.1 \
|
|
121
|
+
numpy==1.23.5 numba==0.56.4 llvmlite==0.39.1 \
|
|
122
|
+
librosa==0.9.1 scipy==1.9.3 \
|
|
123
|
+
soundfile>=0.12.1 pyworld==0.3.2 resampy==0.4.2 \
|
|
124
|
+
fastapi==0.88.0 uvicorn==0.20.0 \
|
|
125
|
+
fairseq==0.12.2 faiss-cpu
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
装完立即验证关键依赖能 import(fairseq 是 hubert 加载的依赖,最容易出问题):
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
python -c "import torch, fairseq, faiss, numpy, librosa; from fairseq import checkpoint_utils; print('deps ok', torch.__version__, numpy.__version__)"
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
- 若 `fairseq` 装不上(源码编译失败):先 `pip install --no-build-isolation fairseq==0.12.2`;还不行就试 RVC 官方用的 fork:`pip install "fairseq @ git+https://github.com/One-sixth/fairseq.git"`;都失败就**记录完整报错并继续**(这本身就是测试要收集的信息)。
|
|
135
|
+
- 若报 `np.float` / `np.int` 之类 numpy 兼容错误:`pip install "numpy<1.24"` 强制降回。
|
|
136
|
+
- 若新版 macOS 上 torch 2.0.0 装不上:改 `torch==2.6.0 torchaudio==2.6.0`(`rvc-server.py` 已内置 torch≥2.6 的 `weights_only=False` 补丁,Windows 侧 torch 2.7 验证过)。
|
|
137
|
+
|
|
138
|
+
# 步骤 4:获取被测代码并启动服务
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
git clone https://github.com/1624318455/dsh-plugin-tts.git ~/dsh-plugin-tts
|
|
142
|
+
cp ~/dsh-plugin-tts/rvc-server.py ~/rvc-work/
|
|
143
|
+
cp ~/dsh-plugin-tts/tools/mac-verify.sh ~/rvc-work/
|
|
144
|
+
|
|
145
|
+
cd ~/rvc-work
|
|
146
|
+
nohup venv/bin/python rvc-server.py --port 4892 > server.log 2>&1 &
|
|
147
|
+
sleep 8
|
|
148
|
+
tail -20 server.log
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
**成功的样子**:日志出现 `dsh-plugin-tts RVC server: http://127.0.0.1:4892 (device=cpu, half=False)`。
|
|
152
|
+
(不要传 `--device cuda`——macOS 没有 CUDA,`--device auto` 默认就是 cpu。)
|
|
153
|
+
启动失败就贴完整报错,先排查再继续。
|
|
154
|
+
|
|
155
|
+
# 步骤 5:端到端验证(核心)
|
|
156
|
+
|
|
157
|
+
跑验证脚本(它会依次测 `/health` → `/files` → `/load` → `/convert` → 输出文件 → `/compact-index`):
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
cd ~/rvc-work
|
|
161
|
+
PY=~/rvc-work/venv/bin/python bash mac-verify.sh \
|
|
162
|
+
~/rvc-work/assets/weights/model.pth \
|
|
163
|
+
~/rvc-work/assets/weights/guanguanV1.index
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
预期:
|
|
167
|
+
|
|
168
|
+
- `/health`:`ok:true`、`device:"cpu"`、`cuda_available:false`、`index_cache:true`;
|
|
169
|
+
- `/files`:列出下载的 model.pth;
|
|
170
|
+
- `/load`:`ok:true`,返回模型绝对路径(首次会打印 `Loaded model ... (v2, f0=1, ...)`);
|
|
171
|
+
- `/convert`:首次要加载 hubert+rmvpe(约 30~90 秒,之后快),返回 `sample_rate` 与转换后 wav;输出文件是 RIFF,时长≈输入(约 3 秒);
|
|
172
|
+
- `/compact-index`:返回 `reduction_pct`(几十 %,因为源索引本身不大)。
|
|
173
|
+
|
|
174
|
+
脚本会自己判断 PASS/FAIL。**如果脚本某步失败,不要只报"失败"**——手工复现那一步(curl / python),把 HTTP 状态码、响应体、服务端日志(server.log 尾部)都收集进报告。
|
|
175
|
+
|
|
176
|
+
# 步骤 6(可选):打包脚本 `package-runtime.py` 的 darwin 分支
|
|
177
|
+
|
|
178
|
+
**仅当这台 Mac 上已有一个 RVC WebUI 安装(目录里含 `runtime/` 和 `infer/`)时执行**;没有就跳过并在报告里注明「无 RVC 安装,跳过」。
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
python3 ~/dsh-plugin-tts/tools/package-runtime.py \
|
|
182
|
+
--rvc-dir <RVC安装目录> --out ~/rvc-portable-mac --platform darwin
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
验证产物:
|
|
186
|
+
|
|
187
|
+
1. 结构正确:`~/rvc-portable-mac/runtime/bin/python` 存在、`infer/`、`assets/hubert/`、`assets/rmvpe/`、`rvc-server.py`、`start-rvc-server.sh`(且 `ls -l` 有 x 权限);
|
|
188
|
+
2. 用产物启动并重测一遍核心链路:
|
|
189
|
+
```bash
|
|
190
|
+
~/rvc-portable-mac/start-rvc-server.sh & # 或 ~/rvc-portable-mac/runtime/bin/python ~/rvc-portable-mac/rvc-server.py --port 4893
|
|
191
|
+
PY=~/rvc-portable-mac/runtime/bin/python bash mac-verify.sh \
|
|
192
|
+
~/rvc-portable-mac/assets/weights/model.pth "" 127.0.0.1:4893
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
# 必须汇报的内容(最终报告格式)
|
|
196
|
+
|
|
197
|
+
1. **环境**:macOS 版本、芯片(`uname -m`)、Python 版本、torch 版本、numpy 版本;
|
|
198
|
+
2. **步骤 1-4 的产物**:用了方案 A 还是 B、各文件是否就位(ls 大小);
|
|
199
|
+
3. **步骤 5 结果**:mac-verify.sh 每步 PASS/FAIL + 关键输出(/health 的 JSON、/convert 的耗时与 sample_rate、out.wav 时长);
|
|
200
|
+
4. **耗时数据**:`/convert` 的 wall 耗时与「几倍实时」(CPU 慢正常,记录下来即可);
|
|
201
|
+
5. **任何报错**:完整堆栈/响应体/服务端日志,不要截断;
|
|
202
|
+
6. **步骤 6**:执行了/跳过了;执行了就给产物结构 + 重测结果;
|
|
203
|
+
7. **结论**:macOS 上能否端到端使用;哪些地方需要作者修复或改文档。
|
|
204
|
+
|
|
205
|
+
**重要**:如实汇报。失败、装不上的包、跑不通的步骤都是本次测试的正当产出——宁可报失败,也不要为了让报告好看而省略或掩盖。
|
|
206
|
+
|
|
207
|
+
# 常见坑速查
|
|
208
|
+
|
|
209
|
+
- **HuggingFace 下载慢/超时** → 换 `https://hf-mirror.com/...` 前缀;
|
|
210
|
+
- **GitHub raw 下载慢** → ghproxy 类镜像或让用户拷文件;
|
|
211
|
+
- **fairseq 装不上** → 先 `pip install "pip<24.1"` 降 pip(实测根因是 omegaconf 的
|
|
212
|
+
`PyYAML>=5.1.*` 元数据被新 pip 拒绝,`--no-build-isolation` 无效);再不行才试
|
|
213
|
+
One-sixth fork(见步骤 3);
|
|
214
|
+
- **numpy 2.x 报错** → `pip install "numpy<1.24"`;
|
|
215
|
+
- **缺 `pkg_resources` / librosa 导入失败** → `pip install "setuptools<81"`(新 setuptools 移除了它);
|
|
216
|
+
- **缺 `av` / `parselmouth` / `torchcrepe`** → 旧版 infer 的隐式依赖,`pip install av praat-parselmouth torchcrepe`;
|
|
217
|
+
- **faiss-cpu 装了 1.13 与 numpy 1.23.5 冲突** → `pip install "faiss-cpu==1.7.3"`;
|
|
218
|
+
- **/convert 报 `mode must be 'r', 'w', or None, got: rb`** → PyAV≥10 拒绝 `"rb"/"wb"`
|
|
219
|
+
(macOS 无法装老 PyAV 绕开):手动把 `infer/lib/audio.py` 的
|
|
220
|
+
`av.open(i,"rb")→av.open(i,"r")`、`av.open(o,"wb",...)→av.open(o,"w",...)`;
|
|
221
|
+
用 `package-runtime.py --platform darwin` 打包会自动打此补丁;
|
|
222
|
+
- **mac-verify.sh 第 5 步误报 "not a RIFF file"(exit 1)** → 脚本自身 bug:macOS 的
|
|
223
|
+
`od` 字节间双空格使 `grep "52 49 46 46"` 匹配不到。用新版(已改去空格比 hex)或
|
|
224
|
+
确认 `file out.wav` 确实是 "RIFF ..." 即视为通过;
|
|
225
|
+
- **方案 B 的 infer 目录结构与 rvc-server.py 不匹配** → 当前 HEAD 已重构,用旧 tag
|
|
226
|
+
`2.2.231006`(见步骤 1);
|
|
227
|
+
- **端口被占用** → 换 `--port 4893`,verify 脚本第三个参数跟着改;
|
|
228
|
+
- **/convert 报 `no model loaded`** → 先 /load 成功再 /convert;
|
|
229
|
+
- **/convert 报 `audio decode failed`** → 确认系统 ffmpeg 可用(`ffmpeg -version`);
|
|
230
|
+
- **/convert 超时/极慢** → CPU 推理正常慢,等;若 15 分钟无响应再查 server.log。
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# Windows GPU 回归实测 Prompt(粘贴给 Windows 上的 LLM)
|
|
2
|
+
|
|
3
|
+
> 用法:把本文全文(从「# 任务」到文末)粘贴给 Windows 上的 LLM(或放入其工作目录让它读取)。
|
|
4
|
+
> 它是自包含的:Windows 上的 LLM 看不到 Mac/其他端的对话,一切信息都在下面。
|
|
5
|
+
> 目标:给 `dsh-plugin-tts` 的 **Windows + NVIDIA GPU 路径**做一次完整回归,如实上报(含失败)。
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# 任务
|
|
10
|
+
|
|
11
|
+
你是运行在一台 **Windows 电脑**(NVIDIA GPU,例如 RTX 5070)上的 AI 助手。你的任务是**在真实 Windows + CUDA 环境里对 `dsh-plugin-tts` 做一次完整回归**,确认它的 RVC 变声服务在 GPU 上仍能端到端正常使用,并如实报告(包括失败、装不上的包、跑不通的步骤——这些全是正当产出,不要为了好看而掩盖)。
|
|
12
|
+
|
|
13
|
+
背景:该插件已在 macOS(Apple Silicon)上完整验证过(含 CPU 转换、边界加固、中英文国际化),本次要补的是 **Windows GPU(CUDA)路径**——因为 GPU 才用到 `is_half=True`、`--device cuda`、`torch 2.7+cu128` 这些分支,Mac 上没有动过。
|
|
14
|
+
|
|
15
|
+
# 被测对象
|
|
16
|
+
|
|
17
|
+
`dsh-plugin-tts`:一个文本转语音插件,「自定义音色(RVC)」模式:
|
|
18
|
+
1. 本地 HTTP 服务 `rvc-server.py` 包装 RVC 推理核心(`infer/` 目录,通常来自一套 RVC WebUI 安装);
|
|
19
|
+
2. 插件把文字用 Edge TTS 读成原声,再 POST 给该服务做音色转换,拿回转好的 wav。
|
|
20
|
+
|
|
21
|
+
HTTP 协议(JSON + base64,无额外依赖):
|
|
22
|
+
- `GET /health` — 状态、设备、已加载模型
|
|
23
|
+
- `GET /files?kind=pth|index` — 扫描模型/索引
|
|
24
|
+
- `POST /load {"model":"<路径>","index":"<路径或空>"}` — 加载音色
|
|
25
|
+
- `POST /convert {"audio_base64":"<wav的base64>","params":{...}}` — 转换(`f0_method` 默认 `rmvpe`)
|
|
26
|
+
- `POST /compact-index {"index":"<.index路径>","target_vectors":2000}` — 压缩大索引
|
|
27
|
+
|
|
28
|
+
在 **Windows + CUDA** 上:`--device cuda`(或 `auto` → 有 CUDA 自动选)应得到 `device=cuda`、`cuda_available=true`、`is_half=true`,转换走 GPU、比 CPU 快得多(正常现象,记录耗时即可)。
|
|
29
|
+
|
|
30
|
+
# 前置条件(Windows 侧一般已具备)
|
|
31
|
+
|
|
32
|
+
1. Windows 10/11、NVIDIA GPU(RTX 50 系为佳)、已装 NVIDIA 驱动;
|
|
33
|
+
2. 一套 **RVC WebUI 安装**(目录里含 `runtime\python.exe` 与 `infer\`),例如 Windows 上已验证的 `E:\AI\RVC20240604Nvidia\RVC20240604Nvidia`(内含 `assets\weights`、`assets\indices`、`assets\hubert`、`assets\rmvpe`,以及一个音色 `.pth`+`.index`);
|
|
34
|
+
3. `git`、`ffmpeg`(RVC runtime 自带或系统有);
|
|
35
|
+
4. `node`(≥22,Edge TTS worker 使用原生 `WebSocket`,见 README)与 `npm`(跑插件自带测试用)。
|
|
36
|
+
|
|
37
|
+
# 步骤 1:获取被测代码
|
|
38
|
+
|
|
39
|
+
```powershell
|
|
40
|
+
git clone https://github.com/1624318455/dsh-plugin-tts.git C:\dsh-plugin-tts
|
|
41
|
+
cd C:\dsh-plugin-tts
|
|
42
|
+
$env:DSH_RVC = "E:\AI\RVC20240604Nvidia\RVC20240604Nvidia" # 指向你的 RVC WebUI 根目录,下面都用这个变量
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
仓库内容(供参考):`rvc-server.py`(被测服务)、`lib/`(插件 host/client,i18n 已zh/en)、`tools/mac-verify.sh`、`tools/package-runtime.py`、`tests/`(标准测试:smoke/live/patch/i18n/client)、`.github/workflows/test.yml`(CI,跑在 ubuntu,**不含 GPU**)。
|
|
46
|
+
|
|
47
|
+
> ⚠️ 重要说明:GitHub 的 CI(`.github/workflows/test.yml`)跑在 **ubuntu CPU** 上,**不是** Windows GPU 回归的载体;真正补 Windows GPU 的是你接下来手动执行的内容。
|
|
48
|
+
|
|
49
|
+
# 步骤 2:跑平台无关的自动测试(快速确认代码本身没坏)
|
|
50
|
+
|
|
51
|
+
```powershell
|
|
52
|
+
cd C:\dsh-plugin-tts
|
|
53
|
+
npm install --no-audit --no-fund
|
|
54
|
+
npm test # smoke:43 项(真实 Edge TTS + mock RVC,不需要本地 GPU 服务)
|
|
55
|
+
npm run test:i18n # i18n:6 项(zh/en 键集一致、无残留硬编码中文)
|
|
56
|
+
npm run test:client # client-load:14 项(mock 浏览器渲染)
|
|
57
|
+
npm run test:patch # patch:4 项(darwin-only 的 PyAV 补丁,Windows 不应受影响)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
预期:这些全 PASS(它们平台无关)。若 smoke 因 Edge TTS 联网失败,记录报错即可(网络问题不算产品缺陷)。
|
|
61
|
+
|
|
62
|
+
# 步骤 3:启动 RVC 服务(GPU 路径,核心)
|
|
63
|
+
|
|
64
|
+
用你的 RVC runtime 的 python,**传 `--rvc-dir` 指到 RVC WebUI 根目录**,并显式用 cuda:
|
|
65
|
+
|
|
66
|
+
```powershell
|
|
67
|
+
cd C:\dsh-plugin-tts
|
|
68
|
+
$env:PY = "$env:DSH_RVC\runtime\python.exe"
|
|
69
|
+
|
|
70
|
+
& $env:PY rvc-server.py --rvc-dir $env:DSH_RVC --device cuda --port 4892 | Out-File server.log
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
> 若 `--device cuda` 报无 CUDA,先确认 torch 是 cu 版本(见「常见坑」)。`auto` 也会在有 CUDA 时自动选 cuda。
|
|
74
|
+
|
|
75
|
+
**成功的样子**:日志出现 `dsh-plugin-tts RVC server: http://127.0.0.1:4892 (device=cuda:0, half=True)`。
|
|
76
|
+
启动失败就贴完整报错,先排查再继续。
|
|
77
|
+
|
|
78
|
+
# 步骤 4:GPU 端到端回归(核心)
|
|
79
|
+
|
|
80
|
+
```powershell
|
|
81
|
+
# 任选一个你的真实音色模型/索引(换成实际存在的路径)
|
|
82
|
+
$MODEL = "$env:DSH_RVC\assets\weights\<你的模型>.pth"
|
|
83
|
+
$INDEX = "$env:DSH_RVC\assets\indices\<你的索引>.index" # 可留空走免索引
|
|
84
|
+
|
|
85
|
+
$env:RVC_URL = "http://127.0.0.1:4892"
|
|
86
|
+
npm run test:live # 场景(health/files/load/convert/compact-index) + 边界(坏base64/空音频/未知f0_method/并发)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
`tests/rvc-server-live.mjs` 会自动连 `RVC_URL`,并从 `$RVC_WORK\assets\weights\model.pth`(默认 `~/rvc-work`,Windows 上可设 `RVC_WORK`)找模型/索引做场景测试。想让 **live 场景自动全跑**(别跳过),最省事是把它要的布局准备出来:
|
|
90
|
+
|
|
91
|
+
```powershell
|
|
92
|
+
$env:RVC_WORK = "C:\rvc-live-work"
|
|
93
|
+
New-Item -ItemType Directory -Force -Path "$env:RVC_WORK\assets\weights" | Out-Null
|
|
94
|
+
Copy-Item "$MODEL" "$env:RVC_WORK\assets\weights\model.pth"
|
|
95
|
+
# index 有就拷成 guanguanV1.index,没有就免(场景里 index 可选)
|
|
96
|
+
if (Test-Path $INDEX) { Copy-Item "$INDEX" "$env:RVC_WORK\assets\weights\guanguanV1.index" }
|
|
97
|
+
$env:RVC_URL = "http://127.0.0.1:4892"
|
|
98
|
+
npm run test:live
|
|
99
|
+
```
|
|
100
|
+
即使这样,也**务必**再按下面「手工核对」过一遍 GPU 专属点(健康响应/转换耗时/边界 400),不要只依赖自动化。
|
|
101
|
+
|
|
102
|
+
**务必手工核对以下 GPU 专属点**(这是 MAC 没测过的,最重要):
|
|
103
|
+
|
|
104
|
+
1. `/health` 必须返回:
|
|
105
|
+
```json
|
|
106
|
+
{ "ok": true, "device": "cuda:0", "cuda_available": true, "is_half": true, "index_cache": true }
|
|
107
|
+
```
|
|
108
|
+
2. `/convert` 成功:返回 `sample_rate` 与 `audio_base64`,输出是合法 RIFF wav(下载出来 `ffprobe`/听一下/看时长≈输入),**记录 wall 秒数与「几倍实时」**(GPU 应远快于实时,如 0.05–0.2×)。
|
|
109
|
+
3. 边界:`/convert` 传坏 `audio_base64`、空音频、未知 `f0_method`,应分别返回 **400**(不是 500 崩溃)——这是本轮 macOS 上补的加固,Windows GPU 上必须同样生效。
|
|
110
|
+
4. `/compact-index` 成功:返回 `reduction_pct`(几十 %)。
|
|
111
|
+
|
|
112
|
+
可用一段 PowerShell/Node 快速 curl(等效 `tests/rvc-server-live.mjs` 的场景):
|
|
113
|
+
```powershell
|
|
114
|
+
# health
|
|
115
|
+
curl.exe -s http://127.0.0.1:4892/health
|
|
116
|
+
# load
|
|
117
|
+
curl.exe -s -X POST http://127.0.0.1:4892/load -H "Content-Type: application/json" -d "{\"model\":\"$MODEL\",\"index\":\"$INDEX\"}"
|
|
118
|
+
# convert:把任意 ~2-3s 的 wav 转 base64 发过去(可用 ffmpeg 生成测试音,或录一段话)
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
# 步骤 5(可选但推荐):打包脚本的 Windows 分支
|
|
122
|
+
|
|
123
|
+
```powershell
|
|
124
|
+
python C:\dsh-plugin-tts\tools\package-runtime.py --rvc-dir $env:DSH_RVC --out C:\rvc-portable --skip-torch
|
|
125
|
+
```
|
|
126
|
+
- 产物应含 `runtime\python.exe`、`infer\`、`rvc-server.py`、`启动服务.bat`;
|
|
127
|
+
- **重点核对**:`C:\rvc-portable\infer\lib\audio.py` 里 `av.open(...)` 应**保持原样 `"rb"/"wb"`**(darwin-only 的 PyAV 补丁不能误伤 Windows——若被改成 `"r"/"w"` 说明打包逻辑有 bug,请报)。
|
|
128
|
+
- 用产物启动并重测一遍 `/health` + `/convert`。
|
|
129
|
+
|
|
130
|
+
# 必须汇报的内容(最终报告格式)
|
|
131
|
+
|
|
132
|
+
1. **环境**:Windows 版本、GPU 型号/驱动版本、显存、Python 版本、torch 版本(确认是 cu 版)、numpy 版本、Node/npm 版本;
|
|
133
|
+
2. **步骤 2**:smoke/i18n/client/patch 各自的 PASS/FAIL + 项数;
|
|
134
|
+
3. **步骤 3**:rvc-server 是否 GPU 启动成功,日志里 `device=`/`half=` 那行;
|
|
135
|
+
4. **步骤 4**:`/health` JSON、`/convert` 的 **wall 秒数与几倍实时**、输出 wav 是否合法、边界三步是否 400、`/compact-index` 结果;
|
|
136
|
+
5. **任何报错**:完整堆栈/响应体/服务端日志,不要截断;
|
|
137
|
+
6. **步骤 5**:执行/跳过;执行了就报产物结构 + 重测结果 + `audio.py` 是否被误改;
|
|
138
|
+
7. **结论**:Windows GPU 上能否端到端使用;哪里需要作者修复或改文档。
|
|
139
|
+
|
|
140
|
+
**重要**:如实汇报。失败、异常都是正当产出。
|
|
141
|
+
|
|
142
|
+
# 常见坑速查
|
|
143
|
+
|
|
144
|
+
- **torch 无 CUDA**(`/health` 显示 `cuda_available:false` 或 `--device cuda` 报错)→ 说明 torch 是 CPU 版。用官方 pytorch 索引装 cu 版(RTX 50 系用 cu128):
|
|
145
|
+
`runtime\python.exe -m pip install torch torchaudio --index-url https://download.pytorch.org/whl/cu128`
|
|
146
|
+
国内慢可换 `https://mirrors.aliyun.com/pytorch-wheels/cu128`。
|
|
147
|
+
- **`av` 报 `mode must be 'r','w', or None, got: rb`**(Windows 上若用现代 PyAV 会遇到)→ 这是老 infer 与新 PyAV 的兼容问题;Windows RVC WebUI 自带的旧 PyAV 一般没这问题。若遇到,记录并在报告里标注「发生在 Windows 的 PyAV 版本是 X」。
|
|
148
|
+
- **fairseq 装不上** → 用 RVC runtime 自带环境即可;若自装,`pip<24.1` 再 `pip install fairseq==0.12.2`。
|
|
149
|
+
- **端口占用** → `--port 4893`,并让 `RVC_URL` 跟着改。
|
|
150
|
+
- **/convert 报 `no model loaded`** → 先 `/load` 再 `/convert`。
|
|
151
|
+
- **/convert 极慢或无响应** → 看 server.log;GPU 首次加载 hubert/rmvpe 要少许时间。
|