Commit d8fd2d15 d8fd2d15ecdcd77313117c6a0c7020a6926cbd7c by cnb.bofCdSsphPA

Preserve a fast handoff entrypoint for the ACR roadmap

Constraint: The startup handoff must reflect the new Phase-1 encoder-only and PostgreSQL v2 decisions without carrying stale timeline noise
Rejected: Keep appending runtime logs to session-handoff.md | It obscures the current start point for the next session
Confidence: high
Scope-risk: narrow
Directive: Keep session-handoff.md focused on where to resume next, and move detailed chronology into changelog/history docs
Tested: git diff --check -- docs/session-handoff.md docs/CHANGELOG.md
Not-tested: No link checker or markdown linter was run
1 parent 4b23f546
## 2026-06-04
- 重写 [session-handoff 交接文档](./session-handoff.md),将其从历史流水账收敛为“下次启动即用”的启动手册,明确当前稳定结论、推荐阅读顺序、已验证/未验证边界,以及下一步应从 PostgreSQL v2 schema 与 Phase-1 encoder-only 执行链开始推进。
- 新增 [Phase-1 实施清单](./phase1-implementation-checklist.md),把 encoder-only 路线拆成主数据、reference set、feature set、索引、评测的可执行阶段。
- 新增 [模型与 Feature Set 初始化手册](./model-feature-registry-bootstrap.md),补齐 model_registry / feature_set_registry / reference_set_registry 的初始化约定与示例 SQL。
- 重构文档主阅读路径,新增按角色划分的文档入口:架构、开发、运维、模型底座。
......
# Session Handoff / 持续开发交接文档
> 更新:2026-06-02
> 目的:让新 session / 新代理进入仓库后,能在最短时间内理解项目现状并继续开发。
## 一页结论
### 最新交付快照(2026-06-03 本地 20-song + voice pipeline)
- 当前样本策略已明确分层:
- `/workspace` 仅作为样本/素材来源
- `acr-engine/` 才是训练、检索、评测、服务主工程
- 当前本地 20-song 验证路线已固定:
- 本地小样本优先 **FAISS**
- `chromadb` 作为可选对照后端
- 生产环境继续保留 **pgvector**
- 新增本地 20-song 入口:
- `acr-engine/scripts/local_music20_acr.py`
- 结果产物:`acr-engine/data/local_eval/music20_summary.json`
- 当前本地 20-song 结果:
- `type_1 -> type_11`: `top1=1.0`, `top3=1.0`
- `type_7 -> type_11`: `top1=0.45`, `top3=0.65`
- `type_8 -> type_11`: `top1=0.4667`, `top3=0.7333`
- `type_16 -> type_11`: `top1=0.4167`, `top3=0.4167`
- 新增哼唱/录音接入基础能力:
- `acr-engine/src/data/voice_chunker.py`:voice -> chunk
- `acr-engine/scripts/build_humming_eval_manifest.py`:chunk -> `humming_real` manifest
- `acr-engine/src/utils/context_exporter.py`:命中 reference window -> 上下文 clip(默认 10s)
- FastAPI 服务当前状态:
- `acr-engine/src/service/app.py` 已新增 `POST /recognize/voice`
- `/health` 可正常启动并返回 `ok`
- architect review: approved with watch;当前 split(本地 FAISS / 可选 ChromaDB / 生产 pgvector)方向成立
- 当前 `POST /recognize/voice` 已跨过依赖缺失与超时阶段:CPU 版 `torch` 已安装、`uvicorn` / `fastapi` / `python-multipart` 已安装、`/health` 可返回 `ok`;同时 voice smoke 已切到 `corpus=workspace_music20`,返回 `chunk_count=1`, `top_song_id=109`, `has_context=true`,并附带真实 `/workspace` reference 路径。当前剩余问题是继续校验该 top1 是否与业务预期一致,而不是链路未通。
- 当前 docs 已做第一轮简化:
- `docs/README.md` 只保留最新架构与最短阅读顺序
新 session 最短启动路径(当前推荐):
1.`docs/session-handoff.md`
2.`docs/README.md`
3.`docs/CHANGELOG.md`
4. 直接从 `acr-engine/README.md``acr-engine/scripts/local_music20_acr.py` 继续
当前最重要的下一步:
1. 给当前解释器安装/修复 `torch`
2. 真正跑通 `POST /recognize/voice`
3. 把哼唱评测集接入 `evaluate.py` 或独立评测脚本
4. 继续做 docs 第二轮收敛,只保留当前有效主文档
- 已新增 song_id 级 pgvector 评测脚手架:
- `acr-engine/scripts/export_workspace_music20_embeddings_jsonl.py`
- `acr-engine/scripts/evaluate_songid_pgvector_path.py`
- 当前 `acr-engine/data/pgvector_eval/music20/songid_eval_report.json` 结果:
- overall: `top1=0.9091`, `top3=0.9545`
- `query_type=1`: `top1=1.0`, `top3=1.0`
- `query_type=7`: `top1=0.0`, `top3=0.5`
- 注意:当前 20-song 导出里 `query_type=8/16` 行数仍不足(0 行),说明下一步需要专门扩 business reference / query 选择,而不是只沿用当前前 20 首 reference。
- 当前 `workspace_music20` 业务正确性初测(`acr-engine/data/local_eval/voice_workspace20_type7_eval.json`):
- `num_queries=20`
- `top1=0.0`
- `top3=0.05`
- 说明当前 business sample 语义虽然已通路,但 song_id 正确性还很差,必须继续优化,不可直接当成可用识别能力。
- 当前已继续补齐 `type_8 / type_16` 的 business-corpus voice correctness 基线:
- `voice_workspace20_type8_eval.json`: `num_queries=15`, `top1=0.0`, `top3=0.0`
- `voice_workspace20_type16_eval.json`: `num_queries=12`, `top1=0.0`, `top3=0.0`
- 说明当前基于 `/workspace` 的本地 chroma+FAISS voice lane 在 hard query 上几乎不可用,后续应优先切向更接近生产的 embedding/pgvector 评测路径。
- architect review 当前结论:`APPROVED (WATCH)`,允许继续沿当前架构推进,但需要明确区分“链路通”与“业务正确”。
### 最新补充(2026-06-03 voice service runtime)
- 已确认当前解释器 `/usr/local/miniconda3/bin/python` 下:
- `torch==2.3.1+cpu`
- `uvicorn==0.48.0`
- `fastapi==0.136.3`
- `python-multipart==0.0.30`
- `acr-engine/src/service/app.py` 当前可启动并通过:
- `GET /health`
- `GET /ready`
- `POST /recognize/voice` 当前不再报缺依赖,但端到端 smoke 仍会超时。
- 当前最可能的下一步排查点:
1. `voice_to_chunks` 默认切出的 chunk 数过多(当前样例可到 9 个)
2. 首次 `_load_engine()` + `engine.recognize()` CPU 推理耗时过长
3. `context_exporter` 在每个候选上再次做 reference 滑窗,进一步拉长总耗时
- 下一 session 建议直接从:
- `acr-engine/src/service/app.py`
- `acr-engine/scripts/service_voice_smoke.py`
- `acr-engine/src/data/voice_chunker.py`
- `acr-engine/src/utils/context_exporter.py`
继续收敛超时问题。
### 最新交付快照(2026-06-02 16:12 UTC)
- 当前状态:先交付,后续重启继续
- 当前最佳候选:`hum_focus`
- 最新复核:`hum_guard` 未超过 `hum_focus`
- 当前可继承的文档:
- `docs/CHANGELOG.md`
- `docs/changelist-2026-06-02.md`
- `docs/delivery-handoff-2026-06-02.md`
- 新 session 最短启动路径:
1. 读本文件
2. 读 changelog
3.`hum_focus` 继续做小步优化
### 最新交付快照(2026-06-02 16:03 UTC)
- 当前远程同步基线:`9c3f182`(更新前)
- 当前最重要的新事实:**dual-axis 候选已收敛到 hum_focus**
- `hum_focus`
- `top1=0.7`
- `topk=0.85`
- `humming_like=0.5`
- `confused=0.25`
- `hum_balanced`
- `top1=0.65`
- `topk=0.95`
- `humming_like=0.25`
- `confused=0.25`
- 结论:
- `hum_focus` 当前是这轮双轴搜索的最佳候选
- 下一轮应围绕 `hum_focus` 微调,而不是回到 `v6` 或继续盲搜
- 新 session 第一优先级:
1. 围绕 `hum_focus` 做小步权重搜索
2. 优先保住 `humming_like` 优势
3. 再做 real-path clean + synthetic hard-case 双轨复测
### 最新可观测性修复(2026-06-02 15:18 UTC)
- 已为 `run_demo.py``src/engines/chromaprint_matcher.py``src/engines/ecapa_embedder.py` 的关键 `print()` 增加 `flush=True`
- 极小样本复现 `/tmp/chroma_repro_tiny12` 已验证:
- 日志文件不再保持 `0 bytes`
- traceback 可实时落盘
- 当前已确认:至少“失败时无日志”这个问题已被修复;下一步继续追真实路径 root cause。
- 验证结果补充:`RC=1`,日志中可见 `ValueError: No reference embeddings were produced ...`
这是一个正在从原型向工业化推进的 **音乐 ACR / music retrieval** 项目。
当前已经完成:
1. **原型可运行**
- synthetic 数据生成
- 训练
- 建索引
- 识别
- 评测
2. **开放数据接入链路完整闭环**
- inspect-local / inspect-batch
- prepare-local
- validate-local
- train
- build-index
- evaluate
- generate_artifacts
3. **文档已浓缩**
- docs 入口已分成 4 组
- 相对路径支持跳转
- 开放数据工作流有单页文档
当前最重要的下一步:
- 用真实本地 FMA / MTG-Jamendo 音频目录替换 synthetic stand-in
- 跑真实开放数据 smoke
- 继续优化准确率,尤其是 `confused` / `humming_like`
### 最新真实 FMA 运行事实(2026-06-02 补记)
- `fma_small.zip` 已完整落地,并已解压到 `acr-engine/data/raw/fma_small_audio`
- `check-local-ready fma ...` 已验证:
- `ready_for_smoke=true`
- `num_audio_files=8000`
- `eligible_query_files=7994`
- 真实 FMA smoke 已实际启动到:
- 输出目录:`/tmp/fma_real_smoke_stopcheck`
- manifest 校验:`ok=true`
- 当前训练规模:`catalog_references=8000`, `train_queries=6401`, `test_queries=1593`
- 当前环境无 GPU:
- `nvidia-smi` => `NO_NVIDIA_GPU`
- `torch.cuda.is_available() = false`
- 因此本轮真实 smoke 当前表现为 **CPU 长训练**,不是异常卡死。
- 重要:`train.py` 采用 **epoch-end save** 策略,`best_model.pt` 会在 `Epoch 1` 结束后首次落盘;所以训练中途看到空的 `fma_models_smoke/` 目录是正常现象。
---
### 最新 checkpoint(2026-06-02 12:09 UTC)
- 真实 FMA smoke 主进程仍在运行:
- `PID=311494``src/data/external_adapters.py smoke-local fma ...`
- `PID=311629``train.py --data /tmp/fma_real_smoke_stopcheck/fma/manifests ...`
- 最新观测:
- `train.py ELAPSED=12:00`
- `%CPU≈615`
- `%MEM≈10.4`
- manifest 仍有效:
- `catalog_references=8000`
- `train_queries=6401`
- `test_queries=1593`
- `val_queries=0`
- `/tmp/fma_real_smoke_stopcheck/fma_models_smoke/` 当前仍为空目录。
- 这是**符合当前 train.py 保存逻辑**的:`best_model.pt` 要到 `Epoch 1` 结束后才会首次落盘。
### 当前卡点(最新)
1. **真实 FMA smoke 尚未出首个模型文件**
- 原因不是异常,而是当前环境无 GPU,且本次使用真实 FMA 全量 8000 首参考。
2. **MTG-Jamendo 目录仍未就绪**
- `data/raw/mtg_jamendo_audio` 当前仍缺少可用音频文件,暂时无法进入同级别 smoke。
3. **工作树噪音依旧很大**
- 提交时必须继续只显式暂存文档 / 脚本,不能误带 `data/external_smoke``data/raw`、checkpoint、`__pycache__`
### 更新中的 fresh evidence(2026-06-02 12:11 UTC)
- 与上一版交付相比,真实 FMA smoke 仍在持续推进,而不是僵死:
- `train.py ELAPSED=14:25`
- `%CPU≈615`
- `%MEM≈10.4`
- 当前仍仅看到运行中的两个关键进程:
- `PID=311494``external_adapters.py smoke-local fma ...`
- `PID=311629``train.py --data /tmp/fma_real_smoke_stopcheck/fma/manifests ...`
- 仍未出现 `build-index` / `evaluate` 相关新进程。
- `/tmp/fma_real_smoke_stopcheck/fma_models_smoke/` 仍只有目录本身,没有模型文件。
- manifest 再次校验结果未变:
- `catalog_references=8000`
- `train_queries=6401`
- `test_queries=1593`
- `val_queries=0`
- `ok=true`
这说明:
- 当前状态是 **真实 FMA 全量训练仍在 epoch 内部推进**
- 还没有到 `Epoch 1` 结束,因此仍不能期待 `best_model.pt` 已经落盘。
### 再更新的 fresh evidence(2026-06-02 12:12 UTC)
- 真实 FMA smoke 仍在持续推进:
- `train.py ELAPSED=15:12`
- `%CPU≈614`
- `%MEM≈10.5`
- 当前进程结构仍未变化:
- `PID=311494``external_adapters.py smoke-local fma ...`
- `PID=311629``train.py --data /tmp/fma_real_smoke_stopcheck/fma/manifests ...`
- 仍未观测到 `build-index` / `evaluate` 相关新进程。
- `fma_models_smoke/` 仍只有目录本身,没有模型文件。
- manifest 再次校验仍然通过:
- `ok=true`
- `catalog_references=8000`
- `train_queries=6401`
- `test_queries=1593`
- `val_queries=0`
这说明:
- 真实 FMA 全量 smoke 依旧在 `Epoch 1` 内部推进。
- 截至 12:12 UTC,仍未出现首个可落盘模型文件或下游阶段切换。
### 再次刷新的 fresh evidence(2026-06-02 12:14 UTC)
- 真实 FMA smoke 继续推进:
- `train.py ELAPSED=17:07`
- `%CPU≈615`
- `%MEM≈10.4`
- 当前仍只有训练阶段相关进程:
- `PID=311494``external_adapters.py smoke-local fma ...`
- `PID=311629``train.py --data /tmp/fma_real_smoke_stopcheck/fma/manifests ...`
- 仍未观测到 `build-index` / `evaluate` 新进程。
- `fma_models_smoke/` 仍只有目录本身,没有模型文件。
- manifest 复核仍通过:
- `ok=true`
- `catalog_references=8000`
- `train_queries=6401`
- `test_queries=1593`
- `val_queries=0`
这进一步说明:
- 当前 smoke 仍在第一个 epoch 内持续前进。
- 到 12:14 UTC 为止,仍未进入保存首个模型文件或下游检索/评测阶段。
### 再次推进的 fresh evidence(2026-06-02 12:15 UTC)
- 真实 FMA smoke 持续推进到:
- `train.py ELAPSED=18:22`
- `%CPU≈615`
- `%MEM≈10.5`
- 当前进程结构仍未发生阶段切换:
- `PID=311494``external_adapters.py smoke-local fma ...`
- `PID=311629``train.py --data /tmp/fma_real_smoke_stopcheck/fma/manifests ...`
- 仍未出现 `build-index` / `evaluate` 相关新进程。
- `fma_models_smoke/` 仍只有目录本身,没有模型文件。
- manifest 再次复核仍通过:
- `ok=true`
- `catalog_references=8000`
- `train_queries=6401`
- `test_queries=1593`
- `val_queries=0`
这说明:
- 当前依旧只是第 1 个 epoch 内部持续推进。
- 到 12:15 UTC 为止,仍没有首个模型文件或后续检索/评测阶段证据。
### 再次延后的 fresh evidence(2026-06-02 12:16 UTC)
- 真实 FMA smoke 继续推进到:
- `train.py ELAPSED=19:12`
- `%CPU≈614`
- `%MEM≈10.6`
- 当前进程结构仍未发生阶段切换:
- `PID=311494``external_adapters.py smoke-local fma ...`
- `PID=311629``train.py --data /tmp/fma_real_smoke_stopcheck/fma/manifests ...`
- 仍未出现 `build-index` / `evaluate` 相关新进程。
- `fma_models_smoke/` 仍只有目录本身,没有模型文件。
- manifest 再次复核仍通过:
- `ok=true`
- `catalog_references=8000`
- `train_queries=6401`
- `test_queries=1593`
- `val_queries=0`
这说明:
- 当前依旧处于第 1 个 epoch 内部的持续训练阶段。
- 到 12:16 UTC 为止,仍没有首个模型文件或下游检索/评测阶段证据。
### 继续延后的 fresh evidence(2026-06-02 12:17 UTC)
- 真实 FMA smoke 继续推进到:
- `train.py ELAPSED=20:08`
- `%CPU≈614`
- `%MEM≈10.6`
- 当前进程结构仍未发生阶段切换:
- `PID=311494``external_adapters.py smoke-local fma ...`
- `PID=311629``train.py --data /tmp/fma_real_smoke_stopcheck/fma/manifests ...`
- 仍未出现 `build-index` / `evaluate` 相关新进程。
- `fma_models_smoke/` 仍只有目录本身,没有模型文件。
- manifest 再次复核仍通过:
- `ok=true`
- `catalog_references=8000`
- `train_queries=6401`
- `test_queries=1593`
- `val_queries=0`
这说明:
- 当前依旧处于第 1 个 epoch 内部的持续训练阶段。
- 到 12:17 UTC 为止,仍没有首个模型文件或下游检索/评测阶段证据。
### 持续推进的 fresh evidence(2026-06-02 12:19 UTC)
- 真实 FMA smoke 继续推进到:
- `train.py ELAPSED=22:10`
- `%CPU≈615`
- `%MEM≈10.7`
- 当前进程结构仍未发生阶段切换:
- `PID=311494``external_adapters.py smoke-local fma ...`
- `PID=311629``train.py --data /tmp/fma_real_smoke_stopcheck/fma/manifests ...`
- 仍未出现 `build-index` / `evaluate` 相关新进程。
- `fma_models_smoke/` 仍只有目录本身,没有模型文件。
- manifest 再次复核仍通过:
- `ok=true`
- `catalog_references=8000`
- `train_queries=6401`
- `test_queries=1593`
- `val_queries=0`
这说明:
- 当前依旧处于第 1 个 epoch 内部的持续训练阶段。
- 到 12:19 UTC 为止,仍没有首个模型文件或下游检索/评测阶段证据。
### 持续推进的 fresh evidence(2026-06-02 12:20 UTC)
- 真实 FMA smoke 继续推进到:
- `train.py ELAPSED=22:58`
- `%CPU≈615`
- `%MEM≈10.8`
- 当前进程结构仍未发生阶段切换:
- `PID=311494``external_adapters.py smoke-local fma ...`
- `PID=311629``train.py --data /tmp/fma_real_smoke_stopcheck/fma/manifests ...`
- 仍未出现 `build-index` / `evaluate` 相关新进程。
- `fma_models_smoke/` 仍只有目录本身,没有模型文件。
- manifest 再次复核仍通过:
- `ok=true`
- `catalog_references=8000`
- `train_queries=6401`
- `test_queries=1593`
- `val_queries=0`
这说明:
- 当前依旧处于第 1 个 epoch 内部的持续训练阶段。
- 到 12:20 UTC 为止,仍没有首个模型文件或下游检索/评测阶段证据。
### 30 秒窗口后的 fresh evidence(2026-06-02 12:21 UTC)
- 经过额外约 30 秒等待后,真实 FMA smoke 继续推进到:
- `train.py ELAPSED=24:11`
- `%CPU≈615`
- `%MEM≈11.3`
- 当前进程结构仍未发生阶段切换:
- `PID=311494``external_adapters.py smoke-local fma ...`
- `PID=311629``train.py --data /tmp/fma_real_smoke_stopcheck/fma/manifests ...`
- 仍未出现 `build-index` / `evaluate` 相关新进程。
- `fma_models_smoke/` 仍只有目录本身,没有模型文件。
- manifest 再次复核仍通过:
- `ok=true`
- `catalog_references=8000`
- `train_queries=6401`
- `test_queries=1593`
- `val_queries=0`
这说明:
- 即使拉开更有意义的时间窗口,当前仍能确认训练在前进,而不是僵死。
- 到 12:21 UTC 为止,仍没有首个模型文件或下游检索/评测阶段证据。
### 120 秒窗口后的 fresh evidence(2026-06-02 12:25 UTC)
- 经过更长的约 120 秒观察窗口后,真实 FMA smoke 继续推进到:
- `train.py ELAPSED=27:54`
- `%CPU≈615`
- `%MEM≈11.2`
- 当前进程结构仍未发生阶段切换:
- `PID=311494``external_adapters.py smoke-local fma ...`
- `PID=311629``train.py --data /tmp/fma_real_smoke_stopcheck/fma/manifests ...`
- 仍未出现 `build-index` / `evaluate` 相关新进程。
- `fma_models_smoke/` 仍只有目录本身,没有模型文件。
- manifest 再次复核仍通过:
- `ok=true`
- `catalog_references=8000`
- `train_queries=6401`
- `test_queries=1593`
- `val_queries=0`
这说明:
- 在更长的观察窗口下,训练依然持续前进,而不是假性活动或僵死。
- 到 12:25 UTC 为止,仍没有首个模型文件或下游检索/评测阶段证据。
### 180 秒窗口后的 fresh evidence(2026-06-02 12:29 UTC)
- 经过更长的约 180 秒观察窗口后,真实 FMA smoke 继续推进到:
- `train.py ELAPSED=31:47`
- `%CPU≈615`
- `%MEM≈11.0`
- 当前进程结构仍未发生阶段切换:
- `PID=311494``external_adapters.py smoke-local fma ...`
- `PID=311629``train.py --data /tmp/fma_real_smoke_stopcheck/fma/manifests ...`
- 仍未出现 `build-index` / `evaluate` 相关新进程。
- `fma_models_smoke/` 仍只有目录本身,没有模型文件。
- manifest 再次复核仍通过:
- `ok=true`
- `catalog_references=8000`
- `train_queries=6401`
- `test_queries=1593`
- `val_queries=0`
这说明:
- 在更长的观察窗口下,训练依然持续前进,而不是假性活动或僵死。
- 到 12:29 UTC 为止,仍没有首个模型文件或下游检索/评测阶段证据。
### 重大阶段切换证据(2026-06-02 12:34 UTC)
- 真实 FMA smoke 已跨过最关键的 `Epoch 1` 结束点:
-`train.py` 进程 `PID=311629` 已结束
- `/tmp/fma_real_smoke_stopcheck/fma_models_smoke/best_model.pt` 已出现
- `/tmp/fma_real_smoke_stopcheck/fma_models_smoke/song_to_idx.json` 已出现
- 当前主流程已从训练切换到建索引阶段:
- `PID=424691``run_demo.py build-index --data /tmp/fma_real_smoke_stopcheck/fma/manifests --model /tmp/fma_real_smoke_stopcheck/fma_models_smoke/best_model.pt --output /tmp/fma_real_smoke_stopcheck/fma_index_smoke --device cpu --resume --checkpoint-every-refs 100`
- `external_adapters.py smoke-local ...` 主进程仍在,说明端到端 smoke 还未结束。
- manifest 复核仍通过:
- `ok=true`
- `catalog_references=8000`
- `train_queries=6401`
- `test_queries=1593`
- `val_queries=0`
这说明:
- 之前“模型目录为空是正常现象”的阶段已经结束。
- 现在的下一关键观察点已经从“等待首个模型文件”切换为“等待 `build-index` 完成并进入 `evaluate`”。
### build-index 持续阶段证据(2026-06-02 12:37 UTC)
- 训练结束后的下游流程仍在 `build-index`
- `PID=424691``run_demo.py build-index --data /tmp/fma_real_smoke_stopcheck/fma/manifests --model /tmp/fma_real_smoke_stopcheck/fma_models_smoke/best_model.pt --output /tmp/fma_real_smoke_stopcheck/fma_index_smoke --device cpu --resume --checkpoint-every-refs 100`
- `smoke-local` 主进程仍在:
- `PID=311494``external_adapters.py smoke-local fma ...`
- 当前尚未观测到 `evaluate.py` 进程。
- 索引输出目录已经创建:
- `/tmp/fma_real_smoke_stopcheck/fma_index_smoke/`
- 但截至 12:37 UTC,索引目录下仍未看到新的索引产物文件。
- manifest 再次复核仍通过:
- `ok=true`
- `catalog_references=8000`
- `train_queries=6401`
- `test_queries=1593`
- `val_queries=0`
这说明:
- 当前 smoke 已稳定处于“训练完成 -> 建索引进行中”的阶段。
- 下一关键观察点仍是“索引文件出现”或“切换到 `evaluate.py`”。
### build-index 延续证据(2026-06-02 12:39 UTC)
- 经过额外观察后,主下游进程仍然是:
- `PID=424691``run_demo.py build-index --data /tmp/fma_real_smoke_stopcheck/fma/manifests --model /tmp/fma_real_smoke_stopcheck/fma_models_smoke/best_model.pt --output /tmp/fma_real_smoke_stopcheck/fma_index_smoke --device cpu --resume --checkpoint-every-refs 100`
- `evaluate.py` 仍未出现。
- `smoke-local` 主进程仍在:
- `PID=311494``external_adapters.py smoke-local fma ...`
- 索引目录仍只有目录本身:
- `/tmp/fma_real_smoke_stopcheck/fma_index_smoke/`
- 截至 12:39 UTC,仍未观测到新的索引产物文件。
- manifest 复核仍通过:
- `ok=true`
- `catalog_references=8000`
- `train_queries=6401`
- `test_queries=1593`
- `val_queries=0`
这说明:
- 当前 smoke 已稳定进入并停留在 `build-index` 阶段。
- 下一关键观察点依旧是“索引产物首次出现”或“切换到 `evaluate.py`”。
### build-index 再延续证据(2026-06-02 12:43 UTC)
- 经过更长观察后,主下游进程仍然是:
- `PID=424691``run_demo.py build-index --data /tmp/fma_real_smoke_stopcheck/fma/manifests --model /tmp/fma_real_smoke_stopcheck/fma_models_smoke/best_model.pt --output /tmp/fma_real_smoke_stopcheck/fma_index_smoke --device cpu --resume --checkpoint-every-refs 100`
- `evaluate.py` 仍未出现。
- `smoke-local` 主进程仍在:
- `PID=311494``external_adapters.py smoke-local fma ...`
- 索引目录仍只有目录本身:
- `/tmp/fma_real_smoke_stopcheck/fma_index_smoke/`
- 截至 12:43 UTC,仍未观测到新的索引产物文件。
- manifest 复核仍通过:
- `ok=true`
- `catalog_references=8000`
- `train_queries=6401`
- `test_queries=1593`
- `val_queries=0`
这说明:
- 当前 smoke 仍稳定停留在 `build-index` 阶段。
- 下一关键观察点依旧是“索引产物首次出现”或“切换到 `evaluate.py`”。
### build-index 最新延续证据(2026-06-02 12:51 UTC)
- 截至 12:51 UTC,主下游进程仍然是:
- `PID=424691``run_demo.py build-index --data /tmp/fma_real_smoke_stopcheck/fma/manifests --model /tmp/fma_real_smoke_stopcheck/fma_models_smoke/best_model.pt --output /tmp/fma_real_smoke_stopcheck/fma_index_smoke --device cpu --resume --checkpoint-every-refs 100`
- `evaluate.py` 仍未出现。
- `smoke-local` 主进程仍在:
- `PID=311494``external_adapters.py smoke-local fma ...`
- 索引目录仍只有目录本身:
- `/tmp/fma_real_smoke_stopcheck/fma_index_smoke/`
- 截至该时点,仍未观测到新的索引产物文件。
- manifest 复核仍通过:
- `ok=true`
- `catalog_references=8000`
- `train_queries=6401`
- `test_queries=1593`
- `val_queries=0`
这说明:
- 真实 FMA smoke 仍稳定停留在 `build-index` 阶段。
- 下一关键观察点依旧是“索引产物首次出现”或“切换到 `evaluate.py`”。
### build-index 12:55 UTC 延续证据(2026-06-02)
- 截至 12:55 UTC,主下游进程仍然是:
- `PID=424691``run_demo.py build-index --data /tmp/fma_real_smoke_stopcheck/fma/manifests --model /tmp/fma_real_smoke_stopcheck/fma_models_smoke/best_model.pt --output /tmp/fma_real_smoke_stopcheck/fma_index_smoke --device cpu --resume --checkpoint-every-refs 100`
- `evaluate.py` 仍未出现。
- `smoke-local` 主进程仍在:
- `PID=311494``external_adapters.py smoke-local fma ...`
- 索引目录仍只有目录本身:
- `/tmp/fma_real_smoke_stopcheck/fma_index_smoke/`
- 截至该时点,仍未观测到新的索引产物文件。
- manifest 复核仍通过:
- `ok=true`
- `catalog_references=8000`
- `train_queries=6401`
- `test_queries=1593`
- `val_queries=0`
这说明:
- 真实 FMA smoke 仍稳定停留在 `build-index` 阶段。
- 下一关键观察点依旧是“索引产物首次出现”或“切换到 `evaluate.py`”。
### build-index 12:59 UTC 延续证据(2026-06-02)
- 截至 12:59 UTC,主下游进程仍然是:
- `PID=424691``run_demo.py build-index --data /tmp/fma_real_smoke_stopcheck/fma/manifests --model /tmp/fma_real_smoke_stopcheck/fma_models_smoke/best_model.pt --output /tmp/fma_real_smoke_stopcheck/fma_index_smoke --device cpu --resume --checkpoint-every-refs 100`
- `evaluate.py` 仍未出现。
- `smoke-local` 主进程仍在:
- `PID=311494``external_adapters.py smoke-local fma ...`
- 索引目录仍只有目录本身:
- `/tmp/fma_real_smoke_stopcheck/fma_index_smoke/`
- 截至该时点,仍未观测到新的索引产物文件。
- manifest 复核仍通过:
- `ok=true`
- `catalog_references=8000`
- `train_queries=6401`
- `test_queries=1593`
- `val_queries=0`
这说明:
- 真实 FMA smoke 仍稳定停留在 `build-index` 阶段。
- 下一关键观察点依旧是“索引产物首次出现”或“切换到 `evaluate.py`”。
### build-index 13:04 UTC 延续证据(2026-06-02)
- 截至 13:04 UTC,主下游进程仍然是:
- `PID=424691``run_demo.py build-index --data /tmp/fma_real_smoke_stopcheck/fma/manifests --model /tmp/fma_real_smoke_stopcheck/fma_models_smoke/best_model.pt --output /tmp/fma_real_smoke_stopcheck/fma_index_smoke --device cpu --resume --checkpoint-every-refs 100`
- `evaluate.py` 仍未出现。
- `smoke-local` 主进程仍在:
- `PID=311494``external_adapters.py smoke-local fma ...`
- 索引目录仍只有目录本身:
- `/tmp/fma_real_smoke_stopcheck/fma_index_smoke/`
- 截至该时点,仍未观测到新的索引产物文件。
- manifest 复核仍通过:
- `ok=true`
- `catalog_references=8000`
- `train_queries=6401`
- `test_queries=1593`
- `val_queries=0`
这说明:
- 真实 FMA smoke 仍稳定停留在 `build-index` 阶段。
- 下一关键观察点依旧是“索引产物首次出现”或“切换到 `evaluate.py`”。
### build-index 13:10 UTC 延续证据(2026-06-02)
- 截至 13:10 UTC,主下游进程仍然是:
- `PID=424691``run_demo.py build-index --data /tmp/fma_real_smoke_stopcheck/fma/manifests --model /tmp/fma_real_smoke_stopcheck/fma_models_smoke/best_model.pt --output /tmp/fma_real_smoke_stopcheck/fma_index_smoke --device cpu --resume --checkpoint-every-refs 100`
- `evaluate.py` 仍未出现。
- `smoke-local` 主进程仍在:
- `PID=311494``external_adapters.py smoke-local fma ...`
- 索引目录仍只有目录本身:
- `/tmp/fma_real_smoke_stopcheck/fma_index_smoke/`
- 截至该时点,仍未观测到新的索引产物文件。
- manifest 复核仍通过:
- `ok=true`
- `catalog_references=8000`
- `train_queries=6401`
- `test_queries=1593`
- `val_queries=0`
这说明:
- 真实 FMA smoke 仍稳定停留在 `build-index` 阶段。
- 下一关键观察点依旧是“索引产物首次出现”或“切换到 `evaluate.py`”。
### build-index 13:16 UTC 延续证据(2026-06-02)
- 截至 13:16 UTC,主下游进程仍然是:
- `PID=424691``run_demo.py build-index --data /tmp/fma_real_smoke_stopcheck/fma/manifests --model /tmp/fma_real_smoke_stopcheck/fma_models_smoke/best_model.pt --output /tmp/fma_real_smoke_stopcheck/fma_index_smoke --device cpu --resume --checkpoint-every-refs 100`
- `evaluate.py` 仍未出现。
- `smoke-local` 主进程仍在:
- `PID=311494``external_adapters.py smoke-local fma ...`
- 索引目录仍只有目录本身:
- `/tmp/fma_real_smoke_stopcheck/fma_index_smoke/`
- 截至该时点,仍未观测到新的索引产物文件。
- manifest 复核仍通过:
- `ok=true`
- `catalog_references=8000`
- `train_queries=6401`
- `test_queries=1593`
- `val_queries=0`
这说明:
- 真实 FMA smoke 仍稳定停留在 `build-index` 阶段。
- 下一关键观察点依旧是“索引产物首次出现”或“切换到 `evaluate.py`”。
### build-index 13:22 UTC 延续证据(2026-06-02)
- 截至 13:22 UTC,主下游进程仍然是:
- `PID=424691``run_demo.py build-index --data /tmp/fma_real_smoke_stopcheck/fma/manifests --model /tmp/fma_real_smoke_stopcheck/fma_models_smoke/best_model.pt --output /tmp/fma_real_smoke_stopcheck/fma_index_smoke --device cpu --resume --checkpoint-every-refs 100`
- `evaluate.py` 仍未出现。
- `smoke-local` 主进程仍在:
- `PID=311494``external_adapters.py smoke-local fma ...`
- 索引目录仍只有目录本身:
- `/tmp/fma_real_smoke_stopcheck/fma_index_smoke/`
- 截至该时点,仍未观测到新的索引产物文件。
- manifest 复核仍通过:
- `ok=true`
- `catalog_references=8000`
- `train_queries=6401`
- `test_queries=1593`
- `val_queries=0`
这说明:
- 真实 FMA smoke 仍稳定停留在 `build-index` 阶段。
- 下一关键观察点依旧是“索引产物首次出现”或“切换到 `evaluate.py`”。
### build-index 13:28 UTC 延续证据(2026-06-02)
- 截至 13:28 UTC,主下游进程仍然是:
- `PID=424691``run_demo.py build-index --data /tmp/fma_real_smoke_stopcheck/fma/manifests --model /tmp/fma_real_smoke_stopcheck/fma_models_smoke/best_model.pt --output /tmp/fma_real_smoke_stopcheck/fma_index_smoke --device cpu --resume --checkpoint-every-refs 100`
- `evaluate.py` 仍未出现。
- `smoke-local` 主进程仍在:
- `PID=311494``external_adapters.py smoke-local fma ...`
- 索引目录仍只有目录本身:
- `/tmp/fma_real_smoke_stopcheck/fma_index_smoke/`
- 截至该时点,仍未观测到新的索引产物文件。
- manifest 复核仍通过:
- `ok=true`
- `catalog_references=8000`
- `train_queries=6401`
- `test_queries=1593`
- `val_queries=0`
这说明:
- 真实 FMA smoke 仍稳定停留在 `build-index` 阶段。
- 下一关键观察点依旧是“索引产物首次出现”或“切换到 `evaluate.py`”。
### build-index 13:34 UTC 延续证据(2026-06-02)
- 截至 13:34 UTC,主下游进程仍然是:
- `PID=424691``run_demo.py build-index --data /tmp/fma_real_smoke_stopcheck/fma/manifests --model /tmp/fma_real_smoke_stopcheck/fma_models_smoke/best_model.pt --output /tmp/fma_real_smoke_stopcheck/fma_index_smoke --device cpu --resume --checkpoint-every-refs 100`
- `evaluate.py` 仍未出现。
- `smoke-local` 主进程仍在:
- `PID=311494``external_adapters.py smoke-local fma ...`
- 索引目录仍只有目录本身:
- `/tmp/fma_real_smoke_stopcheck/fma_index_smoke/`
- 截至该时点,仍未观测到新的索引产物文件。
- manifest 复核仍通过:
- `ok=true`
- `catalog_references=8000`
- `train_queries=6401`
- `test_queries=1593`
- `val_queries=0`
这说明:
- 真实 FMA smoke 仍稳定停留在 `build-index` 阶段。
- 下一关键观察点依旧是“索引产物首次出现”或“切换到 `evaluate.py`”。
### 重启后第一优先级动作
1. 先检查真实 FMA smoke 是否完成:
```bash
ps -p 311629 -o pid,etime,%cpu,%mem,cmd
find /tmp/fma_real_smoke_stopcheck/fma_models_smoke -maxdepth 2 \( -type f -o -type d \) | sort
pgrep -af 'train.py --data /tmp/fma_real_smoke_stopcheck|run_demo.py build-index --data /tmp/fma_real_smoke_stopcheck|evaluate.py --data /tmp/fma_real_smoke_stopcheck'
```
2. 如果 smoke 完成:
- 收集 `report.json` / metrics / artifacts
- 回写 `docs/open-dataset-workflow.md`
- 回写 `docs/CHANGELOG.md`
- commit + push
3. 如果 smoke 仍在跑:
- 不要误判为空模型目录是 bug
- 继续等待 `Epoch 1` 结束或切换到 `build-index/evaluate`
## 1. 项目是什么
这是一个面向**音乐片段识别 / 音乐检索**的 ACR 引擎,核心路线是:
- 指纹检索(Chromaprint-like)
- embedding 检索(ECAPA-derived)
- 可选 melody-aware 融合
- retrieval-first 评测与优化
它已经不是单纯的“分类模型训练脚本”,而是一个较完整的工程原型:
- 数据层
- 训练层
- 索引层
- 识别层
- 评测层
- 文档层
- 开放数据接入层
- 发布产物层
---
## 2. 你应该先看哪些文档
### 核心 4 组入口
- [docs/README.md](./README.md)
- [docs/open-dataset-workflow.md](./open-dataset-workflow.md)
- [docs/dataset-spec.md](./dataset-spec.md)
- [docs/industrialization-roadmap.md](./industrialization-roadmap.md)
### 如果你是算法/模型方向
- [docs/dataset-spec.md](./dataset-spec.md)
- [docs/sota-research-2026.md](./sota-research-2026.md)
- [docs/industrial-benchmark-spec.md](./industrial-benchmark-spec.md)
### 如果你是数据接入方向
- [docs/open-dataset-workflow.md](./open-dataset-workflow.md)
- [docs/dataset-sources-and-licensing.md](./dataset-sources-and-licensing.md)
- [acr-engine/data/raw/README.md](../acr-engine/data/raw/README.md)
### 如果你是工程/服务方向
- [docs/service-api.md](./service-api.md)
- [docs/CHANGELOG.md](./CHANGELOG.md)
> 更新:2026-06-04
> 目的:让下次启动的新 session 在 **3~10 分钟内** 明确:
> 1. 当前项目已经走到哪里
> 2. 应该先读哪些文档
> 3. 应该从哪一步开始推进
> 4. 哪些是当前稳定结论,哪些还只是待验证假设
---
## 3. 当前代码结构重点
### 训练与评测主入口
- [acr-engine/train.py](../acr-engine/train.py)
- [acr-engine/evaluate.py](../acr-engine/evaluate.py)
- [acr-engine/run_demo.py](../acr-engine/run_demo.py)
### 数据层
- [acr-engine/src/data/dataset.py](../acr-engine/src/data/dataset.py)
- [acr-engine/src/data/synthetic.py](../acr-engine/src/data/synthetic.py)
- [acr-engine/src/data/manifest_tools.py](../acr-engine/src/data/manifest_tools.py)
- [acr-engine/src/data/external_adapters.py](../acr-engine/src/data/external_adapters.py)
### 检索与模型层
- [acr-engine/src/engines/hybrid_engine.py](../acr-engine/src/engines/hybrid_engine.py)
- [acr-engine/src/engines/ecapa_embedder.py](../acr-engine/src/engines/ecapa_embedder.py)
- [acr-engine/src/engines/chromaprint_matcher.py](../acr-engine/src/engines/chromaprint_matcher.py)
- [acr-engine/src/models/ecapa_tdnn.py](../acr-engine/src/models/ecapa_tdnn.py)
- [acr-engine/src/models/losses.py](../acr-engine/src/models/losses.py)
### 服务层
- [acr-engine/src/service/app.py](../acr-engine/src/service/app.py)
---
## 4. 已经完成的关键能力
## 一页结论
### 4.1 原型与 synthetic 数据
- synthetic dataset 可生成
- `train.py --dry-run` 可通过
- 可训练出 checkpoint
- 可 build-index
- 可 recognize
- 可 evaluate
当前项目主线已经从“原型是否能跑通”切到:
### 4.2 开放数据接入
已经具备以下命令:
> **为版权保护场景建设一个可演进的音乐 ACR / 检索系统**,
> 目标是让 `100w` 音频、约 `30w` 歌曲能够在未来通过
> `canonical_song / work / recording / recording_asset / audio_window`
> 这条主数据链,以及 `model_registry / feature_set_registry`
> 这套模型注册机制,稳定支撑检索、归属、升级与回滚。
- `inspect-local`
- `inspect-batch`
- `prepare-local`
- `validate-local`
- `smoke-local`
当前已经完成的关键交付:
- 文档体系已重构为“角色化阅读路径”
- SOTA 演进路径已明确:**Phase-1 先走 encoder-only**
- PostgreSQL 主数据与特征注册 DDL 已落地为推荐版 schema
- Phase-1 实施 checklist 和 model/feature/reference set 初始化手册已补齐
这些都在:
- [acr-engine/src/data/external_adapters.py](../acr-engine/src/data/external_adapters.py)
当前最重要的下一步不是继续写方案,而是:
### 4.3 文档与发布产物
开放数据 smoke 也能生成:
- benchmark report
- model card
- release checklist
- artifact manifest
1. **按 schema v2 落 PostgreSQL 主数据模型**
2. **把 reference set / audio_window / feature_set 初始化做起来**
3. **接入 MERT / MuQ 的 encoder-only 抽特征链**
4. **跑通 fingerprint lane + semantic lane 的第一版聚合闭环**
---
## 5. 开放数据当前的实际工作方式
## 下次启动先读什么
### 真实音频应该放到哪里
- [acr-engine/data/raw/fma_small_audio/](../acr-engine/data/raw/fma_small_audio/)
- [acr-engine/data/raw/mtg_jamendo_audio/](../acr-engine/data/raw/mtg_jamendo_audio/)
说明文件:
- [acr-engine/data/raw/README.md](../acr-engine/data/raw/README.md)
### 当前最推荐的命令
#### FMA
```bash
/usr/local/miniconda3/bin/python src/data/external_adapters.py smoke-local fma data/raw/fma_small_audio --output-root data/external_smoke --eval-ratio 0.2 --query-duration 8.0 --train-epochs 1 --batch-size 2
```
#### MTG-Jamendo
```bash
/usr/local/miniconda3/bin/python src/data/external_adapters.py smoke-local mtg_jamendo data/raw/mtg_jamendo_audio --output-root data/external_smoke --eval-ratio 0.2 --query-duration 8.0 --train-epochs 1 --batch-size 2
```
### 最短阅读顺序(推荐)
1. [docs/README.md](./README.md)
2. [docs/acr-architecture.md](./acr-architecture.md)
3. [docs/sota-evolution-guide.md](./sota-evolution-guide.md)
4. [docs/postgresql-data-model.md](./postgresql-data-model.md)
5. [docs/phase1-implementation-checklist.md](./phase1-implementation-checklist.md)
6. [docs/model-feature-registry-bootstrap.md](./model-feature-registry-bootstrap.md)
7. [docs/CHANGELOG.md](./CHANGELOG.md)
### 当前 smoke-local 已验证能力
`smoke-local` 会自动跑:
1. inspect-local
2. prepare-local
3. validate-local
4. train
5. build-index
6. evaluate
7. generate_artifacts
如果只想快速恢复上下文,至少读前 5 个。
---
## 6. 目前最重要的验证证据
### 6.1 synthetic-as-open-fixed(开放数据 stand-in)
已成功验证:
- `prepare-local`
- `validate-local`
- `train.py`
- `build-index`
- `evaluate.py`
- `generate_artifacts.py`
## 当前稳定结论(可以直接继承)
关键结果:
- `num_queries=8`
- `top1=1.0`
- `topk=1.0`
### 1. 技术方向
- **当前 ECAPA 路线保留为 baseline,不再作为长期主底座。**
- **Phase-1 主推 encoder-only foundation 路线。**
- exact lane:`Chromaprint`
- semantic lane 主 baseline:`MERT-v1-95M`
- semantic lane challenger:`MuQ`
- **Phase-2 才考虑 version / cover lane。**
- **Phase-3 再进入工业化检索/重排/治理。**
相关目录:
- [acr-engine/data/external_ingested/synthetic_as_open_fixed/](../acr-engine/data/external_ingested/synthetic_as_open_fixed/)
- [acr-engine/reports/open-smoke-fixed/fma/](../acr-engine/reports/open-smoke-fixed/fma/)
### 2. 数据主链
后续主数据一律围绕:
### 6.2 一键 smoke-local
已验证:
```bash
/usr/local/miniconda3/bin/python src/data/external_adapters.py smoke-local fma data/synthetic_v2/songs --output-root data/external_smoke --eval-ratio 0.2 --query-duration 5.0 --train-epochs 1 --batch-size 2
```text
canonical_song -> work -> recording -> recording_asset -> audio_window
```
关键结果:
- `num_audio_files=24`
- `catalog=24`
- `train_queries=16`
- `test_queries=8`
- `top1=1.0`
- `topk=1.0`
相关目录:
- [acr-engine/data/external_smoke/](../acr-engine/data/external_smoke/)
---
## 0. 当前交付状态(本次 checkpoint)
### 已可交付
- 文档体系、数据规范、切片策略、评测公平性控制已成型。
- 新 session 已可依据本文件和 `AGENT.md` 继续推进。
不要再退回到仅有 `song_id` 的扁平结构。
### 当前卡点
- `cap48 top2 seed=999` 已完成,三 seed aggregate 已可计算。
- 工作区存在大量数据与模型产物,当前只建议精确提交文档文件。
### 3. 模型/特征主链
后续 encoder、feature、索引一律围绕:
## 0.5 当前 bucket/style-aware 基线结论
完整 bucket 汇总已完成:
- 汇总文件:`/tmp/ab_smoke_bucketed_smoke/report.json`
- `prefix_000_a`:winner=`hybrid`
- `prefix_000_b`:winner=`high_energy`
- aggregate:
- `hybrid``mean_top1=1.0, mean_topk=1.0, mean_num_queries=4.0`
- `high_energy``mean_top1=1.0, mean_topk=1.0, mean_num_queries=3.5`
当前解释:
- toy bucket 已经足够证明“不同子集可出现不同 winner”。
- 但它仍不是业务语义 bucket,因此只能作为方法学基线,不能当成最终产品结论。
### 最新验证证据(2026-06-02 18:21 UTC 左右)
- `hybrid` 的 reference index 已完成:
- `refs_done=48 / refs_total=48`
- `windows_done=491`
- `embedding_shape=[491, 192]`
- `elapsed_sec=80.26`
- 对应文件已写出:
- `/tmp/ab_smoke_seg_cap48_top2_seed999/hybrid/fma_index_smoke/reference_embs.npy`
- `/tmp/ab_smoke_seg_cap48_top2_seed999/hybrid/fma_index_smoke/reference_ids.npy`
- `/tmp/ab_smoke_seg_cap48_top2_seed999/hybrid/fma_index_smoke/reference_progress.json`
- 进程树已确认进入:
- `evaluate.py --data /tmp/ab_smoke_seg_cap48_top2_seed999/hybrid/fma/manifests ... --output-json /tmp/ab_smoke_seg_cap48_top2_seed999/hybrid/fma_reports_smoke/eval.json --seed 999 --max-queries 24`
- 最终结果(seed=999):
- `hybrid``num_queries=24, top1=0.875, topk=1.0`
- `high_energy``num_queries=24, top1=0.9167, topk=1.0`
- winner:`high_energy`
- 三 seed aggregate(cap48):
- `high_energy``mean_top1=0.9167, min=0.9167, max=0.9167, stdev=0.0`
- `hybrid``mean_top1=0.8750, min=0.7917, max=0.9583, stdev=0.0680`
### 文档入口最新状态
- `docs/README.md` 已补齐业务数据接入导航与最短链说明。
- `docs/README.md` 已新增“新 session 最短阅读顺序”。
- `docs/README.md` 已新增“新 session 最短可跑命令”。
- `AGENT.md` 已同步最短可跑命令。
- 已把本地 smoke 临时文件加入 `.gitignore`
- 已补充 Python 缓存噪音忽略规则。
## 第一条可跑命令(重启后先验证)
```bash
cd /workspace/acr-engine
/usr/local/miniconda3/bin/python scripts/business_export_offline_smoke.py \
--output-root /tmp/business_export_offline_smoke
```text
model_registry -> feature_set_registry -> audio_embedding / audio_fingerprint -> retrieval_index_registry
```
预期
- 业务导出离线链跑通
- 项目 `catalog/train/test/val` 成功生成
- `train.py --dry-run` 通过
不要设计成固定列
- `mert_embedding`
- `muq_embedding`
- `ecapa_embedding`
### 最优先待办
1. 把已完成的 toy bucket baseline 升级为语义 bucket(风格 / 结构 / hard-case)。
- 模板:`acr-engine/configs/buckets/fma_semantic_bucket_template.json`
- 业务型素材优先看:[business-music-bucket-and-type-guide.md](./business-music-bucket-and-type-guide.md)
- Manifest/角色映射看:[business-manifest-and-type-role-spec.md](./business-manifest-and-type-role-spec.md)
- SQL/CSV/JSONL 导出参考:[business-export-cookbook.md](./business-export-cookbook.md)
- 规范化脚本:`acr-engine/scripts/normalize_business_export.py`
- 角色拆分脚本:`acr-engine/scripts/split_business_manifest_ready.py`
- 项目 manifest 适配:`acr-engine/scripts/build_business_project_manifests.py`
2. 对比 cap48 与 cap64 的不一致现象,补充分规模结论。
3. 继续补 cap64 multi-seed,而不是只保留单 seed。
4. 继续优化 `hybrid`,重点降低波动并提升 hard case 稳定性。
5. 在 bucket 基线下继续提交与推送。
### 续跑时不要做的事
- 不要 `git add .`
- 不要提交 `data/raw``data/external_smoke``/tmp``__pycache__`、模型与索引产物
## 7. 当前最重要的待办
### 优先级 A:真实开放数据替换
目标:
- 用真实本地 FMA / MTG-Jamendo 音频替换 synthetic stand-in
操作:
1. 把真实音频放进:
- `acr-engine/data/raw/fma_small_audio/`
-`acr-engine/data/raw/mtg_jamendo_audio/`
2. 直接运行 `smoke-local`
3. 记录:
- inspect 规模
- train/test query 数
- top1/topk
- artifact bundle
### 优先级 B:hard-case 精度继续优化
当前历史结论:
- naive oversampling:失败
- type-aware weighting:部分有效
- sample-level weighting:提升 `confused`
- retrieval fusion tuning:更稳定有效
下阶段重点:
- `confused`
- `humming_like`
- 真实开放数据上的 hard-case bucket
### 优先级 C:foundation model / SOTA baseline
已经在文档中记录:
- MERT
- MuQ
- 更强 retrieval-first 路线
后续可以做:
- frozen backbone baseline
- adapter fine-tune
### 4. reference 集合
当前结论是:
- 需要显式 `reference_set_registry`
- `is_reference=true` 仍然保留,但不再足够表达生产切换
- 未来热 reference 集、A/B、回滚、encoder 升级都要依赖 reference set 版本化
---
## 8. 最新关键提交(便于新 session 快速定位)
近几次关键提交建议优先看:
- `6232787` Make segmentation strategy benchmarks comparable under fixed query budgets
- `f04a314` Benchmark real FMA segmentation strategies on a capped smoke subset
- `d7a0894` Favor beat-aligned candidate segments for music ACR training/query generation
- `b6cdf66` Add high-energy and onset-aware music segment selection
- `d221852` Add explicit drop zones for real open-music corpora
- `eee15ac` Automate the full open-dataset smoke workflow behind one command
- `8795907` Generate release artifacts for the open-dataset smoke path
- `dc9ef1b` Close the open-dataset smoke loop through evaluation
---
## 9. 最新真实数据切片 benchmark 状态(重启后优先续跑这里)
### 已完成的最新事实
当前项目已经不是“只有 random 切片”:
- 训练/外部 query 生成支持:
- `random`
- `silence_aware`
- `high_energy`
- `onset_aware`
- `beat_aware`
- `repeated_section_aware`
- `hybrid`
- 已接入的 `librosa` 逻辑:
- `effects.split`
- `onset.onset_detect`
- `beat.beat_track`
- `feature.chroma_cqt`
### 已完成的小规模 capped 验证
命令:
```bash
cd /workspace/acr-engine
/usr/local/miniconda3/bin/python scripts/ab_smoke_segmentation.py \
--dataset fma \
--input-dir data/raw/fma_small_audio \
--work-root /tmp/ab_smoke_cap \
--subset-size 6 \
--query-duration 8 \
--train-epochs 1 \
--batch-size 2 \
--device cpu \
--strategies hybrid \
--max-test-queries 5 \
--output-json /tmp/ab_smoke_cap/report.json
```
结果:
- `max_test_queries = 5`
- `num_queries = 5`
- `top1 = 1.0`
- `topk = 1.0`
### 正在进行的中规模 capped FMA benchmark
命令:
```bash
cd /workspace/acr-engine
/usr/local/miniconda3/bin/python scripts/ab_smoke_segmentation.py \
--dataset fma \
--input-dir data/raw/fma_small_audio \
--work-root /tmp/ab_smoke_seg_cap16 \
--subset-size 16 \
--query-duration 8 \
--train-epochs 1 \
--batch-size 2 \
--device cpu \
--strategies hybrid beat_aware high_energy repeated_section_aware \
--max-test-queries 12 \
--output-json /tmp/ab_smoke_seg_cap16/report.json
```
在本次交接时,cap16 已完成,最终结果如下:
| 策略 | num_queries | top1 | topk | 状态 |
|---|---:|---:|---:|---|
| `hybrid` | 12 | 1.0 | 1.0 | 已完成 |
| `high_energy` | 12 | 1.0 | 1.0 | 已完成 |
| `beat_aware` | 12 | 0.9167 | 1.0 | 已完成 |
| `repeated_section_aware` | 12 | 0.8333 | 1.0 | 已完成 |
### 重启后第一优先动作
## 本轮新增/修改的关键文件
1. 先检查:
```bash
pgrep -af 'ab_smoke_seg_cap16|external_adapters.py smoke-local fma /tmp/ab_smoke_seg_cap16|evaluate.py --data /tmp/ab_smoke_seg_cap16|run_demo.py build-index --data /tmp/ab_smoke_seg_cap16'
```
2. 如果 `report.json` 已存在,优先读取并同步文档
3. 如果中断:
- 保留已有 `/tmp/ab_smoke_seg_cap16/*` 结果作人工记录
- 重新跑缺失策略,或单独跑:
### 主文档
- [docs/README.md](./README.md)
- [docs/acr-architecture.md](./acr-architecture.md)
- [docs/sota-evolution-guide.md](./sota-evolution-guide.md)
- [docs/postgresql-data-model.md](./postgresql-data-model.md)
- [docs/phase1-implementation-checklist.md](./phase1-implementation-checklist.md)
- [docs/model-feature-registry-bootstrap.md](./model-feature-registry-bootstrap.md)
```bash
cd /workspace/acr-engine
/usr/local/miniconda3/bin/python src/data/external_adapters.py smoke-local \
fma /tmp/ab_smoke_seg_cap16/subset_audio \
--output-root /tmp/ab_smoke_seg_cap16/high_energy \
--eval-ratio 0.2 \
--query-duration 8.0 \
--query-strategy high_energy \
--segment-strategy high_energy \
--train-epochs 1 \
--batch-size 2 \
--device cpu \
--max-test-queries 12 \
--seed 42
```
### SQL / schema
- `acr-engine/sql/acr_pg_schema_v2.sql`
4. 当前这轮 cap16 的最终建议已经形成:
- 默认优先:`hybrid`
- 强次选:`high_energy`
- `beat_aware` / `repeated_section_aware` 更适合作为补充对照,而不是默认策略
### 历史/补充说明(仍有参考价值)
- [docs/sota-research-2026.md](./sota-research-2026.md)
- [docs/production-encoder-freeze-and-embedding-strategy.md](./production-encoder-freeze-and-embedding-strategy.md)
- [docs/training-data-and-pgvector-guide.md](./training-data-and-pgvector-guide.md)
---
## 10. cap24 top2 对照实验(进行中)
为进一步判断 `hybrid``high_energy` 的并列关系,已经启动更大的真实 FMA 对照:
```bash
cd /workspace/acr-engine
/usr/local/miniconda3/bin/python scripts/ab_smoke_segmentation.py \
--dataset fma \
--input-dir data/raw/fma_small_audio \
--work-root /tmp/ab_smoke_seg_cap24_top2 \
--subset-size 24 \
--query-duration 8 \
--train-epochs 1 \
--batch-size 2 \
--device cpu \
--strategies hybrid high_energy \
--max-test-queries 16 \
--output-json /tmp/ab_smoke_seg_cap24_top2/report.json
```
当前 fresh evidence:
| 策略 | subset | max_test_queries | top1 | topk | 状态 |
|---|---:|---:|---:|---:|---|
| `hybrid` | 24 | 16 | 1.0 | 1.0 | 已完成 |
| `high_energy` | 24 | 16 | 0.8125 | 1.0 | 已完成 |
## 当前推荐的启动动作
恢复检查命令:
## 路线 A:如果下次 session 继续“补文档/补设计”
优先顺序:
1.**数据导入手册**:100w 音频如何映射到 `canonical_song/work/recording/recording_asset`
2.**检索聚合设计文档**:fingerprint lane + semantic lane 的分数融合与 song/work 聚合规则
3.**索引与版本治理文档**:reference set / feature set / index set 的上线切换规则
```bash
pgrep -af 'ab_smoke_seg_cap24_top2|external_adapters.py smoke-local fma /tmp/ab_smoke_seg_cap24_top2|evaluate.py --data /tmp/ab_smoke_seg_cap24_top2|run_demo.py build-index --data /tmp/ab_smoke_seg_cap24_top2'
```
cap24 top2 最终结论:
- `hybrid``16 / 1.0 / 1.0`
- `high_energy``16 / 0.8125 / 1.0`
- 这个结果比 cap16 更能说明问题:**当前默认策略应明确固定为 `hybrid`**
## 路线 B:如果下次 session 开始“进入实现”
直接按下面顺序推进:
1. 建库执行 `acr-engine/sql/acr_pg_schema_v2.sql`
2. 初始化 `canonical_song / work / recording / recording_asset`
3. 初始化 `reference_set_registry`
4. 生成 `audio_window`
5. 初始化 `model_registry / feature_set_registry`
6. 接入 MERT / MuQ encoder-only 抽特征
7. 构建 semantic index
8. 跑通 query -> candidate -> canonical_song 闭环
---
## 11. cap32 top2 对照实验(已完成)
为了确认 cap24 的结论不是偶然,已继续启动更大的真实 FMA top2 对照:
## 下次 session 第一条可直接复制执行的检查命令
```bash
cd /workspace/acr-engine
/usr/local/miniconda3/bin/python scripts/ab_smoke_segmentation.py \
--dataset fma \
--input-dir data/raw/fma_small_audio \
--work-root /tmp/ab_smoke_seg_cap32_top2 \
--subset-size 32 \
--query-duration 8 \
--train-epochs 1 \
--batch-size 2 \
--device cpu \
--strategies hybrid high_energy \
--max-test-queries 20 \
--output-json /tmp/ab_smoke_seg_cap32_top2/report.json
cd /workspace
sed -n '1,220p' docs/README.md
sed -n '1,260p' docs/phase1-implementation-checklist.md
sed -n '1,260p' docs/model-feature-registry-bootstrap.md
sed -n '1,260p' docs/postgresql-data-model.md
```
最终结果:
| 项目 | 状态 |
|---|---|
| `subset_size` | `32` |
| `max_test_queries` | `20` |
| `hybrid` | `num_queries=20`, `top1=0.95`, `topk=1.0` |
| `high_energy` | `num_queries=20`, `top1=0.5`, `topk=1.0` |
| `report.json` | 已生成 |
恢复检查命令:
如果要直接看 schema:
```bash
pgrep -af 'ab_smoke_seg_cap32_top2|external_adapters.py smoke-local fma /tmp/ab_smoke_seg_cap32_top2|evaluate.py --data /tmp/ab_smoke_seg_cap32_top2|run_demo.py build-index --data /tmp/ab_smoke_seg_cap32_top2|train.py --data /tmp/ab_smoke_seg_cap32_top2'
cd /workspace
sed -n '1,320p' acr-engine/sql/acr_pg_schema_v2.sql
```
cap32 top2 最终结论:
- `hybrid``20 / 0.95 / 1.0`
- `high_energy``20 / 0.5 / 1.0`
- cap24 与 cap32 两轮更大真实子集都指向同一结论:**默认策略固定为 `hybrid`**
---
## 12. cap48 top2 对照实验(已完成)
## 当前实现与未来实现的边界
为继续扩展真实数据证据链,已启动更大的 FMA top2 对照:
### 当前仓库已经有的东西
- `Chromaprint` 原型链
- `ECAPA` embedding baseline
- hybrid engine 原型
- 早期 pgvector prototype schema
```bash
cd /workspace/acr-engine
/usr/local/miniconda3/bin/python scripts/ab_smoke_segmentation.py \
--dataset fma \
--input-dir data/raw/fma_small_audio \
--work-root /tmp/ab_smoke_seg_cap48_top2 \
--subset-size 48 \
--query-duration 8 \
--train-epochs 1 \
--batch-size 2 \
--device cpu \
--strategies hybrid high_energy \
--max-test-queries 24 \
--output-json /tmp/ab_smoke_seg_cap48_top2/report.json
```
最终结果:
### 当前还没做完的东西
- PostgreSQL v2 schema 的实际落库
- Phase-1 的 reference set 初始化
- MERT / MuQ encoder-only 特征抽取与入库
- semantic lane 的第一版 production-oriented 聚合
| 项目 | 状态 |
|---|---|
| `subset_size` | `48` |
| `max_test_queries` | `24` |
| `high_energy` | `num_queries=24`, `top1=0.9167`, `topk=1.0` |
| `hybrid` | `num_queries=24`, `top1=0.7917`, `topk=1.0` |
| `report.json` | 已生成 |
所以:
恢复检查命令:
```bash
pgrep -af 'ab_smoke_seg_cap48_top2|external_adapters.py smoke-local fma /tmp/ab_smoke_seg_cap48_top2|evaluate.py --data /tmp/ab_smoke_seg_cap48_top2|run_demo.py build-index --data /tmp/ab_smoke_seg_cap48_top2|train.py --data /tmp/ab_smoke_seg_cap48_top2'
```
cap48 top2 最终结论:
- `high_energy``24 / 0.9167 / 1.0`
- `hybrid``24 / 0.7917 / 1.0`
- 这轮结果与 cap24 / cap32 不一致,说明当前默认策略结论**还不能视为彻底封板**
- 下一步应优先做:
1. 更大 subset(如 64+)
2. 多 seed 复跑
3. style-aware bucket benchmark
> 当前项目的“方案层”已经足够启动实现,
> 下次 session 不应再从头讨论“要不要 song/work/recording”,
> 而应该直接进入 **Schema -> Reference Set -> Feature Set -> Extraction -> Retrieval** 的执行链。
---
## 13. cap48 top2 第二个 seed(已完成)
为验证 cap48 的“high_energy 反超”是否稳定,已启动第二个 seed:
## 当前验证状态
```bash
cd /workspace/acr-engine
/usr/local/miniconda3/bin/python scripts/ab_smoke_segmentation.py \
--dataset fma \
--input-dir data/raw/fma_small_audio \
--work-root /tmp/ab_smoke_seg_cap48_top2_seed123 \
--subset-size 48 \
--query-duration 8 \
--train-epochs 1 \
--batch-size 2 \
--device cpu \
--strategies hybrid high_energy \
--max-test-queries 24 \
--seed 123 \
--output-json /tmp/ab_smoke_seg_cap48_top2_seed123/report.json
```
最终结果:
| 项目 | 状态 |
|---|---|
| `subset_size` | `48` |
| `max_test_queries` | `24` |
| `seed` | `123` |
| `hybrid` | `num_queries=24`, `top1=0.9583`, `topk=1.0` |
| `high_energy` | `num_queries=24`, `top1=0.9167`, `topk=1.0` |
| `report.json` | 已生成 |
### 已验证
- 新文档结构已补齐并接入 README
- Phase-1 方案、PostgreSQL 设计、实施 checklist、registry bootstrap 均已提交
- architect 审核结论:**APPROVED**
- 代码已推送远端
seed123 最终结论:
- `hybrid``24 / 0.9583 / 1.0`
- `high_energy``24 / 0.9167 / 1.0`
- cap48 至少已经表现出明显的 **seed 敏感性**
- 因此当前默认策略的判断应基于 **多 seed 聚合**,而不是单次 cap48 反转
### 未验证 / 仍是缺口
- **未执行 live PostgreSQL apply**(当前环境缺少 `psql`
- **未实际跑 MERT / MuQ encoder-only 特征抽取**
- **未落 reference set 的真实业务数据**
- **未定义最终线上分数融合细则**
### cap48 两次 seed 的当前聚合结论
| 策略 | runs | mean_top1 | min_top1 | max_top1 | stdev_top1 |
|---|---:|---:|---:|---:|---:|
| `high_energy` | 2 | 0.9167 | 0.9167 | 0.9167 | 0.0 |
| `hybrid` | 2 | 0.8750 | 0.7917 | 0.9583 | 0.0833 |
当前最稳妥的解释:
- `high_energy` 在 cap48 两次 seed 上的**均值暂时领先**
- `hybrid` 结果波动更大,但单轮峰值更高
- 后续默认策略不应只看某一次单跑,而应继续累计 seed / style bucket 的聚合结果
- `b766c74` Make open-dataset manifests trainable end to end
- `fa23144` Add a single-page open dataset workflow for training prep
- `af33be3` Condense docs and add manifest validation before training
这些 commit 基本覆盖了当前开放数据与文档演进主线。
因此下次 session 应优先从这些未验证缺口里挑一条推进,而不是重复写总方案。
---
## 9. 新 session 接手时的推荐动作
如果你是新的 session,建议顺序:
1. 读:
- [docs/README.md](./README.md)
- [docs/open-dataset-workflow.md](./open-dataset-workflow.md)
- [docs/session-handoff.md](./session-handoff.md)
- [docs/current-capability-map.md](./current-capability-map.md)
- [docs/training-data-and-pgvector-guide.md](./training-data-and-pgvector-guide.md)
- [acr-engine/FIRST_RUN_CHECKLIST.md](../acr-engine/FIRST_RUN_CHECKLIST.md)
- FMA 真实子集下载脚手架已存在:[acr-engine/scripts/fetch_fma_subset.py](../acr-engine/scripts/fetch_fma_subset.py);最近验证结果是旧直链 `403`、页面级历史 URL `404`;但 `https://modelscope.cn/datasets/pengzhendong/fma/resolve/master/fma_small.zip` 已验证 `200 OK` 且支持 range
- 运行 [acr-engine/scripts/status_snapshot.py](../acr-engine/scripts/status_snapshot.py)
- 或直接查看最新落盘快照:`acr-engine/.omx/latest_status_snapshot.json`
2. 检查真实数据是否已落位:
- `acr-engine/data/raw/fma_small_audio/`
- `acr-engine/data/raw/mtg_jamendo_audio/`
3. 如果已有真实音频:
- 直接跑 `smoke-local`
4. 如果还没有真实音频:
- 继续优化 synthetic-as-open-fixed
- 或继续补开放数据下载/清洗自动化
5. 每完成一个阶段:
- 更新 [docs/CHANGELOG.md](./CHANGELOG.md)
- `git commit`
- `git push`
---
## 最近相关提交
## 10. 注意事项
按当前 handoff 相关主线,最近重要提交是:
- `a549d1d` — Clarify the ACR evolution path and freeze a production-grade data model
- `e514a6c` — Keep the new ACR architecture guide clean for follow-up edits
- `4b23f54` — Make the Phase-1 ACR plan executable for each delivery role
- 这个仓库里存在已跟踪的 `__pycache__` 文件;提交时要小心不要让它们污染变更。
- 当前最稳定的改进方向不是盲目调训练权重,而是:
- retrieval-time fusion
- 更真实开放数据
- 更真实评测
- 开放数据布局现在依赖“自包含输出根”:
- `audio/`
- `manifests/`
这一点后续不要破坏。
如果下次需要追踪文档补充点,可以从这三个提交开始看。
---
## Sources
- [README.md](./README.md)
- [open-dataset-workflow.md](./open-dataset-workflow.md)
- [CHANGELOG.md](./CHANGELOG.md)
- FMA 下载完成后可直接执行:[acr-engine/scripts/fma_postdownload_ready.py](../acr-engine/scripts/fma_postdownload_ready.py)
- 若需要等待下载完成并自动切到解压/就绪检查,可直接执行:[acr-engine/scripts/wait_for_fma_and_prepare.py](../acr-engine/scripts/wait_for_fma_and_prepare.py)
## 99. 本次 checkpoint 的明确结论
- `hybrid` 的 seed=999 评测结果已先行落盘:`top1=0.875, topk=1.0, num_queries=24`
- 本次已经完成“交接可续跑化”交付。
- 本次没有等待 `seed=999` 长时 CPU benchmark 完成,因此算法默认策略不做新结论跳变。
- 当前最新稳妥表述仍然是:
- `high_energy` 在已知两轮 cap48 aggregate 中更稳
- `hybrid` 上限更高但波动更大
- 最终默认策略要看更多 seed 聚合结果
## 100. 新一轮验证已启动:cap64
- 已启动:`/tmp/ab_smoke_seg_cap64_top2`
- 配置:`subset_size=64`, `max_test_queries=32`, `seed=42`
- 当前最新证据:
- cap64 已完成:
- `hybrid``num_queries=32, top1=0.875, topk=1.0`
- `high_energy``num_queries=32, top1=0.625, topk=1.0`
- cap64 winner:`hybrid`
- 当前结论已进入“分子集规模不一致”阶段,必须继续做 bucket/style-aware benchmark
## 101. bucket/style-aware benchmark 基线已落地
- 新脚本:`acr-engine/scripts/ab_smoke_bucketed.py`
- 已通过:`py_compile`
- 已验证首个 bucket:`prefix_000_a`
- `hybrid`: `4 / 1.0 / 1.0`
- `high_energy`: `3 / 1.0 / 1.0`
- winner: `hybrid`
- 当前第二个 bucket `prefix_000_b` 仍在继续执行
## 最新 checkpoint(2026-06-02 13:36 UTC)
- 当前仍存在两个关键活跃进程:
- `311494``/usr/local/miniconda3/bin/python src/data/external_adapters.py smoke-local fma data/raw/fma_small_audio --output-root /tmp/fma_real_smoke_stopcheck --eval-ratio 0.2 --query-duration 8.0 --train-epochs 1 --batch-size 2 --device cpu --max-test-queries 8 --seed 123`
- `424691``/usr/local/miniconda3/bin/python run_demo.py build-index --data /tmp/fma_real_smoke_stopcheck/fma/manifests --model /tmp/fma_real_smoke_stopcheck/fma_models_smoke/best_model.pt --output /tmp/fma_real_smoke_stopcheck/fma_index_smoke --device cpu --resume --checkpoint-every-refs 100`
- 已确认训练完成后的关键文件存在:
- `best_model.pt`
- `song_to_idx.json`
- `validate-splits /tmp/fma_real_smoke_stopcheck/fma/manifests` =>
- `ok=true`
- `catalog_references=8000`
- `train_queries=6401`
- `test_queries=1593`
- `val_queries=0`
- 当前仍未观测到 `evaluate.py`
- 当前仍未在 `fma_index_smoke/` 下观测到首个索引产物文件。
### 新 session 恢复顺序
## 一句话交接
1. 先检查 `build-index` 是否仍在运行。
2. 再检查 `fma_index_smoke/` 是否出现首个文件。
3.`evaluate.py` 出现,立即记录 metrics / report 路径。
4. 仅更新交接文档并提交,不要误带 `data/raw``data/external_smoke``/tmp`
> **下次启动不要再从“要不要换模型、要不要重构数据结构”开始讨论。**
> 这些方向已经定了。直接从 **PostgreSQL v2 schema 落库 + Phase-1 encoder-only 执行链** 开始推进。
......