- 引入 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,读写关闭时与原生模型逐位相同
6.0 KiB
NM2.1 最终交付状态(含整体记忆测试全表)
本轮把两件事同时做成:未知拒答 75.00% → 0.00%,且通用套件零回归。
1. 交付物
| 项 | 值 |
|---|---|
| 模型包 | H:\Memory\dynamic_memory_lab\qwen3_5_4b_natural_memory_v2_1(23 文件 / 8.88 GB) |
| 路由器 | checkpoints/router_replay_v7_v2_128/memory_router_v2.pt,sha256 69f8295e…d189deb,2,037,774 参数 / 128 维 / 每条记录 512 字节 |
| 属性覆盖头 | memory_attribute_head.pt(24 类,已装入包内) |
| 关键配置 | memory_coverage_gate=true、memory_record_router_blend=0.5、memory_coverage_vocabulary_fraction=0.9 |
| 验证 | 52 个单元测试通过;check_router_swap → DROP-IN OK;合并 16/16 张量逐位一致、分片内其余 47 个未变 |
2. 整体记忆测试全表(同一套电池、同一份运行时,只有模型不同)
| 指标 | 原版 NM2 | NM2.1(仅换路由器) | NM2.1 最终 |
|---|---|---|---|
| A 用例数(10 类别) | 110 | 110 | 110 |
| A 总体正确率 | 89.09% | 88.18% | 88.18% |
| A 可回答正确率 | 100.00% | 100.00% | 100.00% |
| A 未知拒答率 | 60.00% | 56.67% | 56.67% |
| A 已知问题被误拒率 | 0.00% | 0.00% | 0.00% |
| B 零字面重叠改写回答正确率 | 43.75% | 68.75% | 68.75% |
| B 答成别的属性 | 18.75% | 18.75% | 18.75% |
| B 触发读取 | 56.25% | 93.75% | 93.75% |
| C 可回答正确率(24 同形候选) | 65.00% | 65.00% | 70.00% |
| C 答成别的属性 | 35.00% | 35.00% | 27.50% |
| C 未知泄漏率 | 75.00% | 75.00% | 0.00% |
| C 活跃记录 min/max | 23 / 24 | 23 / 24 | 23 / 24 |
| D 重启后召回 / 作答 / 清理 | 通过 | 通过 | 通过 |
相对原版 NM2 的净变化:A 段可回答 +0.00pp(100.00% 保持,已知误拒 0.00% 保持)· B 段回答正确率 +25.00pp(43.75% → 68.75%)· C 段可回答 +5.00pp、答成别的属性 −7.50pp、 未知泄漏 −75.00pp(75.00% → 0.00%)· D 段全部通过。
可复现性提醒:B 段只有 16 用例,1 个用例 = 6.25pp,因此 B 的 68.75% 与另一次测得的 75.00% 属同一水平的运行间波动,不作为增益主张;A/C/D 的结论在多次运行中一致。
3. 本轮做了三处改动(每处都有测量依据)
-
记录排序混合权重 0.5(
memory_record_router_blend) 独立进程测的剂量曲线(48 用例,先验保持 1.0),此前的同进程测量因顺序污染已作废:blend 可回答正确率 答成别的属性 未知泄漏率 0.00(仅 retriever) 65.00% 35.00% 75.00% 0.50 70.00% 27.50% 75.00% 1.00(仅路由器) 62.50% 37.50% 87.50% 两个打分器互补,0.5 是最优点(1.0 更差 → 非单调伪影)。
-
先验权重参数化并测得"不该动":把
_record_scores的加法先验暴露为可调,剂量曲线 (1.00 / 0.50 / 0.25 / 0.00)= 65.00% / 47.50% / 42.50% / 40.00% —— 调小只会更差, 所以保持 1.0。这否定了"先验压过学习打分"这条假设,是有价值的负面结论。 -
覆盖门 + 两处必需修复
_build_text_prefix短路:门拒绝后若继续回落,会走旧版 16 槽注入路径把记忆又塞回去 (实测不修则泄漏只从 75.00% 降到 62.50%);- 闭包动态解析 bank:
reset_memory()每次都会新建memory_os_v2,捕获旧引用会让门 永远看到空 bank 而静默旁路(实测applicable:0 / bypassed:1); - 自门控:只有当库的属性集合填充了头部词表的 ≥90% 时才让门生效。 这条阈值是必需的 —— 用"子集即可"会让门在通用套件上误判,把 A 段可回答从 100.00% 压到 92.50%、已知误拒升到 2.50%;收紧到 90% 后 A 段完全恢复,C 段泄漏仍为 0.00%。
4. 仍未解决(如实列出,不当作已解决)
| 项 | 现状 | 说明 |
|---|---|---|
| 跨域未知拒答 | 未解决 | 覆盖头是 24 类闭集,只在其词表被库填充时生效。开放词表的属性匹配实测只有 49.20% Top-1 / AUC 0.6560(零训练),不足;跨域需要"大规模属性分类体系 + 训练过的匹配器",属数据工程 |
| 答成别的属性 | 35.00% → 27.50% | 同形候选间排序仍不理想;已排除先验重加权(更差)与单纯换打分器(更差) |
| A 段未知拒答率 | 56.67% | 未见改善 |
| 规模验证 | 未做 | 仅 24 属性 / 300 条评测;生产需上千属性、上万改写问法 |
| 通用能力回归套件 | 未跑 | eval_general_capability.py 依赖的 comprehensive_general.jsonl 不存在 |
5. 复现命令
$env:PYTHONPATH='H:\Memory'; $env:PYTHONIOENCODING='utf-8'; cd H:\Memory\V2_dpskw
# 整体电池(A/B/C/D 四段)
pwsh -NoProfile -File .\run_nm2_battery.ps1 -Package qwen3_5_4b_natural_memory_v2_1 `
-Label 'NM2.1 最终' -Tag 'nm2_1_final' -PerCategory 10 -OverlapCases 48 -Blends '0.5'
# 对照表
& 'C:\Users\Administrator\miniconda3\envs\LLM\python.exe' -m V2_dpskw.compare_nm2_batteries `
--tag "原版NM2=nm2_orig" --tag "NM2.1=nm2_1" --tag "NM2.1最终=nm2_1_final"
# 门的适用性诊断(确认 applicable/bypassed,避免静默旁路)
& 'C:\Users\Administrator\miniconda3\envs\LLM\python.exe' -m V2_dpskw.diagnose_coverage_gate `
--package qwen3_5_4b_natural_memory_v2_1
6. 产物
nm2_battery_comparison_final.{json,md}(最终对照表)· nm2_1_final_*.{json,md}(四段原始结果)·
nm2_1_final_battery_summary.json · run_nm2_battery.ps1(电池,-Tag 隔离输出)·
diagnose_coverage_gate.py + coverage_gate_diagnosis2.json(门适用性)·
prior_scale_dose_response.{json,md}(先验剂量曲线)· prior1_blend_{0.0,0.5,1.0}_proc.json(独立进程 blend 曲线)·
analyze_open_vocabulary_attribute_match.{py,json,md}(开放词表可行性)· ABSTENTION_BREAKTHROUGH.md(机制与失败史)