training-data-and-pgvector-guide.md 12.9 KB

Training Data, Input Format, and pgvector Guide / 训练数据、输入格式与 pgvector 指南

更新:2026-06-02

一页结论

如果后面要把这个 ACR 项目做成稳定可持续的数据工程,建议把数据分成 4 层:

  1. 原始音频层:BGM、歌曲母带、录音、直播切片、手机录音
  2. 标准音频资产层:统一采样率、声道、文件命名后的可训练音频
  3. manifest 层catalog.json / train.json / test.json / val.json
  4. 向量索引层:embedding、metadata、pgvector/ANN 检索库

当前项目真正训练时吃进去的,不是“任意音频文件夹”,而是:

  • 音频文件
  • 配套 manifest
  • song_id 级别标签
  • query/reference 角色划分

如果未来要接 pgvector,推荐做法不是直接把原始音频塞进数据库,而是:

  • 音频留文件系统/对象存储
  • metadata 落 PostgreSQL
  • embedding 向量落 pgvector
  • song_id / segment_id / type / offset 做结构化列

1. 分层结构图

flowchart LR
    A[原始 BGM / 录音 / 歌曲] --> B[标准化音频资产]
    B --> C[Reference Catalog]
    B --> D[Query Segments]
    C --> E[Manifest JSON]
    D --> E
    E --> F[训练 / 评测]
    C --> G[Embedding / Fingerprint 索引]
    G --> H[pgvector / 检索服务]

2. 当前代码实际接受什么数据

2.1 音频层要求

从当前代码看,核心读取逻辑是:

  • librosa.load(..., sr=16000, mono=True)
  • 默认训练片段长度:5s
  • 外部数据 query 推荐长度:8s
  • 频谱输入:Mel spectrogram
  • 当前文档目标输入层:128 Mel

所以推荐原始资产先标准化为:

项目 推荐值 说明
文件类型 .wav / .mp3 / .flac / .ogg 当前转换工具支持这些后缀
采样率 16k 训练/评测读取时会统一到 16k
声道 mono 当前 pipeline 按 mono 读取
reference 时长 尽量完整曲目 用于建索引
query 时长 5s8s 训练常用 5s,开放数据切 query 常用 8s

2.2 manifest 层要求

当前项目的实际关键字段:

字段 必需 用途
song_id 主标签,同一首歌所有 query/reference 共享
audio_path 音频相对路径
duration 时长,控制切片与合法性
type reference / clean / augmented / confused / humming_like
offset 建议 query 在原曲中的起始偏移
segment_type 建议 intro / mid / outro / external_query
source_dataset 建议 数据来源标记

3. 训练数据到底应该长什么样

3.1 Reference 数据

Reference 表示“曲库真身”,用于建索引。

示例:

{
  "song_id": "song_0001",
  "audio_path": "audio/song_0001.wav",
  "duration": 183.4,
  "type": "reference",
  "source_dataset": "internal_bgm"
}

要求:

  • 一首歌至少 1 条 reference
  • reference 通常是整首歌或较长主版本
  • 不建议把噪音重、混响重、环境录音直接当 reference 主资产

3.2 Query 数据

Query 表示“我要识别的输入样本”。

示例:

{
  "song_id": "song_0001",
  "audio_path": "audio/song_0001_query_03.wav",
  "duration": 5.0,
  "type": "clean",
  "offset": 63.2,
  "segment_type": "mid",
  "source_dataset": "internal_bgm"
}

Query 的内容应该是:

  • 原曲中的 5s/8s 切片
  • 或人工合成退化片段
  • 或真实世界录音片段

Query 常见类型

type 含义 适合来源
clean 原曲直接切片 标准训练/评测主力
augmented 加噪、混响、压缩、EQ 后的切片 提升鲁棒性
confused 与其他音乐更相似、容易误判的片段 难例强化
humming_like 旋律近似、弱配器、手机录音风格 旋律/哼唱类近似查询

4. 如果我们有 BGM、音乐录音,怎么转成训练数据

4.1 场景 A:你有一批“标准 BGM 母带/成品曲目”

