71 lines
7.1 KiB
Markdown
71 lines
7.1 KiB
Markdown
# Q1 Unified Alignment Adapter:统一数据接口与审计
|
||
|
||
## 目的与边界
|
||
|
||
Q1 现在对外提供一个 `Q1AlignmentAdapter` 和一种 `AlignedMultimodalSample`。Q2、后续 Q3/Q4 使用相同的 `features / observed / coverage / provenance / metadata` 字段读取对齐结果。对齐的**坐标证据**仍必须区分:有原视频、音频与词级时间记录的 Q1 样本采用 `physical`;官方 `unaligned_50.pkl` 只有三条有序特征序列和长度字段,采用 `relative`。两者进入同一个区间求交投影核,但 `relative` 的位置绝不是秒、词边界或物理同步真值。
|
||
|
||
本次只重构数据接口。Q1 原有的词、CTC、视频 PTS、音频采样定位、0.1 秒密集主视图和查询矩阵仍由原生特征包保存;既有 `features_v2/` 文件没有重建。Q2 的结构、损失、超参数、权重和历史指标没有重训或改选。
|
||
|
||
## 共同投影核
|
||
|
||
给定来源区间 `J_r`、目标区间 `I_t`、观测标记 `O_r,d` 和来源质量 `q_r`,核先计算交长 `h_tr = |I_t ∩ J_r|`,再用 `h_tr q_r O_r,d` 对特征逐维加权平均。输出零值但 `observed=false` 表示目标格没有证据;不插值、不移动来源次序。目标格的 `coverage` 单独用 `h_tr O_r` 除以目标宽度,**不乘质量**。`quality_mean` 与 `quality_available_fraction` 分开返回;缺质量字段的 Relative 输入使用单位权重并明确标为不可用。
|
||
|
||
`source_weights` 是目标格到原始来源行的 CSR 权重矩阵:有观测的行和为 1,无观测的行全零。`source_count`、`first_source`、`last_source` 用于快速审计;`observed_dimensions` 与 `coverage_dimensions` 保留物理特征的逐维有效性。`source_span` 是参与构造坐标的跨度,`original_source_length` 是原数组行数。来源区间、目标区间由 [`adapter/coordinates.py`](adapter/coordinates.py) 的物理与相对构造函数建立,数值汇聚只有 [`adapter/projection.py`](adapter/projection.py) 一处实现。
|
||
|
||
| 模式 | 来源区间 | 50 个目标区间 | 可以声称的对应关系 |
|
||
|---|---|---|---|
|
||
| `physical` | Q1 保存的词、音频窗、视频帧真实时间区间 | `[tD/50,(t+1)D/50)`,`D` 为真实片段时长 | 可回查原素材时间与来源行;原有 0.1 秒视图仍单独保存 |
|
||
| `relative` | 每模态独立的 `[r/L,(r+1)/L)` | `[t/50,(t+1)/50)` | 仅表示各自序列中的相对进程,不能声称秒级同步 |
|
||
|
||
`mode="auto"` 只依据输入证据:Q1 物理源须有有效 `duration_s`、`media.status=ok`、源视频 SHA-256 和三模态原生时间区间;官方未对齐行须通过 `from_unaligned_record` 确认顺序、注意力掩码和长度。缺证据或物理证据损坏会报错,不根据数组是 50 行还是 500 行猜模式,也不在物理失败时悄悄退化为 Relative。
|
||
|
||
## 官方未对齐数据的来源规则
|
||
|
||
文本 `L` 取 `text_bert` 注意力掩码的连续有效前缀;掩码外的非零填充向量不参与投影。音频 `L` 取 `audio_lengths`,其后若仍有非零观测行则报错。视觉 `L=max(vision_lengths, 最后非零行位置+1)`;发现冲突时保留已知观测行,并设置 `length_conflict` 和 `tail_ambiguous`。全维零行代表该官方预计算序列中的未观测行,单个特征维度的零值不代表缺失。每个模态先各自规范化到 `[0,1)`,因此同一目标格只是一种有明确假设的输入组织方式。
|
||
|
||
## 标准接口
|
||
|
||
```python
|
||
import sys
|
||
sys.path.insert(0, "math/Q1")
|
||
from adapter import Q1AlignmentAdapter
|
||
|
||
adapter = Q1AlignmentAdapter(target_steps=50)
|
||
physical = adapter.from_q1_sample("-iRBcNs9oI8/8")
|
||
|
||
# split 是官方 unaligned_50.pkl 的 train、valid 或 test 字典
|
||
relative = adapter.from_unaligned_record(split, index=0)
|
||
features, mask = relative.q2_arrays()
|
||
assert features["text"].shape == (50, 768)
|
||
assert mask.shape == (50, 3)
|
||
|
||
weights = relative.provenance["audio"].source_weights.getrow(10)
|
||
original_rows, contributions = weights.indices, weights.data
|
||
```
|
||
|
||
`features[m]` 为 `(50,d)` float32,`observed[m]` 与 `coverage[m]` 各为 `(50,)`;`quality_mean[m]` 和 `quality_available_fraction[m]` 也按目标位置给出。`provenance[m]` 保存 CSR、来源跨度、原数组长度、官方报告长度、冲突标记和逐维有效性。`metadata` 明确写出 `coordinate_mode`、`coordinate_unit`、`physical_time_alignment`、`target_steps`、质量字段可用性、版本及样本 ID。Q2 的 [`data.py`](../Q2/data.py) 仅调用统一接口的 `adapt_official_split`,再沿用已有 `SplitData` 和模型输入;旧 [`unaligned_adapter.py`](unaligned_adapter.py) 只保留委托到新接口的兼容入口。
|
||
|
||
## 全量审计与兼容性
|
||
|
||
审计覆盖官方未对齐 train/valid/test 全部 **3,395 / 728 / 727,共 4,850 条**,并读取 Q1 物理样本 100 条。新 Relative 结果与重构前冻结的基线比较:每个划分的文本、音频、视觉 float32 数组和 `(N,50,3)` mask 的 SHA-256 **全部逐字节一致**。各划分的有效长度分布、`L<K / L=K / L>K` 数量、目标观测格及覆盖率分布、文本掩码外非零行、长度冲突、全缺失模态与目标格、非有限值、来源权重行和误差、输出形状及坐标模式均见 [`full_audit.json`](results/unified_adapter/full_audit.json)。冻结基线和直接对照分别见 [`legacy_relative_baseline.json`](results/unified_adapter/legacy_relative_baseline.json) 与 [`equivalence_report.json`](results/unified_adapter/equivalence_report.json)。
|
||
|
||
| 划分 | 样本 | 视觉长度冲突及尾部歧义 | 文本掩码外非零行 | 视觉无观测目标格 | 视觉全缺失样本 | 非有限输出 |
|
||
|---|---:|---:|---:|---:|---:|---:|
|
||
| train | 3,395 | 618 | 86,078 | 6,448 | 30 | 0 |
|
||
| valid | 728 | 141 | 17,772 | 1,085 | 0 | 0 |
|
||
| test | 727 | 131 | 18,041 | 1,316 | 8 | 0 |
|
||
|
||
物理样本 100/100 均进入 `physical`,三模态均为 50 步、无非有限输出,来源权重最大行和误差 `2.39e-7`。Relative 来源权重最大行和误差 `1.20e-7`。视觉长度冲突来自官方长度与非零行不一致,无法用当前文件证明尾部的真实视频时长。审计没有把索引覆盖率或质量回退值解释为检测质量或物理时间准确率。
|
||
|
||
Q2 的真实加载入口已完成**只读冒烟检查**:三个划分均保留原样本数及标签,输出文本 `(N,50,768)`、音频 `(N,50,74)`、视觉 `(N,50,35)`、掩码 `(N,50,3)`;记录见 [`q2_smoke.json`](results/unified_adapter/q2_smoke.json)。16 个单元测试涵盖 `L=K`、展开、聚合、部分/全部缺失、文本填充、音频/视觉长度冲突、来源权重守恒、两类坐标、Q2 形状、非有限值、全量旧新等价以及 `auto` 证据拒绝规则。
|
||
|
||
在仓库根目录复核:
|
||
|
||
```bash
|
||
uv run --project math/Q1 python -m unittest discover -s math/Q1/tests -p 'test_unified_adapter.py' -v
|
||
uv run --project math/Q1 python math/Q1/audit_unified_adapter.py
|
||
uv run --project math/Q1 python math/Q1/smoke_q2_adapter.py
|
||
```
|
||
|
||
附件三的未对齐版仍缺少这里所需的 `text`、`text_bert`、`audio_lengths`、`vision_lengths`,不能在没有可信缺失/长度元数据时自动套用这个 Relative 构造器。相关限制和原理细节见 [`UNALIGNED_ADAPTER.md`](UNALIGNED_ADAPTER.md)。
|