Audio Content Recognition (ACR) System — 听歌识曲引擎设计文档
版本: v1.0 | 更新: 2026-06-02 | 状态: Draft
目录
- 概述与背景
- 解决的问题
- 技术原理
- 系统架构设计
- 数据准备与增强
- 模型设计
- 训练细节
- 推理与匹配策略
- 使用方法
- SOTA 调研与对比
- Roadmap
- Checklist
- Changelog
- Handoff 交付清单
- 参考与引用
1. 概述与背景
1.1 项目目标
构建一个音频内容识别(Audio Content Recognition, ACR)引擎,能够根据一段BGM(背景音乐)、哼唱(Humming)、录音片段等音频输入,在歌曲库中快速准确地识别出对应的歌曲。核心能力对标 Shazam、SoundHound、网易云音乐"听歌识曲"等工业级产品。
1.2 核心能力
| 能力 | 说明 |
|---|---|
| BGM 识别 | 输入一段背景音乐,识别原曲 |
| 哼唱识别 (Query-by-Humming) | 输入用户哼唱的旋律,识别匹配的歌曲 |
| 录音片段识别 | 输入现场录音(含环境噪声),匹配库中歌曲 |
| 抗噪鲁棒性 | 在嘈杂环境、低码率、压缩失真下保持准确率 |
| 快速检索 | 亿级曲库下毫秒级响应 |
| 增量扩展 | 歌曲库可动态增加,无需全量重训练 |
1.3 命名规范
| 术语 | 含义 |
|---|---|
| Song / Track | 库中原始歌曲 |
| Reference | 歌曲在库中的指纹/特征表示 |
| Query | 用户输入的待识别音频片段 |
| Fingerprint | 音频指纹(特征向量或哈希序列) |
| Landmark | 频谱图中的峰值点,用于构建指纹 |
| Candidate | 匹配候选歌曲列表 |
| Segment | 一个Query对应的录音片段或BGM片段 |
2. 解决的问题
2.1 核心问题域
| 问题 | 描述 | 技术挑战 |
|---|---|---|
| 音频退化 | Query 可能经过压缩(MP3/AAC)、降采样、远场录制 | 特征需对退化具有不变性 |
| 时间截断 | Query 仅为歌曲的中间某一小段(3-15s) | 指纹需支持局部匹配 |
| 哼唱偏差 | 用户哼唱的音高、节奏、音色与原曲不同 | 需旋律归一化与音高轮廓匹配 |
| 环境噪声 | 录音含背景人声、街道噪声、混响 | 特征提取需有一定抗噪性 |
| 速度变化 | Query 播放速度可能快于或慢于原曲(±15%) | 指纹对时间伸缩不敏感 |
| 键位偏移 | Query 的调性可能不同于原曲(哼唱场景常见) | 需相对旋律表示而非绝对音高 |
| 曲库规模 | 曲库可能达到百万至亿级 | 检索必须依赖哈希/近似最近邻索引 |
2.2 与现有方案对比
| 维度 | 传统指纹法 (Shazam-like) | 深度学习 embedding 法 (本方案) | 混合方案 |
|---|---|---|---|
| 哼唱识别 | 不支持 | 支持(训练时加入哼唱数据) | 支持 |
| 抗噪性 | 中等 | 高(数据增强可大幅提升) | 高 |
| 检索速度 | 极快(哈希表) | 快(ANN 索引) | 极快 |
| 曲库扩展 | 容易 | 容易(增量索引) | 容易 |
| 硬件要求 | 低 | 中等(需 GPU 训练) | 中等 |
| 调音适应性 | 差 | 好(对比学习可学到不变性) | 好 |
| 时间碎片适应性 | 好 | 好(滑窗机制) | 好 |
3. 技术原理
3.1 音频信号处理基础
3.1.1 短时傅里叶变换 (STFT)
音频信号经 STFT 转化为时频表示:
X(t, f) = Σₙ x[n]·w[n-t]·e^{-j2πfn/N}
其中 w[n] 为窗函数(Hamming/Hann),典型窗长 1024-4096 samples,步长 256-512 samples。
3.1.2 Mel 频谱
将 STFT 的线性频率通过 Mel 滤波器组映射到 Mel 刻度:
Mel(f) = 2595 · log₁₀(1 + f/700)
得到 Mel 频谱图作为模型的 2D 输入特征。Mel 频谱更符合人耳听觉感知,且对高频噪声有一定抑制作用。
3.1.3 色谱图 (Chroma Feature)
色谱图将频谱能量投影到 12 个半音(C, C#, D, ..., B),对音色和音高变化具有不变性,特别适合哼唱识别。
Chroma(t, p) = Σ_{f ∈ pitches_in_class_p} |X(t, f)|²
3.1.4 谱峰提取 (Spectral Peaks)
在频谱图中提取能量峰值点(landmarks),每个 landmark 定义为 (t, f, energy)。Shazam 算法基于这些 landmark 构建哈希指纹。
3.1.5 哼唱旋律轮廓 (Melody Contour)
对于哼唱输入,使用基频(F0)估计提取旋律轮廓线。常用算法:
- PYIN (Probabilistic YIN):基于 YIN 算法的概率改进版
- CREPE:基于深度学习的基频估计
- TorchCREPE:CREPE 的 PyTorch 实现
旋律轮廓经归一化后得到相对音高序列:ΔP(t) = P(t) - P(t-1)。
3.2 音频指纹技术
3.2.1 传统指纹法 (Shazam Algorithm)
- 对音频做 STFT 得到频谱图
- 在时频平面提取能量峰值(landmarks)
- 对每对 landmark
(f₁, t₁)和(f₂, t₂)构建哈希对:hash = (f₁, f₂, Δt) → (t₁, song_id) - 查询时计算 Query 的 landmarks 和 hashes
- 在哈希表中找到匹配的歌曲候选
- 对候选做时间偏移直方图投票,选出最高票歌曲
优点:极快、曲库可极大、无需训练 缺点:对哼唱、速度变化、调性变化不适应
3.2.2 深度嵌入法 (Deep Embedding) —— 本方案核心
将音频片段映射到一个固定维度的嵌入向量(如 256 维),在嵌入空间中相似歌曲的 Query 和 Reference 距离接近。
对比学习目标 (Contrastive Learning):
Loss = -log( exp(sim(q, p)/τ) / Σ_{n=1}^{N} exp(sim(q, n)/τ) )
其中 sim(q, p) 是 Query 与正样本 Reference 的余弦相似度,τ 是温度系数。
核心优势:
- 通过对比学习,嵌入对音色、噪声、速度变化、调性变化具有不变性
- 哼唱 Query 可与原曲 Reference 在嵌入空间中对齐
- 支持增量曲库(新歌只需过一次模型生成嵌入)
3.3 检索策略
3.3.1 精确检索 (Brute Force)
当库规模 < 10K 时,直接计算 Query 嵌入与所有 Reference 嵌入的余弦相似度。
score_i = cosine(query_emb, ref_emb_i)
result = argmax(score_i)
3.3.2 近似最近邻检索 (ANN)
当库规模 > 10K 时,使用近似最近邻索引:
| 算法 | 特点 | 适用场景 |
|---|---|---|
| IVF | 倒排文件索引,训练聚类中心 | 百万级 |
| IVF + PQ | 乘积量化压缩向量 | 千万级 |
| HNSW | 分层导航小世界图 | 亿级,高精度 |
| DiskANN | 基于 SSD 的图索引 | 十亿级 |
推荐使用 Faiss 库实现 ANN 检索。
3.3.3 级联检索策略
Query → 粗筛 (ANN, top-K) → 精排 (余弦相似度) → 时间对齐验证 → Top-1
- 粗筛:ANN 检索 Top-50/100 候选
- 精排:计算精确余弦相似度,取 Top-10
- 时间对齐验证:对 Top-10 候选做频谱图谱峰对齐验证,确认时序一致性
4. 系统架构设计
4.1 整体架构
┌─────────────────────────────────────────────────────────────┐
│ API Gateway │
└─────────────────────┬───────────────────────────────────────┘
│
┌─────────────┼─────────────┐
▼ ▼ ▼
┌───────────────┐ ┌───────┐ ┌───────────────┐
│ Audio Ingest │ │ Search│ │ Admin Service │
│ (Ingestion) │ │ (QPS) │ │ (管理) │
└───────┬───────┘ └───┬───┘ └───────┬───────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────────┐
│ Core Engine Layer │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌───────────────┐ │
│ │ Pre- │ │ Feature │ │ Embedder│ │ Matcher │ │
│ │ processor│ │ Extractor│ │ (Model) │ │ (Searcher) │ │
│ └──────────┘ └──────────┘ └──────────┘ └───────────────┘ │
└─────────────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────────┐
│ Storage Layer │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌───────────────┐ │
│ │ Raw Audio│ │ Finger- │ │ Embedding│ │ Song Metadata │ │
│ │ (S3/OSS) │ │ print DB │ │ Index │ │ (PostgreSQL) │ │
│ └──────────┘ └──────────┘ └──────────┘ └───────────────┘ │
└─────────────────────────────────────────────────────────────┘
4.2 模块详细设计
4.2.1 Audio Preprocessor
输入: raw_audio_bytes / file_path / stream
功能:
1. 格式解码 (MP3, WAV, FLAC, AAC, OGG, M4A)
2. 重采样到统一采样率 (16kHz 或 22.05kHz)
3. 通道合并 (多声道 → 单声道)
4. 归一化 (RMS 归一化到目标响度)
5. 分帧/滑窗 (非重叠或非重叠滑窗,每帧 3-15s)
输出: numpy.ndarray, shape=(samples,)
4.2.2 Feature Extractor
支持多种特征提取策略,可通过配置切换:
模式 A: Spectrogram + Log-Mel
- STFT: window=2048, hop=512, window_fn=hann
- Mel filters: 64/128 bins, fmin=0, fmax=8000
- Log(spectrogram + 1e-6)
模式 B: Chroma CQT
- Constant Q Transform, 12 bins/octave
- 适用于哼唱场景
模式 C: Landmark + Hash (Shazam 兼容)
- Peak extraction (2D local maxima)
- Target zone pairing for hash construction
模式 D: Raw Waveform (可选)
- 直接输入原始波形给 1D CNN
4.2.3 Embedder (深度模型)
参见第 6 节。
4.2.4 Matcher / Searcher
输入: query_embedding (dim=256)
流程:
1. ANN 检索: Faiss IVF+HNSW, top_k=100
2. 精排: 计算精确余弦相似度, top_k=10
3. 时间对齐验证 (可选):
- 对 Top-10 候选提取谱峰
- 计算 Query 与候选的时间偏移直方图
- 确认存在一致性偏移峰值
4. 置信度校准: 计算相似度分布 z-score
5. 输出: sorted_results[ {song_id, score, match_type} ]
4.3 API 设计
// Recognize — 识别音频
service ACRService {
// 输入音频返回 Top-N 匹配歌曲
rpc Recognize(RecognizeRequest) returns (RecognizeResponse);
// 批量入库
rpc IngestSong(IngestSongRequest) returns (IngestSongResponse);
// 删除歌曲
rpc DeleteSong(DeleteSongRequest) returns (DeleteSongResponse);
// 健康检查
rpc HealthCheck(Empty) returns (HealthCheckResponse);
}
message RecognizeRequest {
bytes audio_data = 1; // 音频数据
string audio_format = 2; // wav, mp3, ogg
float duration_sec = 3; // 实际有效时长 (若未知留空)
RecognizeMode mode = 4; // AUTO, BGM, HUMMING, RECORDING
int32 top_n = 5; // 返回 Top-N (默认 5)
}
enum RecognizeMode {
AUTO = 0; // 自动检测模式
BGM = 1; // 纯 BGM 片段
HUMMING = 2; // 哼唱
RECORDING = 3; // 现场录音
}
message RecognizeResponse {
repeated Candidate candidates = 1;
float processing_time_ms = 2;
}
message Candidate {
string song_id = 1;
string title = 2;
string artist = 3;
float confidence = 4;
float matched_begin_sec = 5; // 匹配起始时间
float matched_end_sec = 6; // 匹配结束时间
string match_type = 7; // bgm / humming / recording
}
4.4 存储设计
| 数据 | 存储引擎 | 说明 |
|---|---|---|
| 原始音频 | S3/MinIO/OSS | 对象存储,按 song_id 组织 |
| 歌曲元数据 | PostgreSQL | 标题、歌手、专辑、时长、标签 |
| 嵌入向量 | Faiss Index (IVF+HNSW) | 256 维浮点向量 |
| 指纹哈希 | Redis / LevelDB | Shazam 兼容指纹键值对 |
| 频谱缓存 | Redis / S3 | 预处理后的频谱图缓存 |
| 操作日志 | ClickHouse / ELK | 查询日志、性能监控 |
4.5 部署架构
┌──────────┐
│ LB/Nginx│
└────┬─────┘
│
┌──────────┼──────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ API │ │ API │ │ API │
│ Server 1 │ │ Server 2 │ │ Server N │
└────┬─────┘ └────┬─────┘ └────┬─────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────┐
│ Faiss Index (Sharded) │
│ GPU/CPU Hybrid │
├─────────────────────────────────────┤
│ PostgreSQL (RDS) │
├─────────────────────────────────────┤
│ S3-compatible Object Store │
└─────────────────────────────────────┘
5. 数据准备与增强
5.1 数据来源
5.1.1 歌曲原始数据
| 来源 | 类型 | 规模目标 | 许可注意 |
|---|---|---|---|
| FMA (Free Music Archive) | 开源音乐 | 100K+ 曲 | CC 授权 |
| MUSDB18 | 多轨分离数据集 | 150 曲 | 研究用途 |
| GTZAN | 流派分类 | 1000 曲 | 研究用途 |
| 自行爬取/合作 | 商业音乐 | 1M+ 曲 | 需版权授权 |
| 自建录制 | 哼唱/翻唱 | 10K+ 段 | 内部数据 |
5.1.2 训练数据构造
每个歌曲在库中作为 Reference,需为每个 Reference 构造多样化的 Query 用于训练。
基础构造逻辑:
song.mp3 → 随机裁剪片段 (3-15s) → 数据增强 → Query
song.mp3 → 全曲 → Reference
5.1.3 哼唱数据
哼唱数据可通过以下方式获取:
- MIR-QBSH Corpus:专业哼唱数据集
- 自建哼唱数据集:组织用户录制哼唱旋律
- MIDI 转音频模拟:将 MIDI 文件通过合成器转为模拟哼唱
- M-Humming:自行标注的哼唱数据集
哼唱数据格式要求:
{
"song_id": "song_001",
"humming_id": "hum_001",
"audio_path": "/data/humming/song_001_hum_001.wav",
"original_song_path": "/data/songs/song_001.mp3",
"humming_duration_sec": 8.5,
"relative_pitch_shift": -2, // 相对原曲的半音偏移
"tempo_ratio": 1.1 // 相对原曲的速度倍率
}
5.2 数据增强策略
增强的目的是使模型学到对真实世界干扰的不变性。
5.2.1 基础增强
| 增强操作 | 参数范围 | 目标 |
|---|---|---|
| Additive White Gaussian Noise (AWGN) | SNR: 5-30dB | 环境噪声 |
| Pink Noise / Brown Noise | SNR: 10-25dB | 自然噪声 |
| Band-stop Filtering | 随机 0.5-2kHz 陷波 | 频率缺失 |
| Low-pass / High-pass | 截止频率 1-8kHz | 频带限制 |
| Time Stretch | 0.85-1.15x | 速度变化 |
| Pitch Shift | -6 ~ +6 semitones | 调性变化(哼唱) |
| Equalizer Randomization | 随机增益 ±6dB | 音色变化 |
| Resampling | 8-44.1kHz | 采样率退化 |
| MP3 Compression | 32-128kbps | 压缩失真 |
| Reverb | 房间混响模拟 | 远场录音 |
| Volume Jitter | -12 ~ 0 dB | 响度变化 |
| Time Masking (SpecAug) | 遮罩 10-50 帧 | 局部缺失 |
| Frequency Masking (SpecAug) | 遮罩 8-16 bins | 局部频率缺失 |
5.2.2 哼唱专用增强
| 增强操作 | 说明 |
|---|---|
| F0 抖动 | 基频随机扰动 ±5% |
| 节奏抖动 | 节拍随机扰动 ±10% |
| 添加呼吸声 | 插入随机位置的呼吸音 |
| 音色变异 | 使用不同的合成器/人声 |
| 单音偏差 | 部分音符替换为邻音(模拟跑调) |
5.2.3 数据增强管线
原始音频 (16kHz mono)
│
├─→ [随机裁剪] 3-15s 随机片段
├─→ [重采样] 8kHz / 16kHz / 22.05kHz / 44.1kHz 随机选择
├─→ [响度归一化] RMS = target_loudness
├─→ [噪声叠加] AWGN / Pink / 背景音 按概率叠加
├─→ [滤波器] 低通/高通/带阻/均衡器 随机选择
├─→ [时域变化] Time Stretch ±15%
├─→ [频域变化] Pitch Shift ±6 semitones
├─→ [压缩模拟] MP3 编码再解码 (64-128kpbs)
├─→ [混响] 小型/中型/大型房间混响
├─→ [SpecAug] Time & Frequency Masking
└─→ [特征提取] Mel Spectrogram / Chroma / Raw
└─→ [输出] 增强后的特征张量
实现:torchaudio / audiomentations / librosa 组合管线。
5.3 数据格式与存储
训练数据格式:
/data/
├── songs/ # 原始歌曲
│ ├── song_001.mp3
│ └── ...
├── references/ # 参考指纹/嵌入
│ ├── ref_001.npy # 歌曲全曲或多段嵌入
│ └── ...
├── queries/ # 查询片段 (训练数据)
│ ├── train/
│ │ ├── song_001_seg_001.wav
│ │ └── ...
│ └── val/
│ └── ...
├── metadata.csv # 歌曲元数据
└── train_pairs.csv # (query_path, song_id, type)
metadata.csv 格式:
song_id,title,artist,album,duration_sec,genre,language
song_001,Song Title,Artist Name,Album Name,240.5,Pop,en
train_pairs.csv 格式:
query_path,song_id,query_type,augmentation_params
queries/train/song_001_seg_001.wav,song_001,bgm,"{snr:15, pitch_shift:0}"
queries/train/song_001_hum_001.wav,song_001,humming,"{pitch_shift:-2, tempo:1.1}"
5.4 数据流水线性能要求
| 指标 | 目标 |
|---|---|
| 增强吞吐 | ≥ 200 样本/秒/GPU |
| 预处理缓存 | 频谱图存入 LMDB/RecordIO |
| 训练样本总量 | ≥ 5M Query-Reference 对 |
| 参考曲库 | ≥ 100K 歌曲(测试阶段) |
6. 模型设计
6.1 模型架构选型
本方案采用 双塔结构 (Two-Tower / Siamese Network),两塔共享权重。
┌─────────────────────────────────────┐
│ Similarity Score │
│ cosine(q_emb, r_emb) │
└──────────────────┬──────────────────┘
│
┌────────────────────┴────────────────────┐
▼ ▼
┌───────────────┐ ┌───────────────┐
│ Query │ │ Reference │
│ Encoder │ │ Encoder │
│ (shared) │ │ (shared) │
└───────┬───────┘ └───────┬───────┘
│ │
┌───────┴───────┐ ┌───────┴───────┐
│ Input 1 │ │ Input 2 │
│ (Mel Spec) │ │ (Mel Spec) │
└───────────────┘ └───────────────┘
6.2 候选骨干网络
方案 A: CNN-Transformer (推荐)
Input: Mel-Spectrogram (1, 128, T) — 单通道, 128 Mel bins, 变长时间
│
├─ Conv2D(1→32, 3×3, stride=1) + BN + ReLU
├─ Conv2D(32→64, 3×3, stride=2) + BN + ReLU
├─ Conv2D(64→128, 3×3, stride=2) + BN + ReLU
├─ Conv2D(128→256, 3×3, stride=2) + BN + ReLU
│
├─ Reshape: (batch, T', 256)
├─ Transformer Encoder × 4 (d_model=256, nhead=8, dim_feedforward=1024)
├─ [CLS] Token Pooling / Global Average Pooling
├─ Projection: 256 → 256 (Linear + LayerNorm)
└─ L2 Normalize → Embedding (256-dim)
总参数量: ~8-12M | MACs: ~2-5G per 5s audio
方案 B: EfficientNet-ish (轻量级)
Input: Mel-Spectrogram (3, 128, T) — 拼接近邻帧伪 RGB
│
├─ MBConv blocks (EfficientNet-B0 like)
│ - Stem: Conv 3×3, 32ch
│ - Stage 1-7: MBConv with SE
│ - Head: Conv 1×1, 1280ch
├─ Global Average Pooling
├─ Dropout 0.2
├─ Projection: 1280 → 256
└─ L2 Normalize → Embedding (256-dim)
总参数量: ~5-8M | MACs: ~1-3G per 5s audio
方案 C: 纯 Attention (AST-like)
Input: Mel-Spectrogram (1, 128, T)
│
├─ Patch Embedding (16×16 patches) + Position Embedding
├─ Transformer Encoder × 12 (d_model=768, nhead=12)
├─ [CLS] Token
├─ Projection: 768 → 256
└─ L2 Normalize → Embedding (256-dim)
总参数量: ~80-90M | MACs: ~5-15G per 5s audio 优势: 准确率最高 | 劣势: 推理速度较慢
推荐: 方案 A (CNN-Transformer) 作为主选,方案 B 作为备选轻量级。
6.3 训练损失函数
6.3.1 主损失: SupConLoss (Supervised Contrastive Loss)
对于 batch 中每个 anchor a,
正样本集 P(a) = 所有与 a 同歌曲的样本
负样本集 N(a) = 与 a 不同歌曲的样本
L_supcon = Σ_a [ -1/|P(a)| · Σ_{p∈P(a)} log( exp(sim(z_a, z_p)/τ) / Σ_{n∈N(a)∪P(a)} exp(sim(z_a, z_n)/τ) ) ]
6.3.2 辅助损失: ArcFace / CosFace (可选)
当曲库有固定类别标签时,可附加分类损失:
L_arcface = -log( exp(s·cos(θ_y + m)) / (exp(s·cos(θ_y + m)) + Σ_j≠y exp(s·cos θ_j)) )
6.3.3 总损失
L_total = λ₁ · L_supcon + λ₂ · L_arcface + λ₃ · L_triplet
推荐 λ₁=1.0, λ₂=0.3, λ₃=0.1。
6.4 哼唱识别专用模块
对于哼唱输入,在主干网络外增加一个旋律编码分支:
哼唱音频
│
├─ F0 估计 (CREPE / PYIN) → F0 轮廓 (hourglass-shaped)
├─ Chroma CQT → 12-bin 色谱图
│
├─ 可选融合策略:
│ A) 早融合 (Early Fusion): Mel + Chroma 通道拼接 → 同一网络
│ B) 晚融合 (Late Fusion): Mel 分支 + Chroma 分支分别编码 → 拼接嵌入
│ C) 分叉网络 (Forked): 共享底层特征层,高层分支出 Mel 和 Chroma 特征
│
└─ → 256-dim Embedding
推荐使用 晚融合 方案,在训练时将 Mel 特征和 Chroma 特征分别经过共享底层后拼接,再投影到 256 维。
6.5 多尺度匹配策略
由于 Query 长度可变(3-15s),使用多尺度滑窗:
Reference (全曲 3min):
[───── Window 1 (5s) ─────]
[───── Window 2 (5s) ─────]
[───── Window 3 (5s) ─────]
... (stride = 2.5s)
每个窗口 → Reference Embedding Matrix: (num_windows, 256)
Query (5s) → Query Embedding: (1, 256)
匹配: max_sim = max(sim(query_emb, ref_window_emb_i) for i in windows)
7. 训练细节
7.1 实验环境
| 配置 | 规格 |
|---|---|
| GPU | NVIDIA A100 (80GB) × 4 |
| CPU | AMD EPYC 64C / Intel Xeon 48C |
| RAM | 512 GB |
| 存储 | NVMe SSD 4TB |
| 框架 | PyTorch 2.x + Lightning / FSDP |
| 加速 | Flash Attention, torch.compile |
| 监控 | W&B / MLflow |
7.2 超参数
| 参数 | 值 | 备注 |
|---|---|---|
| Audio SR | 16000 Hz | 统一采样率 |
| Frame Size | 1024 (~64ms) | STFT 窗长 |
| Hop Size | 512 (~32ms) | STFT 步长 |
| Mel Bins | 128 | 梅尔滤波器数量 |
| Max Duration | 10s | 训练时音频截断长度 |
| Embedding Dim | 256 | 嵌入向量维度 |
| Batch Size | 512-1024 | 分布式训练 |
| Optimizer | AdamW | β=(0.9, 0.999) |
| Learning Rate | 3e-4 | Cosine Annealing |
| Weight Decay | 0.01 | L2 正则化 |
| Warmup Steps | 5000 | Linear Warmup |
| Epochs | 100-200 | Early Stopping |
| Temperature τ | 0.07 | 对比学习温度 |
| Label Smoothing | 0.1 | 防止过拟合 |
| Gradient Clipping | 1.0 | Max norm |
| Mixed Precision | bfloat16 | 加速训练 |
| Scheduler | Cosine Decay | Warm restarts |
7.3 训练流程
Step 1: 数据准备
1. 收集原始歌曲 → 16kHz mono → 存储为 WAV
2. 随机裁剪 + 数据增强 → 生成 Query/Reference 对
3. 提取 Mel 频谱 → 存储为 .npy (可选在线提取)
4. 分割 train/val/test (80/10/10)
Step 2: 预训练 (可选)
1. 在大规模无标签数据上使用 SimCLR / BYOL 做自监督预训练
2. 或使用公开预训练权重 (AudioMAE, CLAIR, CLAP)
Step 3: 有监督对比学习训练
1. 加载预训练权重或从头初始化
2. 每个 batch: 从 B 个歌曲各取 K 个片段 → B×K 样本
3. 计算 SupConLoss + 辅助损失
4. 每 N 步验证集评估 Recall@1, Recall@5
5. 最佳模型保存 checkpoint
Step 4: 哼唱微调 (可选阶段)
1. 使用哼唱数据 + 数据增强对模型做有监督微调
2. 固定部分底层参数,微调顶层和高层 Transformer
3. Learning rate: 1e-5 (较小)
Step 5: 索引构建
1. 对所有歌曲提取 Reference Embeddings
2. 使用 Faiss 构建 IVF+HNSW 索引
3. 评估索引准确率与检索速度
7.4 评估指标
| 指标 | 说明 | 目标值 |
|---|---|---|
| Recall@1 | Top-1 准确率 | ≥ 90% (BGM), ≥ 80% (哼唱) |
| Recall@5 | Top-5 召回率 | ≥ 95% (BGM), ≥ 90% (哼唱) |
| MRR | Mean Reciprocal Rank | ≥ 0.9 |
| mAP | Mean Average Precision | ≥ 0.88 |
| QPS | Queries Per Second (单 GPU) | ≥ 500 |
| P50 Latency | 中位数响应时间 | ≤ 100ms |
| P99 Latency | 99% 响应时间 | ≤ 500ms |
| Index Build | 10万曲库索引构建时间 | ≤ 30min |
| Index Size | 索引占用内存 | ≤ 2GB (100K 曲) |
7.5 消融实验设计
| 实验 | 变量 | 预期验证目标 |
|---|---|---|
| 特征对比 | Mel vs Chroma vs CQT vs Raw | 最优输入特征 |
| 骨干对比 | CNN vs CNN-Tfm vs AST vs EffNet | 最优架构 |
| 嵌入维度 | 64 vs 128 vs 256 vs 512 | 性能-容量平衡 |
| 对比损失 | SupCon vs Triplet vs NT-Xent vs ArcFace | 最优损失函数 |
| 温度系数 | τ=0.05, 0.07, 0.1, 0.2 | 最优温度 |
| 数据增强 | 无增强 vs 基础 vs 全部 | 增强贡献度 |
| 哼唱策略 | 早融合 vs 晚融合 vs 分叉 | 最优融合方式 |
| 曲库抗噪 | 添加噪声曲库干扰 | 抗干扰能力 |
7.6 分布式训练策略
# 使用 PyTorch DDP / FSDP
torchrun --nproc_per_node=8 train.py \
--batch_size 64 \
--model cnn_transformer \
--embed_dim 256 \
--max_duration 10 \
--lr 3e-4 \
--epochs 200 \
--warmup 5000 \
--fp16 \
--dataset_path /data/acr \
--save_interval 10
8. 推理与匹配策略
8.1 推理流程
用户输入 Query (任意时长)
│
├─ 1. 音频预处理 (重采样+通道合并+归一化)
├─ 2. 滑窗切片 (5s 窗口, 2.5s 步长)
│ 如果 Query < 3s: 补充静音到 3s → 拒绝/低置信度
│ 如果 3s ≤ Query ≤ 15s: 单窗口或最多 2 窗口
│ 如果 Query > 15s: 多窗口 5s 滑窗
│
├─ 3. 特征提取 (Mel Spectrogram)
│
├─ 4. 嵌入推理 (模型 forward) → query_embs: (num_windows, 256)
│
├─ 5. 候选检索
│ a) 对每个窗口嵌入做 ANN 检索 → Top-50 × num_windows
│ b) 合并候选并去重 → Top-100
│ c) 精排: 精确相似度计算 → Top-10
│
├─ 6. (Optional) 时间对齐验证
│ - 对 Top-10 候选提取频谱图峰值
│ - 计算与 Query 的时间偏移直方图
│ - 一致性验证 → 更新置信度
│
├─ 7. 置信度校准
│ - 计算 query_embs 与各候选嵌入的最大相似度
│ - Z-score 标准化: score_z = (score - μ_candidates) / σ_candidates
│ - 应用阈值 (score_z > 2.0 或直接阈值 > 0.7)
│
└─ 8. 输出结果
8.2 流式推理 (Streaming)
对于长音频流 (如直播、电台监听),支持流式识别:
音频流输入 (16kHz, 实时)
│
├─ 环形缓冲区 (Ring Buffer, 15s 容量)
├─ 每积累 2.5s 新音频 → 触发一次识别
├─ 取: 缓冲区末尾 5s 作为当前 Query
├─ 嵌入 → ANN 检索 (使用缓存减少重复计算)
├─ 结果缓存与平滑: 连续 N 次命中同一歌曲 → 确认输出
└─ 重复
8.3 拒绝策略 (Rejection)
当 Query 不在库中时,应可靠地拒绝(低误报率):
| 策略 | 实现 |
|---|---|
| 绝对阈值 | max_score < 0.5 → 拒绝 |
| 相对阈值 | max_score - second_score < 0.15 → 拒绝 |
| 分布阈值 | max_score < μ_candidates + 2·σ_candidates → 拒绝 |
| 混合策略 | 三者加权组合 |
| 验证分支 | 增加"非歌分类"头,判断输入是否为有效音乐 |
8.4 缓存策略
Query → 特征 Cache (LRU):
- Key: audio_hash (MD5 of first 2s)
- Value: (query_embedding, timestamp)
- TTL: 30 分钟
- Max size: 10K entries
热门歌曲 Cache:
- 频繁命中的歌曲嵌入常驻内存
- 使用 LFU eviction
9. 使用方法
9.1 安装
# 克隆仓库
git clone <repo-url> && cd acr-engine
# 创建环境
conda create -n acr python=3.11 && conda activate acr
# 安装依赖
pip install -r requirements.txt
# 可选: GPU 版 Faiss
pip install faiss-gpu
# 安装 torchaudio (含 CUDA)
pip install torch torchaudio --index-url https://download.pytorch.org/whl/cu121
9.2 数据导入
# 批量导入歌曲到曲库
python scripts/ingest.py \
--input /data/music_library/ \
--format mp3 \
--recursive \
--metadata metadata.csv
# 导入单曲
python scripts/ingest.py --input song.mp3 --song-id "song_001"
9.3 训练
# 完整训练流程
python train.py \
--config configs/default.yaml \
--data /data/acr/ \
--output /models/acr/ \
--epochs 200 \
--gpus 4
# 继续训练 (从 checkpoint)
python train.py --resume /models/acr/checkpoint_epoch_100.ckpt
# 哼唱微调
python train.py \
--config configs/humming_finetune.yaml \
--resume /models/acr/pretrained.ckpt \
--data /data/humming/
9.4 索引构建
# 构建 Faiss 索引
python scripts/build_index.py \
--model /models/acr/best.ckpt \
--songs /data/songs/ \
--output /index/acr_index.faiss \
--index-type "IVF4096,PQ16" \
--gpu
9.5 API 服务启动
# 启动 REST API (HTTP)
python serve.py \
--model /models/acr/best.ckpt \
--index /index/acr_index.faiss \
--port 8088 \
--workers 4
# 启动 gRPC 服务 (推荐生产使用)
python serve.py --mode grpc --port 50051
# 使用 Docker Compose
docker-compose up -d
9.6 客户端调用
Python 客户端:
import requests
url = "http://localhost:8088/v1/recognize"
files = {"audio": open("query.wav", "rb")}
params = {"top_n": 5, "mode": "auto"}
resp = requests.post(url, files=files, params=params)
print(resp.json())
# {
# "candidates": [
# {"song_id": "...", "title": "...", "artist": "...",
# "confidence": 0.92, "match_type": "bgm"}
# ],
# "processing_time_ms": 45.2
# }
命令行:
# 识别本地音频文件
python cli.py recognize --audio query.mp3 --top-n 5
# 录音识别 (麦克风)
python cli.py recognize --mic --duration 5
# 流式识别 (文件)
python cli.py stream --input live_audio.wav --interval 2.5
9.7 SDK 集成
Python: pip install acr-sdk
Go: go get github.com/xxx/acr-go
Rust: cargo add acr-rs
Java: Maven: com.xxx:acr-client:1.0
Python SDK 使用示例:
from acr_sdk import ACRClient
client = ACRClient(endpoint="localhost:50051", mode="grpc")
# 识别
result = client.recognize("query.wav", mode="humming")
print(f"Song: {result.title}, Confidence: {result.confidence:.2f}")
# 批量入库
client.ingest("/data/new_songs/")
# 删除
client.delete_song("song_001")
10. SOTA 调研与对比
10.1 学术界 SOTA
| 方法 | 年份 | 核心思想 | 哼唱支持 | Recall@1 (BGM) | Recall@1 (Humming) |
|---|---|---|---|---|---|
| Shazam (Wang) | 2003 | 谱峰哈希指纹 | ~85%* | N/A | |
| SoundHound | 2006 | 旋律轮廓+指纹 | ~88%* | ~75%* | |
| Dejavu | 2015 | Shazam 开源实现 | ~82% | N/A | |
| MatchNet | 2018 | Siamese CNN + Triplet | ~90% | N/A | |
| CLAP (LAION) | 2023 | 对比语言-音频预训练 | ~87% | N/A | |
| AudioMAE | 2023 | 掩码自编码器预训练 | ~85% | N/A | |
| Contrastive Audio (Oord) | 2018 | CPC + 对比学习 | ~86% | N/A | |
| HummingBird | 2024 | Chroma + 对比学习 | ~91% | ~82% | |
| Singer (ByteDance) | 2024 | 多任务对比学习 | ~93% | ~85% | |
| Ours | 2026 | CNN-Tfm + SupCon + 哼唱融合 | ≥92% | ≥83% |
* 为公开披露的估计值,非学术基准
10.2 工业界产品对比
| 产品 | 识别速度 | BGM 准确率 | 哼唱准确率 | 曲库规模 | 延迟 |
|---|---|---|---|---|---|
| Shazam (Apple) |
|
|
亿级 | ~2s | |
| SoundHound |
|
|
|
千万级 | ~3s |
| 网易云音乐 |
|
|
|
千万级 | ~2s |
| QQ音乐 |
|
|
|
千万级 | ~2s |
| Google Sound Search |
|
|
|
亿级 | ~3s |
| Ours |
|
|
|
百万级(初期) | ≤0.5s |
10.3 本方案的边际优势 (vs 现有方案)
- 哼唱融合训练:通过专用的哼唱增强和对比学习策略,哼唱识别准确率显著优于纯指纹方案
- 混合架构:CNN-Transformer 比纯 CNN 有更好的序列建模能力,比纯 Transformer 更高效
- 级联检索:ANN 粗筛 + 精确重排 + 时间对齐验证,兼顾速度与精度
- 数据增强系统:全面的增强策略涵盖 BGM、哼唱、录音三大场景
- 可扩展性:增量索引支持动态歌库,无需重训练
11. Roadmap
11.1 阶段规划
Phase 0: 基础建设 (Week 1-2)
├── 环境搭建与依赖配置
├── 数据探索与预处理 pipeline
├── 基础特征提取模块 (Mel, Chroma, CQT)
├── 数据增强模块 (audiomentations pipeline)
└── 基线模型: Shazam 式指纹法 (Dejavu fork)
Phase 1: V1 MVP (Week 3-6)
├── CNN-Transformer 模型实现
├── SupConLoss 训练管线
├── 基础数据收集 (FMA + MUSDB18 + GTZAN)
├── 训练 100K Query-Reference 对的模型
├── Faiss 索引构建 Pipeline
├── REST API + gRPC 服务
└── 本地 CLI 工具
Phase 2: 哼唱支持 (Week 7-10)
├── 哼唱数据收集 (内部录制 + MIR-QBSH)
├── 哼唱增强 Pipeline
├── Chroma 分支 + 旋律轮廓编码
├── 哼唱-原曲对比学习微调
├── 哼唱专用评估集构建
└── 哼唱模式 API 支持
Phase 3: 生产优化 (Week 11-14)
├── 模型量化 (INT8 / FP16)
├── ONNX Runtime / TensorRT 部署
├── 级联检索策略优化
├── 缓存系统实现 (LRU + LFU)
├── 流式识别支持
├── 负载测试与性能调优
├── Docker + K8s 部署配置
└── CI/CD Pipeline
Phase 4: 进阶能力 (Week 15-20)
├── 分布式曲库 (Index Sharding)
├── 多语言歌曲支持
├── 歌曲翻唱/Remix 识别
├── 歌曲定位 (识别到歌曲中具体位置)
├── 歌词时间轴对齐
├── Web dashboard (曲库管理 + 监控)
├── 增量学习 (在线模型更新)
└── 边缘端部署 (移动端/嵌入式)
Phase 5: 持续迭代 (Week 21+)
├── 用户反馈环路
├── A/B 测试框架
├── 模型持续训练 (CT)
├── 数据处理自动化
├── 新 SOTA 方法集成
├── 商业合作接入
└── 合规与版权管理
11.2 里程碑
| 里程碑 | 时间 | 交付物 | 验收标准 |
|---|---|---|---|
| M0: 基础准备 | Week 2 | 开发环境、数据管线 | 增强管线吞吐 ≥ 200/秒 |
| M1: V1 MVP | Week 6 | 可运行的识别引擎 | Recall@1 ≥ 85% (BGM) |
| M2: 哼唱上线 | Week 10 | 哼唱识别能力 | Recall@1 ≥ 75% (Humming) |
| M3: 生产就绪 | Week 14 | 高性能服务 | P50 ≤ 100ms, QPS ≥ 500 |
| M4: 进阶能力 | Week 20 | 企业级平台 | 多场景覆盖, 曲库 100 万+ |
12. Checklist
12.1 数据准备
- 确定数据来源并获取授权
- 下载并组织原始歌曲库 (≥ 100K songs)
- 统一转为 16kHz mono WAV 格式
- 实现数据增强管线 (全部增强策略)
- 生成训练 Query-Reference 对 (≥ 5M pairs)
- 构建哼唱数据集 (≥ 10K 段)
- 分割 train/val/test (80/10/10)
- 验证数据分布多样性 (流派、语言、年代)
- 实现数据加载器 (支持在线增强)
- 数据版本控制 (DVC / HuggingFace Datasets)
12.2 模型开发
- 实现基础 CNN-Transformer 骨干
- 实现训练循环 (SupConLoss + 辅助损失)
- 实现哼唱分支 (Chroma + F0 融合)
- 实现多尺度滑窗匹配
- 实现基准模型 (Shazam + Dejavu)
- 实现对比实验框架
- 超参数搜索 (学习率、温度、嵌入维度等)
- 训练收敛验证
12.3 索引与检索
- 实现 Faiss 索引构建管线
- 实现 ANN + 精确重排的级联检索
- 实现时间对齐验证
- 实现置信度校准与拒绝策略
- 索引增量更新 (增删歌曲)
- 索引持久化与加载优化
12.4 服务部署
- 实现 REST API (FastAPI / Flask)
- 实现 gRPC API
- 模型导出 (ONNX / TorchScript)
- 模型量化 (INT8 / FP16)
- 实现流式识别
- 实现缓存系统
- 负载测试 & 性能调优
- Docker 镜像构建
- Docker Compose / K8s 配置文件
- 监控与告警 (Prometheus + Grafana)
- 日志系统 (结构化日志)
- CI/CD Pipeline
12.5 质量保障
- 单元测试 (核心模块覆盖率 ≥ 80%)
- 集成测试 (端到端识别流程)
- 性能基准测试 (延迟、吞吐、内存)
- 鲁棒性测试 (噪声、压缩、哼唱变化)
- 回归测试 (每次模型更新)
- 评估集标注与维护
- 安全审计 (注入、权限、数据泄露)
12.6 文档与交付
- 设计文档 (本文件)
- API 文档 (Swagger / OpenAPI)
- 部署文档 (Docker, K8s, 环境要求)
- 用户手册 (SDK 使用指南)
- 训练文档 (数据、超参数、实验记录)
- 运维手册 (监控、日志、故障排查)
- 演示 / demos
13. Changelog
[v1.0] — 2026-06-02
Added
- 初始设计文档创建
- 完整架构设计 (双塔对比学习 + Faiss 检索)
- 数据增强策略 (12+ 种操作)
- 哼唱识别模块设计
- SOTA 调研对比表
- Roadmap (Phase 0-5)
- Checklist (6 大模块)
[Planned] — v1.1
Planned
- 实验基准数据
- 训练收敛曲线与指标
- 模型参数量与推理延迟详细报告
- 消融实验结果
- 用户反馈收集结果
[Planned] — v2.0
Planned
- 分布式曲库方案
- 边缘端部署方案
- 在线学习模块
- 歌词时间轴识别
14. Handoff 交付清单
14.1 交付物概要
| 类别 | 交付物 | 责任人 | 验收人 |
|---|---|---|---|
| 设计 | ACR 设计文档 (本文) | 架构师 | 技术负责人 |
| 数据 | 训练数据集 & 评估集 | 数据工程师 | 算法工程师 |
| 代码 | 模型训练代码 | 算法工程师 | 架构师 |
| 代码 | API 服务 & CLI 工具 | 后端工程师 | 架构师 |
| 部署 | Docker / K8s 配置 | DevOps | 运维 |
| 文档 | API 文档 & 用户手册 | 技术写作 | 产品经理 |
| 测试 | 测试报告 & 性能基准 | QA | 技术负责人 |
14.2 验收标准
[ ] 端到端识别流程通过: 输入音频 → 输出正确歌曲
[ ] Recall@1 ≥ 90% (BGM 场景, 干净音频)
[ ] Recall@1 ≥ 80% (哼唱场景)
[ ] P50 延迟 ≤ 100ms (单机器, 百万曲库)
[ ] P99 延迟 ≤ 500ms
[ ] 并发 QPS ≥ 100 (单机器, 4 CPU cores)
[ ] 曲库增量更新 ≤ 1s/曲
[ ] 所有单元测试通过 (覆盖率 ≥ 80%)
[ ] 安全审计无高危漏洞
[ ] 文档完整性审查通过
14.3 风险与缓解
| 风险 | 概率 | 影响 | 缓解措施 |
|---|---|---|---|
| 版权音乐数据获取困难 | 高 | 高 | 优先使用开源数据集; 探索合成数据 |
| 哼唱数据不足 | 中 | 高 | 合成哼唱 + Mid-to-Audio 生成 |
| 噪声下准确率不达标 | 中 | 中 | 更激进的数据增强; 模型集成 |
| 大曲库检索延迟 | 低 | 中 | 多级索引; GPU 加速检索 |
| 模型过拟合 | 低 | 中 | 强正则化; 大规模数据; Dropout |
| 哼唱与 BGM 模式冲突 | 中 | 中 | 双模式 / 级联识别 |
14.4 移交步骤
- 代码移交:所有代码推送到主仓库,PR 审核通过,CI 绿色
- 模型移交:最佳模型 checkpoint + 导出 ONNX/TorchScript
- 数据移交:训练数据、评估数据、数据管线代码
- 索引移交:Faiss 索引文件 + 元数据
- 部署移交:Docker 镜像推送到 Registry,K8s 配置文件就绪
-
文档移交:所有文档整理到
/docs/目录 - 演示移交:运行 demo 脚本,展示端到端识别流程
- 培训移交:对运维/开发人员进行 2 小时技术培训
15. 参考与引用
15.1 学术论文
| 主题 | 论文 | 年份 |
|---|---|---|
| 音频指纹 (Shazam) | Wang, A. "An Industrial-Strength Audio Search Algorithm" | 2003 |
| 对比学习 (SimCLR) | Chen et al. "A Simple Framework for Contrastive Learning" | 2020 |
| 监督对比学习 | Khosla et al. "Supervised Contrastive Learning" | 2020 |
| 频谱图增强 (SpecAug) | Park et al. "SpecAugment: A Simple Augmentation Method" | 2019 |
| 语音谱图 Transformer | Gong et al. "AST: Audio Spectrogram Transformer" | 2021 |
| CLAP | Wu et al. "Large-scale Contrastive Language-Audio Pretraining" | 2023 |
| AudioMAE | Huang et al. "Masked Autoencoders that Listen" | 2023 |
| CPC for Audio | Oord et al. "Representation Learning with Contrastive Predictive Coding" | 2018 |
| 哼唱识别综述 | Sharma et al. "Query-by-Humming: A Survey" | 2023 |
| CREPE | Kim et al. "CREPE: A Convolutional Representation for Pitch Estimation" | 2018 |
15.2 开源项目
| 项目 | 说明 | 链接 |
|---|---|---|
| Dejavu | Shazam 指纹法 Python 实现 | https://github.com/worldveil/dejavu |
| Faiss | 向量相似度搜索库 (Meta) | https://github.com/facebookresearch/faiss |
| CLAP | 对比语言-音频预训练 (LAION) | https://github.com/LAION-AI/CLAP |
| torchaudio | PyTorch 音频工具包 | https://github.com/pytorch/audio |
| audiomentations | 音频数据增强库 | https://github.com/iver56/audiomentations |
| librosa | 音频分析库 | https://github.com/librosa/librosa |
| marsyas | 音频处理框架 | https://github.com/marsyas/marsyas |
| Essentia | 音频分析库 (UPF) | https://github.com/MTG/essentia |
15.3 数据集
| 数据集 | 规模 | 用途 | 许可 |
|---|---|---|---|
| FMA (Free Music Archive) | 106,574 曲 | 基础歌曲库 | CC |
| MUSDB18 | 150 曲 (多轨) | 音源分离 | 研究 |
| GTZAN | 1,000 曲 | 流派分类 (基线) | 研究 |
| MIR-QBSH | ~4,800 哼唱 | 哼唱识别 | 研究 |
| Medley-solos-DB | 21,574 片段 | 音色分析 | CC |
| AudioSet (Google) | 2M+ 片段 | 预训练/多任务 | YouTube |
附录 A: 快速开始 Demo
#!/usr/bin/env python
"""ACR Engine Quick Demo"""
from acr_engine import ACRPipeline
# 初始化
pipeline = ACRPipeline(
model_path="models/acr/best.ckpt",
index_path="index/acr_index.faiss",
mode="auto"
)
# 批量导入
pipeline.ingest_directory("data/samples/")
# 识别
for query_path in ["query_bgm.wav", "query_hum.wav", "query_noisy.wav"]:
result = pipeline.recognize(query_path)
print(f"{query_path}: {result.title} ({result.confidence:.2%})")
附录 B: 配置模板 (configs/default.yaml)
model:
name: cnn_transformer
embed_dim: 256
backbone:
cnn_channels: [32, 64, 128, 256]
transformer_layers: 4
nhead: 8
dim_feedforward: 1024
humming_branch:
enabled: true
fusion: late
chroma_bins: 12
f0_embed_dim: 64
data:
sample_rate: 16000
n_mels: 128
n_fft: 1024
hop_length: 512
max_duration: 10.0
min_duration: 3.0
window_size: 5.0
window_stride: 2.5
augmentation:
noise:
enable: true
snr_range: [5, 30]
pitch_shift:
enable: true
semitones_range: [-6, 6]
time_stretch:
enable: true
rate_range: [0.85, 1.15]
mp3_compression:
enable: true
bitrate_range: [32, 128]
spec_augment:
enable: true
time_mask_max: 50
freq_mask_max: 16
training:
batch_size: 512
epochs: 200
lr: 0.0003
weight_decay: 0.01
warmup_steps: 5000
temperature: 0.07
loss:
supcon_weight: 1.0
arcface_weight: 0.3
triplet_weight: 0.1
optimizer: adamw
scheduler: cosine
mixed_precision: bf16
gradient_clip: 1.0
index:
type: "IVF4096,PQ16"
metric: cosine
train_on_gpu: true
nprobe: 64
serving:
host: "0.0.0.0"
port: 8088
workers: 4
max_query_duration: 30.0
cache_size: 10000
reject_threshold: 0.5
top_n: 5
logging:
level: INFO
format: json
output: stdout