这是最容易的情况。

推荐做法

  1. 每首完整 BGM 作为 reference
  2. 从同一首 BGM 中随机切出多个 query 片段
  3. 给这些片段打上同一个 song_id
  4. query 再按用途分到 train/test/val

结果结构

flowchart TD
    A[完整 BGM] --> B[reference]
    A --> C1[query 1]
    A --> C2[query 2]
    A --> C3[query 3]
    C1 --> D[train/test]
    C2 --> D
    C3 --> D

关键点

  • song_id 必须稳定
  • 曲目版本要分清:主版本、纯伴奏版、短版、重编版不要误当同一首
  • 如果版本差异大,建议拆成不同 song_id

4.2 场景 B:你有“手机录音/环境录音/直播录屏”

这类数据不应直接全部当 reference 主资产,而更适合作为 query 或 hard-case 样本。

推荐角色

资产 角色
清晰母带 / 官方音源 reference
手机录音 / 环境录音 query
直播采集片段 query
背景噪声下的短片段 query

标注建议

如果录音可以明确对应某首 reference:

{
  "song_id": "song_0001",
  "audio_path": "queries/phone/song_0001_live_01.wav",
  "duration": 5.0,
  "type": "augmented",
  "segment_type": "external_query",
  "source_dataset": "phone_recording"
}

如果录音非常嘈杂、很接近旋律轮廓但音色严重失真:

  • 可标 type=humming_like
  • 或单独增加你们自己的扩展类型,如 field_recording

但要注意:

  • 训练前最好先映射回当前系统已有类型,避免代码完全不认识

4.3 场景 C:你只有一堆音频文件夹,还没做精标注

先做“弱监督标准化”比不做强。

最低可行办法

  • 一首文件 = 一个 song_id
  • 整首文件 = reference
  • 从整首里随机切 query = clean
  • 后续再人工修正错标/重名/版本冲突

这也是当前:

  • manifest_tools.py audio-dir-to-splits
  • external_adapters.py prepare-local

在做的事情。

适用场景

  • FMA
  • MTG-Jamendo
  • 你本地一批 BGM 文件夹
  • 一批已知 song-level 但未做 segment 级标注的数据

5. label 应该怎么设计

5.1 主标签:song_id

这是最重要的标签。

同一首歌的:

  • reference
  • clean query
  • 手机录音 query
  • 混响/噪声 query

都应该共享同一个 song_id

推荐命名

场景 推荐形式
内部 BGM bgm_000001
商业曲库 catalog_000001
开源数据 fma_012345
多版本项目 song_0001_vocal / song_0001_inst

5.2 辅助标签

建议额外保留:

字段 作用
version_id 区分原版 / 伴奏版 / 重编版
segment_type 区分 intro / mid / outro
recording_type 区分 studio / phone / live / screen_capture
noise_level 区分 clean / mild / heavy
source_dataset 保留来源审计

当前代码最少已经建议保留:

  • type
  • offset
  • segment_type
  • source_dataset

6. 如果以后接 pgvector,当前应该怎么处理

6.1 不要直接把原始音频塞进 pgvector

推荐分工:

存放位置
原始音频文件 对象存储 / 文件系统
manifest / metadata PostgreSQL 普通表
embedding 向量 pgvector
音频指纹 PostgreSQL JSON / 独立索引 / 文件

6.2 推荐表结构

flowchart TD
    A[songs] --> B[segments]
    A --> C[references]
    C --> D[reference_embeddings]
    B --> E[query_embeddings]

songs

说明
song_id 主键/唯一业务键
title 曲名
artist 作者/演出者
version_id 版本标识
source_dataset 来源
license 许可证

references

说明
reference_id 主键
song_id 外键
audio_uri 文件路径/对象存储地址
duration_sec 时长
sample_rate 采样率

segments

说明
segment_id 主键
song_id 外键
audio_uri query 文件路径
offset_sec 起始偏移
duration_sec 片段长度
type clean/augmented/confused/humming_like
segment_type intro/mid/outro/external_query
split train/test/val

