# LLMT **Repository Path**: zli/LLMT ## Basic Information - **Project Name**: LLMT - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-06-18 - **Last Updated**: 2026-07-13 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Hippocampal Sparse Orthogonal QA Training 本项目实现一种面向**单条 QA 在线训练**的类海马记忆方案。目标不是把每条样本都写进同一套大模型权重,而是模拟人脑的双系统记忆结构: ```text 皮层 Cortex = 冻结或极慢更新的通用大模型 海马 Hippocampus = 稀疏、正交、可快速写入的情景记忆层 ``` 核心目标: - 每次只训练一条 QA,不构造 batch 数据集。 - 主模型不直接被单条样本噪声污染。 - 单条 QA 默认写入低重叠稀疏 LoRA / Adapter slots,恢复训练期正交隔离。 - 仍可用 `--write-mode all` 实验整库写入。 - 推理时默认激活 checkpoint 中的整个海马 slot bank,不通过外部索引按 `context-id` / `qa-id` 查找 slot。 ## 方案共识 我们讨论后确定:**用 LoRA / Adapter Slot 作为海马体主体更合适,独立小模型更适合作为海马管理器。** 原因: ```text LoRA 海马体 写在主模型隐层旁边,能直接参与生成和推理。 单条 QA 的 loss 可以直接反向传播到稀疏 slot。 主模型冻结,只更新少量隔离参数。 独立小模型海马体 物理隔离更强,但很难直接影响主模型内部推理。 容易退化成外部 RAG 或提示词补丁。 更适合做路由、筛选、遗忘、睡眠巩固控制器。 ``` 推荐总结构: ```text Qwen / 图文基座模型 = 皮层,负责通用语言、视觉和推理能力 Sparse LoRA Slot Bank = 海马记忆本体,负责单条 QA 快速写入 Small Memory Manager = 海马管理器,后续可负责 slot 路由、遗忘、合并和睡眠巩固 ``` 当前第一版先实现: ```text 冻结主模型 + 稀疏 LoRA slot bank + 单条 QA 写入 + 模式分离 slot 分配 + 低影响梯度 mask ``` ## 类脑机制映射 ### 1. 双互补学习系统 CLS ```text 皮层 = Hugging Face causal LM / future VLM backbone 海马 = sparse orthogonal LoRA adapter slots ``` 训练单条 QA 时,主模型参数被冻结。新记忆只进入海马 slot,不直接修改通用表征。 ### 2. 稀疏正交编码 默认训练使用 `--write-mode sparse`,只激活低重叠稀疏 slots 来写入记忆;`chat.py --activate auto` 仍激活整个 slot bank,因此无需外部索引即可使用记忆。 ```text active_slots = num_slots * active_ratio --write-mode sparse 时默认 active_ratio = 0.03 --slot-scale-mode auto 会为 sparse 写入使用 train_count 缩放,避免全 slot 推理时稀释稀疏记忆 ``` 模式分离器会尽量分配和历史 QA 低重叠的 slot 组合: ```text QA_001 -> slots [12, 77, 341] QA_002 -> slots [5, 188, 600] ``` 这样相似 QA 也不会轻易覆盖同一组参数。 ### 3. 内容与上下文分离 每条 QA 会生成两个 key: ```text content_key = 问题/图像内容的语义标识 context_key = 场景、对话、图片或 qa_id 的上下文标识 ``` 内容负责“是什么”,上下文负责“这次记忆属于哪个场景”。这样可以避免把“路边”错误写成“猫”的固有属性。 ### 4. 睡眠巩固与主动遗忘 当前代码尚未实现完整睡眠巩固,但设计上预留: ```text 海马 slot 中短期保存单条 QA 后台筛选重复、稳定、有预测价值的记忆 少量蒸馏进 cortex adapter 低价值或孤立噪声记忆逐步衰减或删除 ``` 后续可以增加: ```text consolidate.py forget.py memory_manager.py ``` ### 5. 少改参数 稀疏模式下,训练时不仅只打开少量 slot,还会在 active slots 内继续做低影响梯度筛选: ```text score = abs(grad) / (sqrt(importance) + eps) ``` 只保留低历史重要性且当前 QA 需要更新的梯度,其他梯度置零。 ## 当前训练流程 单条 QA 训练过程: ```text 1. 加载 --init 指定的 HF 模型或 outputs/checkpoint-N 2. 冻结主模型参数 3. 给目标 Linear 层挂载 HippocampusLinear 4. 根据 question / image / context-id 生成 content_key 与 context_key 5. 默认由 PatternSeparator 分配低重叠 active slots;`--write-mode all` 时才激活全部 slots 6. 只更新海马 adapter 参数,主模型保持冻结 7. 当前 QA 前向计算 loss 8. 反向传播到 LoRA slots 9. 可选使用 importance 做低影响梯度 mask 10. optimizer.step 只更新海马参数 11. 保存 checkpoint、slot 参数、importance 和 memory 索引 ``` 这不是普通 SFT,也不是 replay 训练。它是: ```text single-QA online sparse hippocampal write ``` ## V3 Fast-Weight Neural Memory V3 is implemented alongside the original sparse-LoRA prototype. It keeps the base causal LM frozen and stores online knowledge in one compact neural matrix instead of allocating and evaluating every LoRA slot. ```text frozen prompt hidden state -> deterministic semantic key projection -> fast-weight neural memory -> RLS novelty / null-memory gate -> final hidden-state residual / vocabulary-logit bias ``` The recursive inverse-covariance state has three jobs: - unrelated prompts stay on the explicit null-memory path; - novel writes are projected toward less-used key-space directions; - memory saturation can be measured without reading a QA index at inference. The V3 checkpoint contains only configuration, neural tensors, and operational metadata. Questions and answers are not copied into the checkpoint, and `v3_chat.py` does not read a QA or vector database. Train one memory: ```powershell python v3_train.py ` --init Qwen/Qwen3.5-2B-Base ` --question "路边那只猫是什么颜色?" ` --answer "路边那只猫是白色的。" ` --output-dir outputs/v3 ``` Continue from the accepted checkpoint: ```powershell python v3_train.py ` --init outputs/v3/checkpoint-v3-000001 ` --question "刚才那只白猫在哪里?" ` --answer "它在路边。" ` --output-dir outputs/v3 ``` Each accepted input record is atomically committed as its own checkpoint. A candidate write is rolled back when the answer prefix is not greedy top-1, teacher-forced target-token accuracy is too low, weighted answer loss does not improve, the loss becomes non-finite, or the configured locality KL limit is exceeded. The first and hardest answer tokens receive extra weight so an easy average teacher-forcing loss cannot hide a failed generation prefix. Chat and inspect neural-memory routing: ```powershell python v3_chat.py ` --init outputs/v3/checkpoint-v3-000002 ` --question "那只猫在哪里?" ` --debug-memory ``` Evaluate exact QA loss before and after the neural-memory contribution: ```powershell python v3_eval.py ` --init outputs/v3/checkpoint-v3-000002 ` --input examples/qa.txt ``` Run the offline V3 tests: ```powershell python -m unittest discover -s tests -v ``` V3.0 deliberately uses a prompt-level residual at the frozen model's output head. Episodic meta-training of the key/write controller, multiple memory blocks, and slow cortex consolidation remain follow-up V3.1/V3.2 work. ## Install ```bash pip install -r requirements.txt ``` ## Train One QA Linux / macOS: ```bash python train.py \ --init Qwen/Qwen3.5-2B-Base \ --question "路边那只猫是什么颜色?" \ --answer "路边那只猫是白色的。" \ --context-id scene-001 ``` Windows PowerShell: ```powershell python train.py ^ --init Qwen/Qwen3.5-2B-Base ^ --question "路边那只猫是什么颜色?" ^ --answer "路边那只猫是白色的。" ^ --context-id scene-001 ``` Resume from a previous checkpoint: ```bash python train.py \ --init outputs/checkpoint-1 \ --question "刚才那只白猫在哪里?" \ --answer "它在路边。" \ --context-id scene-001 ``` `train.py` can process one QA from command-line arguments, or multiple QA records from `--input`. `--max-steps` is the upper bound for each QA record. By default training stops earlier once `--target-loss` is reached after `--min-steps`, which reduces verbatim overfitting on a single memory. By default `train.py` uses `--write-mode sparse`, `--slot-scale-mode auto`, `--gate-mode sigmoid`, `--gate-init-bias 2.0`, `--gate-top-k 16`, gate normalization, `--max-steps 30`, `--target-loss 0.02`, `--min-steps 3`, `--preserve-weight 0.2`, `--preserve-top-k 0`, `--lr 1e-3`, `--slot-dropout 0`, `--low-impact-keep-ratio 1`, and a generic `--memory-instruction` for short-term memory writes that do not require external slot lookup at chat time. The internal sigmoid gate learns input-dependent slot strength inside each adapter layer. At inference it keeps only the strongest gated slot deltas and normalizes by gate mass, so many trained memories do not simply add together and corrupt ordinary answers. The preservation loss records base-model logits with hippocampus slots disabled on generic unrelated prompts, then penalizes full-slot activation when it disturbs those outputs. Together these reduce memory leakage without reading `qa_records.jsonl` or `masks.jsonl` at chat time. Batch input format: ```text q-1:question text a-1:answer text q-2:question text a-2:answer text ``` Batch training: ```bash python train.py \ --init Qwen/Qwen3.5-2B-Base \ --input /path/train_samples.txt \ --context-id scene-001 ``` ## Chat ```bash python chat.py \ --init outputs/checkpoint-2 \ --question "刚才那只猫在哪里?" ``` `chat.py --activate auto` activates all hippocampal slots in the checkpoint. It does not read `memory/masks.jsonl` to route by `content_key`, `context-id`, `image`, or `qa-id`. `--context-id` is only training metadata for slot allocation and is not used by `chat.py`. For sparse checkpoints, adapter scaling is saved as `slot_scale_mode=train_count`, so activating all slots at chat time does not divide a sparse memory by the full slot count. For gated checkpoints, `chat.py --activate auto` still activates the whole slot bank, but each adapter computes neural gate values from the current hidden state before adding slot deltas. By default chat reuses the checkpoint `memory_instruction`, uses deterministic decoding (`--temperature 0`), and applies mild repetition controls (`--repetition-penalty 1.08`, `--no-repeat-ngram-size 6`) to avoid repeating a memorized answer block. Pass `--memory-instruction ""` to disable the instruction for a run. To inspect routing: ```bash python chat.py \ --init outputs/checkpoint-117 \ --question "训练文件中的某个 q-N 原问题" \ --temperature 0 \ --debug-activation ``` General questions can run without memory: ```bash python chat.py \ --init outputs/checkpoint-2 \ --question "猫通常是什么动物?" \ --activate none ``` ## Checkpoint Layout ```text outputs/checkpoint-N/ state.json hippocampus/ config.json slots.pt importance.pt slot_usage.json memory/ qa_records.jsonl masks.jsonl ``` 说明: ```text state.json 记录 base_model、global_step、last_slots 等元数据 config.json 记录海马 slot 配置 slots.pt 保存 LoRA / Adapter slot 参数 importance.pt 保存历史参数重要性 slot_usage.json 统计 slot 使用次数 qa_records.jsonl 保存 QA、key、slot、loss 等记录 masks.jsonl 保存 QA 到 active slots 的映射 ``` Only adapter memory is saved. The frozen base model is referenced by name or path in `state.json`. ## 当前限制 - 当前代码使用 causal language model 路径,`--image` 目前作为上下文 key 和文本占位信息使用。 - 真正的图文输入需要接入具体 VLM 的 processor,例如 Qwen-VL 系列的 `pixel_values` / image token 流程。 - 当前睡眠巩固、主动遗忘、小模型 memory manager 仍是设计预留,尚未作为脚本实现。 ## 后续路线 建议演进顺序: ```text Phase 1: Sparse LoRA Slot Hippocampus 已实现:单条 QA 写入、稀疏 slot、低影响梯度、checkpoint 管理 Phase 2: Memory Manager 增加独立小模型或轻量 router 负责判断是否写入、分配 slot、推理时选择 slot Phase 3: Sleep Consolidation 增加后台巩固流程 把稳定、高复用记忆蒸馏到 cortex adapter 噪声和低价值记忆衰减或删除 Phase 4: Vision-Language Support 接入 Qwen-VL processor 将 image embedding 与 context_key / content_key 分离使用 ``` 可以实现,但应区分两个目标: V3-A:给现有冻结 LLM 增加可持久化的 fast-weight 神经记忆层——我可以在当前项目中实现,工程可行性高。 V3-B:从底层用 TTT/Titans 类结构重新预训练完整语言模型——代码可做,但需要大规模数据和算力,不适合作为当前项目第一阶段。 建议先做 V3-A。 V3-A 的具体定义 ```mermaid flowchart LR A["问题 Q"] --> B["冻结 LLM 编码"] B --> C["Key Encoder"] C --> D["Fast-Weight MLP 记忆"] D --> E["Read Gate / Null Memory"] E --> F["注入上层 Transformer"] F --> G["生成答案"] H["新 QA"] --> I["Value Encoder"] I --> J["Surprise / Write Controller"] J --> K["1~3 次局部神经更新"] K --> D ``` 这里不再为每条 QA 创建一个 LoRA 槽位。所有知识被压缩到一个或少量可训练 MLP/矩阵的参数中。 TTT 已验证“隐藏状态本身是一个测试时更新的小模型”,实验规模达到 125M~1.3B;Titans 也验证了神经长期记忆模块路线。TTT、Titans 但这些论文主要解决长序列内记忆;我们要做的“跨会话保存、逐条事实更新、抗投毒和回滚”还需要额外工程。 核心读写机制 写入一条 QA: \[ k=f_k(h_Q),\qquad v=f_v(h_{Q,A}) \]神经记忆预测: \[ \hat v=M_{\phi}(k) \]只更新记忆参数: \[ \phi_{t+1}= \phi_t-\eta_t\nabla_\phi \left[ \lVert M_\phi(k)-v\rVert^2 +\beta L_{stability} \right] \]其中学习率、更新强度、是否写入由控制器产生: \[ (\eta_t,\rho_t,w_t)= WriteController(surprise,confidence,gradient) \]查询时: \[ m=M_\phi(f_k(h_Q)) \]再将记忆作为残差注入少数上层: \[ h'_l=h_l+c(Q)\,P_l(m) \]c(Q) 包含真正的 Null Memory:不相关问题可以令 c≈0,完全关闭记忆。 为什么比当前实现更好 项目 当前 LoRA 槽位 V3 fast-weight 写入 哈希分配槽位并反向训练 学习型写入规则 参数增长 槽位越多参数越大 初期固定大小 推理 计算全部槽位再 top-k 一次紧凑神经记忆读取 语义泛化 依赖槽位 gate key/value 编码器专门训练 不相关问题 gate 难以完全关闭 显式 Null Memory 逐条学习 多步 LoRA 微调 1~3次 fast-weight 更新 跨会话 保存槽位权重 保存 fast-memory 参数 数据库查询 不查询 同样不查询 2026 年的 MoNe 也展示了“冻结 Transformer + 外挂 fast-weight 神经记忆”的可插拔方向,不过它主要评估长上下文而不是无限期事实学习。MoNe 最大技术难点 1. 不是写进去,而是让生成模型用得上 把 QA→向量 写进 MLP 不难。困难在于让记忆向量稳定影响下一 token。 需要通过 episodic meta-training 学习: Key Encoder; Value Encoder; Read Projection; Read Gate; Write Controller; 初始 memory 参数。 训练 episode 应模拟真实使用: 依次写入 QA1、QA2、QA3…… → 查询原问题 → 查询同义改写 → 查询旧问题 → 查询无关问题 → 查询纠错后的最新版本 内循环更新 fast memory,外循环更新“如何读写”。 2. 固定容量最终仍会饱和 单个 MLP 不可能无限保存独立事实。后续需要扩展成: Null Memory Fast Memory Block 0 Fast Memory Block 1 ... Slow Consolidated Memory 当干扰分数超过阈值时增加新块,而不是无限扩大一个 MLP。块数量远少于“每条 QA 一个 LoRA 专家”。 3. 元训练成本 如果对完整 LLM 的内循环进行二阶反向传播,显存和时间会很高。因此实现上采用: 基础模型完全冻结; 只对小型 memory/controller 求梯度; first-order meta-learning; 截断内循环梯度; 先使用 Linear Memory,再升级为两层 MLP。 近期研究也承认深层测试时记忆存在训练效率和硬件利用率问题;TNT 的工作正是在解决这一瓶颈。TNT 我可以实现的交付阶段 V3.0:可运行神经记忆原型 新增: hsoa/v3/ fast_memory.py key_value_encoder.py memory_adapter.py write_controller.py online_learner.py checkpoint.py evaluation.py tests/v3/ 完成: Linear fast-weight memory; 单条 QA 写入; 神经读取并注入冻结模型; Null Memory; fast state 保存、恢复和回滚; 不读取 QA 文件进行回答; 与现有 LoRA 版本进行 A/B 评测。 V3.1:学习如何写入 增加 episodic meta-training: QA 顺序流; 同义改写; 无关负样本; 冲突和纠错; 保持旧知识的外循环损失; 学习写入率、遗忘率和读门控。 这一步之后,才能称为真正的“学习如何学习”。 V3.2:多块记忆与巩固 增加: 新颖度检测; 多 fast-memory block; 神经路由和 null block; 容量监控; 高价值记忆蒸馏到 slow adapter; 噪声记忆衰减。 可行性结论 目标 判断 在当前代码库实现 V3 原型 高 单条 QA 写入神经参数 高 回答时完全不查数据库 高 同义改写后仍能回忆 中高,依赖元训练 连续学习数百至数千条 中,需要多块记忆 比当前 256 槽位更省推理计算 高 固定容量、无限记忆、零遗忘 不可保证 直接达到生产级通用 LLM 需要较长实验和数据闭环 最合理的实现决策是:**保留当前代码作为 V1 对照基线,新建独立 hsoa/v3/,先完成 Linear fast-weight memory 和评测,验证有效后再做 MLP、元学习和睡眠巩固。**这样不会破坏现有实现,也能清楚判断 V3 是否真的优于当前 LoRA 槽位方案。 已完成 V3.0 实现,并保留原 V1 代码不变。 主要实现: [Fast-weight 神经记忆](C:/Users/zhangli/Desktop/LLMT/hsoa/v3/fast_memory.py):固定容量神经矩阵、RLS 逆协方差、Null Memory、饱和度检测。 [在线学习器](C:/Users/zhangli/Desktop/LLMT/hsoa/v3/online_learner.py):只更新 fast weight,支持低干扰投影、局部性约束、验收与回滚。 [原子检查点](C:/Users/zhangli/Desktop/LLMT/hsoa/v3/checkpoint.py):每条成功记忆独立提交,不保存原始问答。 [训练入口](C:/Users/zhangli/Desktop/LLMT/v3_train.py) [推理入口](C:/Users/zhangli/Desktop/LLMT/v3_chat.py) [评测入口](C:/Users/zhangli/Desktop/LLMT/v3_eval.py) [使用说明](C:/Users/zhangli/Desktop/LLMT/README.md) [核心测试](C:/Users/zhangli/Desktop/LLMT/tests/test_v3_fast_memory.py)、[在线学习测试](C:/Users/zhangli/Desktop/LLMT/tests/test_v3_online_learner.py) 使用示例: python v3_train.py --init Qwen/Qwen3.5-2B-Base ` --question "路边那只猫是什么颜色?" ` --answer "路边那只猫是白色的。" 然后使用输出的检查点: python v3_chat.py ` --init outputs/v3/checkpoint-v3-000001 ` --question "那只猫是什么颜色?" ` --debug-memory 验证结果: 5 个离线核心测试全部通过; Null Memory、相关 key 激活、旧方向保护、拒绝回滚、检查点恢复均已覆盖; 24 个 Python 文件语法解析通过; 三个 V3 CLI 均能正常加载; 最终差异检查无空白或补丁错误。 当前 V3.0 使用提示级、最终隐藏空间的神经残差。尚未包含 V3.1 的 episodic meta-training、多记忆块和慢速 cortex 巩固。完整 2B 模型端到端实验尚未运行,需要本地可用的基础模型和相应 GPU;下一步应先用较小模型连续写入约 100 条 QA,对比 V1/V3 的记忆保持率、无关问题漂移和推理速度。