bluryar commited on
Commit
f00d065
·
verified ·
1 Parent(s): b1a1e63

Create README.md

Browse files
Files changed (1) hide show
  1. README.md +646 -0
README.md ADDED
@@ -0,0 +1,646 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ base_model:
3
+ - openbmb/VoxCPM-0.5B
4
+ ---
5
+ # VoxCPM ONNX
6
+
7
+ [Github Repo](https://github.com/bluryar/VoxCPM-ONNX)
8
+
9
+ VoxCPM ONNX 是对 [OpenBMB/VoxCPM](https://github.com/OpenBMB/VoxCPM) 开源模型的 ONNX 导出与推理扩展项目。支持将 VoxCPM 文本转语音模型导出为 ONNX 格式并提供高效的推理服务,支持 CPU 和 GPU 部署,提供 REST API 接口。
10
+
11
+ > ⚠️ **重要声明**
12
+ > 1. 本项目代码与本文档完全由生成式AI驱动生成!
13
+ > 2. 使用本项目需遵守VoxCPM以及相关方面的版权规定
14
+ > 3. 当前导出代码因为将所有Decode步骤合并到一个模块中,不得不把固定求解欧拉方程的`timesteps`参数(默认为10,但经过测试timesteps=5也是可用的,并且解码速度可大大提升)
15
+ > 4. 当前导出代码重复导出了两份VoxCPM的权重(Prefill和Decode)
16
+
17
+ ## 项目背景
18
+
19
+ 本项目基于 OpenBMB 团队的 VoxCPM 模型,该模型是一个无需分词器的文本转语音系统,具有以下特点:
20
+ - **上下文感知语音生成**: 能够理解文本内容并生成适当的韵律
21
+ - **真实声音克隆**: 仅需短参考音频即可实现零样本声音克隆
22
+ - **高效合成**: 支持流式合成,适用于实时应用场景
23
+
24
+ 我们的扩展工作专注于 ONNX 导出和推理优化,使模型更易于部署和使用。
25
+
26
+ ## 功能特性
27
+
28
+ ### 原始 VoxCPM 模型能力
29
+ - 🎯 **无需分词器的 TTS**: 直接在连续空间中建模语音,克服离散分词限制
30
+ - 🗣️ **上下文感知语音生成**: 理解文本内容并生成适当的韵律和表达
31
+ - 🎭 **真实声音克隆**: 仅需短参考音频即可实现零样本声音克隆
32
+ - ⚡ **高效合成**: 支持流式合成,适用于实时应用场景
33
+
34
+ ### ONNX 扩展功能
35
+ - 🚀 **ONNX 导出**: 将 PyTorch 模型导出为 ONNX 格式
36
+ - 🔧 **模型优化**: 自动优化导出的 ONNX 模型
37
+ - 🐳 **容器化部署**: 支持 Docker Compose 一键部署
38
+ - 🎯 **REST API**: 提供 OpenAI 兼容的 TTS API
39
+ - 💻 **多平台支持**: 支持 CPU 和 GPU 推理
40
+ - 🎙️ **高质量语音**: 支持多种语音风格和参考音频
41
+
42
+ ## 项目结构
43
+
44
+ ```
45
+ VoxCPM-ONNX/
46
+ ├── onnx/ # ONNX 导出脚本
47
+ │ ├── export_audio_vae_encoder.py
48
+ │ ├── export_audio_vae_decoder.py
49
+ │ ├── export_voxcpm_prefill.py
50
+ │ └── export_voxcpm_decode.py
51
+ ├── src/
52
+ │ ├── onnx_infer/ # ONNX 推理引擎
53
+ │ └── server/ # FastAPI 服务
54
+ ├── export.sh # ONNX 导出主脚本
55
+ ├── opt.sh # 模型优化脚本
56
+ ├── docker-compose.yml # Docker 部署配置
57
+ ├── pyproject.toml # 项目配置和依赖管理
58
+ ├── uv.lock # uv 依赖锁定文件
59
+ └── infer.py # 独立推理脚本
60
+ ```
61
+
62
+ ## 快速开始
63
+
64
+ ### 1. 环境准备
65
+
66
+ #### 系统要求
67
+ - Python 3.10+
68
+ - CUDA 11.8+ (GPU 版本)
69
+ - Docker 和 Docker Compose (可选)
70
+
71
+ #### 环境管理
72
+
73
+ 本项目使用 [uv](https://docs.astral.sh/uv/) 进行环境管理,确保依赖的一致性和可重现性。
74
+
75
+ **使用 uv 创建开发环境:**
76
+ ```bash
77
+ # 克隆项目后,使用 uv 同步环境
78
+ uv sync
79
+
80
+ # 激活虚拟环境
81
+ uv run bash
82
+ # 或
83
+ source .venv/bin/activate
84
+ ```
85
+
86
+ **安装依赖:**
87
+
88
+ **开发环境 (完整功能):**
89
+ ```bash
90
+ uv pip install -e .
91
+ # 或
92
+ pip install -r pyproject.toml
93
+ ```
94
+
95
+ **CPU 推理环境:**
96
+ ```bash
97
+ uv pip install -r requirement.txt
98
+ # 或
99
+ pip install -r requirement.txt
100
+ ```
101
+
102
+ **GPU 推理环境:**
103
+ ```bash
104
+ uv pip install -r requirement-gpu.txt
105
+ # 或
106
+ pip install -r requirement-gpu.txt
107
+ ```
108
+
109
+ ### 2. 获取预训练模型
110
+
111
+ 从官方 VoxCPM 仓库下载预训练模型(VoxCPM-0.5B):
112
+
113
+ **自动下载(推荐):**
114
+ ```python
115
+ from huggingface_hub import snapshot_download
116
+ snapshot_download("openbmb/VoxCPM-0.5B")
117
+ ```
118
+
119
+ **手动下载:**
120
+ ```bash
121
+ # 创建模型目录
122
+ mkdir -p VoxCPM-0.5B
123
+
124
+ # 下载模型文件到该目录
125
+ # 访问 https://huggingface.co/openbmb/VoxCPM-0.5B 获取模型文件
126
+ ```
127
+
128
+ **可选增强模型(用于语音增强和提示处理):**
129
+ ```python
130
+ from modelscope import snapshot_download
131
+ snapshot_download('iic/speech_zipenhancer_ans_multiloss_16k_base')
132
+ snapshot_download('iic/SenseVoiceSmall')
133
+ ```
134
+
135
+ ### 3. 导出 ONNX 模型
136
+
137
+ 使用一键导出脚本将 PyTorch 模型导出为 ONNX 格式:
138
+
139
+ ```bash
140
+ # 基本用法
141
+ bash export.sh
142
+
143
+ # 自定义参数
144
+ MODEL_PATH=./VoxCPM-0.5B OUTPUT_DIR=./onnx_models TIMESTEPS=10 CFG_VALUE=2.0 bash export.sh
145
+ ```
146
+
147
+ 导出过程将生成以下模型文件:
148
+ - `audio_vae_encoder.onnx` - 音频 VAE 编码器
149
+ - `audio_vae_decoder.onnx` - 音频 VAE 解码器
150
+ - `voxcpm_prefill.onnx` - VoxCPM 预填充模型
151
+ - `voxcpm_decode_step.onnx` - VoxCPM 解码步骤模型
152
+
153
+ ### 4. 优化 ONNX 模型
154
+
155
+ 使用优化脚本对导出的模型进行进一步优化:
156
+
157
+ ```bash
158
+ bash opt.sh
159
+ ```
160
+
161
+ 优化后的模型将保存在 `onnx_models_processed/` 目录中。
162
+
163
+ ### 5. 启动服务
164
+
165
+ #### 使用 Docker Compose (推荐)
166
+
167
+ **GPU 版本:**
168
+ ```bash
169
+ # 确保已安装 NVIDIA Container Toolkit
170
+ docker-compose up voxcpm-gpu
171
+ ```
172
+
173
+ **CPU 版本:**
174
+ ```bash
175
+ # 取消 docker-compose.yml 中 voxcpm-cpu 服务的注释
176
+ docker-compose up voxcpm-cpu
177
+ ```
178
+
179
+ 服务启动后,API 将在以下地址可用:
180
+ - 主服务: http://localhost:8100
181
+ - 健康检查: http://localhost:8100/health
182
+ - **📚 交互式API文档**: http://localhost:8100/docs (Swagger UI界面,可在线测试所有接口)
183
+
184
+ #### 手动启动
185
+
186
+ **GPU 版本:**
187
+ ```bash
188
+ # 设置环境变量
189
+ export VOX_OUTPUT_DIR=./outputs
190
+ export VOX_SQLITE_PATH=./ref_feats.db
191
+ export VOX_DEVICE=cuda
192
+ export VOX_DEVICE_ID=0
193
+ export VOX_MODELS_DIR=./models/onnx_models_quantized
194
+ export VOX_TOKENIZER_DIR=./models/onnx_models_quantized
195
+ export PYTHONPATH=./src
196
+
197
+ # 启动服务
198
+ python -m uvicorn src.server.app:app --host 0.0.0.0 --port 8000
199
+
200
+ # 服务启动后访问
201
+ # 📚 交互式API文档: http://localhost:8000/docs
202
+ ```
203
+
204
+ **CPU 版本:**
205
+ ```bash
206
+ # 设置环境变量
207
+ export VOX_OUTPUT_DIR=./outputs
208
+ export VOX_SQLITE_PATH=./ref_feats.db
209
+ export VOX_DEVICE=cpu
210
+ export VOX_DEVICE_ID=0
211
+ export VOX_MODELS_DIR=./models/onnx_models_quantized
212
+ export VOX_TOKENIZER_DIR=./models/onnx_models_quantized
213
+ export PYTHONPATH=./src
214
+
215
+ # 启动服务
216
+ python -m uvicorn src.server.app:app --host 0.0.0.0 --port 8000
217
+ ```
218
+
219
+ ## API 使用
220
+
221
+ ### 可用端点
222
+
223
+ **📚 API文档**: 部署Docker服务后,访问 `http://<HOST>:<PORT>/docs` 即可查看所有接口的交互式文档(Swagger UI)!
224
+
225
+ **健康检查:**
226
+ - `GET /health` - 检查服务状态和模型加载情况
227
+
228
+ **参考音频管理:**
229
+ - `POST /ref_feat` - 上传参考音频并编码存储特征到数据库
230
+
231
+ **文本转语音:**
232
+ - `POST /tts` - TTS语音生成(POST方式,支持文件上传)
233
+ - `GET /tts` - TTS语音生成(GET方式,仅URL参数)
234
+
235
+ ### 接口详细说明
236
+
237
+ #### 1. 健康检查 (GET /health)
238
+ ```bash
239
+ curl http://localhost:8100/health
240
+ ```
241
+ **响应示例:**
242
+ ```json
243
+ {
244
+ "status": "ok",
245
+ "initialized": true,
246
+ "models_dir": "/root/code/VoxCPM/onnx_models",
247
+ "device_type": "cuda",
248
+ "device_id": 0
249
+ }
250
+ ```
251
+
252
+ #### 2. 上传参考音频 (POST /ref_feat)
253
+
254
+ **功能说明**: 上传参考音频文件,系统会提取音频特征并持久化存储到 SQLite 数据库中。上传后的参考音频可以通过 `feat_id` 在后续的 TTS 请求中重复使用。
255
+
256
+ **使用场景**:
257
+ - 创建个性化的语音克隆
258
+ - 保存特定说话人的声音特征
259
+ - 避免重复上传相同的参考音频
260
+
261
+ **请求参数**:
262
+ - `feat_id` (必填): 参考音频的唯一标识符,后续通过此 ID 引用该音频
263
+ - `prompt_audio` (必填): 参考音频文件 (支持 WAV、MP3 等格式)
264
+ - `prompt_text` (可选): 参考音频对应的文本内容,有助于提高合成质量
265
+
266
+ **使用示例**:
267
+ ```bash
268
+ curl -X POST http://localhost:8100/ref_feat \
269
+ -F "feat_id=my_voice" \
270
+ -F "prompt_audio=@reference.wav" \
271
+ -F "prompt_text=这是参考文本内容,可以帮助模型更好地理解声音特征"
272
+ ```
273
+
274
+ **响应示例:**
275
+ ```json
276
+ {
277
+ "feat_id": "my_voice",
278
+ "patches_shape": [1, 100, 64]
279
+ }
280
+ ```
281
+
282
+ **持久化存储**: 上传的参考音频特征会永久保存在 SQLite 数据库中(路径由 `VOX_SQLITE_PATH` 环境变量配置),服务重启后仍然可用。
283
+
284
+ #### 3. 文本转语音 - POST方式
285
+
286
+ **voice 参数作用说明**:
287
+ - `"default"`: 使用系统默认的参考音频进行语音合成
288
+ - 自定义 `feat_id`: 使用通过 `/ref_feat` 上传的参考音频进行语音克隆
289
+ - 留空或不传: 不使用参考音频,仅基于文本进行基础合成
290
+
291
+ **使用场景**:
292
+ - **默认声音**: 快速测试或基础语音合成
293
+ - **自定义声音**: 个性化语音克隆,复现已上传的说话人声音
294
+ - **声音切换**: 在同一服务中使用多个不同的说话人声音
295
+
296
+ **请求示例**:
297
+ ```bash
298
+ # 使用默认声音
299
+ curl -X POST http://localhost:8100/tts \
300
+ -F "input=你好,这是一个测试文本。" \
301
+ -F "voice=default" \
302
+ -F "response_format=mp3"
303
+
304
+ # 使用自定义参考声音(需要先通过 /ref_feat 上传)
305
+ curl -X POST http://localhost:8100/tts \
306
+ -F "input=使用自定义声音合成这段文本。" \
307
+ -F "voice=my_custom_voice" \
308
+ -F "response_format=mp3"
309
+
310
+ # 完整参数示例
311
+ curl -X POST http://localhost:8100/tts \
312
+ -F "input=你好,这是一个测试文本。" \
313
+ -F "voice=my_voice" \
314
+ -F "response_format=mp3" \
315
+ -F "speed=1.0" \
316
+ -F "min_len=2" \
317
+ -F "max_len=2000" \
318
+ -F "cfg_value=2.0" \
319
+ --output output.mp3
320
+ ```
321
+
322
+ #### 4. 文本转语音 - GET方式
323
+
324
+ **voice 参数说明**: 与 POST 方式相同,支持 `"default"`、自定义 `feat_id` 或留空。
325
+
326
+ **使用示例**:
327
+ ```bash
328
+ # 使用默认声音
329
+ curl "http://localhost:8100/tts?input=你好,世界!&voice=default&response_format=mp3" \
330
+ --output output.mp3
331
+
332
+ # 使用自定义参考声音
333
+ curl "http://localhost:8100/tts?input=使用自定义声音合成这段文本��&voice=my_custom_voice&response_format=wav" \
334
+ --output custom_output.wav
335
+
336
+ # 不使用参考音频(基础合成)
337
+ curl "http://localhost:8100/tts?input=基础语音合成测试&response_format=mp3" \
338
+ --output basic_output.mp3
339
+ ```
340
+
341
+ ### 参数说明
342
+
343
+ **通用参数:**
344
+ - `input` (必填): 要转换的文本内容
345
+ - `voice`: 参考音频ID,支持 "default" 或自定义ID
346
+ - `response_format`: 输出格式 (mp3, wav, opus, aac, flac, pcm),默认 mp3
347
+ - `speed`: 语速 (占位符,暂不支持变速)
348
+ - `prompt_text`: 参考音频对应的文本内容
349
+ - `min_len`: 最小音频长度,默认 2
350
+ - `max_len`: 最大音频长度,默认 2000
351
+ - `cfg_value`: CFG系数,默认 2.0
352
+
353
+ ### 完整工作流程示例
354
+
355
+ #### 步骤 1: 上传参考音频(一次性操作)
356
+ ```python
357
+ import requests
358
+
359
+ # 上传参考音频文件
360
+ with open("my_reference_audio.wav", "rb") as f:
361
+ files = {"prompt_audio": f}
362
+ data = {
363
+ "feat_id": "speaker_john", # 自定义标识符
364
+ "prompt_text": "这是参考音频的文本内容"
365
+ }
366
+ response = requests.post("http://localhost:8100/ref_feat", files=files, data=data)
367
+
368
+ if response.status_code == 200:
369
+ print(f"参考音频上传成功: {response.json()}")
370
+ # 输出: {'feat_id': 'speaker_john', 'patches_shape': [1, 100, 64]}
371
+ else:
372
+ print(f"上传失败: {response.text}")
373
+ ```
374
+
375
+ #### 步骤 2: 使用上传的参考音频进行语音合成
376
+ ```python
377
+ import requests
378
+
379
+ # 使用已上传的参考音频进行语音合成
380
+ response = requests.post(
381
+ "http://localhost:8100/tts",
382
+ data={
383
+ "input": "使用约翰的声音合成这段文本。",
384
+ "voice": "speaker_john", # 使用步骤1中上传的参考音频ID
385
+ "response_format": "mp3",
386
+ "cfg_value": 2.0
387
+ }
388
+ )
389
+
390
+ if response.status_code == 200:
391
+ with open("john_voice_output.mp3", "wb") as f:
392
+ f.write(response.content)
393
+ print("语音合成成功,文件已保存为 john_voice_output.mp3")
394
+ else:
395
+ print(f"合成失败: {response.text}")
396
+ ```
397
+
398
+ #### 步骤 3: 验证参考音频是否可用
399
+ ```python
400
+ import requests
401
+
402
+ # 检查服务状态和已上传的参考音频
403
+ response = requests.get("http://localhost:8100/health")
404
+ health_info = response.json()
405
+
406
+ if health_info["initialized"]:
407
+ print("服务正常运行")
408
+ print(f"模型目录: {health_info['models_dir']}")
409
+ print(f"设备类型: {health_info['device_type']}")
410
+ else:
411
+ print(f"服务未初始化: {health_info.get('error', '未知错误')}")
412
+ ```
413
+
414
+ ### Python 客户端示例
415
+
416
+ #### 基础TTS请求
417
+ ```python
418
+ import requests
419
+
420
+ # GET方式简单请求
421
+ response = requests.get(
422
+ "http://localhost:8100/tts",
423
+ params={
424
+ "input": "欢迎使用 VoxCPM ONNX 文本转语音服务。",
425
+ "voice": "default",
426
+ "response_format": "wav"
427
+ }
428
+ )
429
+
430
+ # 保存音频文件
431
+ with open("output.wav", "wb") as f:
432
+ f.write(response.content)
433
+ ```
434
+
435
+ #### 上传参考音频
436
+ ```python
437
+ import requests
438
+
439
+ # 上传参考音频
440
+ with open("reference.wav", "rb") as f:
441
+ files = {"prompt_audio": f}
442
+ data = {
443
+ "feat_id": "my_custom_voice",
444
+ "prompt_text": "这是参考音频的文本内容"
445
+ }
446
+ response = requests.post("http://localhost:8100/ref_feat", files=files, data=data)
447
+
448
+ print(response.json())
449
+ ```
450
+
451
+ #### 使用自定义参考音频进行TTS
452
+ ```python
453
+ import requests
454
+
455
+ # 使用已上传的参考音频
456
+ response = requests.post(
457
+ "http://localhost:8100/tts",
458
+ data={
459
+ "input": "使用自定义声音合成这段文本。",
460
+ "voice": "my_custom_voice",
461
+ "response_format": "mp3"
462
+ }
463
+ )
464
+
465
+ with open("custom_voice_output.mp3", "wb") as f:
466
+ f.write(response.content)
467
+ ```
468
+
469
+ ## 环境变量配置
470
+
471
+ | 变量名 | 说明 | 默认值 |
472
+ |--------|------|--------|
473
+ | `VOX_OUTPUT_DIR` | 输出音频文件目录 | `./outputs` |
474
+ | `VOX_SQLITE_PATH` | 参考特征数据库路径 | `./ref_feats.db` |
475
+ | `VOX_DEVICE` | 推理设备 (cpu/cuda) | `cuda` |
476
+ | `VOX_DEVICE_ID` | GPU 设备 ID | `0` |
477
+ | `VOX_MODELS_DIR` | ONNX 模型目录 | `./models/onnx_models_quantized` |
478
+ | `VOX_TOKENIZER_DIR` | 分词器目录 | `./models/onnx_models_quantized` |
479
+ | `VOX_KEEP_AUDIO_FILES` | 是否保留生成的音频文件 | `false` |
480
+ | `PYTHONPATH` | Python 模块路径 | `./src` |
481
+
482
+ ## 高级配置
483
+
484
+ ### 导出参数
485
+
486
+ 在运行 `export.sh` 时,可以通过环境变量自定义以下参数:
487
+
488
+ | 变量名 | 说明 | 默认值 |
489
+ |--------|------|--------|
490
+ | `MODEL_PATH` | 原始模型路径 | `./VoxCPM-0.5B` |
491
+ | `OUTPUT_DIR` | ONNX 模型输出目录 | `./onnx_models` |
492
+ | `OPSET_VERSION` | ONNX 算子集版本 | `20` |
493
+ | `AUDIO_LENGTH` | 音频长度 | `16000` |
494
+ | `LATENT_LENGTH` | 潜变量长度 | `100` |
495
+ | `LATENT_DIM` | 潜变量维度 | `64` |
496
+ | `TIMESTEPS` | 扩散步数 | `10` |
497
+ | `CFG_VALUE` | CFG 系数 | `2.0` |
498
+ | `RTOL` | 验证相对容差 | `1e-3` |
499
+ | `ATOL` | 验证绝对容差 | `1e-4` |
500
+ | `NUM_TESTS` | 验证测试次数 | `5` |
501
+
502
+ ### 自定义参考音频
503
+
504
+ 1. 准备参考音频文件(WAV 格式,16kHz)
505
+ 2. 使用 `infer.py` 脚本提取特征:
506
+
507
+ ```bash
508
+ python infer.py \
509
+ --model_dir ./models/onnx_models_quantized \
510
+ --ref_audio ./reference.wav \
511
+ --ref_text "参考文本内容" \
512
+ --feat_id custom_voice
513
+ ```
514
+
515
+ ## 技术说明与限制
516
+
517
+ ### 当前实现限制
518
+
519
+ 1. **Timesteps 参数固定**: 由于将所有 Decode 步骤合并到一个 ONNX 模块中,求解欧拉方程的 `timesteps` 参数被固定。默认值为 10,但测试表明 timesteps=5 也可用,且能显著提升解码速度。
520
+
521
+ 2. **权重重复导出**: 当前导出代码会重复导出两份 VoxCPM 权重(Prefill 和 Decode),这会增加模型文件大小。
522
+
523
+ 3. **模型优化**: 建议使用 `opt.sh` 脚本对导出的模型进行优化,以减少模型大小并提升推理性能。
524
+
525
+ ### 性能优化建议
526
+
527
+ - **调整 Timesteps**: 对于速度敏感的应用,可以尝试 timesteps=5 以提升性能
528
+ - **模型量化**: 使用 ONNX 量化工具进一步优化模型大小
529
+ - **批处理**: 对于批量推理场景,考虑使用动态批处理提升吞吐量
530
+
531
+ ## 故障排除
532
+
533
+ ### 常见问题
534
+
535
+ **1. ONNX 导出失败**
536
+ - 检查 PyTorch 和 ONNX 版本兼容性
537
+ - 确保模型文件完整且路径正确
538
+ - 验证 CUDA 驱动版本(GPU 版本)
539
+
540
+ **2. Docker 容器启动失败**
541
+ - 检查 NVIDIA Container Toolkit 安装(GPU 版本)
542
+ - 验证端口是否被占用
543
+ - 检查卷挂载路径是否正确
544
+
545
+ **3. 推理速度慢**
546
+ - GPU 版本:检查 CUDA 和 cuDNN 版本
547
+ - CPU 版本:尝试调整 `OMP_NUM_THREADS` 环境变量
548
+ - 确保模型已优化 (`opt.sh`)
549
+
550
+ **4. 音频质量差**
551
+ - 检查输入文本质量
552
+ - 尝试不同的 `cfg_value` 参数
553
+ - 验证参考音频质量(如使用参考音频)
554
+
555
+ ### 性能优化
556
+
557
+ **GPU 优化:**
558
+ ```bash
559
+ export CUDA_VISIBLE_DEVICES=0
560
+ export OMP_NUM_THREADS=4
561
+ export ONNXRUNTIME_SESSION_OPTIONS_INTRA_OP_NUM_THREADS=4
562
+ ```
563
+
564
+ **CPU 优化:**
565
+ ```bash
566
+ export OMP_NUM_THREADS=$(nproc)
567
+ export ONNXRUNTIME_SESSION_OPTIONS_INTRA_OP_NUM_THREADS=$(nproc)
568
+ ```
569
+
570
+ ## 开发指南
571
+
572
+ ### 与原始 VoxCPM 项目的关系
573
+
574
+ 本项目是 VoxCPM 的 ONNX 导出和推理扩展,专注于:
575
+ - 将 PyTorch 模型导出为 ONNX 格式以提高部署效率
576
+ - 提供基于 ONNX Runtime 的高性能推理引擎
577
+ - 添加 REST API 服务接口
578
+ - 支持容器化部署
579
+
580
+ 原始 VoxCPM 项目专注于模型训练和 PyTorch 推理,而本项目专注于生产环境的 ONNX 部署。
581
+
582
+ ### 本地开发
583
+
584
+ 1. 克隆仓库
585
+ 2. 使用 uv 创建开发环境
586
+ 3. 安装开发依赖
587
+ 4. 运行测试
588
+
589
+ ```bash
590
+ # 使用 uv 创建开发环境
591
+ uv sync
592
+
593
+ # 激活虚拟环境
594
+ uv run bash
595
+ # 或
596
+ source .venv/bin/activate
597
+
598
+ # 安装开发依赖
599
+ uv pip install -e .
600
+
601
+ # 运行测试
602
+ pytest tests/
603
+
604
+ # 代码格式化
605
+ black src/
606
+ isort src/
607
+ ```
608
+
609
+ ### 添加新功能
610
+
611
+ 1. 在 `src/onnx_infer/` 中添加新的推理模块
612
+ 2. 更新 `src/server/app.py` 中的 API 接口
613
+ 3. 添加相应的测试用例
614
+ 4. 更新文档
615
+
616
+ ## 许可证与免责声明
617
+
618
+ ### 版权说明
619
+ - 本项目基于原始 VoxCPM 模型的许可证
620
+ - 使用本项目需遵守 VoxCPM 以及相关方面的版权规定
621
+ - 请确保在使用前阅读并理解相关许可证条款
622
+
623
+ ### AI 生成声明
624
+ **重要**: 本项目代码与本文档完全由生成式AI驱动生成!
625
+
626
+ ### 使用限制
627
+ - 本项目仅供学习和研究用途
628
+ - 商业使用需获得相关授权
629
+ - 使用者需自行承担使用风险
630
+
631
+ ## 致谢
632
+
633
+ - VoxCPM 原始模型和团队
634
+ - ONNX Runtime 项目
635
+ - FastAPI 框架
636
+
637
+ ## 支持
638
+
639
+ 如遇到问题,请:
640
+ 1. 查看本 README 的故障排除部分
641
+ 2. 检查 GitHub Issues
642
+ 3. 提交新的 Issue 并提供详细信息
643
+
644
+ ---
645
+
646
+ **注意**: 本项目专注于 ONNX 推理部署,如需原始 PyTorch 模型训练,请参考 VoxCPM 官方仓库。