- 引入 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.8 KiB
Natural Memory v2:正式路由器训练
这一阶段只训练 MemoryRouterV2,不更新 Qwen 主干。训练目标是让路由器在真实自然语言查询下学会:
- 从候选记忆中找出一个或多个证据;
- 遇到多跳问题时保留多个支持项;
- 碰到未知事实时拒绝读取;
- 区分同属性冲突、旧值、新值和无关噪声;
- 在个人事实、对话记忆、代码/文档和通用 QA 之间泛化。
训练分为两个文件级阶段:
公开/本地数据
↓
prepare_memory_router_dataset.py
↓ 先写出并 hash
train.jsonl + eval.jsonl
↓
train_memory_router_large.py
↓ 一次性生成 Qwen 冻结特征
CPU feature bank + router training
当前环境
已检查 Conda LLM:
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:
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
输出:
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:多跳证据选择;
- CodeSearchNet:自然语言到代码/文档检索;
- FEVER:支持证据、冲突和无证据样本。
网络可用时执行:
& 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 行;不能把失败的在线源计入实验结果。也可以手动指定来源:
--hf-source DATASET_ID|SPLIT|CONFIG(optional)|SPLIT_KIND(optional)
例如:
--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;之后重新训练会复用它:
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,不是额外步数:
& 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 没有把证据融合进答案”的全部问题;那是后续证据融合/生成控制实验,必须单独报告。