Ubuntu部署DDSP-SVC 6.3音色克隆大模型和使用(基于SVC Fusion整合包)

目录

说在前面的话

下载代码到服务器本地

整体流程

环境安装

一、数据预处理

1.上传训练文件

2.批量转wav格式

3.切片

4.划分训练集和验证集

5.预处理

6.额外补充:配置文件

a、权重文件保存规则

[b、step 和 epoch的核心关系](#b、step 和 epoch的核心关系)

二、训练

三、推理

四、混音


最近项目在搞一个音色克隆功能,具体来说就是用户上传一段自己的音频,然后上传一首歌,可以将这首歌人声 音色转化为 用户自己的音色,实现唱歌功能,一般可以用自己喜欢的动漫角色训练然后唱歌,都非常不错~

说在前面的话

本人在经历了一番痛苦的环境依赖折磨后,又经历了模型生成效果差,有电音,杂音等,真的测试付出了不少精力,测试不同的测试集的质量的影响,比如去混声,底噪,杂声后,又测试不同推理源对于结果的影响,然后调整模型的不同参数的影响。

最后得出的一个结论:

SO-VITS-SVC4.1模型对于训练集和推理源的音频质量要求极高,不能混有任何杂声,底噪,否则效果将会出现哑音,电音,杂音等;

DDSP-SVC 6.3 基于rectified-flow模型,对训练集和推理源质量要求低,训练时间低(快SO-VITS-SVC 10倍左右,平常的人声训练100步左右就有很好的结果) ,而且推理效果极佳。

但这个DDSP也不是平常的开源项目DDSP-SVC,而是SVC Fusion整合包下的DDSP-SVC,我试过原本的,效果就不是不太可以,哪怕加上扩散模型,也是不太可以。对于我们这种需要快速克隆出音色效果的功能来说是不合适的。

但是带有UI界面的整合包,合成的效果很快,效果也很好。因此我从整合包界面开始,深扒背后执行的源码,py脚本文件,然后再总结脚本的作用,执行命令,梳理出了一套基于SVC整合包的DDSP-SVC6.3的音色克隆流程 ,该模型在一张NVIDIA A100-SXM4显卡,80GB显存的情况下,只需要1分钟(训练100steps)即可生成非常好的效果。 整合包里面我拿我自己的也试过(RTX 4070ti,16GB显存),差不多2分钟左右也很快。

我觉得这应该是全网首位把SVC整合包里的内容,整合部署到服务器上了,我还写了脚本完成了自动化的全流程和基于Flask框架,封装成api格式供外部调用,稳定性也很不错。那么接下来,我就记录下我的所有工作流程,以及一些命令。注意:教程不会特别详细,有不懂的欢迎私信~


下载代码到服务器本地

SVC Fusion整合包文档

进入这个整合包官网,下载好后,先自己本地启动一下试一试,差不多这个样子,感兴趣的可以先UI试试效果,再进行后面的部署工作(非常建议,因为一套流程下来你所需要的模型文件,编码器等等,底模都给你安装好了)

把基本的代码和编码器模型,底模等等装一装,省的后面部署到服务器上时,缺什么模型还得去官网手动下载,再拖上去

把这个目录,上一级整体打包成zip压缩文件

然后将该压缩文件上传到服务器上,然后解压缩

然后cd 到 project 目录,我们后续主要在这个目录进行代码的执行

我这里装了两个模型,ddsp-svc6.3和sovits-svc,但我们主要使用第一个模型


整体流程

整体的训练流程分为以下几步

预处理 ------> 训练 ------> 推理 ------> 混音

预处理又分为以下几步:

上传音频文件 ------> ffmpeg转wav格式 ------> 数据集切片 ------> 划分训练集和验证集 ------> 生成音频特征文件(如f0,volume等等)


环境安装

我这里不会用过多时间讲解,因为这东西怎么说呢,按照requirements.txt安装的时候各种依赖报错,我的建议是 照着这个安装好大部分依赖后,直接按照我后面的步骤运行,缺什么模型再补什么就好了,这个我感觉比盲目解决依赖冲突高效多了,建议搭配着豆包或GPT解决,把报错信息复制,直接给你好的命令运行即可

还有最好(强烈建议) 在docker中安装环境,这样搞坏了方便从头再来,镜像源找一个带有cuda的即可,我早忘了一开始的镜像源使用了哪个了,因为最初的镜像源在我打包好新的镜像之后被我删了...

我容器内的配置主要的:python 3.10,pytorch 2.9.1 ,cuda 12.8

不过貌似整合包里没有requirements.txt,直接去ddsp-svc官网:yxlllc/DDSP-SVC: Real-time end-to-end singing voice conversion system based on DDSP (Differentiable Digital Signal Processing)

找到requirements.txt下载下来,或者自己新建文件复制进去

复制代码
einops
fairseq
flask
flask_cors
gin
gin_config
librosa
local_attention
matplotlib
numpy==1.26.4
praat-parselmouth
pyworld
PyYAML
resampy
scikit_learn
scipy
SoundFile
tensorboard
torchcrepe
torchfcpe
tqdm
transformers
wave
FreeSimpleGUI
sounddevice
gradio

然后运行以下命令,安装所需的依赖

bash 复制代码
pip install -r requirements.txt 

如果有报错,能解决就解决,解决不了到时候就按正常流程执行,缺什么模块 pip install 安装什么就行,结合着ai,很管用的。


一、数据预处理

1.上传训练文件

这一步,我们需要把我们需要克隆的音频文件,放到固定的目录下,ddsp默认为dataset_raw目录下,一定要是wav格式音频文件,如果不是也没关系,就看下一步就行

2.批量转wav格式

上一步上传为音频后,如果音频文件格式不是wav格式,执行以下指令转化为wav格式,此命令需要安装ffmpeg工具

注意在project目录下执行

bash 复制代码
python3.10 fap/__main__.py to-wav "./dataset_raw/hyx/" "./dataset_raw/hyx/"

第一个路径"./dataset_raw/hyx/" 表示待转化wav的目录下的所有文件

第二个路径"./dataset_raw/hyx/" 表示转化后的wav文件输出目录

3.切片

转化好以后,音频可能比较长,我们需要对音频文件进行切分,会自动识别静音段和说话声,切分成几秒左右的片段,当然最大最小切片时长我们可以手动控制,命令如下

在project目录下执行

bash 复制代码
python3.10 fap/__main__.py slice-audio-v2 "./dataset_raw/" "./data/train/audio/" --max-duration 15.0 --num-workers 4 --flat-layout --merge-short --clean --min-duration 1.0

**"./dataset_raw/":**为要切片的目录下的文件,我要切./dataset_raw/目录下的所有音频文件

"./data/train/audio/":为切片后的音频文件输出目录,这个同时也作为训练集的目录

**--min-duration 1.0:**最小的切片时长为 1s,小于这个时长的会被skip

**--max-duration 15:**最大的切片时长为15s,大于这个时长会被强制切片

里面的日志是我自己改代码输出的,正常一些东西会没有,属于正常的

4.划分训练集和验证集

我们看一下训练集和验证集的目录,存在于data目录下

**train是训练集目录, val 是验证集目录。**44k是so-vits-svc模型的目录,我们不用管,你如果没下载这个模型,也不会有的

我们上一步将切片后的所有音频放到了data/train/audio下,所以本步是从这些训练集中的音频文件抽取一些放到验证集中

bash 复制代码
python3.10 ddspsvc_6_3/draw.py -t ./data/train/audio/ -v ./data/val/audio/ -r 10

**./data/train/audio/ :**需要抽取的训练集目录

**./data/val/audio/ :**抽取的验证集的目录存放的位置,默认就好

-r 10 : -r 参数是【百分比】,代码会自动除以 100 转成**小数比例,**即10%的比例,也就说如果有10个训练集文件,那么就会抽1个音频文件作为训练集。

但是该脚本有规则!验证集的抽取区间在[2,10]个之间,所以你如果计算出来得到1个验证集文件,那么也会抽取2个文件来放入验证集。所以当训练集数量只有2个时,会全部抽完作为验证集,会导致训练集为空,会导致训练时完全没用,这点注意!!!

解决办法自己去改源代码,不难,改一下文件头部的变量;或者传一些长的音频文件,多切片即可。

还有两个风险:

风险 1: 训练集文件数 = 3 个 → 会被抽走 2 个,训练集仅剩 1 个,同样的逻辑,max(2, 计算值) 强制抽 2 个,训练集几乎被掏空,样本量完全不够训练。

风险 2: 原脚本用的是 shutil.move() 【剪切】,不是复制 → 抽走的文件彻底从训练集消失,无法恢复

这个是叠加风险!如果是copy复制,训练集还在;但原脚本是move剪切,文件从训练集「消失」并出现在验证集,一旦抽空,训练集就真的空了,数据不可逆丢失!


5.预处理

该过程是对训练集和验证集进行预处理

自动遍历指定目录下的训练集+验证集 原始音频文件(默认 wav 格式),分别执行预处理逻辑,训练集带数据增强,验证集纯提取无增强,保证验证集纯净。

核心提取的声学特征(最终生成 .npy 格式特征文件,供模型训练读取)

✅ 提取基频 (F0):音频的音调 / 音高特征,决定语音的声调高低;

✅ 提取音量 (Volume):音频的响度特征,含原始音量 + 增强后音量;

✅ 提取语义单元 (Units):音频的文本语义特征(核心特征,由预训练编码器生成);

✅ 提取梅尔频谱 (Mel):音频的频谱特征,还原语音的音色 / 音质细节,含原始梅尔谱 + 增强后梅尔谱;

命令:

bash 复制代码
python3.10 -m ddspsvc_6_3.preprocess -c configs/ddsp6.3.yaml -d cuda:0 

执行后,会在data/train/ 和 data/val目录下生成以下目录:

这样训练的条件就具备了,我们可以开始进行训练了,但在此之前需要解释下配置文件


6.额外补充:配置文件

配置文ddsp6.3.yaml内容如下,在configs目录下

XML 复制代码
data:
  block_size: 512                # 音频分帧步长
  cnhubertsoft_gate: 10          # cnhubertsoft编码器门限值
  duration: 2                    # 音频片段截取时长,单位秒
  encoder: contentvec768l12tta2x # 语义特征编码器类型
  encoder_ckpt: pretrain/contentvec/checkpoint_best_legacy_500.pt # 编码器预训练权重文件路径
  encoder_hop_size: 160          # 编码器分帧步长
  encoder_out_channels: 768      # 编码器输出特征维度
  encoder_sample_rate: 16000     # 编码器输入音频采样率
  extensions:                    # 支持处理的音频文件格式
  - wav
  f0_extractor: rmvpe            # 基频提取算法类型
  f0_max: 800                    # 提取基频的最大值,单位Hz
  f0_min: 65                     # 提取基频的最小值,单位Hz
  sampling_rate: 44100           # 音频采样率
  train_path: data/train         # 训练集数据路径
  valid_path: data/val           # 验证集数据路径
  volume_smooth_size: 1024       # 音量特征平滑窗口大小
device: cuda:0                   # 指定训练使用的计算设备
env:
  expdir: exp/workdir            # 实验日志与模型权重保存目录
  gpu_id: 0                      # 训练使用的GPU编号
infer:
  infer_step: 50                 # 推理阶段的采样步数
  method: euler                  # 推理阶段的采样方法
model:
  n_aux_chans: 512               # 模型辅助特征通道数
  n_aux_layers: 6                # 模型辅助特征网络层数
  n_chans: 1024                  # 模型主特征通道数
  n_layers: 6                    # 模型主网络层数
  n_spk: 1                       # 说话人数量
  t_start: 0.0                   # 模型起始时间步
  type: RectifiedFlow            # 模型架构类型
  use_attention: false           # 是否启用注意力机制
  use_norm: true                 # 是否启用层归一化
  use_pitch_aug: true            # 是否启用音调数据增强
  win_length: 2048               # 梅尔频谱计算窗长
model_type_index: 4              # 模型类型索引标记
spks:
- hyx                            # 说话人名称列表
train:
  amp_dtype: fp16                # 混合精度训练的数据类型
  batch_size: 30                 # 训练批次大小
  cache_all_data: false          # 是否将全部数据缓存至内存
  cache_device: cpu              # 数据缓存的设备
  cache_fp16: true               # 缓存数据是否采用fp16精度
  decay_step: 4000               # 学习率衰减的步数阈值
  epochs: 100                    # 训练总轮数
  gamma: 0.9                     # 学习率衰减系数
  interval_force_save: 10000     # 强制保存模型的步数间隔
  interval_log: 1                # 日志打印的轮数间隔
  interval_val: 100              # 模型验证的轮数间隔
  lambda_ddsp: 1                 # ddsp损失项的权重系数
  lr: 0.0002                     # 模型训练学习率
  num_workers: 2                 # 数据加载的工作线程数
  save_opt: false                # 是否保存优化器的状态信息
  save_tensorboard: false        # 是否保存tensorboard日志文件
  weight_decay: 0.1              # 权重衰减系数
use_pretrain: true               # 是否启用预训练权重进行训练
vocoder:
  ckpt: pretrain/nsf_hifigan/model # 声码器预训练权重路径
  type: nsf-hifigan              # 声码器类型

我们需要关注的几个属性即可:

**train_path:**训练集路径

valid_path: 验证集路径

**epochs:**训练总轮数

interval_val 100: 每训练 100 个 epoch,执行一次验证集评估,评估完成后自动保存一次模型权重

interval_force_save 10000: 每训练1000步强制保存一次权重文件

我们训练就是为了得到这个权重文件,一定要关心什么时候保存


a、权重文件保存规则

① 按【步数 (step)】强制保存权重:train -> interval_force_save: 10000

含义:每训练 10000 个 step,无条件强制保存一次模型权重文件

② 按【轮数 (epoch)】验证后保存权重:train -> interval_val: 100

含义:每训练 100 个 epoch,执行一次验证集评估,评估完成后自动保存一次模型权重(训练类模型的常规保存逻辑,保存的是该阶段最优权重)

b、stepepoch的核心关系


1. 各自的定义

  • epoch(训练轮数) :把 训练集里的【全部数据】完整的训练一遍 ,就记作 1个epoch。比如你的训练集有 3000 条音频,模型把这 3000 条全部跑完一次 = 训练了 1 epoch。

  • step(训练步数 / 迭代步) :模型读取 1 个批次(batch)的数据 ,完成「前向计算 + 损失计算 + 反向传播 + 参数更新」这一整套流程,就记作 1个step。配置里 train -> batch_size: 30,代表 每读取 30 条音频 = 训练了 1 step。

补充说明:

  • epoch 是「宏观训练进度」,step 是「微观训练进度」,训练日志里一般会这样显示:epoch: [7/100], step: [700/xxxx],代表「第 7 轮训练,当前训练到第 700 步」。
  • 你的配置里所有带 step 的参数,都是按「微观步数」计算,和 epoch 无关:
    • interval_force_save:10000 → 纯按步数,不管跑了几轮
    • decay_step:4000 → 训练到 4000step 时,学习率开始按系数衰减
  • 你的配置里所有带 interval 的参数,带 log/val 后缀的是按 epoch 计算:
    • interval_log:1 → 每 1 个 epoch 打印一次训练日志
    • interval_val:100 → 每 100 个 epoch 跑一次验证

二、训练

我们利用刚才划分好的训练集特征文件,开始进行训练,训练后会生成一个.pt权重文件,存放在exp/workdir目录下,注意!一定要事先把基模(model_0.pt)放入该目录下,不然训练效果会非常差,一定要加!!!

执行命令

XML 复制代码
python3.10 -m ddspsvc_6_3.train_reflow -c configs/ddsp6.3.yaml

模型便开始执行训练过程

这张图是我封装为api后输出的日志,主要看后面就行,可能和你正常执行命令的输出不一样,但不影响

可以看到第一行,训练好的权重模型已经保存到对应的目录下,这个目录我有修改过,所以以你的为准即可

其他属性:

1. test_ddsp_loss: 0.5299260020256042

  • 含义:DDSP 声码器的损失值,衡量「模型生成的声学特征」与「真实音频声学特征」的差距
  • 判定:该值 0.53 → ✅【优秀】,语音合成中该损失值 < 1 就是合格,< 0.6 就是非常好,越小代表特征拟合越精准

2. test_reflow_loss: 0.08837877213954926

  • 含义:RectifiedFlow 整流流模型的核心损失值,这个模型主架构是 RectifiedFlow,这个值是核心核心指标
  • 判定:该值 0.088 → ✅【极佳】,该损失值 < 0.2 为合格,< 0.1 为优秀,看到我的数值已经接近 0,说明模型的流匹配效果拉满,合成的音频会非常贴合原声

3. 综合验证损失 loss: 0.618.

  • 含义:上述两个损失的加权综合值(对应配置里 lambda_ddsp:1 权重)
  • 判定:该值 0.618 → ✅【优秀】,综合损失 < 1 就是合格,这个数值证明你的模型对训练数据的拟合程度非常高,没有过拟合 / 欠拟合问题

  • Mel Val MSE(梅尔频谱均方误差) → 数值:0.635

    • 含义:衡量「合成梅尔谱」与「真实梅尔谱」的像素级误差,越小越好
    • 判定:【优秀】,MSE < 1 为合格,< 0.7 为优秀,值 0.635,说明合成的梅尔谱和真实的几乎一致,音色还原度极高
  • Mel Val SNR(梅尔频谱信噪比) → 数值:52.65

    • 含义:衡量合成音频的「有效语音信号」和「杂音 / 噪声」的比值,越大越好
    • 判定:✅【极佳】,SNR > 30 为合格,> 40 为优秀,> 50 为顶级,值 52+,说明合成的音频几乎无杂音、无电音、无失真,纯净度拉满
  • Mel Val PSNR(梅尔频谱峰值信噪比) → 数值:51.72

    • 含义:在 SNR 基础上,侧重「音频峰值信号」的还原度,越大越好
    • 判定:✅【极佳】,PSNR > 40 为优秀,值 51+,说明合成音频的音量、音调、峰值细节和原声完全一致,不会出现音量忽大忽小、破音等问题
  • Mel Val SI-SNR(梅尔频谱尺度不变信噪比) → 数值:52.65

    • 含义:语音合成专属核心指标 ,专门针对人声设计,剔除了音量、尺度等无关因素,只衡量「语音内容 + 音色」的还原度,这个指标的优先级最高!
    • 判定:✅【顶级】,SI-SNR > 40 为优秀,> 50 为顶级,值 52+,这个数值代表模型合成的音频,在「音色、语调、语音细节」上和你的训练集原声几乎一模一样,这是语音合成的顶级效果

还有个tensorboard ,可以可视化的看训练的曲线,通过configs中配置文件的save_tensorboard改为true,然后运行tensorboard会有一个界面,访问即可。

最终效果会生成一个以训练步数为后缀的权重文件,model_100.pt 代表我训练了100step

你可以用 Tensorboard 来查看训练过程中的损失函数值 (loss) 趋势,试听音频,从而辅助判断模型训练状态。但是,就 So-VITS-SVC 这个项目而言,损失函数值(loss)并没有什么实际参考意义(你不用刻意对比研究这个值的高低),真正有参考意义的还是推理后靠你的耳朵来听!

后续我们就使用该权重文件进行推理

三、推理

用刚才的权重文件进行推理,命令如下:

bash 复制代码
python3.10 -m ddspsvc_6_3.main_reflow -m exp/workdir/model_100.pt -i ../../../qinghuaci2.wav -o ./qinghuaci2_output.wav -d cuda:0 -id 1 -step 50

exp/workdir/model_100.pt : 模型权重文件路径

../../../qinghuaci2.wav: 要转化的歌曲人声,比如我要翻唱周杰伦的青花瓷,这个就是青花瓷的纯人声,是纯人声,没有伴奏,需要自己手动去除,我们是刚好有一个人声分离的接口,所以直接调用那个接口分离的,如果需要代码里应该也有,我看到过但没太细看,感兴趣的可以找下

./qinghuaci2_output.wav: 输出路径

-step : 推理步数

推理好以后便在指定目录下生成我唱的青花瓷人声了


四、混音

这个整合包竟然自带自动混音功能,真是感动至极,非常感谢开源作者大大

可以写个脚本文件run_mix.py

python 复制代码
from automix import automix, ReverbLevel, MusicGenre, VoiceType, DeEsserStrength, CompressionStrength, EQStyle, EchoLevel

# ========== 只需要修改这两行路径 ==========
VOCAL_PATH = "你的人声文件.wav"
BGM_PATH = "你的伴奏文件.wav"

# ========== 调用混音函数,参数和你最初的完全一致 ==========
out_path = automix(
    voc_path=VOCAL_PATH,
    inst_path=BGM_PATH,
    sample_rate=44100,
    reverb_gain=0,
    headroom=-8,
    voc_input=-4,
    reverb_level=ReverbLevel.MODERATE,
    music_genre=MusicGenre.POP,
    voice_type=VoiceType.FEMALE,
    deesser_strength=DeEsserStrength.MODERATE,
    compression_strength=CompressionStrength.MODERATE,
    eq_style=EQStyle.NEUTRAL,
    echo_level=EchoLevel.OFF,
)
print(f"混音完成!输出文件路径: {out_path}")

然后运行即可

bash 复制代码
python run_mix.py

这个命令把伴奏文件和刚才推理后生成的人声混合在一起,最终生成一个完整的歌曲

不知道其他环境下能不能运行。。。


至此,将DDSP-SVC6.3模型部署到Ubuntu服务器的大概流程就结束了,也是花了不少时间来部署并研究使用的,我也针对于此,写了一套全流程自动化执行的代码,并且封装为api的格式,

只需要上传对应的音色id,用户音频,伴奏音频,人声(干声)音频,即可自动完成推理和混音之后的结果,并返回对应的url,返回响应:

写在这里只是说明这些代码改造和拓展性是很强的,可以自己发挥能力改造

写了这点博客也写了好久,真快累死了,不过最后听到自己的声音完整自动化的克隆出了一首歌,成就感还是很高的,作者也是从0开始接触的,到最后可以完整使用,不乏元旦放假从下午搞到凌晨五点小姑还是不行的绝望感,绝望的扒拉着源码看,希望有突破口,等后面突然灵光一闪,才想到了把整个整合包放进去,既然是UI界面,那么背后依赖的肯定还是那些py脚本,便深入了解如何执行的那些脚本,最后经过自己的改进,最终有个不错的效果,希望大家遇到问题也不要放弃,不要提到源码就害怕,勇于改进,每个脚本不过是实现了一些功能,大不了重新还原脚本就行了。

从一开始的so-vits-svc模型实验了各种参数不行,到最后勇敢换模型到ddsp-svc6.3模型还是不符合要求后,又大胆的直接使用整合包那些复杂的代码来使用,到最后生成出不错的效果,每次都是大胆的尝试。 怎么发现的呢,我一开始部署的是ddsp-svc6.3模型,但是生成的声音效果不好,奇怪的是整合包的就很好,我便把整合包生成的权重文件 copy到我的项目文件里使用,发现运行不起来,可能是参数配置那里有问题,深入看源码,才发现整合包有自己的一套流程和配置,所以直接copy下来,太阴了哈哈,不过非常感谢作者大大!

相关推荐
NAGNIP8 小时前
一文搞懂深度学习中的通用逼近定理!
人工智能·算法·面试
冬奇Lab9 小时前
一天一个开源项目(第36篇):EverMemOS - 跨 LLM 与平台的长时记忆 OS,让 Agent 会记忆更会推理
人工智能·开源·资讯
冬奇Lab9 小时前
OpenClaw 源码深度解析(一):Gateway——为什么需要一个"中枢"
人工智能·开源·源码阅读
哥不是小萝莉10 小时前
OpenClaw 架构设计全解析
ai
AngelPP13 小时前
OpenClaw 架构深度解析:如何把 AI 助手搬到你的个人设备上
人工智能
宅小年13 小时前
Claude Code 换成了Kimi K2.5后,我再也回不去了
人工智能·ai编程·claude
九狼13 小时前
Flutter URL Scheme 跨平台跳转
人工智能·flutter·github
ZFSS13 小时前
Kimi Chat Completion API 申请及使用
前端·人工智能
warm3snow13 小时前
Claude Code 黑客马拉松:5 个获奖项目,没有一个是"纯码农"做的
ai·大模型·llm·agent·skill·mcp
天翼云开发者社区14 小时前
春节复工福利就位!天翼云息壤2500万Tokens免费送,全品类大模型一键畅玩!
人工智能·算力服务·息壤