1.原理简介
最近AI在音乐生成方面的进展引起了极大的关注,但现有的方法面临着严重的限制。一些当前的生成模型只能合成人声或伴奏轨道。虽然一些模型可以生成组合的人声和伴奏,但它们通常依赖于精心设计的多阶段级联架构和复杂的数据管道,阻碍了可扩展性。此外,大多数系统仅限于生成短音乐片段而不是全长歌曲。此外,广泛使用的基于语言模型的方法受到推理速度慢的困扰。DiffRhythm是第一个基于潜在扩散模型的歌曲生成模型,能够在短短 10 秒内合成具有人声和伴奏的完整歌曲,持续时间长达 4m45s,保持高音乐性和可理解性。
尽管 DiffRhythm 具有卓越的功能,但它的设计简单而优雅:它无需复杂的数据准备,采用简单的模型结构,并且在推理过程中只需要歌词和样式提示。此外,其非自回归结构确保了快速的推理速度。这种简单性保证了 DiffRhythm 的可扩展性。
模型结构如下:

有兴趣的同学可以阅读这篇论文:DiffRhythm: Blazingly Fast and Embarrassingly Simple
End-to-End Full-Length Song Generation with Latent Diffusion。
简单总结一下原理:
DiffRhythm 是一种基于潜在扩散的端到端歌曲生成模型,它能够以 44.1 kHz 的采样率生成长达 4 分 45 秒的完整立体声音乐作品,并通过歌词和风格提示进行引导。该模型的主要特点如下:
- 端到端生成: 与许多现有模型不同,DiffRhythm 能够同时生成人声和伴奏,无需复杂的级联架构或数据管道。
- 简单高效: 模型结构简洁,数据预处理简单,推理速度快,使其易于扩展和应用。
- 高质量输出: 即使生成完整的歌曲,DiffRhythm 也能保持高水平的音乐性和可理解性。
DiffRhythm 的关键组件:
-
变分自动编码器 (VAE): 用于学习音频的紧凑潜在表示,同时保留感知音频细节,从而降低扩散模型训练的计算需求。
-
扩散 Transformer (DiT): 在 VAE 学习到的潜在空间中生成歌曲,通过迭代去噪的方式完成。具体过程如下:初始化: DiT 接收来自 VAE 编码器的潜在表示作为输入,并添加随机噪声。条件输入: DiT 的输入除了潜在表示外,还包括风格提示、时间步长和歌词信息。风格提示用于控制歌曲的风格,时间步长指示当前的去噪步骤,歌词用于控制人声内容。Transformer 解码器: DiT 由多个 LLaMA 解码器层堆叠而成,每个层包含注意力机制和前馈网络。去噪: 在每个时间步长,DiT 预测潜在表示中噪声的分布,并使用该分布更新潜在表示,逐步去除噪声。重复步骤: DiT 重复进行注意力机制和前馈网络计算,以及去噪步骤,直到潜在表示中的噪声被完全去除,最终生成完整的歌曲。
-
歌词到潜在对齐机制: 用于解决全歌曲生成中的歌词和人声对齐问题,通过句级对齐方式实现高可理解性。具体步骤为:歌词预处理: 将歌词转换为音素序列,并与时间戳信息关联起来。音素到潜在对齐:初始化一个与潜在表示等长的潜在对齐序列,将其转换为音素序列。将音素序列覆盖到 对应的时间位置。
2.安装部署
安装需要的库:
sudo apt-get install espeak-ng
克隆项目:
git clone https://github.com/ASLP-lab/DiffRhythm.git
cd DiffRhythm
创建虚环境:
conda create -n diffrhythm python=3.10
conda activate diffrhythm
安装依赖:
pip install -r requirements.txt
简单运行源码示例:
bash scripts/infer_wav_ref.sh
或者输入提示进行音乐创作:
bash scripts/infer_prompt_ref.sh
用文字prompts示例:
azzy Nightclub Vibe, Pop Emotional Piano or Indie folk ballad, coming-of-age themes, acoustic guitar picking with harmonica interludes
无需音频参考!
生成纯音乐:
"Arctic research station, theremin auroras dancing with geomagnetic storms"
3.编写图形界面
源码没有带着图形界面,使用不方便,这里我用gradio写了一个简单的界面:
import gradio as gr
import subprocess
import os
import shutil
from datetime import datetime
import sys
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
# 配置参数
OUTPUT_DIR = "gradio_outputs"
os.makedirs(OUTPUT_DIR, exist_ok=True)
def generate_music(
lrc_text,
ref_audio,
ref_prompt,
use_chunked
):
"""核心音乐生成函数"""
# ====== 输入验证 ======
# 处理歌词输入
if not lrc_text.strip():
raise gr.Error("❗ 请输入歌词内容")
lrc_content = lrc_text
# 验证风格输入
if not (ref_audio or ref_prompt):
raise gr.Error("❗ 需要音频参考或文字描述")
if ref_audio is not None and ref_prompt.strip() != "":
raise gr.Error("❗ 请选择音频参考或文字描述中的一种方式")
# ====== 创建临时目录 ======
timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
temp_dir = os.path.join(OUTPUT_DIR, timestamp)
os.makedirs(temp_dir, exist_ok=True)
try:
# ====== 保存歌词文件 ======
lrc_path = os.path.join(temp_dir, "input.lrc")
with open(lrc_path, "w", encoding="utf-8") as f:
f.write(lrc_content)
# ====== 处理参考音频 ======
ref_audio_path = None
if ref_audio:
if isinstance(ref_audio, dict): # 适配新版Gradio
ref_audio_path = ref_audio["name"]
else:
ref_audio_path = ref_audio
ref_prompt = "" # 强制清空文字描述
# 验证逻辑
if not ref_audio_path and not ref_prompt.strip():
raise gr.Error("❗ 必须提供参考音频或风格描述!")
if ref_audio_path and ref_prompt.strip():
raise gr.Error("❗ 请选择一种风格参考方式!")
# ====== 构建执行命令 ======
cmd = [
"python3", "infer/infer.py",
"--lrc-path", lrc_path,
"--audio-length", "95",
"--repo_id", "ASLP-lab/DiffRhythm-base",
"--output-dir", temp_dir
]
if use_chunked:
cmd.append("--chunked")
if ref_audio_path:
cmd += ["--ref-audio-path", ref_audio_path]
else:
cmd += ["--ref-prompt", ref_prompt]
# ====== 执行生成命令 ======
result = subprocess.run(
cmd,
capture_output=True,
text=True,
check=True
)
# ====== 获取输出结果 ======
output_path = os.path.join(temp_dir, "output.wav")
if not os.path.exists(output_path):
raise FileNotFoundError("生成结果文件不存在")
# 返回两个相同的路径给音频组件和文件下载组件
return output_path, output_path
except subprocess.CalledProcessError as e:
error_detail = f"""
🚨 生成失败!
命令: {' '.join(e.cmd)}
错误信息: {e.stderr}
"""
raise gr.Error(error_detail)
except Exception as e:
raise gr.Error(f"🚨 发生未知错误: {str(e)}")
# ====== 界面布局 ======
with gr.Blocks(title="AI音乐工作室", theme=gr.themes.Soft(), css=".dark {background: #f0f2f6}") as demo:
gr.Markdown("""
<div style="text-align: center; padding: 20px;">
<h1 style="color: #2563eb;">🎵 AI音乐工作室</h1>
<p style="color: #4b5563;">通过人工智能生成个性化音乐作品</p>
</div>
""")
with gr.Row(variant="panel"):
# 输入区
with gr.Column(scale=1):
# 歌词输入
lrc_text = gr.Textbox(
label="直接输入歌词(LRC格式)",
placeholder="""示例格式:
[00:00.00] 开始你的音乐之旅
[00:05.00] 用代码创造旋律
[00:10.00] 人工智能生成音乐""",
lines=8,
max_lines=20,
visible=True
)
# 风格控制区
with gr.Tabs():
with gr.Tab("🎧 音频参考"):
ref_audio = gr.Audio(
label="上传参考音频(支持WAV/MP3)",
type="filepath",
sources=["upload"],
waveform_options={"show_controls": True}
)
with gr.Tab("📝 文字描述"):
ref_prompt = gr.Textbox(
label="音乐风格描述(英文)",
placeholder="例如:epic orchestral, dramatic strings, choir vocals",
lines=3
)
# 高级选项
with gr.Accordion("⚙️ 高级设置", open=False):
use_chunked = gr.Checkbox(
label="启用分块解码(推荐生成长音频)",
value=True
)
generate_btn = gr.Button("🚀 开始生成", variant="primary")
# 输出区
with gr.Column(scale=1):
gr.Markdown("### 🎧 生成结果")
audio_output = gr.Audio(
label="试听音频",
interactive=False,
waveform_options={"show_controls": True}
)
output_file = gr.File(
label="下载文件",
file_types=[".wav"],
visible=True
)
# ====== 交互逻辑 ======
generate_btn.click(
fn=generate_music,
inputs=[lrc_text, ref_audio, ref_prompt, use_chunked],
outputs=[audio_output, output_file]
)
# ====== 启动应用 ======
if __name__ == "__main__":
demo.launch(
server_name="0.0.0.0",
server_port=7860,
show_error=True,
share=False
)
4.测试
用DeepSeek按照DiffRhythm要求的风格生成歌词,prompts:
请你帮我生成一首能用于作曲的歌词,表现出大学生积极向上,热爱学习,报效祖国的斗志。为了使生成的歌词能用于后面作曲,请你参考如下格式作词,格式参考如下:“00:16.53]我一大早 起不来
[00:19.82]我的眼睛 都没睁开
[00:22.69]蝴蝶 都飞起来
[00:26.61]畅快
[00:28.18]忽然听见
[00:29.20]好听的音乐
[00:32.35]就继续用力
[00:33.29]闭上 我的眼睛 baby
[00:39.37]这音乐 太动听 我怎么办
[00:43.05]我太开心 所有烦恼 被洗干净
[00:51.61]我一大早 就起来
[00:54.85]我的声音 都没放开
[00:57.79]歌声 却飞起来
[01:26.28]一道光 两支花 三个人 四分五裂
[01:29.58]六六大顺 七上八下”
生成的歌词:
# 青春的旋律
[00:00.00]清晨的阳光 洒在脸上
[00:03.25]唤醒沉睡的 梦想
[00:06.45]校园里回荡 知识的声浪
[00:09.70]我们心向远方
[00:12.90]教室里的灯光 闪烁希望
[00:16.15]书本散发墨香
[00:19.35]智慧的种子 在心中生长
[00:22.60]未来由我们开创
[00:25.80]实验室里 探索真相
[00:29.05]代码在指尖流淌
[00:32.25]创新的火花 点亮夜的迷茫
[00:35.50]真理等待丈量
[00:38.70]运动场 上挥洒汗水
[00:41.95]青春的力量无法掩盖
[00:45.15]团结拼搏 是我们的风采
[00:48.40]梦想展翅豪迈
[00:51.60]啊 祖国母亲 我们时刻准备着
[00:54.85]用知识为您添砖加瓦
[00:58.05]在时代的舞台上大放光芒
[01:01.30]让世界见证我们的力量
风格设置为:
Inspirational Rock
上传参考音频重新作曲,这里我用的是“那条街”做参考音频: