受人类启发的情节记忆:实现无限上下文 LLM

受人类启发的情节记忆:实现无限上下文 LLM

ArXiv ID: 2407.09450
作者: Zafeirios Fountas, Martin A Benfeghoul, Adnan Oomerjee, Fenia Christopoulou, Gerasimos Lampouras, Haitham Bou-Ammar, Jun Wang
机构: Huawei Noah’s Ark Lab, University College London
发布日期: 2024-07-12


摘要

大型语言模型(LLM)在处理长上下文时面临严重困难,限制了它们在长序列上保持连贯性和准确性的能力。相比之下,人类大脑擅长在跨越一生的广阔时间尺度上组织和检索情节性体验。本文提出 EM-LLM,一种将人类情节记忆和事件认知的关键方面集成到 LLM 中的新方法,无需微调即可处理百万 token 级别的输入。在多个长文本任务上,EM-LLM 相比传统方法记忆检索准确率提升40%,计算成本降低60%


问题背景

LLM 的长上下文挑战

1
2
3
4
5
6
7
8
9
10
11
12
13
14
当前 LLM 上下文限制:

模型 | 原生上下文 | 实际可用 | 主要瓶颈
--------------|------------|----------|----------
GPT-4 Turbo | 128K | ~50K | 注意力稀释
Claude-3 | 200K | ~100K | 成本过高
Gemini 1.5 | 1M+ | ~200K | 延迟过高
开源 7B | 4K-32K | 4K-8K | 训练限制

核心问题:
1. 注意力机制 O(n²) 复杂度
2. 长距离依赖捕获困难
3. "中间丢失"现象(lost-in-the-middle)
4. 计算成本随长度线性增长

人类情节记忆的启示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
人类记忆系统 vs LLM:

人类情节记忆:
┌─────────────────────────────────────────┐
│ 编码 → 事件分割 → 分层存储 → 线索检索 │
│ │
│ • 自动分段:将连续体验分成事件单元 │
│ • 分层组织:从具体到抽象的多层表示 │
│ • 选择性保留:重要事件优先存储 │
│ • 关联检索:基于线索激活相关记忆 │
│ │
│ 容量:理论上无限(约 2.5PB 估计) │
│ 检索:~100ms 量级 │
└─────────────────────────────────────────┘

LLM 注意力机制:
┌─────────────────────────────────────────┐
│ 输入 → 注意力计算 → 输出 │
│ │
│ • 扁平处理:所有 token 同等对待 │
│ • 无分层:单一粒度表示 │
│ • 全保留:无法主动遗忘 │
│ • 计算密集:O(n²) 复杂度 │
│ │
│ 容量:受硬件严格限制 │
│ 检索:随长度二次增长 │
└─────────────────────────────────────────┘

EM-LLM 架构

整体设计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
┌─────────────────────────────────────────────────────────┐
│ EM-LLM Architecture │
│ │
│ 输入流 │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ 事件分割模块 │ ← 认知科学启发的边界检测 │
│ │ Event Segmentation │
│ └─────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ 分层记忆存储 │ ← 多层事件表示 │
│ │ Hierarchical Memory │
│ │ ┌───────────┐ │
│ │ │ Episode │ ← 具体事件层 │
│ │ ├───────────┤ │
│ │ │ Segment │ ← 片段层 │
│ │ ├───────────┤ │
│ │ │ Timeline │ ← 时间线层 │
│ │ └───────────┘ │
│ └─────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ 动态检索模块 │ ← 基于当前上下文的线索检索 │
│ │ Cue-based Retrieval │
│ └─────────────────┘ │
│ │ │
│ ▼ │
│ LLM 主模型 (处理精简上下文) │
│ │ │
│ ▼ │
│ 输出 │
└─────────────────────────────────────────────────────────┘

组件 1:事件分割

基于 surprisal 的边界检测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import numpy as np
import torch

def detect_event_boundaries(token_sequence, model, threshold=0.7):
"""
检测事件边界

基于 surprisal 理论:事件边界处预测误差显著上升

Args:
token_sequence: 输入 token 序列
model: 语言模型
threshold: 边界检测阈值
"""
surprisals = []

# 计算每个 token 的 surprisal
with torch.no_grad():
outputs = model(token_sequence)
logits = outputs.logits

for i in range(len(token_sequence) - 1):
# 预测下一个 token 的概率
next_token_prob = torch.softmax(logits[0, i], dim=-1)[token_sequence[i + 1]]

# Surprisal = -log P
surprisal = -torch.log(next_token_prob + 1e-6)
surprisals.append(surprisal.item())

# 标准化
surprisals = (surprisals - np.mean(surprisals)) / np.std(surprisals)

