Files
WpyQwq 643e22ecb9 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,读写关闭时与原生模型逐位相同
2026-09-19 11:11:31 +08:00

5.5 KiB
Raw Permalink Blame History

NM2.1:合并包 + 整体记忆测试报告

1. NM2.1 是什么

NM2.1 = 原版 NM2 的 Qwen3.5-4B 记忆包 + 本会话交付的路由器,合并方式是把路由器权重 写进模型包本体(不是外挂 sidecar 文件),因此 NM2.1 是一个自包含的模型包。

  • 产物:H:\Memory\dynamic_memory_lab\qwen3_5_4b_natural_memory_v2_1
  • fork 内以 junction 暴露:H:\Memory\V2_dpskw\qwen3_5_4b_natural_memory_v2_1
  • 构建脚本:build_nm2_1_package.py(nm2_1_build_report.json)

合并做法:复制原包 22 个文件后,只把记忆分片 model.safetensors-00005-of-00005.safetensors 里的 16 个 dynamic_memory.memory_router_v2.* 张量替换为交付路由器;其余 47 个张量(含 text_retriever、持久槽、memory policy)逐字节未变。

验证(不是"脚本退出码为 0"):

检查 结果
路由器张量与交付件逐位一致(写出后重新读取比对) 16/16 一致,0 处不符
非路由张量是否被改动 0 处改动
交付件来源 sha256 69f8295e78821e52c0b41b248e7eddbfa47d7e409539f4a13382c0c82d189deb
实际加载(load_qwen_dynamic) router ready: True、text_retriever ready: True
加载出的路由器 == 交付件 True(0 处不符),2,037,774 参数

2. 原版 NM2 已归档

  • 包:E:\归档\01_人工智能\01_训练产物\NM2_原版_qwen3_5_4b_natural_memory_v2_20260912_142722.7z
  • 22 文件 / 9,535,448,852 字节 → 6.55 GB,7z t 报 Everything is Ok
  • 已记入 E:\归档\00_索引\操作日志.jsonl;守恒复核精确对上: 45,059 文件 / 110.147 GB = 改动前 45,058 / 103.597 GB + 1 文件 / 6.55 GB
  • 原包仍留在 H: 原地(归档按该归档库惯例是"复制保留"),所以历史基线对照仍可复现

3. 整体记忆测试结果

同一套电池、同一份运行时,只有模型包不同(run_nm2_battery.ps1)。

指标 原版 NM2 NM2.1
A 用例数(10 类别) 110 110
A 总体正确率 89.09% 88.18%
A 可回答正确率 100.00% 100.00%
A 未知拒答率 60.00% 56.67%
A 已知问题被误拒率 0.00% 0.00%
B 零字面重叠改写回答正确率 43.75% 68.75%
B 答成别的属性 18.75% 18.75%
B 触发读取 56.25% 93.75%
B 平均选中记录 3.0625 6.0625
C 可回答正确率(24 同形候选) 65.00% 65.00%
C 答成别的属性 35.00% 35.00%
C 未知泄漏率 75.00% 75.00%
C 活跃记录 min/max 23 / 24 23 / 24
D 重启后召回 / 作答正确 / 清理生效 通过 / 通过 / 通过 通过 / 通过 / 通过

可复现性说明(重要):NM2.1 的 A 段跑了两次,得到 89.09% 与 88.18%(各差 1 个用例), 未知拒答率 60.00% 与 56.67%(同样差 1 个用例)。因此在这套 110 用例的尺度上, < 1 个百分点(≈1 个用例)的差异属于运行间波动,不作为结论。

结论

  1. B 段(零字面重叠改写)真实提升 +25.00pp(43.75% → 68.75%),机制是读取门开启率 从 56.25% 升到 93.75%:原版路由器的 need_memory 门对这类改写提问过于保守,新路由器 更愿意去查记忆,因此拿到证据并答对。门是本配置下路由器唯一影响端到端结果的杠杆, 这与本会话早先的取证完全一致(随机化排序通路端到端零变化、混合权重独立进程复测零变化)。
  2. A、C 两段与基线相同:这两套的答案由打包的 text_retriever 排序与词面/地址先验决定, 换路由器不改变注入记录集合,所以不改结果。换路由器带来的不是"整体都更强", 而是"该查的记忆会去查了"。
  3. D 段两边都通过:写入→保存→重启→召回→作答链路完好,清理也生效。

4. 换路由器没有解决的问题(同一份测试里可见,避免误判)

问题 实测 说明
未知问题泄漏 75.00%(C 段) 问库中不存在的属性时仍然给出编造答案;两组检索最高分分布几乎完全重叠,阈值方案已被测量排除
答成别的属性 35.00%(C 段) 24 个同形候选里排错属性
A 段未知拒答率 56.67~60.00% 未见提升
记录级排序不由路由器决定 —— _record_scores 用打包 text_retriever 覆盖路由器分数(该 retriever 同任务 Top-1 仅 23.20%,路由器 59.60%)

另外:eval_general_capability.py 需要 comprehensive_general.jsonl,该文件不存在, 所以通用能力回归这一项本次没有跑(A 段里的 benchmark_qa / 未知类别可作部分代理)。

5. 产物清单

文件 内容
H:\Memory\dynamic_memory_lab\qwen3_5_4b_natural_memory_v2_1\ NM2.1 合并包本体(22 文件)
build_nm2_1_package.py / nm2_1_build_report.json 合并脚本与构建验证报告
run_nm2_battery.ps1 整体记忆测试电池(-Tag 区分输出,避免互相覆盖)
compare_nm2_batteries.py / nm2_battery_comparison.{json,md} 对照表
nm2_1_e2e.{json,md} / nm2_1_critical_e2e.{json,md} / nm2_1_runtime_e2e.{json,md} / nm2_1_restart.json / nm2_1_battery_summary.json NM2.1 四段结果
nm2_orig_*.json/md 原版 NM2 同套结果(用于对照)
PRODUCTION_ROUTER.md 路由器交付说明(含安装与复现命令)