Commit 9de8092d 9de8092d5982e71e52d18fd3247b5eb11d2ca4eb by cnb.bofCdSsphPA

Freeze the production encoder before scaling the music index

Document the production decision to stabilize the embedding space before onboarding a 300k-song catalog, and record the migration rules for future encoder upgrades.

Constraint: 300k-song production rollout makes embedding churn expensive and risky
Rejected: keep iterating encoder before defining a production embedding version | would force repeated full-vector rebuilds and unstable rollout criteria
Confidence: high
Scope-risk: narrow
Directive: Treat encoder changes as versioned index migrations, not in-place model swaps
Tested: reviewed rendered markdown content, docs index link, changelog entry, and git diff for the three touched docs
Not-tested: git push / remote sync outcome depends on repository remote state
1 parent 73d28fae
1 ### Stage: production encoder freeze FAQ and rollout guidance
2
3 完成项:
4 - 新增文档:
5 - `docs/production-encoder-freeze-and-embedding-strategy.md`
6 - 文档内容覆盖:
7 - 为什么当前应先冻结 encoder
8 - 当前结构的泛化能力边界
9 - 外置模型权重后如何给其他歌曲直接使用
10 - wav/mp3/flac/ogg 集合如何快速进入 manifest -> build-index -> evaluate 链路
11 - 30 万首生产曲库下 embedding/version/index 的治理建议
12 - encoder 升级后哪些数据必须重建、哪些元数据可以保留
13 - docs 入口已补充:
14 - `docs/README.md` 新增该答疑文档链接
15
16 结论:
17 - 当前阶段先冻结 `encoder v1` 是更稳妥的生产决策
18 - 生产环境应把模型文件、embedding 版本、reference 索引与评测报告解耦管理
19 - 后续新 encoder 应走“离线 shadow build -> A/B -> 切换”的升级路径,而不是直接覆盖旧 embedding 库
20
1 ## 2026-06-02 16:11 UTC / hum_guard fresh eval did not beat hum_focus 21 ## 2026-06-02 16:11 UTC / hum_guard fresh eval did not beat hum_focus
2 22
3 -`/tmp/dualaxis_sweep/hum_guard/eval.json` 做了最新复核 23 -`/tmp/dualaxis_sweep/hum_guard/eval.json` 做了最新复核
......
...@@ -91,6 +91,7 @@ cd /workspace/acr-engine ...@@ -91,6 +91,7 @@ cd /workspace/acr-engine
91 - [数据规范](./dataset-spec.md) 91 - [数据规范](./dataset-spec.md)
92 - [开放数据工作流](./open-dataset-workflow.md) 92 - [开放数据工作流](./open-dataset-workflow.md)
93 - [训练数据与 pgvector 指南](./training-data-and-pgvector-guide.md) 93 - [训练数据与 pgvector 指南](./training-data-and-pgvector-guide.md)
94 - [生产 Encoder 冻结与 Embedding 策略答疑](./production-encoder-freeze-and-embedding-strategy.md)
94 - [数据来源与接入](./dataset-sources-and-licensing.md) 95 - [数据来源与接入](./dataset-sources-and-licensing.md)
95 - [工业评测规范](./industrial-benchmark-spec.md) 96 - [工业评测规范](./industrial-benchmark-spec.md)
96 97
......
1 # Production Encoder Freeze & Embedding Strategy / 生产 Encoder 冻结与 Embedding 策略答疑
2
3 > 更新:2026-06-03
4 > 关联文档:[持续开发交接文档](./session-handoff.md) · [训练数据与 pgvector 指南](./training-data-and-pgvector-guide.md) · [开放数据工作流](./open-dataset-workflow.md) · [服务接口](./service-api.md)
5
6 ## 一页结论
7
8 围绕你当前最关心的生产问题,可以先压缩成 6 句话:
9
10 1. **当前先冻结 encoder 是正确决定。** 对 30 万首生产曲库来说,先稳定 embedding 空间,比继续频繁改模型更重要。
11 2. **当前结构具备泛化能力。** 线上识别主路径是“固定 encoder 抽 embedding + reference 检索”,不是只能识别训练时见过的 closed-set 分类标签。
12 3. **模型权重可以外置复用。** 你可以把当前 `best_model.pt` 当成独立 encoder,用在别的 wav/mp3/flac/ogg 歌曲集合上。
13 4. **如果 encoder 变了,向量库就必须重建。** 歌曲元数据不用重做,但所有旧 embedding / ANN index / pgvector 向量都应视为旧版本。
14 5. **30 万首场景下必须做 embedding 版本化。** 不建议“直接覆盖旧库”,而应并行维护 `encoder_version=v1/v2/...`
15 6. **最稳的上线策略是:先冻结 v1,上线使用;新模型只做离线 shadow build + A/B,收益足够大再切换。**
16
17 ---
18
19 ## 1. 当前项目进度:已经走到哪里
20
21 ## 1.1 当前状态
22
23 根据 [持续开发交接文档](./session-handoff.md),当前项目已经从“原型是否能跑通”进入“真实数据验证 + 工程化推进”阶段:
24
25 - synthetic 数据链路已跑通:生成、训练、建索引、识别、评测都已具备
26 - 开放数据链路已闭环:`inspect-local -> prepare-local -> validate-local -> train -> build-index -> evaluate -> generate_artifacts`
27 - 当前最佳候选方向已收敛到 `hum_focus`
28 - 真实 FMA smoke 已跨过训练,进入了 `build-index` 阶段
29
30 这说明当前不是“从零开始想方案”,而是已经具备:
31
32 1. **一个可以独立抽 embedding 的 encoder**
33 2. **一个可以对 reference 曲库建索引的 pipeline**
34 3. **一个可以对 query 做识别的 hybrid 检索链路**
35
36 ## 1.2 当前最适合的策略
37
38 在这个阶段,最重要的不是继续频繁换 encoder,而是:
39
40 ```mermaid
41 flowchart TD
42 A[已有可运行模型与索引链] --> B[冻结生产 Encoder v1]
43 B --> C[完成 30 万首建库与使用]
44 C --> D[收集真实线上/离线问题]
45 D --> E[离线评估新 Encoder v2]
46 E --> F[证明显著收益后再迁移]
47 ```
48
49 也就是:**先让一版可用的 embedding 体系稳定下来,再做后续升级。**
50
51 ---
52
53 ## 2. 当前结构是否有泛化能力
54
55 ## 2.1 简短回答
56
57 **有。**
58
59 但这里的“泛化”要分成两层理解:
60
61 | 泛化层次 | 当前是否支持 | 说明 |
62 |---|---|---|
63 | 新歌曲入库后可被识别 | 支持 | 只要用同一 encoder 生成 reference embedding 即可 |
64 | 完全未知分布上保持稳定高精度 | 尚未完全证明 | 当前更多是结构可行、真实大规模效果还需继续验证 |
65
66 ## 2.2 为什么说当前结构具备泛化能力
67
68 当前识别主链路不是:
69 - “输入 query -> 分类头直接输出某个固定 song class”
70
71 而是:
72 - “输入 query -> encoder 抽 embedding -> 在 reference embedding 库中做相似度检索”
73
74 结构图如下:
75
76 ```mermaid
77 flowchart LR
78 Q[query wav/mp3 片段] --> E1[冻结 Encoder v1]
79 E1 --> QE[query embedding]
80 QE --> S[similarity search]
81
82 R[30 万首 reference 曲库] --> E2[同一个冻结 Encoder v1]
83 E2 --> RE[reference embeddings]
84 RE --> S
85
86 S --> O[候选歌曲 + 分数]
87 ```
88
89 这种结构天然支持:
90
91 - 新歌曲加入 reference 曲库
92 - 不重训模型的情况下扩歌库
93 - 针对 query 做检索而不是固定类分类
94
95 ## 2.3 但泛化能力的上限受什么影响
96
97 当前真实效果主要还受这些因素制约:
98
99 1. **训练数据分布**
100 - 目前 hard case 已关注 `humming_like` / `confused`
101 - 但你的线上 30 万首曲库是否和当前训练/验证分布一致,仍需要真实数据验证
102
103 2. **reference 建库方式**
104 - 当前 reference 端是 **5 秒窗口 + 2.5 秒 stride** 的重叠滑窗
105 - 这对片段识别是好的,但代价是窗口数上升、建库成本变高
106
107 3. **query 形式差异**
108 - 无损整曲、压缩 mp3、录音片段、截短片段、混响/手机采样等都会影响效果
109
110 4. **混合检索策略**
111 - 当前不是纯 embedding 检索,而是 `chromaprint + embedding + melody rerank` 的 hybrid
112 - 这对鲁棒性是加分项,但也意味着线上治理时要同时考虑指纹索引和向量索引
113
114 ---
115
116 ## 3. 为什么当前先冻结 Encoder
117
118 ## 3.1 业务原因
119
120 你现在的生产环境里有 **30 万首歌曲**。这会带来一个决定性的工程事实:
121
122 > **一旦 encoder 改了,就不是“换个模型文件”这么简单,而是整套向量空间都可能变。**
123
124 如果还没冻结 encoder,就会出现这些问题:
125
126 - 今天建的 30 万 embedding,明天可能全部作废
127 - pgvector / Faiss / Milvus / 自研 ANN 索引都要全量重建
128 - 离线评测和线上灰度无法稳定对齐
129 - 回滚困难:你很难知道 query 是按哪个模型算的,reference 又是按哪个模型建的
130
131 ## 3.2 工程原因
132
133 冻结 encoder 后,你才能稳定以下这些对象:
134
135 | 资产 | 是否应随 encoder 冻结 | 原因 |
136 |---|---|---|
137 | `best_model.pt` | 是 | 它决定向量空间 |
138 | `n_mels/sample_rate/window/stride` | 是 | 这些决定 embedding 分布 |
139 | `embedding_dim` | 是 | 向量表结构和索引依赖它 |
140 | reference embeddings | 是 | 必须和 query embedding 同版本 |
141 | ANN index / pgvector 索引 | 是 | 建立在具体 embedding 空间上 |
142
143 ## 3.3 当前建议的冻结定义
144
145 建议把当前生产 encoder 冻结为一组明确配置,而不是只记一个文件名。
146
147 推荐至少记录这些字段:
148
149 ```yaml
150 encoder_version: ecapa_hum_focus_v1
151 checkpoint_path: /abs/path/to/best_model.pt
152 embedding_dim: 192
153 sample_rate: 16000
154 n_mels: 128
155 n_fft: 512
156 hop_length: 160
157 reference_window_sec: 5.0
158 reference_stride_sec: 2.5
159 query_runtime_window_sec: 5.0
160 feature_family: mel
161 index_family: hybrid_chromaprint_ecapa
162 status: frozen_for_production
163 ```
164
165 ---
166
167 ## 4. 模型权重能否外置,给其他歌曲使用
168
169 ## 4.1 简短回答
170
171 **可以,而且应该这样做。**
172
173 你可以把当前冻结好的 `best_model.pt` 视为一个独立的音乐 embedding encoder,用来处理:
174
175 - 新增歌曲入库
176 - 旧歌库全量建 embedding
177 - 任意 query 音频片段识别
178 - 后续 pgvector / ANN 向量服务对接
179
180 ## 4.2 外置使用时的推荐组织方式
181
182 推荐把“模型”和“索引产物”分开管理:
183
184 ```mermaid
185 flowchart TD
186 A[models/] --> A1[ecapa_hum_focus_v1/best_model.pt]
187 A --> A2[ecapa_hum_focus_v1/encoder_manifest.yaml]
188
189 B[indexes/] --> B1[ecapa_hum_focus_v1/chromaprint.pkl]
190 B --> B2[ecapa_hum_focus_v1/reference_embs.npy]
191 B --> B3[ecapa_hum_focus_v1/reference_ids.npy]
192 B --> B4[ecapa_hum_focus_v1/index_metadata.json]
193
194 C[metadata/] --> C1[song_catalog.csv]
195 C --> C2[manifests/catalog.json]
196 ```
197
198 ## 4.3 外置后能做什么
199
200 ### 场景 A:直接给新歌曲建库
201
202 - 你有一批新歌(wav/mp3/flac/ogg)
203 - 不重训
204 - 用冻结 encoder 直接建 reference embedding
205 - 加入曲库识别
206
207 ### 场景 B:给 query 片段做识别
208
209 - 你有 5~10 秒左右的查询片段
210 - 用同一 encoder 抽 query embedding
211 - 在 reference 库做相似度匹配
212
213 ### 场景 C:离线批量生成 pgvector/ANN 数据
214
215 - 你可以把 reference embeddings 作为离线产物导出
216 - 再灌入 PostgreSQL + pgvector / Faiss / Milvus / 自研检索服务
217
218 ---
219
220 ## 5. 你手头有无损、压缩、片段等 wav/mp3 文件集合,应该怎么直接使用
221
222 ## 5.1 总体原则
223
224 你手头的文件不需要先人工区分“是不是训练专用格式”。
225
226 当前最重要的是把它们统一进入这套结构:
227
228 ```mermaid
229 flowchart LR
230 A[原始 wav/mp3/flac/ogg] --> B[标准化目录]
231 B --> C[manifest]
232 C --> D[reference 建库]
233 C --> E[query 验证]
234 D --> F[线上识别/检索]
235 ```
236
237 ## 5.2 建议先分三类素材
238
239 | 类别 | 作用 | 建议处理方式 |
240 |---|---|---|
241 | 完整歌曲 / 主版本 | 做 reference | 全部入库 |
242 | 截断片段 / 业务 query 样本 | 做评测 query | 固定留作测试集 |
243 | 低码率/手机录音/混响压缩片段 | 做 hard case query | 用来验证鲁棒性 |
244
245 ## 5.3 最短直接使用流程
246
247 ### 第 1 步:冻结 encoder v1
248
249 先不要继续换模型,先把当前决定好的 checkpoint 固定下来。
250
251 ### 第 2 步:准备音频目录
252
253 例如:
254
255 ```text
256 input_music/
257 song_a.flac
258 song_b.mp3
259 song_c.wav
260 ...
261 ```
262
263 ### 第 3 步:检查目录是否适合进入当前链路
264
265 ```bash
266 cd /root/vprecog/acr-engine
267 /usr/local/miniconda3/bin/python src/data/manifest_tools.py inspect-audio-dir \
268 /abs/path/to/input_music \
269 --query-duration 8.0 \
270 --eval-ratio 0.2
271 ```
272
273 ### 第 4 步:生成统一 manifest
274
275 ```bash
276 cd /root/vprecog/acr-engine
277 /usr/local/miniconda3/bin/python src/data/manifest_tools.py audio-dir-to-splits \
278 /abs/path/to/input_music \
279 /abs/path/to/output_dataset \
280 --source-dataset prod_music \
281 --eval-ratio 0.2 \
282 --query-duration 8.0 \
283 --query-strategy hybrid \
284 --query-stride 2.5
285 ```
286
287 建议说明:
288 - `query-duration=8.0`:适合作为线下验证 query 长度
289 - `query-strategy=hybrid`:更贴近当前项目已有的音乐感知切片方向
290 - `query-stride=2.5`:如果你希望验证覆盖率更高,可以生成更多 query
291
292 ### 第 5 步:用冻结 encoder 建 reference index
293
294 ```bash
295 cd /root/vprecog/acr-engine
296 /usr/local/miniconda3/bin/python run_demo.py build-index \
297 --data /abs/path/to/output_dataset/manifests \
298 --model /abs/path/to/frozen/best_model.pt \
299 --output /abs/path/to/output_index \
300 --device cpu
301 ```
302
303 ### 第 6 步:做离线识别验证
304
305 ```bash
306 cd /root/vprecog/acr-engine
307 /usr/local/miniconda3/bin/python evaluate.py \
308 --data /abs/path/to/output_dataset/manifests \
309 --model /abs/path/to/frozen/best_model.pt \
310 --index-prefix /abs/path/to/output_index/reference \
311 --split test \
312 --device cpu \
313 --fast-eval \
314 --output-json /abs/path/to/output_reports/eval.json
315 ```
316
317 ### 第 7 步:确认后再推到生产向量库
318
319 当离线评测满足最低要求后,再把 reference embedding 导入生产检索系统,而不是一上来直接刷 30 万首正式库。
320
321 ---
322
323 ## 6. 如果要快速微调,应该怎么做
324
325 ## 6.1 原则
326
327 **“快速微调”不等于“马上用 30 万首全量重训”。**
328
329 对你当前场景,最合理的是:
330
331 1. 先冻结生产 encoder v1
332 2. 用一个代表性子集训练/微调候选 v2
333 3. 只在离线环境评估 v2
334 4. 证明收益大于迁移成本,才考虑升级生产 encoder
335
336 ## 6.2 推荐的微调子集组成
337
338 建议优先抽一个 **几千到几万首规模的代表性集合**,覆盖:
339
340 - 无损高质量版本
341 - 常见压缩版本(mp3/aac 等)
342 - 短片段
343 - 开头/中段/结尾片段
344 - 旋律近似、编曲相似的易混淆歌曲
345 - 手机采样 / 录屏 / 二次压缩音频
346 - 业务上最常见失败样本
347
348 ## 6.3 推荐微调流程
349
350 ```mermaid
351 flowchart TD
352 A[冻结 Encoder v1] --> B[抽代表性子集]
353 B --> C[生成 manifests]
354 C --> D[训练 v2 候选]
355 D --> E[建 v2 索引]
356 E --> F[固定测试集评测]
357 F --> G{收益显著?}
358 G -- 否 --> H[继续使用 v1]
359 G -- 是 --> I[准备 30 万首离线重刷 v2]
360 ```
361
362 ## 6.4 微调时的判断标准
363
364 不要只看训练 loss,至少要看:
365
366 | 指标 | 作用 |
367 |---|---|
368 | top1 / topk | 基本识别率 |
369 | hard-case 命中率 | 看压缩/片段/混淆样本提升是否真实 |
370 | 新增模型对旧强项的回退 | 防止“补一个洞,漏一大片” |
371 | 全量建库速度 | 看新模型是否导致生产成本显著上升 |
372 | 线上 query 延迟 | 看推理成本是否可接受 |
373
374 ## 6.5 微调后的发布原则
375
376 微调完成后不要立刻替换 v1,而要:
377
378 1. 标记为 `encoder_version=v2_candidate`
379 2. 只做离线建库和评测
380 3. 在真实样本上和 v1 做 A/B
381 4. 显著更优后再升级
382
383 ---
384
385 ## 7. 如果 embedding 变了,哪些数据必须重建
386
387 ## 7.1 要区分“元数据”和“向量数据”
388
389 | 数据类型 | 是否需要重建 | 说明 |
390 |---|---|---|
391 | 歌曲主数据(song_id/路径/业务标签) | 通常不需要 | 这些不依赖向量空间 |
392 | manifest | 通常不需要全重做 | 除非你的切片策略/数据治理规则也变了 |
393 | reference embeddings | 必须重建 | 因为 encoder 变了 |
394 | query embeddings 缓存 | 必须重建 | 否则和 reference 不同空间 |
395 | pgvector 行数据 | 必须重建 | 向量本体变了 |
396 | ANN 索引(Faiss/Milvus/HNSW/IVF 等) | 必须重建 | 建立在旧向量之上 |
397 | chromaprint 索引 | 不一定 | 只要指纹算法不变,可独立复用 |
398
399 ## 7.2 为什么必须重建
400
401 因为向量相似度检索默认假设:
402
403 > query embedding 和 reference embedding 来自同一个特征空间。
404
405 如果 query 用的是 `encoder v2`,reference 还停留在 `encoder v1`,就会出现:
406
407 - 分数不可比
408 - recall 明显下降
409 - 线上结果随机波动
410 - A/B 结论失真
411
412 ## 7.3 推荐的迁移策略
413
414 不要“原地覆盖旧 embedding”,而应采用双版本并行:
415
416 ```mermaid
417 flowchart LR
418 A[Encoder v1] --> B[index_v1]
419 C[Encoder v2] --> D[index_v2]
420 E[Query] --> F{使用哪个版本?}
421 F --> B
422 F --> D
423 ```
424
425 推荐步骤:
426
427 1. 保留 `v1` 生产库不动
428 2. 离线刷 `v2` 的 30 万 embedding
429 3.`v2` 的 ANN / pgvector 索引
430 4. 用相同 query 集对比 v1/v2
431 5. 确认收益后切主流量
432 6. 回滚时直接切回 v1
433
434 ---
435
436 ## 8. 30 万首生产环境推荐的版本化方案
437
438 ## 8.1 推荐最小字段
439
440 ### 歌曲元数据表
441
442 | 字段 | 说明 |
443 |---|---|
444 | `song_id` | 稳定歌曲 ID |
445 | `audio_uri` | 原始音频路径/对象存储地址 |
446 | `duration_sec` | 时长 |
447 | `codec/container` | 格式信息 |
448 | `catalog_status` | 是否可入 reference 库 |
449 | `business_tags` | 业务标签 |
450
451 ### embedding 表
452
453 | 字段 | 说明 |
454 |---|---|
455 | `song_id` | 对应歌曲 |
456 | `encoder_version` | 如 `ecapa_hum_focus_v1` |
457 | `window_index` | 第几个 reference window |
458 | `offset_sec` | 窗口起点 |
459 | `embedding_dim` | 例如 192 |
460 | `embedding` | 向量本体 |
461 | `built_at` | 构建时间 |
462 | `source_audio_hash` | 原音频指纹/摘要,便于查重与失效控制 |
463
464 ### index manifest
465
466 | 字段 | 说明 |
467 |---|---|
468 | `encoder_version` | 当前索引对应的 encoder |
469 | `checkpoint_path` | 模型文件 |
470 | `feature_config` | mel/n_mels/sample_rate 等 |
471 | `reference_window_sec` | 例如 5.0 |
472 | `reference_stride_sec` | 例如 2.5 |
473 | `catalog_size` | 曲库规模 |
474 | `num_reference_windows` | 总窗口数 |
475 | `built_at` | 构建时间 |
476
477 ## 8.2 推荐目录结构
478
479 ```text
480 prod_artifacts/
481 models/
482 ecapa_hum_focus_v1/
483 best_model.pt
484 encoder_manifest.yaml
485
486 indexes/
487 ecapa_hum_focus_v1/
488 chromaprint.pkl
489 chromaprint_progress.json
490 reference_embs.npy
491 reference_ids.npy
492 index_metadata.json
493
494 reports/
495 ecapa_hum_focus_v1/
496 eval.json
497 hard_case_eval.json
498 ```
499
500 ---
501
502 ## 9. 当前建议的生产操作手册
503
504 ## 9.1 目标
505
506 当前目标不是继续改模型,而是先完成:
507
508 1. 冻结 encoder v1
509 2. 用 v1 支撑第一版 30 万首曲库建库
510 3. 建立版本化规范
511 4. 为后续 v2 升级预留迁移机制
512
513 ## 9.2 分步操作
514
515 ### Phase 1:冻结与归档
516
517 - [ ] 选定当前生产 checkpoint
518 - [ ] 为该 checkpoint 生成 `encoder_manifest.yaml`
519 - [ ] 记录 `encoder_version`
520 - [ ] 固定 reference window / stride / mel 配置
521 - [ ] 禁止直接覆盖此 checkpoint
522
523 ### Phase 2:小规模真实集验证
524
525 - [ ] 抽 1k~10k 首真实歌曲做第一次建库
526 - [ ] 抽真实 query 集做评测
527 - [ ] 统计 top1/topk/hard-case 结果
528 - [ ] 验证索引构建速度、磁盘占用、查询延迟
529
530 ### Phase 3:30 万首全量离线建库
531
532 - [ ] 清洗 song_id 与元数据
533 - [ ] 生成标准 catalog/manifests
534 - [ ] 用冻结 encoder v1 批量生成 reference embeddings
535 - [ ] 生成 chromaprint / 向量索引
536 - [ ] 导入生产检索服务
537
538 ### Phase 4:上线与观测
539
540 - [ ] 上线 v1
541 - [ ] 记录 query 失败样本
542 - [ ] 归档 hard-case
543 - [ ] 为 v2 微调准备离线样本集
544
545 ### Phase 5:未来升级
546
547 - [ ] 训练 `v2_candidate`
548 - [ ] 离线全量重刷 `index_v2`
549 - [ ] 做离线 A/B
550 - [ ] 收益显著后再切换主版本
551
552 ---
553
554 ## 10. 常见问题 FAQ
555
556 ## 10.1 我现在有一大堆 wav/mp3,可以直接用吗?
557
558 **可以。**
559
560 先不要纠结格式本身,先把它们组织成统一音频目录,再生成 manifests,再用冻结 encoder 建 reference index。
561
562 ## 10.2 无损和压缩版本要不要分开?
563
564 **建议保留来源信息,但 reference 主库优先保留“主版本”。**
565
566 如果同一首歌有多个编码版本:
567 - 主版本作为 reference 主资产
568 - 其他压缩版本优先作为评测 query / hard case
569
570 这样更利于真实评估鲁棒性。
571
572 ## 10.3 片段文件可以直接拿来做 query 吗?
573
574 **可以。**
575
576 尤其适合作为:
577 - clean query
578 - compressed query
579 - hard case query
580
581 但如果要把它当训练样本,最好仍然能回溯到稳定的 `song_id` 和原 reference。
582
583 ## 10.4 如果后面发现 encoder 不够好怎么办?
584
585 不要直接替换现网。正确做法是:
586
587 1. 保持 v1 不动
588 2. 离线训练 v2
589 3. 离线重刷 v2 的全量 embedding
590 4. 对比 v1/v2
591 5. 确认收益后再切
592
593 ## 10.5 现在有没有必要立刻上全量 30 万首?
594
595 **建议先做一轮中等规模验证,再上全量。**
596
597 推荐先做:
598 - 1k 首小验证
599 - 1w~5w 首中等规模验证
600 - 验证速度/精度/存储后,再上 30 万
601
602 ## 10.6 现阶段最重要的一句话建议是什么?
603
604 > **先冻结 encoder v1,把 embedding/version/index 治理做好,再讨论 v2。**
605
606 ---
607
608 ## 11. 最终建议
609
610 对你现在的阶段,我的建议优先级是:
611
612 1. **冻结当前 encoder**
613 2. **建立 embedding 版本化规范**
614 3. **先做小到中规模真实集建库验证**
615 4. **再推进 30 万首全量建库**
616 5. **把新模型升级变成“离线重刷 + A/B + 切换”的标准动作**
617
618 这样做的好处是:
619
620 - 你现在就能开始用
621 - 后面也不会因为继续调模型把生产库拖乱
622 - 未来升级有明确路径,不会出现“模型变了,数据全乱了”的问题
623
624 ## Sources
625 - [持续开发交接文档](./session-handoff.md)
626 - [训练数据与 pgvector 指南](./training-data-and-pgvector-guide.md)
627 - [开放数据工作流](./open-dataset-workflow.md)
628 - [服务接口](./service-api.md)
629 - [acr-engine/train.py](../acr-engine/train.py)
630 - [acr-engine/run_demo.py](../acr-engine/run_demo.py)
631 - [acr-engine/src/engines/ecapa_embedder.py](../acr-engine/src/engines/ecapa_embedder.py)
632 - [acr-engine/src/data/manifest_tools.py](../acr-engine/src/data/manifest_tools.py)