reference_embeddings / query_embeddings

说明
id 主键
song_id 外键
segment_id / reference_id 外键
embedding vector(n)
model_version 模型版本
created_at 生成时间

6.3 pgvector 推荐实践

如果当前 embedding 维度是 192,那么可以设计:

embedding vector(192)

推荐额外保留字段

  • model_version
  • data_version
  • index_version
  • source_dataset
  • type
  • offset_sec
  • segment_type

这样以后你能做:

  • 按模型版本重建 embedding
  • 按数据集来源筛选候选
  • 按 query 类型分析误判
  • segment_type 做 intro/outro 针对性策略

6.4 当前项目要为 pgvector 提前准备什么

现在就该做的,不是先建数据库,而是先保证这些字段规范:

  1. song_id 稳定且唯一
  2. audio_path 可追踪
  3. type 明确
  4. offset 可回溯
  5. source_dataset 清晰
  6. 模型产出的 embedding 可以和 metadata 一一对应

换句话说:

先把 manifest 设计好,未来接 pgvector 才不会返工。


7. 推荐的落地目录与数据加工流程

7.1 原始层

acr-engine/data/raw/
  bgm_master/
  phone_recordings/
  live_captures/
  fma_small_audio/

7.2 标准化层

acr-engine/data/curated/
  my_bgm_v1/
    audio/
    manifests/

7.3 训练/评测层

catalog.json
train.json
test.json
val.json

8. 针对你当前项目的推荐操作方式

8.1 如果你现在手上有 BGM

最推荐:

  1. 每首完整 BGM 先放入一个目录
  2. 用统一命名整理
  3. 运行:
/usr/local/miniconda3/bin/python src/data/external_adapters.py inspect-local fma <你的目录>
/usr/local/miniconda3/bin/python src/data/external_adapters.py prepare-local fma <你的目录> --output-root data/external_ingested
/usr/local/miniconda3/bin/python src/data/external_adapters.py validate-local fma data/external_ingested/fma/manifests

如果只是你自有 BGM,不一定非要叫 fma,后面可以再做一个内部 adapter。


8.2 如果你现在手上有录音/采集片段

建议:

  • 不要把这批录音直接当 reference 主库
  • 先把它们映射到已有 reference 的 song_id
  • 作为 query / hard-case 数据进入训练或评测

如果当前无法人工全标:

  • 先放到单独目录
  • 先做 song-level 或 file-level 对齐
  • 后续逐步补 segment-level 标注

9. 一张总表

你手上的数据 推荐转化方式 在系统里的角色
完整 BGM 母带 整首保留 + 随机切 query reference + clean query
官方歌曲文件 整首保留 + 切片 reference + clean query
手机录音 对齐到已有 song_id augmented / humming_like query
直播录屏 截出音乐段并对齐 song_id external query
背景噪声录音 作为 hard case confused / augmented
开源整包数据集 inspect-local/prepare-local baseline train/eval corpus

10. 你现在最值得立刻固化的字段

如果后面确定要上 pgvector,现在最少要保证每条样本都能追踪:

  • song_id
  • audio_path
  • duration
  • type
  • offset
  • segment_type
  • source_dataset
  • split
  • model_version(生成 embedding 时记录)

11. 推荐文档跳转

12. 可直接落地的 pgvector 模板

仓库里现在已经补了两个可直接参考的模板:

导出示例

cd acr-engine
/usr/local/miniconda3/bin/python scripts/export_manifest_to_pgvector_json.py \
  --data data/synthetic_v2 \
  --split test \
  --source-dataset synthetic_v2 \
  --output reports/pgvector_manifest_export_test.json

当前已验证结果

  • songs=24
  • references=24
  • segments=20

这一步还不会直接写 PostgreSQL,作用是:

  1. 先把项目现有 manifest 规范转换成 pgvector-friendly 结构化 JSON
  2. 后续你们可以再用 bulk insert / COPY / ETL 把这些行落到 PostgreSQL
  3. embedding 生成后再写入 vector(192)

Sources