微调指南

本指南介绍如何使用两种方式微调 VoxCPM:LoRA(参数高效)与全量微调。二者使用相同的训练脚本与数据格式。


环境准备

软件要求

依赖

版本

Python

训练建议使用 3.10–3.11

PyTorch

2.5.0+

CUDA

12.0+

safetensors

推荐(若不可用则回退到 .bin / .ckpt

训练脚本还会用到以下 Python 包:tensorboardXargbindtransformers (余弦调度器)、librosa (验证用 mel 频谱)。

硬件要求

配置

LoRA

Full Fine-Tuning

VoxCPM 1.5 (750M)

约 12 GB 显存

约 24 GB 显存

VoxCPM 2 (2B)

约 20 GB 显存

约 40 GB 显存

以上为在 batch_size=16max_batch_tokens=8192 下的粗略估算;实际占用取决于音频长度与梯度累积步数。若出现 OOM,请参阅 微调常见问题

多卡训练可通过 torchrun 进行:

CUDA_VISIBLE_DEVICES=0,1,2,3 torchrun --nproc_per_node=4 \
    scripts/train_voxcpm_finetune.py --config_path your_config.yaml

数据准备

数据格式

训练数据为 JSONL 清单文件,每行一个样本:

{"audio": "path/to/audio1.wav", "text": "Transcript of audio 1."}
{"audio": "path/to/audio2.wav", "text": "Transcript of audio 2.", "ref_audio": "path/to/audio1.wav"}
{"audio": "path/to/audio3.wav", "text": "Optional fields.", "duration": 3.5, "dataset_id": 1}

字段

必填

说明

audio

音频文件路径(建议 WAV)

text

与音频内容一致的转写文本

ref_audio

Path to a reference audio clip from the same speaker. It is used as speaker-conditioning context for voice cloning, so it does not need to be an unseen sample. In practice, ref_audio is typically another clip randomly sampled from the same speaker / timbre as the target audio. When present, the training sequence is constructed as [103, ref_feats, 104, text, 101, audio_feats, 102], teaching the model to clone the speaker's voice from the reference. Loss is only computed on the target audio segment.

duration

时长(秒);可加速按长度过滤

dataset_id

多数据集混合用的整数 ID(默认:0)

仓库中的 examples/train_data_example.jsonl 可供参考。

小技巧

Mixing ref_audio and non-ref_audio samples — We recommend that 30–50% of your training samples include ref_audio, so the model retains both zero-shot and reference-based voice cloning abilities. A simple strategy is to randomly choose another clean recording from the same speaker as ref_audio for each target sample.

音频要求

  • 格式: 建议使用 WAV;torchaudio 支持的其它格式也可用。

  • 采样率: 数据加载器会自动重采样到目标模型的采样率,一般无需预先重采样。训练配置中的 sample_rate 必须匹配 AudioVAE 编码器的输入采样率:

    • VoxCPM 1.0:16 kHz

    • VoxCPM 1.5:44.1 kHz

    • VoxCPM 2:16 kHz(编码器以 16 kHz 运行;解码器输出 48 kHz)

  • 时长: 每条片段 3–30 秒较为稳妥。过短(< 1 s)容易不稳定;过长会增加显存占用,并可能被 max_batch_tokens 过滤。

预处理要点

  • 去掉尾部静音,控制在 0.5 秒以内。尾静音过长是微调后「生成停不下来」最常见原因之一。

  • 若录音电平不一致,请做音量归一化

  • 转写要干净: 文本须与音频逐字一致;不匹配会同时损害克隆质量与文本贴合度。

  • 剔除噪声样本。 模型对训练数据中的背景噪声较敏感。

选择哪种微调方式

数据规模与目标决定采用哪种微调方式:

目标

数据量

推荐做法

克隆单个说话人

5–50 条片段

LoRA Fine-Tuning — 快、显存占用低

适配领域或风格

50–500 条片段

LoRA Fine-Tuning — 使用更高 rank(r=32–64

新增语言

500+ 小时

Full Fine-Tuning — 混入部分中英数据以减轻遗忘

大规模定制

1000+ 条片段

Full Fine-Tuning

LoRA 与全量微调一览:

在内部单说话人克隆基准上,LoRA(r=32)的说话人相似度约为全量微调的 98%,显存约减半,checkpoint 体积也小几个数量级。多数任务建议从 LoRA 起步;不同数据与目标下结果会有差异。


LoRA Fine-Tuning

LoRA 在冻结基座的前提下,仅训练少量附加参数(通常 < 模型参数的 1%)。多数微调任务建议从此入手。

Training

配置

请创建 YAML 配置文件。以下为 VoxCPM 2 的示例:

pretrained_path: /path/to/VoxCPM2/
train_manifest: /path/to/train.jsonl
val_manifest: /path/to/val.jsonl   # optional, leave empty to skip validation

sample_rate: 16000        # AudioVAE encoder input rate (NOT the 48kHz output rate)
out_sample_rate: 48000    # AudioVAE decoder output rate; only used at inference, not during training
batch_size: 16
grad_accum_steps: 1
num_workers: 2
num_iters: 1000
log_interval: 10
valid_interval: 500
save_interval: 500

learning_rate: 0.0001
weight_decay: 0.01
warmup_steps: 100
max_steps: 1000
max_batch_tokens: 8192

save_path: /path/to/checkpoints/lora
tensorboard: /path/to/logs/lora

lambdas:
  loss/diff: 1.0
  loss/stop: 1.0

lora:
  enable_lm: true
  enable_dit: true
  enable_proj: false
  r: 32
  alpha: 32
  dropout: 0.0

小技巧

若使用 VoxCPM 1.5,请将 sample_rate 改为 44100,并将 pretrained_path 指向你的 1.5 checkpoint。sample_rate 必须始终匹配 config.json 中 AudioVAE 编码器的输入采样率 — 而非输出采样率。训练脚本会依据 config.json 自动识别模型结构。

LoRA 参数说明

参数

说明

建议值

enable_lm

对语言模型(基座 LM + 残差 LM)应用 LoRA

true

enable_dit

对扩散 Transformer(DiT)应用 LoRA

true (对音质至关重要)

enable_proj

对 LM 与 DiT 之间的投影层应用 LoRA

多数场景用 false

r

LoRA 秩(rank)— 越大容量越高

克隆说话人用 32;风格/语言适配用 64

alpha

缩放因子(scaling = alpha / r

通常取 r2*r,按需调节 LoRA 影响强度。

dropout

LoRA 层上的 Dropout

除非过拟合,否则 0.0

启动

# Single GPU
python scripts/train_voxcpm_finetune.py --config_path conf/your_lora_config.yaml

# Multi-GPU
CUDA_VISIBLE_DEVICES=0,1,2,3 torchrun --nproc_per_node=4 \
    scripts/train_voxcpm_finetune.py --config_path conf/your_lora_config.yaml

LoRA WebUI

VoxCPM 还提供基于 Gradio 的界面,将 LoRA 训练与推理集成在同一处:

python lora_ft_webui.py

训练观察

训练日志写入 TensorBoard。可用如下命令启动查看:

tensorboard --logdir /path/to/logs/lora

关注哪些指标

指标

含义

loss/diff

扩散损失 — 应持续下降后趋于平稳

loss/stop

停止预测损失 — 应较早稳定并保持较低

grad_norm

梯度范数 — 尖峰可能表示坏样本或学习率过高

lr

学习率曲线 — 带 warm-up 的余弦衰减,可用于核对调度是否符合预期

若提供验证清单,脚本还会记录 val/loss,并在每个 valid_interval 在 TensorBoard 中生成样本音频与 mel 频谱。

何时停止

  • 可把 epoch 数当作粗参考。 单说话人克隆通常 1–3 个 epoch 足够;再往后往往弊大于利 — TTS 微调的过拟合可能很早出现。

  • loss/diff 进入平台期,不再有实质下降。

  • TensorBoard 中的生成音频在目标音色/风格上听起来已经满意。

  • 若模型开始忽略输入文本(无论输入什么都生成相似音频),即已过拟合 — 请回退到较早的 checkpoint。

小技巧

验证损失与主观听感未必完全一致。建议在收敛区间附近多存几个 checkpoint,用实际推理试听后再选定最佳。

Checkpoint 目录结构

checkpoints/lora/
├── step_0000500/
│   ├── lora_weights.safetensors
│   ├── lora_config.json
│   ├── optimizer.pth
│   ├── scheduler.pth
│   └── training_state.json
├── step_0001000/
│   └── ...
└── latest -> step_0001000/

若存在 latest/,训练会自动从中恢复;信号处理也会在 SIGTERM / SIGINT 时保存 checkpoint,避免中断丢进度。

推理

命令行

python scripts/test_voxcpm_lora_infer.py \
    --lora_ckpt /path/to/checkpoints/lora/step_0002000 \
    --text "Hello from the fine-tuned model." \
    --output output.wav

Python API

from voxcpm import VoxCPM

model = VoxCPM.from_pretrained(
    "openbmb/VoxCPM2",
    lora_weights_path="/path/to/checkpoints/lora/latest",
)

wav = model.generate(text="Hello from the fine-tuned model.")

运行时热切换 LoRA

无需重启模型即可加载、卸载或切换 LoRA 权重:

# Load a LoRA
model.load_lora("/path/to/lora_a")

# Disable LoRA temporarily (base model only)
model.set_lora_enabled(False)

# Re-enable
model.set_lora_enabled(True)

# Switch to a different LoRA
model.unload_lora()
model.load_lora("/path/to/lora_b")

所有热切换操作均与 torch.compile 兼容。


Full Fine-Tuning

全量微调会更新全部参数。当 LoRA 容量不足时使用 — 常见于新语言或 500+ 条片段的大规模定制。

Training

配置

pretrained_path: /path/to/VoxCPM2/
train_manifest: /path/to/train.jsonl
val_manifest: /path/to/val.jsonl

sample_rate: 16000        # AudioVAE encoder input rate (NOT the 48kHz output rate)
out_sample_rate: 48000    # AudioVAE decoder output rate; only used at inference, not during training
batch_size: 16
grad_accum_steps: 1
num_workers: 2
num_iters: 1000
log_interval: 10
valid_interval: 500
save_interval: 500

learning_rate: 0.00001    # 10x smaller than LoRA
weight_decay: 0.01
warmup_steps: 100
max_steps: 1000
max_batch_tokens: 8192

save_path: /path/to/checkpoints/full
tensorboard: /path/to/logs/full

lambdas:
  loss/diff: 1.0
  loss/stop: 1.0

注意配置中不含 lora 键 — 脚本据此执行全量微调。

与 LoRA 的主要区别

  • learning_rate 建议约为 LoRA 的 1/10(1e-51e-4),以避免灾难性遗忘。

  • 因全部参数都参与求导,显存占用明显更高。

  • checkpoint 更大(完整权重对比仅 LoRA 增量)。

启动

# Single GPU
python scripts/train_voxcpm_finetune.py --config_path conf/your_full_config.yaml

# Multi-GPU
CUDA_VISIBLE_DEVICES=0,1,2,3 torchrun --nproc_per_node=4 \
    scripts/train_voxcpm_finetune.py --config_path conf/your_full_config.yaml

训练观察

TensorBoard 指标与 LoRA 相同(loss/diff、`` loss/stop``、`` grad_norm``、`` lr`` 及验证音频)。

全量微调比 LoRA 更易过拟合。实践中常在 1–2 个 epoch 内达到较优;继续训练可能反而变差。需格外留意:

  • 验证损失与训练损失背离 — 过拟合信号。应停止训练,并采用背离前最后一个 checkpoint。

  • 文本被忽略 — 最常见的过拟合表现。请保持 training_cfg_rate=0.1 (不要设为 0)与 `` weight_decay=0.01``,并在每个 `` save_interval`` 关注 checkpoint。

  • 小数据集更快过拟合。 样本较少时,最优 checkpoint 可能出现在几百步内。

  • 新语言微调: 混入部分中英数据(例如 10–20%),以减轻对原有能力的遗忘。

  • 更多数据未必更好。 超过某一点后边际收益递减;更应重视数据质量与多样性。

Checkpoint 目录结构

checkpoints/full/
├── step_0000500/
│   ├── model.safetensors
│   ├── config.json
│   ├── audiovae.pth
│   ├── tokenizer.json
│   ├── tokenizer_config.json
│   ├── special_tokens_map.json
│   ├── optimizer.pth
│   ├── scheduler.pth
│   └── training_state.json
└── latest -> step_0000500/

每个 checkpoint 都是可直接加载的完整模型目录。

推理

命令行

python scripts/test_voxcpm_ft_infer.py \
    --ckpt_dir /path/to/checkpoints/full/step_0002000 \
    --text "Hello from the fine-tuned model." \
    --output output.wav

# With voice cloning
python scripts/test_voxcpm_ft_infer.py \
    --ckpt_dir /path/to/checkpoints/full/latest \
    --text "Cloned voice with full fine-tuning." \
    --prompt_audio reference.wav \
    --prompt_text "Exact transcript of reference.wav" \
    --output cloned.wav

Python API

该目录即完整模型 — 可直接加载:

from voxcpm import VoxCPM

model = VoxCPM.from_pretrained("/path/to/checkpoints/full/latest")
wav = model.generate(text="Hello from the fine-tuned model.")

常见训练问题(OOM、生成停不下来、LoRA 效果差、checkpoint 报错等)请参阅 微调常见问题