Context Window/上下文窗口:AI的短期记忆
这篇文章带你理解AI的"记忆容量"——上下文窗口,明白为什么AI有"健忘症"。
前言
你有没有遇到这种情况:
让AI总结一篇长文章,它说"内容太长,超出限制" 跟AI聊了很久,它突然忘了前面说过的话 看到模型宣传"128K上下文",不知道是什么意思
这一切都跟一个概念有关:Context Window(上下文窗口)
一、黑话原文 vs 人话翻译
场景模拟
🎯 AI产品经理会议:
PM:"用户反馈说对话太长就忘了前面的内容"
工程师:"那是Context Window限制,4K的窗口用完了"
PM:"能不能扩大一点?"
工程师:"可以,但显存会爆炸,推理也变慢"
PM:"竞品都支持200K了"
工程师:"他们用的Flash Attention,我们下个版本也上"
人话翻译表
| 黑话 | 人话翻译 | 一句话理解 |
|---|---|---|
| Context Window | 上下文窗口 | AI的短期记忆容量 |
| 4K/128K/200K | Token数量限制 | 能记住多少内容 |
| Sliding Window | 滑动窗口 | 只记住最近的内容 |
| Context Overflow | 上下文溢出 | 记不住了 |
| Long Context | 长上下文 | 大容量记忆 |
| Flash Attention | 闪电注意力 | 处理长文本的技术 |
二、Context Window是什么?
2.1 一句话定义
Context Window = AI一次性能处理的最大Token数量
人话版:AI的"短期记忆容量",超过这个限制就会"忘记"前面的内容。
2.2 生活类比
┌─────────────────────────────────────────────────────────────┐
│ Context Window就像... │
├─────────────────────────────────────────────────────────────┤
│ │
│ 📝 便利贴 │
│ - 小便利贴(4K):只能写几句话 │
│ - 大便利贴(128K):能写一篇论文 │
│ │
│ 🧠 人类短期记忆 │
│ - 普通人:能记住刚才说的7±2件事 │
│ - AI:能记住Context Window内的所有内容 │
│ │
│ 📱 手机内存 │
│ - 内存小:开几个App就卡 │
│ - 内存大:开再多也流畅 │
│ │
└─────────────────────────────────────────────────────────────┘
2.3 为什么有这个限制?
技术原因:
1. 显存限制
每个Token都要存储中间计算结果
Token越多 → 占用显存越大
2. 计算复杂度
Attention复杂度是 O(n²)
Token翻倍 → 计算量翻四倍
3. 推理速度
Context越长 → 响应越慢
所以:
Context Window是 效果 vs 成本 的平衡
三、各模型的Context Window
3.1 主流模型对比
| 模型 | Context Window | 约等于中文 |
|---|---|---|
| GPT-3.5-turbo | 4K | ~2000字 |
| GPT-4 | 8K | ~5000字 |
| GPT-4-32K | 32K | ~2万字 |
| GPT-4-Turbo | 128K | ~8万字 |
| Claude 2 | 100K | ~6万字 |
| Claude 3 | 200K | ~13万字 |
| Gemini 1.5 Pro | 1M | ~67万字 |
| Kimi | 200K | ~13万字 |
3.2 Context Window可视化
┌─────────────────────────────────────────────────────────────┐
│ Context Window对比图 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 4K ████ │
│ 8K ████████ │
│ 32K ████████████████████████████ │
│ 128K ████████████████████████████████████████████████████ │
│ 200K ████████████████████████████████████████████████████████████
│ 1M ████████████████████████████████████████████████████████████████████████████████████████████████
│ │
│ 比例:1M = 256个4K │
│ Gemini 1.5 Pro 能处理的书 ≈ 《三体》全集 │
│ │
└─────────────────────────────────────────────────────────────┘
3.3 实际能装多少内容?
┌─────────────────────────────────────────────────────────────┐
│ Context Window容量参考 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 4K (GPT-3.5) │
│ ├── 短文:2-3篇 │
│ └── 对话:10-15轮 │
│ │
│ 32K (GPT-4-32K) │
│ ├── 长文:1-2章小说 │
│ └── 对话:50-80轮 │
│ │
│ 128K (GPT-4-Turbo) │
│ ├── 长文:1本短篇小说 │
│ └── 对话:200+轮 │
│ │
│ 200K (Claude 3) │
│ ├── 长文:2-3本小说 │
│ └── 对话:300+轮 │
│ │
│ 1M (Gemini 1.5) │
│ ├── 长文:《三体》全集 │
│ └── 代码:大型项目全部代码 │
│ │
└─────────────────────────────────────────────────────────────┘
四、超过Context Window会怎样?
4.1 三种处理方式
┌─────────────────────────────────────────────────────────────┐
│ 超出限制的处理 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. 直接报错 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Error: This model's maximum context length is 4096 │ │
│ │ tokens, however you requested 5000 tokens. │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 2. 自动截断 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ [前面内容被截断...] ←后面的内容 │ │
│ │ AI只能看到最后N个Token │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 3. 滑动窗口 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 旧内容[出窗口] → 新内容[进窗口] │ │
│ │ 永远只保留最近N个Token │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
4.2 信息丢失的影响
对话场景:
轮次1:我叫小明,今年25岁,住在北京...
轮次2:我喜欢打篮球和看电影...
...
轮次50:(Context Window满了,轮次1的内容丢了)
轮次51:你还记得我叫什么吗?
AI:抱歉,我不太确定您的名字...
这就是为什么长对话会"失忆"
五、如何处理长文本?
5.1 方案对比
| 方案 | 原理 | 优点 | 缺点 |
|---|---|---|---|
| 分块处理 | 切成小块分别处理 | 简单 | 可能丢失全局信息 |
| 摘要压缩 | 先总结再处理 | 保留要点 | 损失细节 |
| 向量检索 | 只取相关部分 | 高效 | 需要额外索引 |
| 长上下文模型 | 直接支持 | 最直接 | 成本高 |
5.2 分块处理示例
def process_long_text(text, model, chunk_size=3000, overlap=200):
"""
分块处理长文本
"""
# 分块
chunks = []
for i in range(0, len(text), chunk_size - overlap):
chunk = text[i:i + chunk_size]
chunks.append(chunk)
# 分别处理
results = []
for chunk in chunks:
result = model.process(chunk)
results.append(result)
# 合并结果
return merge_results(results)
# 示例:处理10万字的小说
text = "..." # 10万字
summary = process_long_text(text, model)
5.3 RAG方案
# RAG (Retrieval-Augmented Generation)
# 适合:文档问答、知识库检索
def rag_query(query, documents, model, top_k=5):
"""
RAG查询流程
"""
# 1. 文档切片
chunks = split_documents(documents, chunk_size=500)
# 2. 向量化
chunk_embeddings = [get_embedding(chunk) for chunk in chunks]
query_embedding = get_embedding(query)
# 3. 检索相关片段
similarities = [
cosine_similarity(query_embedding, ce)
for ce in chunk_embeddings
]
top_indices = sorted(range(len(similarities)),
key=lambda i: similarities[i],
reverse=True)[:top_k]
# 4. 构建Context
context = "\n".join([chunks[i] for i in top_indices])
# 5. 生成回答
prompt = f"""
根据以下内容回答问题:
{context}
问题:{query}
"""
return model.generate(prompt)
六、Long Context技术
6.1 为什么长上下文这么难?
┌─────────────────────────────────────────────────────────────┐
│ 长上下文的挑战 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. 显存爆炸 │
│ Attention需要存储 n×n 的矩阵 │
│ 4K tokens → 16M 个数 │
│ 128K tokens → 16B 个数 (1000倍!) │
│ │
│ 2. 计算量爆炸 │
│ 复杂度 O(n²) │
│ Token翻倍 → 计算翻四倍 │
│ │
│ 3. 中间迷失 │
│ 信息在长序列中"淹没" │
│ 模型可能忽略中间的重要内容 │
│ │
└─────────────────────────────────────────────────────────────┘
6.2 解决方案
长上下文技术:
Flash Attention:
原理: 优化内存访问模式
效果: 快2-4倍,省显存
代表: GPT-4-Turbo
Ring Attention:
原理: 分片计算
效果: 理论上无限长
代表: 某些研究模型
ALiBi Position Encoding:
原理: 更好的位置编码
效果: 能外推到更长序列
代表: MPT
Sparse Attention:
原理: 只计算部分Attention
效果: 降低复杂度
代表: Longformer
6.3 长上下文的能力
┌─────────────────────────────────────────────────────────────┐
│ 长上下文能做什么 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ✅ 整本书分析 │
│ - 总结全书内容 │
│ - 分析人物关系 │
│ - 找出伏笔 │
│ │
│ ✅ 大型代码库理解 │
│ - 分析整个项目 │
│ - 找出相关代码 │
│ - 理解调用关系 │
│ │
│ ✅ 长期对话记忆 │
│ - 记住之前的对话 │
│ - 保持人设一致 │
│ - 引用历史内容 │
│ │
│ ✅ 多文档综合 │
│ - 对比多个文档 │
│ - 跨文档找信息 │
│ - 综合分析 │
│ │
└─────────────────────────────────────────────────────────────┘
七、Context Window vs 实际使用
7.1 不是越大越好
┌─────────────────────────────────────────────────────────────┐
│ Context Window的权衡 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 大Context Window: │
│ ✅ 能处理更多内容 │
│ ✅ 不容易遗忘 │
│ ❌ 显存占用大 │
│ ❌ 推理速度慢 │
│ ❌ 费用更高 │
│ │
│ 小Context Window: │
│ ✅ 响应快 │
│ ✅ 成本低 │
│ ❌ 内容受限 │
│ ❌ 容易遗忘 │
│ │
│ 结论:根据任务选择合适的Context Window │
│ │
└─────────────────────────────────────────────────────────────┘
7.2 实际建议
| 任务类型 | 推荐Context | 原因 |
|---|---|---|
| 简单问答 | 4K-8K | 够用,响应快 |
| 文档总结 | 32K-128K | 需要看全文 |
| 代码审查 | 32K+ | 代码量可能很大 |
| 长对话 | 32K+ | 积累的对话多 |
| 书籍分析 | 128K+ | 一本书很长 |
小结
| 黑话 | 人话 | 记忆口诀 |
|---|---|---|
| Context Window | 上下文窗口 | AI的短期记忆 |
| 4K/128K | Token限制 | 能记住多少 |
| Sliding Window | 滑动窗口 | 只记最近的 |
| Long Context | 长上下文 | 大容量记忆 |
| Flash Attention | 闪电注意力 | 处理长文本技术 |
关键认知:
- Context Window是AI的记忆容量
- 超过限制会遗忘或报错
- 长文本需要分块或其他策略
- 不是越大越好,要看任务需求
黑话等级
⭐⭐⭐ 进阶级
├── 理解Context Window是什么
├── 知道各模型的限制
└── 会处理长文本场景
恭喜完成Part 2模型架构黑话!
下一部分:训练方法黑话
思考与练习
-
思考题:
- 为什么Attention的复杂度是O(n²)?
- 长上下文有什么实际应用场景?
-
动手练习:
- 测试不同长度文本对模型的影响
- 实现一个简单的分块处理函数
-
延伸探索:
- 了解Flash Attention的原理
- 研究RAG的实现
下期预告
下一篇文章,我们来聊:Pre-training/预训练 - AI的"通识教育"
会解答这些问题:
- 预训练到底训练什么?
- 为什么说预训练是"读万卷书"?
- 预训练和微调有什么区别?
关注专栏,不错过后续更新!
作者:ECH00O00 本文首发于掘金专栏《AI黑话翻译官》 欢迎评论区交流讨论,点赞收藏就是最大的鼓励