# VoxCPM2Studio **Repository Path**: ginkdu/VoxCPM2Studio ## Basic Information - **Project Name**: VoxCPM2Studio - **Description**: VoxCPM2 有声书坊 - 基于 llama.cpp-omni (CUDA) + crispasr (Vulkan) 的双引擎 HTTP 架构,48kHz 原生输出,零 PyTorch 依赖,Nuitka 打包 - **Primary Language**: Unknown - **License**: GPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 0 - **Created**: 2026-06-28 - **Last Updated**: 2026-08-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: VoxCPM2 ## README # VoxCPM2 有声书坊 > **出品:公众号「旺丁旺财杂货铺」** > > 基于 VoxCPM2 的中文有声书制作桌面应用,使用 GGUF 量化模型 + Vulkan/CUDA 加速,全程 48kHz 原生输出,零 PyTorch 依赖。 --- ## 项目简介 本项目是 [VoxCPM2](https://github.com/OpenMOSS/VoxCPM2) 有声书工作流的重构版本,用 **llama.cpp-omni(CUDA)** + **crispasr(Vulkan)** 双引擎 HTTP 架构替代原版 PyTorch/CUDA 后端,并通过 Nuitka 打包为单目录分发的桌面应用。 ### 核心特性 - **48kHz 原生音频**:TTS 输出即为 48kHz,与最终 MP3 合并采样率一致,无需重采样 - **双引擎 HTTP 解耦**:TTS(llama-tts-server,CUDA)常驻;ASR(crispasr,Vulkan)懒加载 - **GGUF 量化支持**:BaseLM 支持 F16(高精度)/ Q8_0(推荐)动态切换,无需重启服务 - **零 PyTorch 依赖**:Python 侧仅 6 个包(PyQt6/requests/PyYAML/numpy/soundfile/scipy) - **中文友好**:HTTP JSON UTF-8 字节传输,彻底绕过 PowerShell ANSI 编码导致的中文乱码问题 - **Nuitka 打包**:standalone 模式输出 `VoxCPM2Studio.exe`,附带完整运行时依赖 --- ## 架构总览 ``` ┌─────────────────────────────────────────────────┐ │ VoxCPM2Studio.exe (PyQt6 GUI) │ │ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │ │ │ 主页 │ │ 音色克隆 │ │ 有声书编辑 │ │ │ │ 引擎启停 │ │ ASR转录 │ │ 分段生成+合成│ │ │ │ 量化切换 │ │ 音色管理 │ │ MP3 输出 │ │ │ └────┬─────┘ └────┬─────┘ └──────┬───────┘ │ │ │ │ │ │ │ └─────────────┴───────────────┘ │ │ │ HTTP │ │ ┌─────────────┴───────────────┐ │ │ │ tts_service / asr_service │ │ │ │ (Python HTTP 客户端封装) │ │ │ └─────────────┬───────────────┘ │ └─────────────────────┼───────────────────────────┘ │ ┌─────────────┴──────────────┐ │ │ ┌───────▼────────┐ ┌────────▼─────────┐ │ llama-tts- │ │ crispasr.exe │ │ server.exe │ │ (Vulkan, 8090) │ │ (CUDA, 9060) │ │ │ │ │ │ 懒加载: │ │ 常驻服务 │ │ 克隆音频时启动 │ │ VoxCPM2 GGUF │ │ SenseVoice GGUF │ │ 48kHz 输出 │ │ 中文 ASR │ └────────────────┘ └──────────────────┘ ``` ### 技术栈 | 层级 | 组件 | 说明 | |------|------|------| | **GUI** | PyQt6 | 5 Tab 布局:主页/单句合成/音色克隆/有声书编辑/设置 | | **服务** | requests | HTTP 客户端封装,JSON UTF-8 字节传输 | | **TTS 引擎** | [llama.cpp-omni](https://github.com/tc-mb/llama.cpp-omni) | CUDA 编译(`-DGGML_CUDA=ON`),HTTP server 模式 | | **ASR 引擎** | [crispasr](https://github.com/lovemef/ASRTools) | Vulkan 二进制,SenseVoice GGUF 模型 | | **TTS 模型** | [DennisHuang648/VoxCPM2-GGUF](https://huggingface.co/DennisHuang648/VoxCPM2-GGUF) | 三件套:BaseLM F16/Q8_0 + Acoustic F16 | | **音频处理** | ffmpeg + numpy + scipy | WAV 合并、MP3 转码、采样率处理 | | **打包** | Nuitka | `--standalone` 模式,生成单目录可分发应用 | --- ## 目录结构 ``` crispasr_vulkan/ ├── VoxCPM2Studio.exe # 打包产物入口(打包后) ├── VoxCPM2Studio/ # Python 源码(开发用) │ ├── main.py # 入口 │ ├── config_manager.py # 配置管理(支持 frozen/开发双模式) │ ├── tts_service.py # TTS HTTP 服务封装 │ ├── asr_service.py # ASR HTTP 服务封装(懒加载) │ ├── crispasr_client.py # HTTP 客户端 │ ├── tts_server_manager.py # llama-tts-server 生命周期管理(QThread) │ ├── asr_server_manager.py # crispasr 生命周期管理(QThread,懒加载) │ ├── worker.py # 后台工作线程 │ ├── audio_processor.py # WAV 合并 + MP3 转码 │ ├── text_parser.py # 文本分段 │ ├── models.py # 数据模型 │ ├── widgets/ # PyQt6 UI 组件 │ ├── config.yaml # 路径与参数配置 │ └── requirements.txt # Python 依赖 ├── bin/ # 引擎二进制 │ ├── llama-cpp-omni/ # llama-tts-server.exe + CUDA DLLs │ ├── crispasr_vulkan/ # crispasr.exe + Vulkan DLLs │ └── ffmpeg.exe ├── Models/ # GGUF 模型 │ ├── voxcpm2/ │ │ ├── VoxCPM2-BaseLM-F16.gguf │ │ ├── VoxCPM2-BaseLM-Q8_0.gguf │ │ └── VoxCPM2-Acoustic-F16.gguf │ └── sensevoice-small-q4_k.gguf ├── personas/ # 音色库(参考音频 + 文本) ├── 启动有声书坊.bat # 开发模式启动脚本 ├── build_nuitka.bat # Nuitka 打包脚本 └── .gitignore ``` --- ## 快速开始 ### 一、获取项目 ```bash git clone https://gitee.com//crispasr_vulkan.git cd crispasr_vulkan ``` ### 二、准备运行时依赖 项目代码不含以下大文件,需自行下载放置: #### 1. VoxCPM2 GGUF 模型 从 [HuggingFace: DennisHuang648/VoxCPM2-GGUF](https://huggingface.co/DennisHuang648/VoxCPM2-GGUF) 下载三件套,放到 `Models/voxcpm2/`: ``` Models/voxcpm2/ ├── VoxCPM2-BaseLM-F16.gguf # ~3.0 GB(高精度) ├── VoxCPM2-BaseLM-Q8_0.gguf # ~1.6 GB(推荐) └── VoxCPM2-Acoustic-F16.gguf # ~1.5 GB ``` #### 2. SenseVoice ASR 模型 从[HuggingFace: cstr/sensevoice-small-GGUF](https://huggingface.co/cstr/sensevoice-small-GGUF/)下载sensevoice-small-q4_k.gguf 放置 `Models/sensevoice-small-q4_k.gguf`(用于克隆流程的 ASR 转录)。 #### 3. 引擎二进制 - **llama-tts-server.exe**:从 [llama.cpp-omni](https://github.com/tc-mb/llama.cpp-omni) 源码编译(`-DGGML_CUDA=ON`),输出到 `bin/llama-cpp-omni/` - **crispasr.exe**:从 [ASRTools](https://github.com/lovemef/ASRTools) 获取 Vulkan 版本,放到 `bin/crispasr_vulkan/` - **ffmpeg.exe**:标准 Windows 静态构建,放到 `bin/` 最终目录结构: ``` bin/ ├── llama-cpp-omni/ │ ├── llama-tts-server.exe │ ├── voxcpm2-cli.exe │ ├── ggml-base.dll / ggml-cpu.dll / ggml-cuda.dll / ggml.dll / llama.dll │ └── cudart64_13.dll / cublas64_13.dll / cublasLt64_13.dll / ... ├── crispasr_vulkan/ │ ├── crispasr.exe │ ├── crispasr.dll / ggml*.dll / whisper.dll / ogg.dll / opus.dll │ └── sensevoice 模型(如外置) ├── ffmpeg.exe ├── ffplay.exe └── ffprobe.exe ``` ### 三、开发模式运行 #### 1. 创建虚拟环境(推荐 uv) ```powershell # 使用 uv(推荐) uv venv .venv --python 3.11 .venv\Scripts\activate uv pip install -r VoxCPM2Studio\requirements.txt # 或使用标准 venv python -m venv .venv .venv\Scripts\activate pip install -r VoxCPM2Studio\requirements.txt ``` #### 2. 启动应用 直接双击 `启动有声书坊.bat`,或手动启动: ```powershell .venv\Scripts\python.exe VoxCPM2Studio\main.py ``` ### 四、Nuitka 打包 #### 1. 安装 Nuitka ```powershell .venv\Scripts\activate uv pip install nuitka ``` #### 2. 执行打包 双击 `build_nuitka.bat`,或在命令行执行: ```powershell .venv\Scripts\python.exe -m nuitka ^ --standalone ^ --enable-plugin=pyqt6 ^ --include-qt-plugins=multimedia ^ --include-data-files=VoxCPM2Studio\config.yaml=config.yaml ^ --include-data-files=VoxCPM2Studio\qt_compat.py=qt_compat.py ^ --include-data-files=VoxCPM2Studio\resources=resources ^ --output-dir=dist ^ --output-filename=VoxCPM2Studio.exe ^ VoxCPM2Studio\main.py ``` #### 3. 拷贝运行时依赖 打包完成后,将以下目录拷贝到 `dist\main.dist\`: ```powershell xcopy /E /I /Y bin dist\main.dist\bin xcopy /E /I /Y Models dist\main.dist\Models xcopy /E /I /Y personas dist\main.dist\personas ``` `build_nuitka.bat` 已包含上述自动拷贝步骤。 #### 4. 运行打包产物 ```powershell dist\main.dist\VoxCPM2Studio.exe ``` --- ## 使用指南 ### 主页:引擎控制 1. **选择 EP**:CUDA(默认,需 NVIDIA GPU)/ Vulkan 2. **选择量化**:Q8_0(推荐,1.6GB)/ F16(高精度,3.0GB) 3. **启动 TTS 引擎**:点击"▶ 启动 TTS 引擎",等待状态变为"✓ 运行中" 4. **动态切换量化**:TTS 运行中可通过下拉框切换,无需重启服务 ### 音色克隆 1. 切到"🎙️ 音色克隆"Tab 2. 拖入或选择一段中文参考音频(建议 5-15 秒,干净人声) 3. 点击"ASR 识别":首次会自动启动 crispasr server(约 10-20 秒) 4. 保存为新的音色(生成 `.wav` + `.txt` 到 `personas/`) ### 有声书编辑 1. 切到"📖 有声书编辑"Tab 2. 加载 TXT 小说文件 3. 在段首添加 `【角色名】` 标签(如 `【旁白】`、`【韩立】`) 4. 点击"🔍 解析角色",自动识别并匹配已有音色 5. 选角后点击"📢 生成有声书",逐句生成 WAV 6. 生成完成后点击"🎵 合成 MP3",自动分段合并为多个 MP3 文件 ### 关键参数 | 参数 | 默认值 | 说明 | |------|--------|------| | `cfg_value` | 2 | CFG 引导强度 | | `inference_timesteps` | 20 | 推理步数(原 CLI 默认 10,本项目提升至 20 以提升质量) | | `temperature` | 1.0 | 采样温度(与 VoxCPM2 原作一致) | | `seed` | 0 | 随机种子(0 = 随机) | | `mp3_sample_rate` | 48000 | MP3 采样率(与 TTS 输出一致,无需重采样) | | `pause_between_segments` | 0.5s | 段间停顿 | --- ## 配置说明 ### config.yaml(路径与默认参数) 位于 `VoxCPM2Studio/config.yaml`,定义所有路径和引擎参数。相对路径基于项目根目录(打包后基于 exe 所在目录)。 关键配置项详见 [VoxCPM2Studio/config.yaml](VoxCPM2Studio/config.yaml)。 ### gui_config.yaml(GUI 运行时状态) 由 GUI 自动维护,保存窗口大小、最近打开文件、字体大小等用户偏好。 --- ## 常见问题 ### Q1:启动 TTS 引擎后提示"TTS server 未就绪" **原因**:`config.yaml` 中的路径未正确解析到 `bin/llama-cpp-omni/llama-tts-server.exe`。 **排查**: - 开发模式:检查 `VoxCPM2Studio/config.yaml` 中 `llama_tts_server_bin: "./bin/llama-cpp-omni/llama-tts-server.exe"` 是否存在 - 打包模式:检查 `dist/main.dist/bin/llama-cpp-omni/llama-tts-server.exe` 是否存在 ### Q2:中文 TTS 生成乱码 **原因**:必须使用 HTTP server 模式,不能直接调用 CLI。PowerShell 传中文参数给 native exe 时会被系统 ANSI 编码损坏。 **解决**:本项目已通过 HTTP JSON UTF-8 字节传输彻底绕过此问题,无需额外处理。 ### Q3:Nuitka 打包后路径错误 **原因**:Nuitka standalone 模式不设置 `sys.frozen`。 **解决**:本项目已通过检测 exe 同级目录是否存在 `config.yaml` 来判断打包模式,无需手动干预。 ### Q4:QtMultimedia 播放器不可用 **原因**:Nuitka 默认不打包 QtMultimedia 后端 DLL。 **解决**:`build_nuitka.bat` 已包含 `--include-qt-plugins=multimedia`,确保 `windowsmediaplugin.dll` 和 `ffmpegmediaplugin.dll` 被打包。 ### Q5:打包后中文源码编译失败(C2001 常量中有换行符) **原因**:MSVC 默认用系统代码页(936/GBK)解析源文件,遇到 UTF-8 编码的中文字符串字面量会报错。 **解决**:`build_nuitka.bat` 已设置 `set CL=/utf-8`,强制 MSVC 按 UTF-8 解析源文件。 --- ## 最近更新 ### 有声书编辑 Tab 支持试听波形裁剪 - **工具栏左移**:有声书编辑页的操作按钮(加载 TXT、保存标签、解析角色、选角、插入标签、选角设置、字体大小)整体移到窗口左侧,标题“原文编辑器...”与右侧编辑框左边缘对齐。 - **试听波形裁剪**:在“试听选中对白”区域新增与「音色克隆」Tab 同款的波形显示控件,支持: - 鼠标拖动起点/终点裁剪线; - 起点/终点数值框精确微调; - 双击波形跳转到指定位置播放; - 【应用裁剪】直接覆盖保存回原音频,并更新该句时长与总时长; - 【重置】恢复到本次选中该句时的原始音频(会话级重置)。 > 适用场景:TTS 生成的短句常在尾部带有空白或无效时长,现在可在试听时直接裁剪,无需借助外部音频工具。 --- ## 技术决策 ### 为什么用 llama.cpp-omni 而不是原版 VoxCPM2? | 维度 | 原版 VoxCPM2 | llama.cpp-omni | |------|--------------|----------------| | 后端 | PyTorch + CUDA | llama.cpp + CUDA | | 模型格式 | .pt/.bin | GGUF(支持量化) | | 内存占用 | 高(PyTorch overhead) | 低(ggml 直接 mmap) | | 部署 | 需 torch+cuda 环境 | 单 exe + 几个 DLL | | HTTP server | 无 | 内置(端口可配) | | 量化切换 | 不支持 | 运行时动态切换 | ### 为什么 ASR 用 Vulkan 而不是 CUDA? - **资源隔离**:TTS(CUDA)和 ASR(Vulkan)使用不同 GPU 后端,避免显存争用 - **兼容性**:Vulkan 支持 AMD/NVIDIA/Intel 全系显卡 - **懒加载**:ASR 仅在克隆流程使用,不必常驻显存 ### 为什么 TTS 默认 20 步而 CLI 是 10 步? 实测 20 步在中文长文本上音质更稳定,10 步偶现吞字和发音模糊。代价是生成时间约 2 倍,但有声书场景对质量要求高于速度。 --- ## 致谢 - [VoxCPM2](https://github.com/OpenMOSS/VoxCPM2):原始 TTS 模型 - [llama.cpp-omni](https://github.com/tc-mb/llama.cpp-omni):GGUF 推理引擎 - [DennisHuang648/VoxCPM2-GGUF](https://huggingface.co/DennisHuang648/VoxCPM2-GGUF):量化模型 - [crispasr](https://github.com/lovemef/ASRTools):Vulkan ASR 引擎 - [SenseVoice](https://github.com/FunAudioLLM/SenseVoice):ASR 模型 --- ## License 本项目仅包含上层应用代码,不包含也不分发以下内容: - VoxCPM2 / SenseVoice 模型权重(用户自行下载,遵循各自 License) - llama.cpp-omni / crispasr 二进制(用户自行编译/下载,遵循各自 License) - ffmpeg 二进制(用户自行下载,遵循 LGPL) 上层应用代码遵循 MIT License。 --- ## 出品 **公众号:旺丁旺财杂货铺** 关注公众号获取更多 AI 工具开发教程与项目动态。