Name Last Update
composition_dedup Loading commit data...
dedup_server Loading commit data...
lyric_dedup Loading commit data...
results Loading commit data...
scripts Loading commit data...
test_api Loading commit data...
tests Loading commit data...
.gitignore Loading commit data...
.python-version Loading commit data...
POSTGRES_MIGRATION.md Loading commit data...
README.md Loading commit data...
TEST_WORKFLOW.md Loading commit data...
main.py Loading commit data...
pyproject.toml Loading commit data...
records.csv Loading commit data...
records2.csv Loading commit data...
records_test.csv Loading commit data...
requirements.txt Loading commit data...
upload_acrcloud_state.json Loading commit data...
upload_dna_state.json Loading commit data...
uv.lock Loading commit data...
性能瓶颈详细分析.md Loading commit data...
曲去重测试样本类型.md Loading commit data...
歌曲作曲结构去重系统V1实施方案.md Loading commit data...
歌曲作曲结构去重系统V2优化方案.md Loading commit data...

歌词查重系统

这是一个使用 PostgreSQL 作为数据存储和候选召回层的歌词查重项目。Python 侧只负责歌词规范化、候选打分和最终判定,不再构建或加载 .pkl 本地索引。

架构

PostgreSQL:
  lyrics               保存原始歌词、规范化文本、原文/翻译文本、exact_hash
  lyric_lines          保存规范化歌词行和 line_hash
  exact_hash 索引      精确重复召回
  pg_trgm 索引         可选的近似文本召回
  line_hash 索引       行级重合召回

Python:
  normalize_lyrics     歌词清洗、时间戳/平台噪声处理、繁简转换、翻译行拆分
  DuplicateChecker     只对 PostgreSQL 召回的候选打分和排序
  决策规则              输出 duplicate / review / new

核心原则:

数据库负责召回候选。
Python 负责最终判断。
不再使用 pickle、本地 MinHash 索引或 outputs/indexes/*.pkl 作为生产链路。

安装依赖

python -m pip install -r requirements.txt

初始化 PostgreSQL

创建数据库:

createdb lyric_dedup

初始化表结构和索引:

python scripts/init_postgres.py \
  --dsn postgresql:///lyric_dedup

会创建:

lyrics
lyric_lines
pg_trgm extension
exact_hash / primary_text_trgm / line_hash 索引

导入曲库

python scripts/import_library_postgres.py \
  --dsn postgresql:///lyric_dedup \
  --lyrics-dir data/library

导入脚本会:

1. 扫描 data/library 下的 .lrc / .txt。
2. 读取并规范化歌词。
3. 写入 lyrics 和 lyric_lines。
4. 默认对 exact_hash 完全一致的记录做 soft delete,只保留质量更高的一条。
5. 输出重复报告到 outputs/results/postgres_exact_duplicates.csv。

如果只导入、不做 exact 去重:

python scripts/import_library_postgres.py \
  --dsn postgresql:///lyric_dedup \
  --lyrics-dir data/library \
  --skip-dedup-exact

检查单个歌词文件

python -m lyric_dedup.cli check-file \
  --dsn postgresql:///lyric_dedup \
  --file data/incoming/new_song.lrc

常用参数:

--recall-limit             每个 PostgreSQL 召回层最多返回多少候选
--max-candidates           最终返回和排序多少候选
--enable-trgm              启用 pg_trgm 近似文本召回
--trgm-threshold           pg_trgm similarity 阈值
--statement-timeout-ms     PostgreSQL statement_timeout

返回字段:

decision         duplicate / review / new
duplicate        仅 decision=duplicate 时为 true,review/new 时为 false
confidence       当前判定置信度
reason           中文判定原因
candidate_count  参与最终排序的候选数

启动 API

export LYRIC_DEDUP_DSN=postgresql:///lyric_dedup
uvicorn lyric_dedup_server.app:app --host 0.0.0.0 --port 8000

接口:

POST /api/v1/check

请求示例:

{
  "url": "https://example.com/song.lrc",
  "title": "Song Title",
  "artist": "Artist"
}

服务会下载 URL 对应的 .lrc / .txt 文件,使用 PostgreSQL 召回候选并判定。若结果为 new,且请求带有 URL,服务会把这首新歌词写入 PostgreSQL。

生成评估集

常规生产口径:

python -m lyric_dedup.cli generate-eval-set \
  --library-dir data/library \
  --lyrics-dir data/generated_eval/incoming \
  --csv data/generated_eval/eval_5000.csv \
  --size 5000 \
  --positive-ratio 0.3

hard 业务边界口径:

python -m lyric_dedup.cli generate-eval-set \
  --profile hard \
  --library-dir data/library \
  --lyrics-dir data/generated_eval/hard_incoming \
  --csv data/generated_eval/eval_hard_5000.csv \
  --size 5000 \
  --positive-ratio 0.3

生成器只写:

评估 CSV
样本歌词文件
manifest.json

不会再生成 .index.pkl。评估时由 PostgreSQL 召回候选,并根据 CSV 里的 source_record_id 排除 holdout 样本自身。

使用 PostgreSQL 评估

严格自动拦截口径:只有 duplicate 算预测应去重。

python scripts/evaluate_postgres.py \
  --dsn postgresql:///lyric_dedup \
  --csv data/generated_eval/eval_hard_5000.csv \
  --base-dir data/generated_eval \
  --out outputs/results/postgres_eval_hard_5000.csv

可疑样本召回口径:duplicatereview 都算抓到。

python scripts/evaluate_postgres.py \
  --dsn postgresql:///lyric_dedup \
  --csv data/generated_eval/eval_hard_5000.csv \
  --base-dir data/generated_eval \
  --positive-decisions duplicate,review \
  --out outputs/results/postgres_eval_hard_5000_review_positive.csv

评估会生成:

outputs/results/*.csv
outputs/results/*.csv.summary.json

summary 重点看:

precision       自动拦截准确率,重点关注 false_positive
recall          应去重样本召回率,重点关注 false_negative
f1              precision 和 recall 的综合指标
duplicate/review/new  三类判定分布