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下来,太阴了哈哈,不过非常感谢作者大大!

相关推荐
凤希AI伴侣18 小时前
从文件到数据库:凤希AI伴侣的存储升级之路-凤希AI伴侣-2026年1月9日
人工智能·凤希ai伴侣
努力变大白18 小时前
借助AI零基础快速学会Python爬取网页信息-以天眼查爬虫为例
人工智能·爬虫·python
tle_sammy18 小时前
【架构的本质 07】数据架构:在 AI 时代,数据是流动的资产,不是静态的表格
人工智能·架构
周周爱喝粥呀18 小时前
LLM 中的自回归模型与非自回归模型:GPT 和 BERT 的区别
人工智能·gpt·ai·回归
共绩算力18 小时前
DeepSeek V3.2 迈向 GPT-5 级别性能的路径:稀疏注意力、大规模强化学习与上下文重用
人工智能·gpt·共绩算力
haiyu_y18 小时前
Day 57 经典时序模型(1)——差分、ACF/PACF 与 AR/MA/ARMA
人工智能·深度学习·ar
duyinbi751718 小时前
【深度学习】使用YOLOv8-MFMMAFPN进行泡沫检测的完整实现
人工智能·深度学习·yolo
AI科技星18 小时前
引力与电磁的动力学耦合:变化磁场产生引力场与电场方程的第一性原理推导、验证与统一性意义
服务器·人工智能·科技·线性代数·算法·机器学习·生活
hkNaruto18 小时前
【AI】AI学习笔记:OpenAI Tools完全指南:从原理到实战入门
人工智能·笔记·学习