# 检测边界(surprisal 峰值)
boundaries = []
for i in range(1, len(surprisals) - 1):
if surprisals[i] > surprisals[i-1] and \
surprisals[i] > surprisals[i+1] and \
surprisals[i] > threshold:
boundaries.append(i)

return boundaries


# 示例:事件分割结果
"""
输入文本:
"约翰走进咖啡厅。他点了一杯拿铁,找了个靠窗的位置坐下。
突然,门被猛地推开,一个陌生人冲了进来。
'所有人都别动!'他大声喊道。"

检测到的事件边界:
[15, 42] ← "约翰走进咖啡厅...坐下" | "突然,门被猛地推开..." | "'所有人都别动!..."]

分段:
- Segment 1: 咖啡厅场景建立(平静)
- Segment 2: 突发事件(紧张)
- Segment 3: 对话开始(冲突)
"""

多粒度边界

粒度 时间尺度 检测特征 示例
微事件 1-10 tokens 句法变化 新句子开始
小事件 10-100 tokens 话题转换 场景变化
大事件 100-1000 tokens 叙事弧 章节转换
超事件 1000+ tokens 主题变更 故事部分

组件 2:分层记忆存储

三层记忆架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
class HierarchicalMemory:
"""分层记忆存储"""

def __init__(self, max_episodes=100, max_segments_per_episode=10):
self.max_episodes = max_episodes
self.max_segments = max_segments_per_episode

# 三层记忆
self.episode_memory = [] # 具体事件层
self.segment_memory = [] # 片段层
self.timeline = [] # 时间线层

def store(self, content, metadata):
"""
存储新事件

Args:
content: 事件内容(token 序列或摘要)
metadata: 元数据(时间戳、重要性分数等)
"""
# 步骤 1: 创建片段表示
segment = {
'id': len(self.segment_memory),
'content': content[:512], # 保留关键部分
'summary': self._summarize(content),
'timestamp': metadata['timestamp'],
'importance': metadata.get('importance', 0.5),
'embedding': self._embed(content)
}

# 步骤 2: 确定所属事件
episode = self._find_or_create_episode(segment)

# 步骤 3: 更新时间线
self._update_timeline(episode, segment)

# 步骤 4: 选择性巩固(重要事件强化)
if segment['importance'] > 0.8:
self._consolidate(segment)

def _summarize(self, content):
"""生成事件摘要"""
# 使用 LLM 生成摘要
prompt = f"Summarize in one sentence: {content}"
return llm_generate(prompt)

def _embed(self, content):
"""生成语义嵌入"""
return embedding_model.encode(content)

def _find_or_create_episode(self, segment):
"""找到或创建事件容器"""
# 基于时间接近性和语义相似性
for episode in self.episode_memory:
if self._belongs_to_episode(segment, episode):
episode['segments'].append(segment)
return episode

# 创建新事件
new_episode = {
'id': len(self.episode_memory),
'segments': [segment],
'time_range': (segment['timestamp'], segment['timestamp']),
'theme': self._extract_theme(segment)
}
self.episode_memory.append(new_episode)
return new_episode

记忆巩固机制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def memory_consolidation(memory, sleep_ratio=0.1):
"""
记忆巩固(类似睡眠中的记忆重放)

灵感来自人类睡眠中的记忆巩固过程
"""
# 选择高重要性记忆进行重放
important_segments = [
seg for seg in memory.segment_memory
if seg['importance'] > 0.7
]

# 重放并强化神经连接(模拟)
for segment in important_segments:
# 重新激活相关神经模式
reactivate_pattern(segment)

# 加强与相关记忆的连接
related = find_related_segments(memory, segment)
for r in related:
strengthen_connection(segment, r)

# 剪枝低重要性记忆
prune_low_importance(memory, threshold=0.3)

组件 3:动态检索

基于线索的检索

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
def cue_based_retrieval(memory, current_context, top_k=5):
"""
基于当前上下文的线索检索

Args:
memory: 分层记忆系统
current_context: 当前处理上下文
top_k: 返回记忆数量
"""
# 步骤 1: 编码当前线索
current_embedding = embedding_model.encode(current_context)

# 步骤 2: 多层检索
retrieved = []

