training-data-and-pgvector-guide.md
12 KB
Training Data, Input Format, and pgvector Guide / 训练数据、输入格式与 pgvector 指南
更新:2026-06-02
一页结论
如果后面要把这个 ACR 项目做成稳定可持续的数据工程,建议把数据分成 4 层:
- 原始音频层:BGM、歌曲母带、录音、直播切片、手机录音
- 标准音频资产层:统一采样率、声道、文件命名后的可训练音频
-
manifest 层:
catalog.json/train.json/test.json/val.json - 向量索引层: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 时长 |
5s 或 8s
|
训练常用 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 母带/成品曲目”
这是最容易的情况。
推荐做法
- 每首完整 BGM 作为
reference - 从同一首 BGM 中随机切出多个 query 片段
- 给这些片段打上同一个
song_id - 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-splitsexternal_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 |
保留来源审计 |
当前代码最少已经建议保留:
typeoffsetsegment_typesource_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_versiondata_versionindex_versionsource_datasettypeoffset_secsegment_type
这样以后你能做:
- 按模型版本重建 embedding
- 按数据集来源筛选候选
- 按 query 类型分析误判
- 按
segment_type做 intro/outro 针对性策略
6.4 当前项目要为 pgvector 提前准备什么
现在就该做的,不是先建数据库,而是先保证这些字段规范:
-
song_id稳定且唯一 -
audio_path可追踪 -
type明确 -
offset可回溯 -
source_dataset清晰 - 模型产出的 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
最推荐:
- 每首完整 BGM 先放入一个目录
- 用统一命名整理
- 运行:
/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_idaudio_pathdurationtypeoffsetsegment_typesource_datasetsplit-
model_version(生成 embedding 时记录)
11. 推荐文档跳转
Sources
- Current code behavior from:
- Existing project docs: