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

173 lines
6.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Natural Memory v2:正式路由器训练
这一阶段只训练 `MemoryRouterV2`,不更新 Qwen 主干。训练目标是让路由器在真实自然语言查询下学会:
- 从候选记忆中找出一个或多个证据;
- 遇到多跳问题时保留多个支持项;
- 碰到未知事实时拒绝读取;
- 区分同属性冲突、旧值、新值和无关噪声;
- 在个人事实、对话记忆、代码/文档和通用 QA 之间泛化。
训练分为两个文件级阶段:
```text
公开/本地数据
↓
prepare_memory_router_dataset.py
↓ 先写出并 hash
train.jsonl + eval.jsonl
↓
train_memory_router_large.py
↓ 一次性生成 Qwen 冻结特征
CPU feature bank + router training
```
## 当前环境
已检查 `Conda LLM`:
```text
Python: C:\Users\Administrator\miniconda3\envs\LLM\python.exe
PyTorch: 2.9.0+cu128
CUDA: available
GPU: NVIDIA GeForce RTX 5070
Transformers: 5.9.0
Datasets: 4.8.3
```
默认使用 `qwen3_5_4b_natural_memory_v2`,Qwen 只在特征预计算阶段工作;训练更新的只有一个小型 `MemoryRouterV2`。默认 GPU 上限是 9 GiB,为模型、系统和 KV 留出安全空间。
## 1. 生成并冻结数据
从仓库已有的训练/评估文件生成正式路由 episode:
```powershell
Set-Location H:\Memory
& C:\Users\Administrator\miniconda3\envs\LLM\python.exe -m V2_dpskw.prepare_memory_router_dataset `
--output-dir data/router_training `
--candidate-count 32 `
--seed 20260907
```
输出:
```text
H:\Memory\V2_dpskw\data\router_training\train.jsonl
H:\Memory\V2_dpskw\data\router_training\eval.jsonl
H:\Memory\V2_dpskw\data\router_training\manifest.json
H:\Memory\V2_dpskw\data\router_training\eval.sha256
```
`eval.jsonl` 会在训练开始前生成,训练器启动时重新计算 SHA-256;如果被修改,可以通过 `--expected-eval-sha256` 让训练直接停止。
当前默认本地混合源包括:
| 领域 | 来源 | 用途 |
|---|---|---|
| 个人事实 | `benchmark_train/eval.jsonl` | 主题改写、实体区分、短事实召回 |
| 原生记忆 | `native_memory/train/eval.jsonl` | 写入—替换—读取链路 |
| 记忆策略 | `production_memory/train/eval.jsonl` | 写入、遗忘、临时信息和噪声 |
| 困难记忆策略 | `production_memory_hard_v2/train/eval.jsonl` | 冲突、引用噪声、旧值、新值 |
| 长上下文压力 | `mega_validation/smoke.jsonl` | 多跳、随机位置、未知拒答等 smoke eval |
## 2. 引入公开数据
脚本内置了可审计的公开数据配方:
- [HotpotQA](https://huggingface.co/datasets/hotpot_qa):多跳证据选择;
- [CodeSearchNet](https://huggingface.co/datasets/code_search_net):自然语言到代码/文档检索;
- [FEVER](https://huggingface.co/datasets/fever):支持证据、冲突和无证据样本。
网络可用时执行:
```powershell
& C:\Users\Administrator\miniconda3\envs\LLM\python.exe -m V2_dpskw.prepare_memory_router_dataset `
--output-dir V2_dpskw/data/router_training_public `
--include-public `
--hf-max-rows 20000 `
--candidate-count 32 `
--seed 20260907
```
如果 Hugging Face 下载失败,`manifest.json` 会写入失败原因,失败源贡献 0 行;不能把失败的在线源计入实验结果。也可以手动指定来源:
```text
--hf-source DATASET_ID|SPLIT|CONFIG(optional)|SPLIT_KIND(optional)
```
例如:
```powershell
--hf-source hotpot_qa|train|distractor|train
--hf-source hotpot_qa|validation|distractor|eval
```
真实用户对话必须先获得同意并去除姓名、地址、密钥、账号等 PII,再通过 `--train-source`/`--eval-source` 加入。脚本不会把用户对话偷偷上传。
## 3. 监督训练
第一次运行会加载 4B 模型,给去重后的 query/candidate 文本生成冻结语义特征,保存到 CPU feature bank;之后重新训练会复用它:
```powershell
Set-Location H:\Memory
& C:\Users\Administrator\miniconda3\envs\LLM\python.exe -m V2_dpskw.train_memory_router_large `
--train-file V2_dpskw/data/router_training/train.jsonl `
--eval-file V2_dpskw/data/router_training/eval.jsonl `
--model-path V2_dpskw/qwen3_5_4b_natural_memory_v2 `
--output-dir V2_dpskw/checkpoints/natural_memory_v2_router_large `
--feature-cache-dir V2_dpskw/checkpoints/natural_memory_v2_router_large/feature_cache `
--gpu-memory-gb 9 `
--encode-batch-size 1 `
--steps 10000 `
--batch-size 64 `
--eval-interval 500 `
--overwrite-metrics
```
控制台和 `metrics.jsonl` 都会记录:
- 每一个 optimizer step 的 `loss`、四个子损失、学习率和梯度范数;
- step 0 初始 eval;
- step 500、1000、1500……的完整 eval;
- 最终 `memory_router_v2.pt`,可直接交给现有的 `build_natural_memory_v2_package.py`。
训练不会输出每 token 的 Qwen 生成,因而不会把推理生成路径混入路由器质量指标。
如果中途停止,使用保存的 checkpoint 恢复;`--steps` 是恢复后的最终全局 step,不是额外步数:
```powershell
& C:\Users\Administrator\miniconda3\envs\LLM\python.exe -m V2_dpskw.train_memory_router_large `
--train-file V2_dpskw/data/router_training/train.jsonl `
--eval-file V2_dpskw/data/router_training/eval.jsonl `
--model-path V2_dpskw/qwen3_5_4b_natural_memory_v2 `
--output-dir V2_dpskw/checkpoints/natural_memory_v2_router_large `
--feature-cache-dir V2_dpskw/checkpoints/natural_memory_v2_router_large/feature_cache `
--resume V2_dpskw/checkpoints/natural_memory_v2_router_large/router_step_00005000.pt `
--steps 10000 `
--eval-interval 500
```
恢复时不要使用 `--overwrite-metrics`,这样历史 loss/eval 会继续追加到同一个 `metrics.jsonl`。
## 4. 评估门槛
训练期间重点看 `eval` 行:
| 指标 | 含义 |
|---|---|
| `route_top1` | 有证据时,Top-1 是否命中支持记忆 |
| `route_recall_at3` | 多跳/多事实时,Top-3 是否包含支持记忆 |
| `route_mrr` | 支持记忆在排序中的平均倒数排名 |
| `need_recall` | 需要记忆时是否愿意读取 |
| `need_specificity` | 不需要/未知时是否能拒绝读取 |
| `need_f1` | 读取和拒绝的综合平衡 |
| `hop_accuracy` | 多跳控制预测是否正确 |
路由器指标不能代替端到端回答率。训练完成后必须重新运行现有的 dirty-corpus、strong-RAG 和 Qwen3.5 4B 对照;最终门槛仍然是端到端正确率、未知拒答、延迟和显存共同达标。
## 5. 重要边界
当前公开数据适配器是通用 schema 适配器,不会把所有数据集都自动变成完美标注。每个公开源的实际行数、错误信息和哈希都在 `manifest.json`。如果某个源的支持证据字段无法解析,它会少贡献 episode,而不是制造伪标签。
路由器训练也不会直接解决“召回正确但 Qwen 没有把证据融合进答案”的全部问题;那是后续证据融合/生成控制实验,必须单独报告。