Keep ACR entity layers simple without collapsing recording assets
Constraint: Preserve the Phase-1 minimal schema story while clarifying when simplification is safe and when it creates future refactor risk. Rejected: Merge recording and recording_asset in the formal schema now | Copyright-scale catalogs will quickly need multi-file and multi-source recording support. Confidence: high Scope-risk: narrow Directive: Use 'song -> recording -> asset -> window -> feature' as the default communication shorthand, but keep recording and asset split in the persisted model. Tested: git diff --check on touched docs; /usr/local/miniconda3/bin/python scripts/check_markdown_links.py --root docs returned OK for 31 markdown files Not-tested: Rendered markdown preview in external viewers
Showing
4 changed files
with
257 additions
and
4 deletions
| ... | @@ -6,6 +6,8 @@ | ... | @@ -6,6 +6,8 @@ |
| 6 | - 清理重复或过期文档:删除 `docs/acr-design.md`、`docs/open-dataset-plan.md`、`docs/external-manifest-template.md`、`docs/roadmap.md`、`docs/changelist-2026-06-02.md`、`docs/delivery-handoff-2026-06-02.md`。 | 6 | - 清理重复或过期文档:删除 `docs/acr-design.md`、`docs/open-dataset-plan.md`、`docs/external-manifest-template.md`、`docs/roadmap.md`、`docs/changelist-2026-06-02.md`、`docs/delivery-handoff-2026-06-02.md`。 |
| 7 | - 历史记录仍保留在 `docs/CHANGELOG.md`,当前有效入口以上述主链为准。 | 7 | - 历史记录仍保留在 `docs/CHANGELOG.md`,当前有效入口以上述主链为准。 |
| 8 | 8 | ||
| 9 | - 在 `docs/postgresql-data-model.md` 与 `docs/acr-architecture.md` 补充“为什么层多、Phase-1 如何简化、`recording` 与 `asset` 是否能合并”的明确口径:推荐保留 `song -> recording -> asset -> window -> feature` 作为最小可用骨架,不建议在正式 schema 中合并 `recording` 与 `recording_asset`。 | ||
| 10 | |||
| 9 | ## 2026-06-04 | 11 | ## 2026-06-04 |
| 10 | 12 | ||
| 11 | - 更新 `docs/README.md` 顶部为与 `session-handoff` 一致的“最短启动路径”,并再次用该入口命令重跑 `run_planner_validation_commands_live.py`,确认 fresh 结果仍为 `executed_count=4`、`all_passed=true`。 | 13 | - 更新 `docs/README.md` 顶部为与 `session-handoff` 一致的“最短启动路径”,并再次用该入口命令重跑 `run_planner_validation_commands_live.py`,确认 fresh 结果仍为 `executed_count=4`、`all_passed=true`。 | ... | ... |
| ... | @@ -93,12 +93,18 @@ cd /workspace/acr-engine | ... | @@ -93,12 +93,18 @@ cd /workspace/acr-engine |
| 93 | - semantic baseline:`MERT-v1-95M`。 | 93 | - semantic baseline:`MERT-v1-95M`。 |
| 94 | - semantic challenger:`MuQ`。 | 94 | - semantic challenger:`MuQ`。 |
| 95 | - `ECAPA` 保留为 historical baseline,不再作为长期主底座。 | 95 | - `ECAPA` 保留为 historical baseline,不再作为长期主底座。 |
| 96 | - PostgreSQL 主链固定为: | 96 | - 可演进完整版主链为: |
| 97 | 97 | ||
| 98 | ```text | 98 | ```text |
| 99 | canonical_song -> work -> recording -> recording_asset -> audio_window | 99 | canonical_song -> work -> recording -> recording_asset -> audio_window |
| 100 | ``` | 100 | ``` |
| 101 | 101 | ||
| 102 | - 如果只看 Phase-1 最小骨架,可以先按下面理解: | ||
| 103 | |||
| 104 | ```text | ||
| 105 | song -> recording -> asset -> window -> fingerprint / embedding | ||
| 106 | ``` | ||
| 107 | |||
| 102 | - 模型/特征主链固定为: | 108 | - 模型/特征主链固定为: |
| 103 | 109 | ||
| 104 | ```text | 110 | ```text |
| ... | @@ -116,7 +122,17 @@ model_registry -> feature_set_registry -> audio_embedding / audio_fingerprint -> | ... | @@ -116,7 +122,17 @@ model_registry -> feature_set_registry -> audio_embedding / audio_fingerprint -> |
| 116 | 122 | ||
| 117 | --- | 123 | --- |
| 118 | 124 | ||
| 119 | ## 5. 补充但不建议作为第一入口 | 125 | ## 5. 文档维护命令 |
| 126 | |||
| 127 | ```bash | ||
| 128 | /usr/local/miniconda3/bin/python scripts/check_markdown_links.py --root docs | ||
| 129 | ``` | ||
| 130 | |||
| 131 | 用途:在清理或重组文档后,快速发现 `docs/` 下的相对链接断链。默认会跳过 `CHANGELOG.md` 这类历史归档文档。 | ||
| 132 | |||
| 133 | --- | ||
| 134 | |||
| 135 | ## 6. 补充但不建议作为第一入口 | ||
| 120 | 136 | ||
| 121 | 以下文档保留用于专题补充,不建议新同学第一轮就读: | 137 | 以下文档保留用于专题补充,不建议新同学第一轮就读: |
| 122 | - [dataset-spec.md](./dataset-spec.md) | 138 | - [dataset-spec.md](./dataset-spec.md) | ... | ... |
| ... | @@ -53,6 +53,50 @@ flowchart TD | ... | @@ -53,6 +53,50 @@ flowchart TD |
| 53 | 53 | ||
| 54 | --- | 54 | --- |
| 55 | 55 | ||
| 56 | ## 2.1 为什么现在会显得“层很多” | ||
| 57 | |||
| 58 | 因为当前蓝图同时覆盖了 3 个维度: | ||
| 59 | |||
| 60 | 1. **业务归属**:`song/work/recording` | ||
| 61 | 2. **音频实体**:`asset/window` | ||
| 62 | 3. **检索计算**:`feature/index/candidate/decision` | ||
| 63 | |||
| 64 | 把这三类问题放在一张总图中,会看起来像一条很长的链。 | ||
| 65 | 但在工程上,它们其实是不同职责: | ||
| 66 | |||
| 67 | - 业务归属层回答:**最后该归谁** | ||
| 68 | - 音频实体层回答:**命中的是哪段音频** | ||
| 69 | - 检索计算层回答:**这段音频是怎么被召回出来的** | ||
| 70 | |||
| 71 | --- | ||
| 72 | |||
| 73 | ## 2.2 当前最小可用架构可以收敛到什么程度 | ||
| 74 | |||
| 75 | 如果当前阶段只追求: | ||
| 76 | |||
| 77 | > 快速稳定地把 query 命中到正确 `song_id` | ||
| 78 | |||
| 79 | 那 Phase-1 完全可以按下面这套最小骨架推进: | ||
| 80 | |||
| 81 | ```text | ||
| 82 | song -> recording -> asset -> window -> fingerprint / embedding | ||
| 83 | ``` | ||
| 84 | |||
| 85 | 保留原因: | ||
| 86 | - `recording` 不能删:同一首歌会有多个版本 | ||
| 87 | - `window` 不能删:它是 offset/evidence/多段投票的最小单元 | ||
| 88 | - `feature_set_registry` 不能删:否则未来换 MERT/MuQ 会把 schema 写死 | ||
| 89 | |||
| 90 | 可以延后: | ||
| 91 | - `work` | ||
| 92 | - 更重的 `retrieval_index_registry` | ||
| 93 | - 更细的全链路审计表 | ||
| 94 | |||
| 95 | 因此推荐口径不是“把所有层都砍掉”,而是: | ||
| 96 | > **Phase-1 先上最小可用层;未来版本归属/cover/work 治理再继续加层。** | ||
| 97 | |||
| 98 | --- | ||
| 99 | |||
| 56 | ## 3. 角色视图 | 100 | ## 3. 角色视图 |
| 57 | 101 | ||
| 58 | ## 3.1 产品 / 架构角色 | 102 | ## 3.1 产品 / 架构角色 | ... | ... |
| 1 | # PostgreSQL 数据模型与 DDL 设计说明 | 1 | # PostgreSQL 数据模型与 DDL 设计说明 |
| 2 | 2 | ||
| 3 | > 更新:2026-06-04 | 3 | > 更新:2026-06-04 |
| 4 | > 关联 SQL:[`acr-engine/sql/acr_pg_schema_v2.sql`](../acr-engine/sql/acr_pg_schema_v2.sql) | 4 | > 关联 SQL:[`acr-engine/sql/acr_pg_schema_v2.sql`](../acr-engine/sql/acr_pg_schema_v2.sql) |
| 5 | > 目标:给出面向版权保护 / 大规模曲库 / 可替换 encoder 的 PostgreSQL 数据字典、DDL 设计意图、流程图与典型使用路径。 | 5 | > 目标:给出面向版权保护 / 大规模曲库 / 可替换 encoder 的 PostgreSQL 数据字典、DDL 设计意图、流程图与典型使用路径。 |
| 6 | 6 | ||
| 7 | ## 一页结论 | 7 | ## 一页结论 |
| ... | @@ -23,6 +23,188 @@ canonical_song -> work -> recording -> recording_asset -> audio_window | ... | @@ -23,6 +23,188 @@ canonical_song -> work -> recording -> recording_asset -> audio_window |
| 23 | 23 | ||
| 24 | --- | 24 | --- |
| 25 | 25 | ||
| 26 | ## 0.1 为什么会感觉链路很多 | ||
| 27 | |||
| 28 | 本质上当前文档把 **3 类问题** 放在同一个总图里,所以看起来链路很长: | ||
| 29 | |||
| 30 | 1. **业务归属层**:`canonical_song / work / recording` | ||
| 31 | - 解决“最终归哪个 song_id / work_id / recording_id” | ||
| 32 | 2. **物理音频层**:`recording_asset / audio_window` | ||
| 33 | - 解决“实际文件是什么、切成了哪些检索窗口” | ||
| 34 | 3. **检索计算层**:`model_registry / feature_set_registry / audio_embedding / audio_fingerprint / retrieval_index_registry` | ||
| 35 | - 解决“用了哪个模型、哪套特征、哪套索引” | ||
| 36 | |||
| 37 | 所以这不是一条单链,而是: | ||
| 38 | - 一条 **归属回溯链** | ||
| 39 | - 一条 **音频资产链** | ||
| 40 | - 一条 **特征/索引链** | ||
| 41 | |||
| 42 | 把三者混看,就会误以为每次查询都要手工经过所有表。实际上在线检索真正关心的是: | ||
| 43 | |||
| 44 | ```text | ||
| 45 | window -> candidate -> recording -> song | ||
| 46 | ``` | ||
| 47 | |||
| 48 | --- | ||
| 49 | |||
| 50 | ## 0.2 当前是否可以简化 | ||
| 51 | |||
| 52 | 可以。 | ||
| 53 | |||
| 54 | 如果当前阶段的目标是: | ||
| 55 | |||
| 56 | > 先服务版权保护场景,让 query 能快速稳定地命中正确 `song_id` | ||
| 57 | |||
| 58 | 那么 Phase-1 完全可以收敛为下面这套 **最小可用骨架**: | ||
| 59 | |||
| 60 | ```text | ||
| 61 | song -> recording -> recording_asset -> audio_window | ||
| 62 | -> audio_fingerprint | ||
| 63 | -> audio_embedding | ||
| 64 | ``` | ||
| 65 | |||
| 66 | 为了支持模型替换,再保留一个轻量版本登记层: | ||
| 67 | |||
| 68 | ```text | ||
| 69 | feature_set_registry | ||
| 70 | ``` | ||
| 71 | |||
| 72 | 也就是说,Phase-1 最小主链可以压缩成: | ||
| 73 | |||
| 74 | ```text | ||
| 75 | song -> recording -> asset -> window -> feature | ||
| 76 | ``` | ||
| 77 | |||
| 78 | 其中 `feature` 可具体落成: | ||
| 79 | - `audio_fingerprint` | ||
| 80 | - `audio_embedding` | ||
| 81 | |||
| 82 | --- | ||
| 83 | |||
| 84 | ## 0.3 哪些层建议 Phase-1 保留,哪些层可以弱化 | ||
| 85 | |||
| 86 | ### 建议保留 | ||
| 87 | |||
| 88 | | 层 | 是否保留 | 原因 | | ||
| 89 | |---|---|---| | ||
| 90 | | `song` | 保留 | 最终业务返回对象 | | ||
| 91 | | `recording` | 保留 | 同一 song 下会有多个版本/录音 | | ||
| 92 | | `recording_asset` | 保留 | 一个 recording 可能有多个真实文件 | | ||
| 93 | | `audio_window` | 保留 | 检索和 evidence 的最小计算单元 | | ||
| 94 | | `feature_set_registry` | 保留 | 避免把 embedding/fingerprint 固化成表列 | | ||
| 95 | | `audio_embedding` / `audio_fingerprint` | 保留 | 真正的检索特征事实表 | | ||
| 96 | |||
| 97 | ### 可以弱化或延期 | ||
| 98 | |||
| 99 | | 层 | 当前建议 | 原因 | | ||
| 100 | |---|---|---| | ||
| 101 | | `work` | 可延期 | 如果当前只需稳定返回 `song_id`,可先不显式拆作品层 | | ||
| 102 | | `canonical_song` | 可与 `song` 合并理解 | 当前重点不是权利层深治理,而是先完成可用归属主键 | | ||
| 103 | | `retrieval_index_registry` | 可先弱化 | Phase-1 可先把索引治理做轻,不必一开始做太重 | | ||
| 104 | | `match_decision` 全量审计 | 可逐步补齐 | 先保证召回闭环,再加强审计/解释性 | | ||
| 105 | |||
| 106 | --- | ||
| 107 | |||
| 108 | ## 0.3.1 `recording` 和 `recording_asset` 能不能合并 | ||
| 109 | |||
| 110 | 可以合并,但**只适合非常早期、非常受控的数据集**。 | ||
| 111 | |||
| 112 | ### 什么时候可以临时合并 | ||
| 113 | |||
| 114 | 只有当下面条件基本都成立时,才可以把二者临时看成一个对象: | ||
| 115 | |||
| 116 | 1. 每个 `song` 只有一个可用录音版本 | ||
| 117 | 2. 每个录音只有一个音频文件 | ||
| 118 | 3. 不区分 master / distribution / captured / query_sample | ||
| 119 | 4. 不需要追踪同一录音的多个来源文件 | ||
| 120 | 5. 不需要后续补高码率、补母带、补平台版本 | ||
| 121 | |||
| 122 | 在这种情况下,可以暂时把模型理解成: | ||
| 123 | |||
| 124 | ```text | ||
| 125 | song -> recording_asset -> audio_window | ||
| 126 | ``` | ||
| 127 | |||
| 128 | 也就是让 `recording_asset` 同时承担“版本对象 + 物理文件对象”的职责。 | ||
| 129 | |||
| 130 | ### 为什么长期不建议合并 | ||
| 131 | |||
| 132 | 因为 `recording` 和 `recording_asset` 回答的是两个不同问题: | ||
| 133 | |||
| 134 | - `recording` 回答:**这是哪个录音版本** | ||
| 135 | - `recording_asset` 回答:**这个录音版本对应哪个具体文件** | ||
| 136 | |||
| 137 | 一旦进入真实版权保护场景,下面几类情况会非常常见: | ||
| 138 | |||
| 139 | 1. **同一录音有多个文件版本** | ||
| 140 | 例如 wav/flac/mp3、不同码率、不同平台导出件。 | ||
| 141 | 2. **同一 song 有多个录音版本** | ||
| 142 | 例如 official/live/remaster/short/bgm cut。 | ||
| 143 | 3. **同一录音要接多个来源** | ||
| 144 | 例如平台抓取、业务导出、人工补档。 | ||
| 145 | 4. **query 命中的是 asset,但归属要落到 recording/song** | ||
| 146 | 如果不拆层,后面聚合和去重会比较乱。 | ||
| 147 | |||
| 148 | ### 当前最推荐的判断 | ||
| 149 | |||
| 150 | 对于你现在这个目标: | ||
| 151 | - 约 `100w` 音频 | ||
| 152 | - 约 `30w` 歌曲 | ||
| 153 | - 面向版权保护 / 听歌识曲 / 版本归属 | ||
| 154 | |||
| 155 | **不建议把 `recording` 和 `recording_asset` 合并进正式 schema。** | ||
| 156 | |||
| 157 | 原因很直接: | ||
| 158 | - 数据量已经不小 | ||
| 159 | - 后续大概率会遇到多版本、多来源、多文件问题 | ||
| 160 | - 现在省掉一层,后面重构成本会更高 | ||
| 161 | |||
| 162 | ### 更务实的折中方案 | ||
| 163 | |||
| 164 | 如果你觉得当前实现心智负担太高,可以不在产品/算法讨论里反复强调 `recording_asset`,而是采用下面口径: | ||
| 165 | |||
| 166 | ```text | ||
| 167 | song -> recording -> asset -> window -> feature | ||
| 168 | ``` | ||
| 169 | |||
| 170 | 也就是说: | ||
| 171 | - **概念上保留** `recording` 和 `asset` 两层 | ||
| 172 | - **沟通上简写** 为 `recording -> asset` | ||
| 173 | - **实现上继续分表**,避免未来返工 | ||
| 174 | |||
| 175 | 这通常是 Phase-1 最稳妥的折中。 | ||
| 176 | |||
| 177 | --- | ||
| 178 | |||
| 179 | ## 0.4 一个更容易理解的口径 | ||
| 180 | |||
| 181 | 建议把当前体系理解为下面两条核心链: | ||
| 182 | |||
| 183 | ### 归属链 | ||
| 184 | |||
| 185 | ```text | ||
| 186 | window -> asset -> recording -> song | ||
| 187 | ``` | ||
| 188 | |||
| 189 | 作用: | ||
| 190 | - 检索命中后,回溯最终归属到哪个 `song_id` | ||
| 191 | |||
| 192 | ### 特征链 | ||
| 193 | |||
| 194 | ```text | ||
| 195 | window -> fingerprint / embedding -> candidate -> aggregate | ||
| 196 | ``` | ||
| 197 | |||
| 198 | 作用: | ||
| 199 | - 真正完成召回、打分、聚合与排序 | ||
| 200 | |||
| 201 | 这样看时,整个设计就不再是“很多层没必要”,而是: | ||
| 202 | - **归属层负责回答是谁** | ||
| 203 | - **窗口层负责回答命中了哪一段** | ||
| 204 | - **特征层负责回答怎么检索出来** | ||
| 205 | |||
| 206 | --- | ||
| 207 | |||
| 26 | ## 1. 设计意图 | 208 | ## 1. 设计意图 |
| 27 | 209 | ||
| 28 | ## 1.1 这套设计想解决什么 | 210 | ## 1.1 这套设计想解决什么 |
| ... | @@ -63,6 +245,15 @@ canonical_song -> work -> recording -> recording_asset -> audio_window | ... | @@ -63,6 +245,15 @@ canonical_song -> work -> recording -> recording_asset -> audio_window |
| 63 | 245 | ||
| 64 | 所以原型版 SQL 适合 demo,不适合你现在的 100w 音频目标。 | 246 | 所以原型版 SQL 适合 demo,不适合你现在的 100w 音频目标。 |
| 65 | 247 | ||
| 248 | ### 当前最建议的简化口径 | ||
| 249 | |||
| 250 | 如果团队正在进入 Phase-1 实施,不必把所有表同时视为“首批必须上线的复杂系统”。 | ||
| 251 | 更推荐按下面顺序理解和落库: | ||
| 252 | |||
| 253 | 1. `song -> recording -> recording_asset -> audio_window` | ||
| 254 | 2. `feature_set_registry -> audio_fingerprint / audio_embedding` | ||
| 255 | 3. `reference_set_registry` 与更重的索引治理随后补齐 | ||
| 256 | |||
| 66 | --- | 257 | --- |
| 67 | 258 | ||
| 68 | ## 2. 数据主链 | 259 | ## 2. 数据主链 | ... | ... |
-
Please register or sign in to post a comment