Reduce chromaprint peak-scan cost without changing fingerprint output
Constraint: the live FMA smoke is still running, so the optimization had to preserve existing hash semantics rather than adopt the faster non-equivalent peak picker Rejected: maximum_filter-based peak picking | changed peak/hash outputs despite much larger speedup Confidence: high Scope-risk: narrow Directive: Keep future chromaprint optimizations hash-equivalent unless evaluation baselines are intentionally regenerated Tested: compared old vs new peaks and hashes on fma_00000.mp3, measured 2.02x speedup, py_compile passed, rechecked live FMA smoke still in build-index Not-tested: full build-index completion on the live 8000-reference FMA run has not finished yet
Showing
2 changed files
with
36 additions
and
7 deletions
| ... | @@ -9,6 +9,7 @@ Implements landmark-based audio fingerprinting: | ... | @@ -9,6 +9,7 @@ Implements landmark-based audio fingerprinting: |
| 9 | 9 | ||
| 10 | import numpy as np | 10 | import numpy as np |
| 11 | import librosa | 11 | import librosa |
| 12 | from numpy.lib.stride_tricks import sliding_window_view | ||
| 12 | from collections import defaultdict | 13 | from collections import defaultdict |
| 13 | from typing import Dict, List, Tuple, Optional | 14 | from typing import Dict, List, Tuple, Optional |
| 14 | import pickle | 15 | import pickle |
| ... | @@ -53,13 +54,18 @@ class ChromaprintMatcher: | ... | @@ -53,13 +54,18 @@ class ChromaprintMatcher: |
| 53 | return S | 54 | return S |
| 54 | 55 | ||
| 55 | def _find_peaks(self, S: np.ndarray) -> List[Tuple[int, int, float]]: | 56 | def _find_peaks(self, S: np.ndarray) -> List[Tuple[int, int, float]]: |
| 56 | peaks = [] | 57 | if S.shape[0] <= self.peak_neighborhood or S.shape[1] <= self.peak_neighborhood: |
| 57 | for t in range(0, S.shape[1] - self.peak_neighborhood): | 58 | return [] |
| 58 | for f in range(0, S.shape[0] - self.peak_neighborhood): | 59 | |
| 59 | region = S[f:f + self.peak_neighborhood, t:t + self.peak_neighborhood] | 60 | windows = sliding_window_view(S, (self.peak_neighborhood, self.peak_neighborhood))[:-1, :-1] |
| 60 | center = S[f, t] | 61 | region_max = windows.max(axis=(-1, -2)) |
| 61 | if center == np.max(region) and center > self.min_peak_energy: | 62 | centers = S[: S.shape[0] - self.peak_neighborhood, : S.shape[1] - self.peak_neighborhood] |
| 62 | peaks.append((t, f, center)) | 63 | mask = (centers == region_max) & (centers > self.min_peak_energy) |
| 64 | |||
| 65 | peaks = [ | ||
| 66 | (int(t), int(f), float(centers[f, t])) | ||
| 67 | for f, t in np.argwhere(mask) | ||
| 68 | ] | ||
| 63 | peaks.sort(key=lambda x: x[2], reverse=True) | 69 | peaks.sort(key=lambda x: x[2], reverse=True) |
| 64 | return peaks[:200] | 70 | return peaks[:200] |
| 65 | 71 | ... | ... |
| 1 | ## 2026-06-02 chromaprint peak scan exact-safe optimization checkpoint | ||
| 2 | |||
| 3 | 完成项: | ||
| 4 | - 将 `acr-engine/src/engines/chromaprint_matcher.py` 的 `_find_peaks()` 从 Python 双层循环改为 `sliding_window_view` 向量化窗口最大值实现。 | ||
| 5 | - 放弃了更激进但会改变 hash 结果的 `maximum_filter` 方案,改用严格保持旧语义的等价版本。 | ||
| 6 | |||
| 7 | 验证结果: | ||
| 8 | - 单曲样本 `/tmp/fma_real_smoke_stopcheck/fma/audio/fma_00000.mp3`: | ||
| 9 | - `old_sec=1.3305` | ||
| 10 | - `new_sec=0.6579` | ||
| 11 | - `speedup_x=2.02` | ||
| 12 | - 等价性验证: | ||
| 13 | - `same_all200=true` | ||
| 14 | - `same_hashes=true` | ||
| 15 | - `old_hashes=609` | ||
| 16 | - `new_hashes=609` | ||
| 17 | - `python -m py_compile src/engines/chromaprint_matcher.py` 通过 | ||
| 18 | - 长跑中的真实 FMA smoke 在 `2026-06-02 13:49:25 UTC` 仍处于 `build-index`,尚未产出 `chromaprint.pkl` / `reference_progress.json` | ||
| 19 | |||
| 20 | 结论: | ||
| 21 | - 这次提交安全降低了 chromaprint 峰值扫描热点成本,且不改变当前 fingerprint/hash 行为。 | ||
| 22 | - 后续可继续观察真实 FMA 全量 smoke 是否更快进入 `chromaprint.pkl` 或 embedding checkpoint。 | ||
| 23 | |||
| 1 | ## 2026-06-02 真实 FMA smoke build-index 13:36 UTC delivery checkpoint | 24 | ## 2026-06-02 真实 FMA smoke build-index 13:36 UTC delivery checkpoint |
| 2 | 25 | ||
| 3 | 完成项: | 26 | 完成项: | ... | ... |
-
Please register or sign in to post a comment