Session Handoff / 持续开发交接文档
目标:让下次启动的新 session 在 3~10 分钟内 知道从哪里开始。
快速对外转交时,先发: delivery-onepager.md
1. 下次启动先做什么
优先直接跑当前主线:
cd /workspace
/usr/local/miniconda3/bin/python acr-engine/scripts/run_songcentric_directory_pipeline_live.py \
--dsn 'postgres://d2:d2pass@127.0.0.1:5432/d2' \
--schema acr_songcentric_test \
--input-root acr-engine/data/songcentric_builder_smoke \
--output-dir acr-engine/data/pgvector_eval/music20
或:
acr-engine/scripts/start_songcentric_shortest_path.sh 'postgres://d2:d2pass@127.0.0.1:5432/d2'
当前 fresh evidence:
song_count = 2asset_count = 2window_count = 5matcher_fingerprint_count = 5fallback_fingerprint_count = 0semantic_runtime_available = truesemantic_runtime_missing = []semantic_runtime_ready_count = 5semantic_fallback_count = 0import_counts = media_entity:9 / audio_object:22 / feature_fact:34 / set_membership:9
2. 当前一句话状态
4 表 song-centric schema 已在 live PostgreSQL 上真实打通了“真实目录 -> 切片 -> exact/semantic feature enrichment -> import -> feature_fact”的宿主链。
下一步最应该做的是:
在不破坏这条宿主链的前提下,继续把 semantic lane 从当前 MERT baseline 扩展到 MuQ challenger。
3. 当前稳定结论
3.1 默认物理模型
media_entity -> audio_object -> feature_fact -> set_membership
3.2 默认逻辑语义
song -> asset -> window -> fingerprint / embedding
3.3 关键设计取舍
- 最终归属对象当前只要求稳定返回
song_id - 同一个
song下允许多个音频文件 -
window仍保留,因为它是切片/evidence/offset/召回最小单元 -
feature_fact统一承载fingerprint与embedding - Phase-1 不先训练/微调,先直接复用开源 encoder
4. 切片 / 模型 / feature 分别在哪张表
| 对象 | 表 | 关键字段 |
|---|---|---|
| song | media_entity |
entity_type='song' |
| asset | audio_object |
object_type='asset' |
| window | audio_object |
object_type='window', parent_object_id=<asset_id>
|
| model identity | feature_fact |
model_name, model_version, feature_set_name
|
| fingerprint payload | feature_fact |
feature_type='fingerprint', fingerprint_value
|
| embedding payload | feature_fact |
feature_type='embedding', embedding_uri/vector_table_name, embedding_dim
|
| set routing | set_membership |
set_type, set_name, member_type, member_id
|
5. 当前流程图
flowchart TD
A[song / media_entity] --> B[asset / audio_object]
B --> C[window / audio_object]
C --> D1[fingerprint / feature_fact]
C --> D2[embedding / feature_fact]
A --> E[set_membership]
B --> E
C --> E
D1 --> F[召回与归属到 song_id]
D2 --> F
6. 当前已经真实验证过什么
live PostgreSQL
- DSN:
postgres://d2:d2pass@127.0.0.1:5432/d2 - schema:
acr_songcentric_test
已验证链路
-
acr-engine/sql/acr_pg_schema_songcentric_v1.sql可真实建表 -
bootstrap_songcentric_phase1_live.py可重复 seed -
import_songcentric_manifest_live.py可幂等导入song/asset/window/membership - manifest 中
windows[].features[]已可直接落feature_fact - 真实目录 -> manifest -> import 已验证通过
- 真实目录 -> fingerprint enrichment -> import 已验证通过
- exact lane 已优先复用仓库内
ChromaprintMatcher - semantic lane 已真实接入
mert-v1-95mbaseline,当前 host 的 live 主链已不再停留在 placeholder 分支
7. 当前 host 的真实 blocker
-
torch / torchaudio / transformers已可导入 - 当前
semantic_runtime_available = true - 当前 semantic 已接上真实
mert-v1-95mbaseline
这说明当前主要 blocker 已从“依赖缺失”推进为:
runtime 已就绪,真实
MERTbaseline 已接入,下一步可继续接MuQ。
当前更具体的 MuQ 目标名可优先按下面口径尝试:
- Hugging Face / 代码线索:
OpenMuQ/MuQ-large-msd-iter - 官方加载入口:
from muq import MuQ+MuQ.from_pretrained("OpenMuQ/MuQ-large-msd-iter") - 当前 host 状态:
muq包已安装,但import muq被RuntimeError: operator torchvision::nms does not exist卡住 - 仓库现有 Phase-1 任务线索:
muq+large-msd-iter
8. 下次继续时先看哪些文件
- README.md
- start-here.md
- research-delivery-roadmap.md
- selected20_songid_eval.md
- postgresql-data-model.md
- postgres_db_schema_samples.md
- CHANGELOG.md
关键代码:
acr-engine/sql/acr_pg_schema_songcentric_v1.sqlacr-engine/scripts/run_songcentric_directory_pipeline_live.pyacr-engine/scripts/build_songcentric_manifest_from_directory.pyacr-engine/scripts/enrich_songcentric_manifest_with_local_features.pyacr-engine/scripts/import_songcentric_manifest_live.pyacr-engine/scripts/start_songcentric_shortest_path.sh
如果要完整看“歌曲怎么入库、怎么查询/评测、交付时要带哪些产物”,直接读:
9. 下一步优先顺序
- 保持当前 4 表 schema 不回退
- 给
enrich_songcentric_manifest_with_local_features.py接真实 semantic adapter - 保留 fallback 分支,不破坏当前 host 的可运行性
- 重新跑主链 runner,确认 semantic lane 有 fresh 证据
9.1 Selected20(20 首歌)当前评估结论
当前 .omx 记录对应的 20 首歌专题产物已经落在:
acr-engine/data/local_eval/selected20_songid_eval_report.jsonacr-engine/data/local_eval/selected20_songid_eval_report_fresh.jsondocs/selected20_songid_eval.mddocs/selected20_songid_eval_repro.mddocs/research-delivery-roadmap.md
评测口径:
- 数据目录:
/root/hikoon_song_files/output/selected_20_songs/downloads - reference:
type_11 - query:
type_1 / type_7 / type_12 / type_16 - 评测目标:song-level
song_id命中率 - 当前方案:
chromaprint_matcher + mert-v1-95m - 融合口径:
0.6 * exact + 0.4 * semantic
当前实测汇总:
| lane | count | top1 | top3 |
|---|---|---|---|
| exact | 123 | 0.6016 | 0.8130 |
| semantic | 123 | 0.4715 | 0.6016 |
| fused | 123 | 0.6341 | 0.8537 |
补充说明:
- 2026-06-04 已做 fresh 重跑
-
selected20_songid_eval_report_fresh.json与当前基线结果一致 - 说明这份 20 首专题基线已具备可重复性,可直接作为后续 MuQ / fusion 变更的回归对照
按 query type 看:
| query_type | count | 结论 |
|---|---|---|
type_1 |
21 | exact / semantic / fused 全部 top1=1.0,当前已打满 |
type_7 |
41 | 当前最弱短板之一;fused top1=0.4390 / top3=0.7561,比单 semantic 好,但仍不够稳 |
type_12 |
23 | 当前最好的一类之一;semantic 单 lane 已 top1=1.0,融合后 top1=0.9130 / top3=1.0
|
type_16 |
38 | 当前另一主要短板;fused top1=0.4737 / top3=0.7895,仅小幅优于 exact |
一句话判断:
这 20 首歌专题里,当前融合链路已经明显优于单独 semantic,也略优于单独 exact;但真正限制实战效果的仍是
type_7 / type_16这类混淆/改写 query,而不是type_1或type_12。
因此下次如果继续推进这个专题,优先顺序应是:
- 先把
selected20_songid_eval_report.json当作小样本回归基线 - 接入 MuQ challenger 后直接复跑这份专题
- 重点比较
type_7 / type_16是否提升,而不是只看 overall - 如果后续切 PostgreSQL online path,也保留这份文件级评测作为快速回归基线
- 继续按 research-delivery-roadmap.md 的 roadmap + checklist 拆下一阶段任务
一句话 handoff
下次不要再从总方案争论开始,直接跑 song-centric runner;如果 exact 正常、semantic 仍 fallback,就继续补真实 semantic adapter 和依赖。
10. 数据关联与当前 live 落库事实
当前最重要的绑定关系只有 3 条:
-
feature_fact.object_id -> audio_object.object_id- feature 绑定到具体音频对象
- Phase-1 默认绑定
window,不是直接绑定 song
-
audio_object.parent_object_id -> audio_object.object_id-
window -> asset父子回溯链
-
-
feature_fact.song_id -> media_entity.entity_id- 用于快速做 song-level 聚合与最终返回
song_id
- 用于快速做 song-level 聚合与最终返回
可以用一句话理解:
audio_object说明“这段音频是谁”,feature_fact说明“这段音频被哪个模型编码成了什么特征”。
当前 live 主链已经真实落了什么
当前 live 新数据已经真实落到:
- exact:
chromaprint_matcher / phase1_local / chromaprint_matcher_5s - semantic baseline:
mert-v1-95m / hf-main / mert_5s_hop2.5_v1
当前默认主链的覆盖率事实
按当前 live 统计,当前默认 song-centric 新主链的模型覆盖率是:
chromaprint_matcher / fingerprint = 5 rowsmert-v1-95m / embedding = 5 rowsmuq-large-msd-iter = 0 rows
对当前 5 个新 window 来说,默认主链都已经至少具备:
chromaprint_matcher:fingerprintmert-v1-95m:embedding
这意味着下次 session 判断 MuQ 是否接入时,最简单的办法就是直接看:
select model_name, feature_type, count(*) as rows
from acr_songcentric_test.feature_fact
where model_name in ('chromaprint_matcher', 'mert-v1-95m', 'muq-large-msd-iter')
group by model_name, feature_type
order by model_name, feature_type;
如果这里开始出现 muq-large-msd-iter,就说明 challenger 已经真正落库。
关于历史脏数据的提醒
当前 acr_songcentric_test 里还保留了一些历史测试行,例如:
local_wavehashlocal_wavehash_embedsemantic_runtime_ready_placeholder- 更早的
chromaprint / mert / muq旧样例
这些行不代表当前默认主链。 当前默认主链判断口径要看:
- 新目录 runner 产出的 manifest
-
chromaprint_matcher行数 -
mert-v1-95m行数 - 是否出现新的
muq-large-msd-iter行数
当前 MuQ 状态:
- 目标模型:
OpenMuQ/MuQ-large-msd-iter - 当前 blocker:
import muq触发RuntimeError: operator torchvision::nms does not exist - 结论:MuQ 仍是下一阶段 challenger,不是当前 live 默认基线
当前 MuQ blocker 的环境事实
本机当前已确认:
torch = 2.12.0+cputorchaudio = 2.11.0+cputorchvision = 0.27.0transformers = 5.10.1muq = 0.1.0
直接导入检查结果:
-
import torch=> OK -
import torchaudio=> OK -
import transformers=> OK -
import torchvision=>RuntimeError: operator torchvision::nms does not exist -
import muq=>RuntimeError: operator torchvision::nms does not exist -
from muq import MuQ当前也因此失败
所以当前更准确的 blocker 不是“MuQ 没装上”,而是:
当前这组
torch / torchvision运行时组合使torchvision::nmsoperator 不可用,从而连带阻塞muq导入。
下次继续时,优先检查的就不是 schema,而是这组包版本兼容性。
一个可直接复核的 live 样例
当前可直接用 feature_id = 34 做人工复核:
feature_id = 34
feature_type = embedding
model_name = mert-v1-95m
model_version = hf-main
feature_set_name = mert_5s_hop2.5_v1
window_id = 22
window_range = 1000-6000 ms
asset_id = 20
asset_uri = /workspace/acr-engine/data/songcentric_builder_smoke/song_beta/artist_b/clip2.wav
song_id = 9
song_biz_key = song_beta
这条样例可以非常直观地证明:
- feature 不是直接挂 song,而是先挂到
window -
window通过parent_object_id回到asset - 最终通过
song_id回到song_beta
当前 manifest 形状(导入前)
{
"song": {"biz_key": "song_alpha", "title": "song alpha"},
"asset": {"storage_uri": ".../clip1.wav"},
"windows": [
{
"start_ms": 0,
"end_ms": 5000,
"features": [
{
"feature_type": "fingerprint",
"model_name": "chromaprint_matcher",
"feature_set_name": "chromaprint_matcher_5s"
},
{
"feature_type": "embedding",
"model_name": "mert-v1-95m",
"feature_set_name": "mert_5s_hop2.5_v1",
"embedding_dim": 768
}
]
}
]
}
下次 session 最直接的继续点
- 不要再验证 MERT 是否接上,已经接上
- 直接处理 MuQ 的
torchvision::nms兼容问题 - 接入
OpenMuQ/MuQ-large-msd-iterchallenger - 重跑主链 runner,确认每个 window 最终可同时看到:
chromaprint_matchermert-v1-95m-
muq-large-msd-iter(或最终统一后的model_name)