# 片段层检索(具体细节)
segment_scores = cosine_similarity(
current_embedding,
[seg['embedding'] for seg in memory.segment_memory]
)
top_segments = top_k_segments(segment_scores, top_k // 2)
retrieved.extend(top_segments)

# 事件层检索(主题上下文)
episode_scores = cosine_similarity(
current_embedding,
[ep['theme_embedding'] for ep in memory.episode_memory]
)
top_episodes = top_k_episodes(episode_scores, top_k // 2)
retrieved.extend(top_episodes)

# 步骤 3: 时间衰减调整
for item in retrieved:
recency_bonus = time_decay(item['timestamp'])
item['score'] *= (1 + recency_bonus)

# 步骤 4: 排序并返回
return sorted(retrieved, key=lambda x: x['score'], reverse=True)[:top_k]


def time_decay(timestamp, half_life=100):
"""时间衰减函数(半衰期 100 个时间单位)"""
elapsed = current_time() - timestamp
return 0.5 ** (elapsed / half_life)

实验结果

实验设置

基准任务

  • BookTest:长篇小说理解(100K-1M tokens)
  • MultiSession:多会话对话(50-200 轮)
  • TimelineQA:时序事件推理
  • LegalDoc:法律文档分析

对比方法

  • Full Attention(完整注意力)
  • Sliding Window(滑动窗口)
  • RAG(检索增强生成)
  • LongLLM(长文本微调模型)

评估指标

  • 检索准确率(Retrieval Accuracy)
  • 回答正确率(Answer Accuracy)
  • 计算成本(FLOPs)
  • 延迟(Latency)

主要结果

BookTest 长篇小说理解

方法 上下文长度 准确率 成本
Full Attention 32K 45.2% 1.0x
Sliding Window 32K 38.5% 0.8x
RAG Unlimited 52.3% 1.5x
LongLLM 128K 58.1% 2.0x
EM-LLM Unlimited 73.5% 0.6x

MultiSession 多轮对话

方法 平均轮数 一致性 相关性
Standard 50 62% 58%
RAG 100 71% 68%
EM-LLM 200+ 85% 82%

记忆检索准确率

方法 @1 @5 @10
BM25 32.1% 58.3% 68.5%
Dense Retrieval 41.5% 67.2% 75.8%
EM-LLM 58.3% 82.1% 89.5%

提升:相比最佳基线 +40% 检索准确率

计算效率

1
2
3
4
5
6
7
8
9
10
11
12
13
14
计算成本对比(相对值):

成本

│ ■ LongLLM: 2.0x

│ ■ RAG: 1.5x

│ ■ Full Attention: 1.0x

│ ■ Sliding Window: 0.8x

│ ■ EM-LLM: 0.6x ← 最低
└─────────────────────────

EM-LLM 效率来源

  1. 稀疏检索替代密集注意力
  2. 分层处理减少计算量
  3. 选择性激活相关记忆

长度泛化能力

1
2
3
4
5
6
7
8
9
10
11
12
13
14
性能 vs 输入长度:

准确率

│ ● EM-LLM (稳定在 70%+)
│ ───────────────
│ ● LongLLM (下降)
│ ╱
│ ● RAG
│ ╱
│ ● Full Attention (快速下降)
└─────────────────────────────
32K 64K 128K 512K 1M+
输入长度

关键发现:EM-LLM 在百万 token 级别仍保持 70%+ 准确率


消融实验

组件贡献

配置 BookTest 检索准确率 成本
EM-LLM (完整) 73.5% 82.1% 0.6x
- 事件分割 65.2% 71.5% 0.7x
- 分层存储 61.8% 65.3% 0.8x
- 动态检索 58.5% 58.2% 0.5x
无记忆(基线) 45.2% 32.1% 1.0x

事件边界质量

边界检测 BookTest 说明
人工标注 75.2% 上限
Surprisal (自动) 73.5% 接近人工
固定长度分段 62.1% 忽视语义
无分段 58.5% 最差

实践指南

使用 EM-LLM

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from em_llm import EMLLM

# 初始化
model = EMLLM(
base_model="meta-llama/Llama-2-7b",
memory_size=10000, # 最大记忆条目
retrieval_top_k=5
)

# 写入记忆(持续进行)
model.remember("用户 Alice 喜欢咖啡,住在伦敦")
model.remember("项目截止日期是下周五")

# 检索并生成
response = model.generate(
"Alice 应该在哪里开会?",
use_memory=True
)
print(response)
# 输出:"考虑到 Alice 住在伦敦,建议安排伦敦的咖啡店..."

超参数配置

参数 推荐值 说明
memory_size 10000 最大记忆容量
retrieval_top_k 5-10 检索记忆数量
boundary_threshold 0.7 事件边界敏感度
importance_threshold 0.3 记忆剪枝阈值

总结

EM-LLM 通过模拟人类情节记忆机制,实现了无限上下文处理:

核心贡献

  1. 事件分割实现语义感知的输入组织
  2. 分层存储支持多粒度记忆访问
  3. 动态检索提供高效的上下文增强

实际价值

  • 百万 token 级上下文处理
  • 40% 检索准确率提升
  • 60% 计算成本降低

资源


评分: 4.5/5.0 ⭐⭐⭐⭐⭐

推荐度: 强烈推荐。长上下文处理的创新方案,认知科学启发设计。

© 2026 Generative AI Discovery All Rights Reserved.
Theme by hiero