dataset-spec.md
9.3 KB
ACR Dataset / 输入输出规范
更新:2026-06-02
关联文档:训练数据与 pgvector 指南 · 开放数据工作流 · 数据来源与接入
一页结论
当前项目的数据规范,最重要的是 4 件事:
- 训练输入不是“整首 mp3 文件”本身,而是 manifest 驱动的 reference + query 样本体系。
- 训练和检索的切窗策略不同:训练端当前是随机裁剪 5s,检索/建索引端当前是5s 窗口 + 2.5s stride 的 50% 重叠滑窗。
- 外部开源数据集进入项目时,必须先转换成统一 manifest,再做训练、评测、索引和 pgvector 入库。
- 当前音乐任务输入层已切换到 128 维 Mel 频谱,并开启 band-split 方向;FMA 这类真实数据建议优先使用 GPU。
1. 数据流图
flowchart LR
A[Raw Audio\nFMA / MTG / 自有 BGM / 录音] --> B[Manifest Conversion]
B --> C[Catalog Manifest\nreference]
B --> D[Train/Test Manifest\nquery]
C --> E[Reference Index Build\nsliding windows]
D --> F[Training / Evaluation]
E --> G[Hybrid Retrieval]
F --> G
G --> H[pgvector / report / service]
2. 数据对象表
| 对象 | 作用 | 必要字段 | 说明 |
|---|---|---|---|
| Reference | 可检索曲库 |
song_id, audio_path, duration, type=reference
|
用于建索引 |
| Query Segment | 待识别片段 |
song_id, audio_path, duration, type
|
用于训练/评测 |
| Catalog Manifest | reference 总表 | JSON list | 用于离线索引 |
| Query Manifest | query 总表 | JSON list | 用于训练与评测 |
3. Manifest 结构图
flowchart TD
M[Manifest] --> R[Reference Records]
M --> Q[Query Records]
R --> R1[song_id]
R --> R2[audio_path]
R --> R3[duration]
R --> R4[type=reference]
Q --> Q1[song_id]
Q --> Q2[audio_path]
Q --> Q3[duration]
Q --> Q4[type=clean/augmented/confused/humming_like]
Q --> Q5[offset]
4. 输入输出总表
| 环节 | 输入 | 输出 |
|---|---|---|
| 训练 | query segments + references | embeddings + logits |
| 索引 | catalog references | chromaprint index + embedding index |
| 识别 | query audio | ranked candidates |
| 评测 | query manifest + catalog | top1/top5/hard-case report |
| 入库 | manifest + embedding | pgvector-ready JSON / SQL rows |
5. 3 分钟 mp3 到 5–8 秒片段:当前到底怎么切
5.1 当前代码里有 3 种不同切法
flowchart TD
A[3min mp3] --> B[训练 Dataset]
A --> C[检索 / 建索引]
A --> D[外部数据集 manifest 生成]
B --> B1[随机裁 1 个 5s clip]
C --> C1[5s 窗 + 2.5s stride]\n50% overlap
D --> D1[每首歌随机采 1 个 query]\n默认 8s
| 场景 | 当前实现 | 是否重叠 | 代码位置 |
|---|---|---|---|
训练 SongPairDataset
|
每次采样随机取一个 5s clip | 否,不是固定滑窗 | acr-engine/src/data/dataset.py |
| 检索 / embedding / 建索引 |
window_sec=5.0, stride_sec=2.5
|
是,50% overlap | acr-engine/src/utils/audio.py, acr-engine/src/engines/ecapa_embedder.py |
audio-dir-to-splits |
每首歌只生成 1 个随机 query | 否 | acr-engine/src/data/manifest_tools.py |
直接回答你的问题
- 有重叠窗口,但只在检索/索引链路里有。
- 当前训练主链路没有对 3 分钟 mp3 预展开成“全量重叠切片集”,而是每次 batch 动态随机裁一个 5s 片段。
- 当前外部数据集 manifest 生成器也没有自动为每首歌生成多个重叠 query。
5.2 为什么这样设计
| 设计点 | 当前好处 | 当前限制 |
|---|---|---|
| 训练随机裁剪 | 节省存储,不必预生成几万切片 | 同一 epoch 暴露到的时间区域有限 |
| 检索重叠滑窗 | 更接近真实 ACR reference coverage | 索引体积更大 |
| 外部数据一首歌一个 query | smoke 更轻、更快验证 | 训练/评测覆盖不充分 |
推荐理解方式:
- 训练端更像“随机数据增强采样器”
- 检索端更像“为了召回覆盖做滑窗索引”
6. 当前训练信号与 hard-case 规则
6.1 Hard-case 训练信号图
flowchart LR
A[Query Segment] --> B{type}
B -->|clean| C[w=1.0]
B -->|augmented| D[w=1.4]
B -->|humming_like| E[w=2.5]
B -->|confused| F[w=4.0]
C --> G[Sample-level SupCon + CE]
D --> G
E --> G
F --> G
| 类型 | 当前训练权重 | 目标 |
|---|---|---|
| clean | 1.0 | 保持基础识别稳定 |
| augmented | 1.4 | 提高常规退化鲁棒性 |
| humming_like | 2.5 | 提高旋律近似查询鲁棒性 |
| confused | 4.0 | 强化最易混淆片段分离能力 |
6.2 检索融合参数图
flowchart LR
A[Chromaprint Score] --> D[Fused Score]
B[ECAPA Score] --> D
C[Melody Score] --> D
| 参数 | 默认值 | 当前验证更优值(fast-eval) | 含义 |
|---|---|---|---|
chroma_weight |
0.25 | 0.20 | 降低纯指纹主导 |
ecapa_weight |
0.50 | 0.55 | 提高 embedding 检索主导 |
melody_weight |
0.25 | 0.25 | 暂时保持不变 |
7. 开源数据集 train/eval 切分图
flowchart LR
A[Open Audio Dir] --> B[audio-dir-to-splits]
B --> C[catalog.json]
B --> D[train.json]
B --> E[test.json]
B --> F[val.json]
| 产物 | 用途 | 说明 |
|---|---|---|
| catalog.json | 建索引 | 所有 reference 曲目 |
| train.json | 训练查询 | query + references |
| test.json | 评估查询 | query + references |
| val.json | 预留验证集 | 当前可为空 |
推荐法则:
- FMA / MTG-Jamendo 可优先用于真实 train/eval baseline
- 至少固定一部分曲目只进 test.json,不要同时参与训练
- 小数据集也要保证至少 1 个 train query + 1 个 test query
CLI 入口:
- 低层工具:acr-engine/src/data/manifest_tools.py
- 高层统一入口:acr-engine/src/data/external_adapters.py
prepare-local <dataset> <input_dir> - 导入前预检查:acr-engine/src/data/external_adapters.py
inspect-local <dataset> <input_dir> - 多目录批量预检查:acr-engine/src/data/external_adapters.py
inspect-batch fma=<dir> mtg_jamendo=<dir> ...
8. 当前项目输入层规范
| 项目 | 当前值/建议 | 说明 |
|---|---|---|
| 采样率 | 16kHz |
统一音频读取口径 |
| 声道 | mono |
当前链路按单声道处理 |
| 频谱 | 128 Mel |
音乐任务输入层 |
| 训练 clip | 5s |
当前训练代码事实 |
| 外部 query manifest 默认 | 8s |
当前 prepare-local/smoke-local 默认 |
| Band split | enabled |
已纳入当前模型配置 |
9. 文字说明
9.1 为什么必须分离 catalog 和 query
工业化系统里,“可搜索曲库”和“训练/评测 query”必须分离,否则评测会和真实服务语义混在一起。
9.2 为什么输入层是 128 Mel
音乐任务需要更丰富的频带表达;128 Mel 比 40 维 MFCC 更适合 timbre/harmony/band-split 建模。
9.3 为什么 query 类型必须显式标注
clean / augmented / confused / humming_like 不只是标签名,而是训练权重、评测 bucket、难例治理的入口。
9.4 关于 5s vs 8s 的一个当前注意点
当前仓库有两组时长:
- 训练 Dataset 与默认模型训练:5s
- 开放数据 manifest/query 默认:8s
这不是同一层配置,因此当前文档和实验报告里必须明确区分;不要把它们误认为一套统一参数。
9.5 当前经验结论
- 简单过采样会导致整体退化
- type-aware weighting 能提升一部分 hard case
- confused 类需要更高权重,但过强偏置会回伤
humming_like - residual confused failure 往往集中在
intro片段,因此segment_type不只是元数据,还应参与后续难负例设计
10. 细节附录
Reference 示例
{
"song_id": "song_0001",
"audio_path": "songs/song_0001.wav",
"duration": 20.0,
"type": "reference"
}
Query 示例
{
"song_id": "song_0001",
"audio_path": "segments/song_0001_seg_04_confused.wav",
"duration": 5.0,
"type": "confused",
"offset": 8.3,
"segment_type": "mid"
}