## 背景
恩谱识别已走 **结构优先** 路线(`ENPU_PIPELINE_MODE=structure`):
| 层 | 职责(现状) |
|----|----------------|
| L1 | 页面级:标题、调号/拍号区、主谱面 ROI |
| L2 | 主谱面谱行(systems/rows),旋律带与和弦/歌词绑定 |
| L3 | 行内纵向 **splits**(主存)→ 派生 measures |
| L4–L5 | 小节内候选与音高 OCR 等(本 Issue **不做**) |
当前 L1–L3 主要依赖 OpenCV / 几何与规则,在真实敬拜谱上仍不稳定。已具备:
- 分层识别与桌面按层编辑(含 L3 拖线等)
- 结构结果可进工程 / API(`structure.items[]`、`structure.barlines[]`、IR 等)
- 手动框/线作为 GT 做评估与单层调参的方向
**缺口:** 尚无「以恩谱工程/结构标注为标准」的 **L1–L3 监督学习数据规范** 与 **独立训练 Framework**,无法系统收集数据并训练可直接输出 L1–L3 布局的 OMR 模型。
本 Issue 目标:打通 **标准训练数据 ← 现有工程格式**,设计 **L1–L3 模型技术方案**,并搭建 **新的训练 App(framework)**(与 `core`/`desktop` 解耦)。
---
## 目标
1. **总结并固化** 现有恩谱工程/结构相关文件格式,形成 **L1–L3 训练数据标准**(含必填字段、坐标约定、与 Score v0.1 的边界)。
2. **设计技术方案**:任务定义、模型输入输出、损失与指标、数据流、与现有 `structure` 管线的对接方式。
3. **搭建训练 Framework(新 App)**:数据集管理、训练/验证循环、导出推理权重、与恩谱 core 集成的最小接口(可后置)。
### 非目标(本 Issue)
- 训练完整 L4–L5 / 端到端音高大模型
- 替换桌面产品为训练工具
- 必须一次超过现有几何基线(先跑通数据→训练→推理闭环)
- 在本 Issue 内完成大规模标注众包
---
## 任务 1:总结现有工程格式 → 训练数据标准
### 1.1 需要盘点的现有产物
| 来源 | 路径/概念 | 与训练的关系 |
|------|-----------|----------------|
| Score 语义 | `docs/jianpu-schema.md`、`enpu-score-v0.1` | **不是** L1–L3 几何 GT;仅作页级元数据(title/key/time)可选对齐 |
| 结构 IR | `core/app/pipeline/structure/ir.py` 等 | PageLayout / StaffSystem / SplitLine / Measure… 布局真源候选 |
| API structure | `structure.items[]`(层、label、box)、`structure.barlines[]`(L3 线) | 与桌面叠图、编辑、rerun 一致,优先作为导出标准 |
| 工程文件 | `.enpu.json` 及结构缓存字段(以仓库实际为准) | 人工校正后的 **可版本化样本** |
| 评测集 | `samples/eval`、manual GT | 可迁移为 val 集,需统一到同一 schema |
**交付物:** `docs/train/l1-l3-data-spec.md`(或等价)
内容至少包括:
1. **一张样本的目录/文件约定**(图 + 标注 JSON)
2. **L1 / L2 / L3 字段表**(名称、类型、必选、坐标系)
3. **与现有 `structure` / IR 的字段映射表**(工程 → 训练样本)
4. **坐标约定**:全图像素、原点、预处理后是否回写(与 `architecture-structure-first` 一致)
5. **L3 语义**:主存 `splits[]`(有序 x),`measures` 仅派生
6. **负例/忽略区** 约定(页眉、纯歌词行是否标)
7. **版本号** `layout_schema_version`(与 `score.schema_version` 分离)
### 1.2 建议的训练样本逻辑结构(草案,任务 1 中定稿)
```text
Sample {
layout_schema_version: "0.1",
image: { path | hash, width, height },
meta?: { title, key, time_signature, source },
l1: {
title?: BBox,
key_time?: BBox,
score_region: BBox
},
l2: {
systems: [{ id, bbox, kind?: "pitch_row" | ... }]
},
l3: {
# 按 system 组织
rows: [{
system_id,
splits: [{ id, x, y1?, y2?, source: "user"|"detect" }]
}]
},
# measures 不强制存盘,可由 L2.bbox + splits 计算;若存盘需可校验一致
}
1.3 从恩谱工程导出
- 脚本:
scripts/export_layout_gt.py(名可改)
- 输入:工程 /
base_structure + 原图
- 输出:符合 data-spec 的样本
- 校验:splits 单调、落在 L2 内、派生 measure 数 = splits+1 规则等
验收(任务 1): 文档合并 + 至少 1 个真实工程 导出为标准样本并通过校验器。
任务 2:技术方案设计
2.1 任务定义(L1–L3 only)
| 子任务 |
输入 |
输出 |
类型建议 |
| L1 |
全图 |
score_region(+ 可选 title/key_time) |
检测 / 分割 |
| L2 |
全图或 score ROI |
水平谱行 systems[] |
行检测 / 多框检测 |
| L3 |
单行 ROI 或全图+行条件 |
该行 splits 的 x(或竖线 segment) |
线检测 / 关键点回归 / 序列 |
原则:多任务可同骨干分头,也可分阶段三模型;首版优先 可训通、可导出 ONNX/Torch,精度第二。
2.2 推荐技术路线(可在设计文档中定一种主路径)
主路径 A(务实)
- Backbone:轻量 CNN(或现成检测骨干)
- L1/L2:目标检测(类别 =
score / system / …)或语义分割再提框
- L3:在 L2 裁切上做 竖线热力图 / 1D 投影序列标签 或关键点 x 回归
- 后处理:NMS、最小间距、与 data-spec 一致的 splits 规范化
主路径 B(若数据极少)
- 先合成布局数据(印刷简谱渲染 → 自动 L1–L3 GT)预训练
- 再用恩谱工程导出的真实 GT 微调
2.3 损失与指标
- L1/L2:IoU、mAP@0.5,score_region 召回优先
- L3:
- 数量:
|n_pred - n_gt|、exact rate
- 位置:匹配后
mean_abs_x_error(与现有 L3 线级评估一致)
- 禁止只用派生 measure 框 IoU 作为唯一主指标
2.4 与恩谱 core 对接
训练 App 导出 weights
→ core 推理适配层(structure 模式可切换 engine=learned_l1l3)
→ 输出仍转为现有 structure.items / barlines / IR
→ 桌面叠图与编辑不改协议
几何规则管线保留为 fallback;learned 与 rule 可对比评测。
2.5 数据与合规
- 训练图仅限授权/自有/可公开 samples;商业谱不进公开集
- 私有 GT 目录约定(如
samples/private/layout/)不入库明文
交付物: docs/train/l1-l3-model-design.md(架构图、头设计、指标、数据流、风险)
验收(任务 2): 设计文档 review 通过;选定 MVP 模型范围(建议:L2 行框 + L3 行内 splits,L1 score_region 可一并或二期)。
任务 3:搭建训练 Framework(新 App)
3.1 定位
- 新应用/新目录(建议
train/ 或独立 repo EnPu-train),不塞进 Tauri 桌面逻辑。
- 职责:数据集、训练、验证、导出;不负责完整敬拜编辑产品功能。
3.2 建议目录
train/ # 或独立仓库
README.md
configs/ # 数据路径、超参、模型
enpu_train/
data/ # Dataset,读 data-spec JSON
models/ # L1L3 网络定义
losses/
metrics/ # IoU、split count、x error
engine/ # train / eval loop
export/ # ONNX / state_dict
scripts/
export_from_enpu_project.py
train.py
eval.py
tests/
3.3 MVP 功能清单
3.4 技术选型建议(可改)
- Python 3.10+、PyTorch(与后续 ONNX 导出常见路径一致)
- 配置 YAML;日志 JSON/TensorBoard 任选
- 不强制上检测大框架;数据少时宁可模型小、管线清
验收(任务 3):
- 使用 ≥1 张真实导出样本 + 若干合成/增强 能完成一次 train epoch 不报错。
- val 脚本输出 L2 框 IoU 或 L3 x 误差中的至少一类硬指标。
- 文档说明与恩谱
structure 字段对应关系。
总任务拆分与顺序
| 顺序 |
任务 |
产出 |
| P0 |
任务 1 格式总结 + 校验 + 导出脚本 |
l1-l3-data-spec.md、样例样本 |
| P0 |
任务 2 技术方案设计定稿 |
l1-l3-model-design.md |
| P1 |
任务 3 Framework 骨架 + toy 训练 |
train/ App |
| P2 |
合成数据 / 真实集扩充、core 推理插件 |
可另开 Issue |
依赖:任务 3 依赖任务 1 的 schema 冻结;任务 2 与任务 1 可并行初稿,但实现以冻结的 data-spec 为准。
验收标准(整 Issue)
- 标准:存在正式 data-spec,且从现有恩谱结构/工程 导出 → 校验通过 的路径可复现。
- 设计:模型输入输出与 L1–L3 语义一致(L3 为 splits 而非无约束自由矩形主存)。
- Framework:独立训练 App 可安装依赖并完成一次最小训练与评估。
- 边界清晰:Score v0.1 语义与 layout GT 分离;本阶段不承诺 L4–L5 学习。
风险
| 风险 |
缓解 |
| 工程里 layout 字段不统一 |
任务 1 先映射表 + 校验器,再训 |
| 真实标注量少 |
合成预训 + 少样本微调;先 L3 行内问题 |
| 与几何管线双轨 |
统一输出 structure schema;A/B 评测 |
| 训练 App 与 core 强耦合 |
仅通过 data-spec 与权重文件交换 |
相关
docs/architecture-structure-first.md(L1–L5、IR、structure 序列化)
docs/jianpu-schema.md(Score v0.1,无布局几何)
docs/l3-split-model.md(若存在)
- L3 分割线模型 / 线级评估(数量 + x 偏差)
- 单层调优与手动 GT 编辑
docs/eval-baseline.md
建议的子 Issue 拆分(可选)
docs(train): L1–L3 layout data-spec 与工程导出
docs(train): L1–L3 学习模型技术方案
feat(train): 训练 Framework 骨架与 toy 训练
1.3 从恩谱工程导出
scripts/export_layout_gt.py(名可改)base_structure+ 原图验收(任务 1): 文档合并 + 至少 1 个真实工程 导出为标准样本并通过校验器。
任务 2:技术方案设计
2.1 任务定义(L1–L3 only)
原则:多任务可同骨干分头,也可分阶段三模型;首版优先 可训通、可导出 ONNX/Torch,精度第二。
2.2 推荐技术路线(可在设计文档中定一种主路径)
主路径 A(务实)
score/system/ …)或语义分割再提框主路径 B(若数据极少)
2.3 损失与指标
|n_pred - n_gt|、exact ratemean_abs_x_error(与现有 L3 线级评估一致)2.4 与恩谱 core 对接
几何规则管线保留为 fallback;learned 与 rule 可对比评测。
2.5 数据与合规
samples/private/layout/)不入库明文交付物:
docs/train/l1-l3-model-design.md(架构图、头设计、指标、数据流、风险)验收(任务 2): 设计文档 review 通过;选定 MVP 模型范围(建议:L2 行框 + L3 行内 splits,L1 score_region 可一并或二期)。
任务 3:搭建训练 Framework(新 App)
3.1 定位
train/或独立 repoEnPu-train),不塞进 Tauri 桌面逻辑。3.2 建议目录
3.3 MVP 功能清单
train.py:loss 曲线、ckpt、val 指标eval.py:在 hold-out 上输出与恩谱 L3 线级指标同构的报告3.4 技术选型建议(可改)
验收(任务 3):
structure字段对应关系。总任务拆分与顺序
l1-l3-data-spec.md、样例样本l1-l3-model-design.mdtrain/App依赖:任务 3 依赖任务 1 的 schema 冻结;任务 2 与任务 1 可并行初稿,但实现以冻结的 data-spec 为准。
验收标准(整 Issue)
风险
相关
docs/architecture-structure-first.md(L1–L5、IR、structure 序列化)docs/jianpu-schema.md(Score v0.1,无布局几何)docs/l3-split-model.md(若存在)docs/eval-baseline.md建议的子 Issue 拆分(可选)
docs(train): L1–L3 layout data-spec 与工程导出docs(train): L1–L3 学习模型技术方案feat(train): 训练 Framework 骨架与 toy 训练