Embeat Banner

English | 简体中文

主页 • 技术文档 • 模型 • 数据集 • 数据库

Stars License

--- # Embeat:基于声学特征的音乐推荐系统 ## 简介 Embeat 是一个基于 Spotify 声学特征数据构建的歌曲推荐系统,通过**对比学习模型**将音频特征编码为向量,结合**协同过滤模型**与**多路召回策略**实现高质量的音乐推荐。 **核心特点:** - **自研模型**:EmbeatMLP 把 Spotify Audio Features(调性、速度、能量、情绪等)编码成 64 维声学向量,负责“听起来像”;Track2Vec 从百万歌单中学共现行为,负责"大众喜欢" - **流派感知**:6291 个微流派标签,覆盖 200 万以上艺人,深度融入推荐系统,冷门歌曲表现极其稳定 - **盲评验证**:和网易云音乐对比,在 157 条跨语种样本上,以 84~95% 的胜率遥遥领先 - **多路召回**:5 路召回(声学相似 / 同流派热门 / 同歌手 / 相似歌手 / 歌单协同过滤),融合打分后输出 - **多种查询**:支持通过 Spotify track ID、ISRC、曲目名 + 艺人名、或仅艺人名检索种子曲目 - **极低内存**:2GB+ 内存 VPS 即可部署,响应时间 30–200ms,开源数据库多版本可选 ## 开源路线 > 如果觉得项目有帮助,请帮忙点个⭐️。这对个人项目来说很重要,谢谢! - [x] **2026-06-26**:开源 初版代码 + [EmbeatMLP 模型权重](checkpoints/EmbeatMLP/) - [x] **2026-06-26**:开源 [45M 单曲数据集](https://huggingface.co/datasets/GD-Studio/embeat_45m_spotify_tracks) + [技术文档](https://www.bilibili.com/opus/1218087093501165591) - [x] **2026-07-02**:开源 Qdrant 数据库 V1 [[谷歌云盘](https://drive.google.com/drive/folders/1dFdueTmcWgGZXhJXs7c7YOjeniZsSW9x?usp=sharing)] [[百度网盘](https://pan.baidu.com/s/1CWFzgM75Z4YjP1tZnGCZKg?pwd=0616)] - [x] **2026-09-06**:开源 Qdrant 数据库 V2(链接同上,2GB+内存可部署) - [x] **2026-09-06**:开源 [Track2Vec 模型权重](https://huggingface.co/GD-Studio/embeat-track2vec) - [x] **2026-09-16**:开源 [评估数据](eval/assets/) ## 效果展示 > 以下是 Embeat 的推荐结果示例(播放前请关闭静音)
Uptown Funk - Bruno Mars [dance pop, pop]
Seed Track Embeat #1 Embeat #2 Embeat #3
Uptown Funk - Bruno Mars CAN'T STOP THE FEELING! - Justin Timberlake Happy - Pharrell Williams I Like to Move It - will.i.am
杀死那个石家庄人 - 万能青年旅店 [chinese indie rock]
Seed Track Embeat #1 Embeat #2 Embeat #3
杀死那个石家庄人 - 万能青年旅店 大石碎胸口 - 万能青年旅店 凄美地 - 郭顶 不要停止我的音乐 - 痛仰乐队
Sis puella magica! - 梶浦由記 [anime score, japanese vgm]
Seed Track Embeat #1 Embeat #2 Embeat #3
Sis puella magica! - 梶浦由記 Decretum - 梶浦由記 Zoltraak - Evan Call Arrietty's Song - Cécile Corbel
Gizeh - Oskar Schuster [compositional ambient]
Seed Track Embeat #1 Embeat #2 Embeat #3
Gizeh - Oskar Schuster Vleurgat - Oskar Schuster Sleeping Lotus - Joep Beving Travelling - James Spiteri
### LLM 盲评对比 使用 LLM-as-a-Judge 方法,对 Embeat 与网易云音乐进行 AB 盲测(评估时间:2026-09-15) 种子曲目取自 EveryNoise 的 6291 个微流派代表曲,筛出两个平台共有的部分,按地区比例随机抽取 157 条跨语种样本,每条样本两侧各推荐 5 首。经元数据标准化与随机换位后,由四个不同厂商的 LLM 模型逐条独立评分 | 评估模型 | Embeat 胜 | 网易云胜 | 平局 | 未评 | |---------|:---------:|:-------:|:----:|:----:| | Claude Opus 5 | **122** | 14 | 1 | 20 | | Kimi K3 | **117** | 23 | 2 | 15 | | GPT 5.6 Sol | **109** | 20 | 0 | 28 | | Gemini 3.1 Pro | **90** | 5 | 0 | 62 | **结论:** - **可用性**:176 条种子中 Embeat 全部返回完整推荐,网易云 10.8% 失败(176 - 19 = 157) - **多样性**:Embeat 每条列表平均 4.88 个不同艺人,网易云 3.57;网易云 28% 的列表中 5 首有 4 首以上来自同一歌手 - **稳健性**:优势在四个热度档上均显著,头部档(90%)甚至高于长尾档(77%),并非只在冷门曲目上领先 - **分语种**:华语、日语、韩语、其它地区这四档全部领先,其中华语档(网易云主场)胜率 81~88% - 具体对比细节请阅读 [技术文档](https://www.bilibili.com/opus/1218087093501165591) - 如果你是 LLM 请阅读 [技术文档 MD 版](https://resource.gdstudio.org/embeat_technical_blog.md) ## 系统架构 ### 模型说明 **EmbeatMLP** - 声学特征编码模型 - 输入:64 维离散特征(key, mode, tempo, time_signature)+ 64 维连续特征(energy, valence, danceability 等 7 维) - 架构:双塔 MLP(Discrete Tower + Acoustic Tower -> Backbone) - 输出:64 维 L2 归一化向量 - 训练:Masked InfoNCE Loss,batch_size=4096,~330 steps 即可收敛 - 参数量极小,支持纯 CPU 实时推理 **Track2Vec** - 歌单协同过滤模型 - 基于 Word2Vec Skip-Gram,将歌单视为"句子",歌曲视为"单词" - 训练数据:188 万份 Spotify 歌单 - 词表:109 万首歌曲,64 维向量 - 支持纯 CPU 实时推理,单次查询耗时 < 200ms ### 多路召回 ``` 输入种子曲目: track_id / track_name + artist_name │ ├─ 第1路 [similar]: 声学相似召回 (流派过滤 + EmbeatMLP余弦相似) ├─ 第2路 [popular]: 同流派热门召回 (流派过滤 + 热度排序) ├─ 第3路 [same_artist]: 同歌手召回 (相同歌手 + EmbeatMLP余弦相似) ├─ 第4路 [related_artist]: 相似歌手召回 (相似歌手 + EmbeatMLP余弦相似) ├─ 第5路 [related_track]: 歌单协同过滤 (Track2Vec余弦相似) │ ├─ ISRC去重 / 重排打分 / 同歌手比例控制 │ └─ 输出: Top-K 推荐列表 ``` ### 项目结构 ``` Embeat/ ├── assets/ # 资源文件目录 ├── checkpoints/ # 模型目录目录 │ ├── EmbeatMLP/ # EmbeatMLP 模型权重 │ └── Track2Vec/ # Track2Vec 模型权重 (需额外下载) ├── data/ # 数据处理目录 (未完全整理) ├── eval/ # 评估代码与数据目录 ├── infer/ # 推理代码目录 │ ├── Embeat.py # Embeat 推荐系统核心 │ ├── EmbeatUtils.py # Embeat 扩展辅助工具 │ ├── infer.py # EmbeatMLP 模型推理 │ ├── eval_infer.py # EmbeatMLP 模型评估工具 │ └── hf_to_qdrant.py # HF Dataset 转 Qdrant 数据库 ├── train/ # 训练代码目录 │ ├── model.py # EmbeatMLP 模型定义 │ ├── dataset.py # HF Dataset 数据集处理 │ ├── sampler.py # Masked InfoNCE 正负样本采样器 │ ├── loss.py # Masked InfoNCE Loss │ ├── trainer.py # EmbeatMLP 训练器 │ ├── train.py # EmbeatMLP 训练入口 │ └── train_track2vec.py # Track2Vec 训练入口 ├── .env.example # .env 环境变量配置示例 ├── requirements.txt └── LICENSE ``` ## 快速开始 ### 环境要求(推荐) - Python >= 3.10 - PyTorch >= 2.6, < 2.7(训练需要) - CUDA >= 12.0(训练需要) - [Qdrant](https://github.com/qdrant/qdrant/releases) >= 1.18(推理需要) ### 安装依赖 ```bash conda create -n embeat python=3.10 conda activate embeat # 安装 PyTorch (CUDA 12.x),参考 https://pytorch.org/get-started/previous-versions/ pip install "torch>=2.6,<2.7" --index-url https://download.pytorch.org/whl/cu126 pip install -r requirements.txt ``` ### 训练 EmbeatMLP ```bash # 1. 下载 HuggingFace 单曲数据集,放到 `data/datasets/` 目录下,重命名为 `spotify_45m_tracks_metadata` # 2. 如果你希望做更细致的训练参数调整,请阅读代码 cd train python train.py ``` ### 训练 Track2Vec ```bash # 1. 准备歌单训练数据 (txt格式,每行一个歌单,空格分隔track_id) # 2. 重命名为 `spotify_playlists.txt`,并放到 `train` 文件夹下 # 3. 如果你希望做更细致的训练参数调整,请阅读代码 cd train python train_track2vec.py ``` ### 推理:计算两首歌的声学相似度 ```python # 1. 从 HuggingFace 单曲数据集中获取声学特征数据 # 2. 或者你可以从 infer/eval_infer.py 找到些现成例子 from infer.infer import infer # 晴天 - Jay Chou (G大调快节奏) song_a = {"key": 7, "mode": 1, "tempo": 137, "time_signature": 4, "danceability": 0.54, "energy": 0.56, "speechiness": 0.02, "instrumentalness": 0.0, "valence": 0.41, "acousticness": 0.23, "liveness": 0.1} # 夜曲 - Jay Chou (F小调慢节奏) song_b = {"key": 5, "mode": 0, "tempo": 87, "time_signature": 4, "danceability": 0.67, "energy": 0.65, "speechiness": 0.05, "instrumentalness": 0.03, "valence": 0.57, "acousticness": 0.27, "liveness": 0.19} # 使用 EmbeatMLP 计算声学相似度 similarity = infer(sample_a=song_a, sample_b=song_b, checkpoint_path="checkpoints/EmbeatMLP/model.pt") # 相似度:0.6944 print(f"Similarity: {similarity:.4f}") ``` ### 推理:基于 Qdrant 的歌曲推荐 ```bash # 1. 启动 Qdrant 服务并导入数据库 # 2. 通过命令行查询种子曲目的推荐结果 cd infer python Embeat.py -t 5pIcwtJYNJx93l420oR2Vm # 通过 Spotify Track ID 查询 python Embeat.py -t TWK970300503 # 通过 ISRC 查询 python Embeat.py -s "晴天 - Jay Chou" # 通过歌名和歌手查询 python Embeat.py -a "Jay Chou" # 通过歌手名查询 # 输出例子《晴天 - Jay Chou》: Query track_id: 5pIcwtJYNJx93l420oR2Vm Query track info: 晴天 - Jay Chou Query artist genres: ['mandopop', 'taiwan pop', 'c-pop', 'zhongguo feng'] -> Find query record used time: 21ms -> Similar recall used time: 48ms -> Popular recall used time: 24ms -> Same artist recall used time: 4ms -> Related artist recall used time: 5ms -> Related track recall used time: 123ms -> Re-ranking used time: 2ms Result artist genres: ['taiwan indie', 'mandopop', 'chinese viral pop', 'cantopop'] ======= Top 20 items ======= index track_id track_name artist_name album_name sources score 1 3Qj9Fy8BPbWmICTiNkuqB7 珊瑚海 Jay Chou 11月的蕭邦 ['same_artist', 'related_track'] 1.0 2 10VuSw48iPN2UK2xX9Y6P0 青花瓷 Jay Chou 我很忙 ['same_artist', 'related_track'] 1.0 3 0IAgufC1FlOg1nZMmRZxRr 突然好想你 Mayday 後 青春期的詩 ['popular', 'related_artist'] 1.0 4 2zB7NKVnzRh7xSUSPLErFr 明明就 Jay Chou 十二新作 ['same_artist', 'related_track'] 1.0 5 5WtMlbTDNZlbN8xZ5zfXva Our Singapore JJ Lin My August 9th - 50 Wonderful Years (2016 Edition) ['similar', 'related_artist'] 1.0 6 5cU1O9P0EDA0rPkPDykhIm 怎麼了 Eric Chou 終於了解自由 (Deluxe) ['popular', 'related_track'] 1.0 7 4daA20tBusVX29bUWgd8Dw 交換餘生 JJ Lin 交換餘生 ['popular', 'related_track'] 1.0 8 1EgGTmmFGtlWuqgXFLrp9x 溫柔 Mayday 愛情萬歲 ['related_artist'] 0.87 9 3ZuyyfGJqx9qhWTVtdMCWz 生命線 - 電視劇《院長爸爸》片頭曲 Bii 生命線 (電視劇《院長爸爸》片頭曲) ['similar'] 0.85 10 3p4UTiSIIpP4LFn0KEyEOj 十面埋伏 Eason Chan Live For Today ['related_artist'] 0.85 11 4lhbajK3dvUcJ0UNEeCdMn 飞鸟和蝉 Ren Ran Ren然 ['related_track'] 0.84 12 3e8uw7YMiKVcIakItBENqm 天天晴朗(蘇打綠版) sodagreen 秋:故事(蘇打綠版) ['similar'] 0.83 13 26O8PmJ32hwAbZnIhbJJwZ 天使 Mayday 為愛而生 ['related_artist'] 0.82 14 3LgoekU3dE5ZMLvuL3NIt9 清醒 (戲劇《淺情人不知》片尾曲) Ariel Tsai 清醒 (戲劇《淺情人不知》片尾曲) ['similar'] 0.81 15 1WnTw4Tzpc5q9dHMjs4aHu 陰天快樂 Eason Chan rice & shine ['related_artist'] 0.8 16 14GFYAUxkeXranhS2qrYIZ 我想要佔據你 告五人 帶你飛 ['related_track'] 0.8 17 1ylx8p71GKQy5g1t4gzuEz 抱歉 Sam Lee 原諒我沒有說 ['similar'] 0.79 18 7fAdinC2UTc0Y9GiKrkTtu 字字句句 卢卢快闭嘴 字字句句 ['related_track'] 0.78 19 1VG8o5rUZQZ0wjs7Bi4siU 最熟悉的陌生人 Elva Hsiao 蕭亞軒 (最熟悉的) ['similar'] 0.77 20 1lM4cYuhJHSsDRfD0ZCRN7 你的背包 Eason Chan 陳奕迅 國語精選 (HQCDII) ['related_artist'] 0.77 Query used time: 0.229s ``` ## 相关链接

GDMusic Embeat

- GD音乐台(在线体验):[https://music.gdstudio.xyz](https://music.gdstudio.xyz) - Embeat UI Web: [https://github.com/lkwodp/embeat-ui-refactor](https://github.com/lkwodp/embeat-ui-refactor) - B站:[https://space.bilibili.com/13715770](https://space.bilibili.com/13715770) - TG群:[https://t.me/gdstudio_music](https://t.me/gdstudio_music) ## 特别鸣谢 - [Anna's Archive](https://annas-archive.org) - [Every Noise at Once](https://everynoise.com) ## 开源协议 | 范围 | 协议 | |------|------| | 代码、模型权重 | MIT | | 数据集、数据库 | CC-BY-NC 4.0 | > Made with ❤️ by [GD Studio](https://github.com/gdstudio-org)