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:
@@ -0,0 +1,74 @@
|
||||
# Natural Memory 路由器 v6 —— 最终报告
|
||||
|
||||
本文件是 v6 阶段的**单一汇总证据**。所有比率均为百分比;所有结论都指向可复现的产物文件。
|
||||
|
||||
## 1. 做了什么
|
||||
|
||||
在分叉 `H:\Memory\V2_dpskw` 内,用**流式加载 + 多线程/批量化特征编码**在修正后的 v6 全量数据集上训练 512 维路由器,并与原版 NM2 路由器在同一冻结评测集上逐轴对比。
|
||||
|
||||
| 环节 | 实现 | 实测 |
|
||||
|---|---|---|
|
||||
| 流式加载 | `stream_feature_bank.py`:只保留 `sha1→行号` 字典,文本落盘;训练器 `train_router_v5.py` 逐行流式建索引 | scan 212 万条唯一文本 **15.1 秒**;训练不解析 episode 进内存 |
|
||||
| 多线程编码 | 8 线程 tokenizer 池 + 按精确 token 长度分组 + token 预算限批 | tokenize **41.8–46.5 秒**(约 5.7 万 texts/s);encode 约 160–180 texts/s |
|
||||
| 特征库 | `features.f16.npy` mmap,10.86 GB(放 D: NVMe) | 打开 1.0 秒;训练按需读页 |
|
||||
| 断点续跑 | `--resume` + `progress.json` + 编码方法指纹 | 两次中断共用已编码的 75 万行 |
|
||||
| 完整性验证 | `verify_feature_bank.py` 全量扫描 | 2,124,552 行、**零值行 = 0** |
|
||||
|
||||
数据:`data/router_training_v6`,train **87,155** / eval **21,920**(10 类别 × 2,000 + policy 1,920),`group_overlap = 0`。
|
||||
|
||||
## 2. 评测协议
|
||||
|
||||
- 冻结 eval 21,920 条,`eval.sha256` 在训练前生成并被训练器强制校验;
|
||||
- 所有路由器在**同一冻结特征库**上评分(编码保真度:与旧缓存共有文本余弦 **0.999983**);
|
||||
- 读取/拒答阈值以 0.50 为主,另给 0.30–0.80 曲线;
|
||||
- 速度轴以 `bench_router_latency.py` 的**交替轮流测量**(5 轮,模型轮转抵消漂移)为准,实测波动带 **2.8–5.3%**,故速度轴用 3% 相对容差,质量轴用严格容差;
|
||||
- 逐轴判定:`verdict_router_v6.py`,对每个候选分别给出「是否全方位超越」。
|
||||
|
||||
## 3. 结果:同存储预算下全方位超越
|
||||
|
||||
| 路由器 | 参数 | 地址字节 | Top-1 | Recall@3 | MRR | 多跳证据全中 | hop | 未知拒答率 | 已知被误拒率 | 延迟(中位) | batch256 QPS | 判定 |
|
||||
|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---|
|
||||
| V2-128 生产(v3) | 2,037,774 | 512 | 41.12% | 46.73% | 47.69% | 43.43% | 73.23% | 0.00% | 0.18% | 1.1558 ms | 199,554 | 基线 |
|
||||
| **V2-128 v6 best** | 2,037,774 | 512 | **94.62%** | **97.81%** | **96.49%** | **97.75%** | **100.00%** | **100.00%** | **0.00%** | 1.1679 ms | 196,829 | **22/22 → 是** |
|
||||
| **V2-128 v6 final** | 2,037,774 | 512 | 94.37% | 96.40% | 95.97% | 95.95% | 100.00% | 100.00% | 0.00% | 1.1653 ms | 198,026 | **22/22 → 是** |
|
||||
| XL-128 v6 best | 6,714,639 | 512 | 95.66% | 98.75% | 97.37% | 98.70% | 99.95% | 99.59% | 0.00% | 1.5783 ms | 141,501 | 18/22 |
|
||||
| V2-512 v6 best | 4,741,902 | 2048 | 95.05% | 98.84% | 97.12% | 98.64% | 100.00% | 99.81% | 0.00% | 1.1623 ms | 154,085 | 20/22 |
|
||||
| XL-512 v6 best | 7,898,127 | 2048 | **95.78%** | 97.59% | 97.24% | 96.86% | 100.00% | 100.00% | 0.00% | 1.5855 ms | 94,647 | 17/22 |
|
||||
|
||||
逐类别拆解、family 拆解、阈值曲线见 `router_scorecard_v6_128.md`(另附 `router_scorecard_v6.md` 为 512 维版本)。
|
||||
|
||||
**相对已交付生产路由器**:Top-1 **+53.49pp**、未知拒答率 **+100.00pp**、已知问题被误拒率 **−0.18pp**、hop **+26.77pp**、多跳证据全中(仅多正例)**37.15% → 99.00%**;参数与地址字节完全相同,延迟/吞吐差异 ≤1.4%(在 2.8–5.3% 的测量噪声带内)。
|
||||
|
||||
## 4. 两个必须如实说明的结论
|
||||
|
||||
1. **512 维配置无法在「地址字节」轴上不劣于 128 维基线**:2048 vs 512 字节是几何决定的 4 倍差异,不是训练能解决的;把它算作失败属于不同存储预算的错位比较。此外 512 维 V2 还真实输一项 batch-256 吞吐(−22.8%)。因此目标里「512 维 + 全部轴不劣」在字面上不可达,在**同预算**下才可达且已达成。
|
||||
2. **新架构 XL 没有赢**:准确率最高(Top-1 95.78%)但吞吐真实低 26–52%(3.3–3.9 倍参数)。本次提升来自**数据与标签**(拒答样本 106→4,106、多跳 2 正例/hop=2、12 倍数据量、10 类别均衡评测),**不是来自更多维度与参数**。该假设被数据否定。
|
||||
|
||||
## 5. 部署就绪:直接替换已验证
|
||||
|
||||
`check_router_swap.py` 结论 `DROP-IN REPLACEMENT OK`:
|
||||
|
||||
- 与生产包第 5 分片 `dynamic_memory.memory_router_v2.*` 的 **16 个键、形状零差异**(缺 0 / 余 0 / 不匹配 0),替换只是重命名;
|
||||
- 可加载进运行时同一 `MemoryRouterV2` 构造(hidden 2560 / dim 128 / heads 8 / hops 3);
|
||||
- 能驱动 `PagedMemoryBankV2` 正常写入与路由(`key_dim = 128`,返回记录数 3)。
|
||||
|
||||
## 6. 过程中发现并修复的缺陷(每条都有验证)
|
||||
|
||||
| 缺陷 | 影响 | 验证方式 |
|
||||
|---|---|---|
|
||||
| mega 适配器把 `metadata.answerable=false` 当成可回答 | 2000 条拒答样本全被错标,拒答轴与多跳轴**无法测量** | 重建后 eval 未知样本 106 → **4,106**;审计表逐类核对 |
|
||||
| multi_hop 只标最终事实、hop 用 `len(positive_ids)` | 多跳证据链缺失、hop 标签全为 1 | 沿实体→值链扩展后 2 正例 / hop=2 |
|
||||
| `_source_candidates` 每条 episode 复制 265.6 万条候选池 | 8 万条 episode 需 **46.8 小时** | 修复后 mega 单条 2105ms → 0.59ms(**3568×**),A/B **sha256 逐字节一致** |
|
||||
| 续跑守卫 `if start < done: continue` 整组跳过 | 49.4 万行保持零值,且写出「完整」manifest,训练已在零值上开跑 | 全量扫描定位缺失区间 → 补齐 → 零值行 0 → 新增完整性标志/训练器拒收/抽样检查 |
|
||||
| 补丁模式误用 `w+` 打开特征库 | 若成功会清零已编码的 183 万行 | `OSError` 中止;改为仅全新运行用 `w+` |
|
||||
| 评分卡 `Recall@k` 用命中**个数**而非比例 | 输出 105%、109% 的"召回率" | 修正为「命中/应有」,全部 ≤100% |
|
||||
| `logits_to_keep=1` 看似省算力 | 实际**慢 1.55×**(非连续视图掉进 bnb 慢路径) | 交替重复 7 轮测量;默认关闭并写入 `--help` |
|
||||
| 用相同文本测吞吐 | 虚高 1.6×(283 vs 真实 175 texts/s) | 用 192 条不同真实文本重测 |
|
||||
|
||||
## 7. 产物清单
|
||||
|
||||
- 数据:`data/router_training_v6/{train,eval,manifest,eval.sha256}`、`router_dataset_audit_v6.json`
|
||||
- 特征库:`H:\Memory\nm_cache\nm_router_v6\feature_cache`(+ `feature_bank_verification.json`)
|
||||
- 路由器:`checkpoints/router_v6_v2_128`、`router_v6_xl128`、`router_v6_v2_512`、`router_v6_xl512`
|
||||
- 证据:`router_scorecard_v6_128.md`、`router_verdict_v6_128.md`、`router_latency_bench.json`、`router_swap_check.json`、`router_scorecard_v6.md`、`router_verdict_v6.md`
|
||||
- 工具:`stream_feature_bank.py`、`train_router_v5.py`、`eval_router_v5.py`、`verify_feature_bank.py`、`bench_router_latency.py`、`check_router_swap.py`、`audit_router_dataset.py`、`verdict_router_v6.py`、`router_xl.py`
|
||||
Reference in New Issue
Block a user