Natural Memory NM2.1: 记忆路由器分叉、数据集缺陷修复与全轴评测证据

- 引入 MemoryRouterXL 与 v5/v6 流式多线程训练/编码管线
- 修复 prepare_memory_router_dataset 候选池重建缺陷(mega 家族 3568x 加速,输出逐字节相同)
- 修复 v5 被破坏的拒答与多跳标签(train 未知样本 319 -> 16319,multi_hop 平均正例 1.00 -> 2.00)
- 同存储预算下 V2-128 v6 逐轴 22/22 通过:Top-1 41.12% -> 94.62%,未知拒答 0.00% -> 100.00%
- 记录三条被实测推翻的显然优化(logits_to_keep=1 反而慢 55%、XL 容量未带来收益)
- 记忆手术跨架构可移植性 14/14,读写关闭时与原生模型逐位相同
This commit is contained in:
WpyQwq
2026-09-19 11:11:31 +08:00
commit 643e22ecb9
484 changed files with 306821 additions and 0 deletions
+77
View File
@@ -0,0 +1,77 @@
# 真实形态语料的结果:此前的增益基本不迁移
## 1. 为什么先做这件事
项目里所有数字此前都建立在**模板语料**上:单一句式("我的X是 VAL-…。")、单一实体(user)、
24 个属性、没有更新冲突/多跳链/噪声/多实体。这些数字内部一致、可复现,但**没有一个能预测真实文本上的表现**。
现在有了 `make_realistic_memory_eval.py`:200 条 / 8 类别(175 可回答 + 25 未知),覆盖
多实体(user/张三/李工/项目 Alpha/客户 Beta)、别名改写、更新冲突、多跳链、近邻属性干扰、
噪声上下文、长事实、未知属性。
**语料本身修过一轮**:第一版有 3 个类别是我构造错的(自相矛盾的别名集、把"未知属性"的句式用在了候选上、
多跳答案靠拼接必然出现),那些低分/满分都不是模型的问题。修正后重测,下面的数字来自修正版。
## 2. 结果(每类 25 条,同一份运行时,只有模型包不同)
| 类别 | 原版 NM2 | **NM2.1** | 差值 |
|---|---:|---:|---:|
| alias_paraphrase(别名改写) | **92.00%** | 80.00% | **−12.00pp** |
| long_fact(长事实) | 76.00% | **84.00%** | +8.00pp |
| multi_entity(多实体) | 92.00% | 92.00% | 0 |
| multi_hop(多跳) | **40.00%** | 32.00% | **−8.00pp** |
| near_miss(近邻干扰) | **52.00%** | 48.00% | −4.00pp |
| noise_context(噪声上下文) | 80.00% | **84.00%** | +4.00pp |
| **unknown_attribute(未知属性)** | **20.00%** | **8.00%** | **−12.00pp** |
| update_conflict(更新冲突) | 64.00% | **72.00%** | +8.00pp |
| **总体(200)** | **64.50%** | **62.50%** | **−2.00pp** |
| 可回答正确率(175) | 70.86% | 70.29% | −0.57pp |
| **未知拒答率(25)** | **20.00%** | **8.00%** | **−12.00pp** |
| 已知问题被误拒率 | 2.86% | 2.29% | −0.57pp |
## 3. 结论:此前的增益在真实形态数据上不复现
| 此前的说法(模板语料) | 真实形态语料上的实际结果 |
|---|---|
| NM2.1 总体 **+6.50pp** | **−2.00pp**(200 条) |
| 可回答 **+7.43pp** | **−0.57pp**(175 条) |
| **未知泄漏 75.00% → 0.00%** | 覆盖门在真实数据上**根本不生效**;未知拒答率 **8.00%**,**低于原版的 20.00%** |
| 零字面重叠改写 **+25.00pp**(16 条) | 别名改写 **−12.00pp**(25 条) |
### 原因(已定位,不是猜测)
1. **覆盖门在真实数据上是关闭的**(这是设计行为):它的词表是模板语料的 24 个属性,而真实事实里的属性
是"张三的值班电话""项目 Alpha 的接口版本号"这类实体前缀属性,属于词表之外 → 自门控判定"词表未被填充"
→ 直接旁路。所以**那个 0.00% 泄漏只在它的专属域里成立**,我在报告里已标注为域内有效,现在有了确凿度量。
2. **路由器替换的收益是分布相关的**:在噪声上下文 / 长事实 / 更新冲突上 +4~+8pp,但在别名改写 / 多跳 /
近邻干扰上 −4~−12pp。模板语料的分布恰好放大了前者的收益。
3. **多跳与近邻在修正后确实变难了**:多跳 40.00% / 32.00%,近邻 52.00% / 48.00% —— 这两个类别的真实水平
远低于我此前用残缺构造测出的 100.00%。
### 统计口径提醒
每类只有 25 条,**1 个用例 = 4.00pp**;总体的 −2.00pp 是 4 个用例,未知的 −12.00pp 是 5 vs 2 个用例。
因此逐类差值都在噪声量级,**不能说"NM2.1 更差",只能说"没有可测出的优势"** —— 与此前"大幅超越"的
表述形成明确对照。
## 4. 这对下一步意味着什么
**优先级必须重排。** 在真实形态数据上,最重要的三个短板是:
1. **多跳只有 32~40%**、**近邻干扰 48~52%** —— 这是检索/排序的真实水平,之前被模板语料掩盖了。
2. **未知拒答 8.00%(原版 20.00%)** —— 覆盖机制必须能处理**从库里动态生成的属性词表**
(实体前缀属性),而不是固定的 24 个;这正是我此前列为"数据工程"的那一项,现在它的优先级最高。
3. **别名改写 80.00%** —— 说明改写泛化能力其实不差(80%),但比原版低 12.00pp,`REPLAY` 的微调在这里
是负收益,需要重做数据配比。
**并且必须在真实形态数据上重新训练**:现在的 v6 数据集本身也是模板生成的,所以"冻结评测集 22/22"
只是"在这个生成分布上 22/22"。要拿到真实可用的路由器,训练集本身得换成真实形态。
## 5. 产物
| 文件 | 内容 |
|---|---|
| `make_realistic_memory_eval.py` | 语料生成器(8 类别,含三处构造 bug 的修复注释) |
| `data/realistic_eval.jsonl` + `.manifest.json` | 200 条真实形态评测语料(含 sha256 与逐类计数) |
| `realistic2_orig_e2e.{json,md}` / `realistic2_nm21_e2e.{json,md}` | **修正版语料上的对照结果(本文档数字来源)** |
| `realistic_orig_e2e.*` / `realistic_nm21_e2e.*` | 第一版(有构造 bug)的结果,保留以说明差异来源 |