Transformer-XL
Transformer 的上下文窗口问题#在我们之前介绍 Transformer时我们提到了位置编码提到了因果掩码但并没有对数据本身展开太多。这里我们先补充一些 Transformer 对文本数据处理细节 展开 Transformer 的上下文窗口逻辑。1.1 长短不一的文本如何统一输入#我们知道注意力本身就是是矩阵运算假设一个 batch 中有三句话文本序列 Tokenize 后 Token 数量“I love AI” [“I”, “love”, “AI”] 3“Transformer is powerful” [“Transformer”, “is”, “powerful”] 3“Hi” [“Hi”] 1显然这种不规则长度根本无法直接组成矩阵。因此Transformer 会使用经典方法Padding填充来把所有序列补齐到同一个长度。例如补到当前 batch 的最长长度原始序列 Padding 后[I, love, AI] [I, love, AI][Transformer, is, powerful] [Transformer, is, powerful][Hi] [Hi, PAD, PAD]这里的 就是填充符 它没有任何语义仅仅用于对齐矩阵来满足模型输入要求。1.2 Attention 如何处理填充符#这里很容易产生一个问题既然填充符也进入了序列那模型会不会真的去关注这些“伪 token”答案是会如果不做额外处理Attention 会把填充符成正常 token 一样参与计算。这显然是无意义的。因此Transformer 引入 Attention Mask也就是注意力掩码它和我们之前提到的解码器阶段的因果掩码不同。它的作用就是在填充的同时生成一组掩码告诉模型输入的哪些位置是填充符不用计算。就像这样显然1 表示有效 token0 表示 PAD.随后在 Attention 内部计算完得到注意力分数后模型会根据掩码把 PAD 位置对应的分数变成这样在进行 Softmax 之时这样PAD 的注意力权重就会归零不污染真正的注意力信息。但是这只是解决了逻辑问题这里还有一个问题计算量问题。1.3 Transformer 如何处理长文本序列#在有了 PAD 后从理论上来说 Transformer 可以处理无限长的序列只要把该 batch 中的其他序列都填充至最长长度就好了。但显然这只是理论。原因在于注意力计算中每一个 token 都要计算和所有 token 的注意力分数,其复杂度为因此计算量会随着序列长度增加而暴涨得到结论Transformer 不可能无限扩展上下文。所以大多数 Transformer 都会设定一个固定长度上下文窗口例如512、1024、2048 等等这就是现在的AI模型记忆的最初形态。当序列长度超过这个窗口长度时Transformer 就会进行切段Segment。例如一个最大上下文窗口长度为的 Transformer如果输入了一篇长度为 1500 tokens 的长文章模型通常会将其切分为以下三段Segment A: [1 ~ 512] tokensSegment B: [513 ~ 1024] tokensSegment C: [1025 ~ 1500] tokens之后这三个 Segment 会只在自己的序列范围内计算注意力从而解决长序列带来的计算量问题。但这也同时带来了新的问题Segment A 中的 token无法看到 Segment B 和 Segment C 中的内容。因为它们不在一个上下文窗口里这就是“看到结尾忘了开头”的原因。这便是 Transformer-XL 的核心改进点同时作者提出了一种改进后的 RPE下面就来详细展开。2.Transformer-XL#现在我们已经理解了原始 Transformer 的核心问题上下文窗口是固定的不同 Segment 之间完全隔离。而 Transformer-XL 的核心思想其实非常直观既然当前窗口看不到历史内容那就把历史窗口缓存下来。下面来分点展开其详细逻辑2.1 记忆缓存 Memory#在展开这部分前我们要先强调一点设计同一个序列的 Segment A、B、C 不会出现在同一个 batch 内而是按顺序出现在前后不同 batch。现在我们来展开 Memory 的内容你就会明白这么设计的原因image.png如图所示我们知道序列数据进入 Transformer block 后会进行注意力计算、融合等处理得到编码信息进行下一步堆叠或其他处理而现在我们新增了一个缓存窗口我们会这这一批次的编码信息存入缓存窗口而下一批次的输出后就会把下一个批次的输出再存入其中。值得一提的是缓存窗口不一定要大于等于上下文窗口。如果设置缓存窗口为 256而上下文窗口是 512 那么只会切分编码信息的最后 256 部分进入缓存窗口。这一步我们是把现在的存下来其作用自然就是在下一步使用来实现“记忆功能”。2.2 Memory 如何参与下一轮 Attention#现在Memory 已经建立好了。接下来真正关键的问题来了历史编码信息到底是如何参与下一轮计算的在这里你会发现这种逻辑非常类似于 RNN 因此我们在这里也称 Memory 为上一轮的隐藏状态而其传递逻辑是这样的image.png这段是递归传递的核心我们来详细展开先回到 Attention 的核心公式我们之前说过Query表示“当前需要什么”Key表示“当前可以提供什么”Value表示“真正携带的信息”因此在当前批次中我们首先要使用自身信息来生成需求即:而为了实现记忆我们就要从当前和缓存中确认供给和真正信息即因此XL 的处理是现将当前批次信息和缓存进行拼接注意这是序列长度维度的拼接所以不会破坏的 Q/K/V 投影计算。展开一下对于其中token 数序列长度embedding 维度如果当前 segment而历史 memory拼接后的结构是这样的相当于memory token1memory token2…current token1current token2…就像把两段句子接起来。所以后面的 KV 投影计算是完全合法的这样在后续的归一化融合部分里当前 token 就可以同时注意当前 segment 和历史 memory实现跨 segment 的注意力。2.3 Segment-Level Recurrence 段级递归#到这里你会发现Transformer-XL 已经开始出现一种“循环结构”了。因为融合了上轮 memory 的当前 segment 的输出会成为下一轮的 memory继续和下一个 segment 融合在各个block 内相继进行这种机制就被称为Segment-Level Recurrence段级递归。image.png这里的“递归”并不是 RNN 那种 token-by-token 的时间递归而是在 Segment 层级上的递归。这种递归保留了 Transformer 的并行计算优势因为 segment 内部仍然是并行 Attention只有 segment 之间是递归的。2.4 Stop Gradient 停止梯度#前面我们已经把正向传播的框架建立完成但一个新的问题就出现了在这种设计里反向传播会让梯度会无限跨 segment 传播。而这会导致反向传播链无限增长训练极度缓慢出现类似 RNN 的长距离依赖问题。因此Transformer-XL 的应对措施是Stop Gradient停止梯度。含义是Memory 可以参与前向传播 但不会参与反向传播。即历史 memory 只作为“只读缓存” 当前 segment 才参与训练更新。image.png当然这也意味着 历史 memory 不会被后续 segment 反向修正。这便催生了后来的研究方向。3.Transformer-XL 里的位置编码问题#前面我们用 Memory 和段级递归解决了跨段信息传递的问题但这同样催生了一个新问题如何进行跨窗口的位置编码举个简单例子假设模型上下文窗口长度为 4一段长文本被切成了两个 segmentSegment 1 Segment 2Position 1 A EPosition 2 B FPosition 3 C GPosition 4 D H引入 Memory 后Segment 2 中的 token 可以看到 Segment 1 的编码信息。这时模型会面对这样一个问题位置 4 到底是指 D第一个 segment 的末尾还是 H第二个 segment 的末尾显然模型无法区分。因为这时的位置编码只依赖在 segment 内部的绝对位置不依赖在原始文本中的实际位置。当两个 segment 的位置编码范围完全相同时模型就出现了位置混淆这就是绝对编码在段级递归场景下的根本缺陷。

相关新闻

现代C++核心特性实战:从C++11到C++20的效率提升与工程实践

现代C++核心特性实战:从C++11到C++20的效率提升与工程实践

1. 项目概述:从“能用”到“好用”的现代C实战演进干了十几年C,从VC6.0的MFC时代一路摸爬滚打到C20,最大的感触就是:语言特性的演进,本质上是在解决我们日常编码中的“不爽”。早期C项目里,满屏的new/delet…

2026/9/26 13:44:37 阅读更多 →
C++适配器模式:解决接口不兼容问题的结构型设计模式

C++适配器模式:解决接口不兼容问题的结构型设计模式

1. 项目概述:为什么我们需要适配器模式?在C的世界里,尤其是在构建大型、复杂的软件系统时,我们常常会遇到一个令人头疼的问题:手头有一个功能强大、逻辑完善的类(或接口),但它提供的…

2026/10/3 20:35:24 阅读更多 →
Python Pygame启动动画开发指南:从原理到实战

Python Pygame启动动画开发指南:从原理到实战

1. 项目概述:为什么我们需要一个启动动画?在桌面应用、独立游戏或者一些工具软件的开发中,第一印象至关重要。用户双击图标后,如果直接弹出一个空白的窗口,或者程序需要几秒钟来加载资源,这段时间的“沉默”…

2026/10/8 12:14:33 阅读更多 →

最新新闻

viewport meta标签:移动Web渲染的底层控制开关

viewport meta标签:移动Web渲染的底层控制开关

1. 为什么“viewport”不是个可有可无的meta标签,而是页面渲染的生死开关你有没有遇到过这样的情况:在手机上打开自己写的网页,文字小得像蚂蚁,图片被强行压缩变形,按钮点不到,滑动卡顿,整个页面…

2026/10/9 10:59:47 阅读更多 →
本地私有知识库搭建:AnythingLLM + Ollama 部署实战指南

本地私有知识库搭建:AnythingLLM + Ollama 部署实战指南

简介:一份面向希望利用本地大模型快速搭建私有知识库的开发者、技术运维及AI应用爱好者的专题PDF,聚焦DeepSeek生态下Ollama与AnythingLLM的集成实践。内容从AnythingLLM的部署方式讲起,覆盖LLM提供商配置、本地文档/Web链接/数据链接三种文档…

2026/10/9 10:59:47 阅读更多 →
编译器是代码的第一位审稿人:从编译流程到高频报错排查

编译器是代码的第一位审稿人:从编译流程到高频报错排查

刚有个读者私信我,说他在Linux下用gcc编译一个C文件,报错信息是“undefined reference tomain”,但他明明写了int main(void)。我看了一眼他的编译命令,只有一个gcc test.c -o test,按说不会缺main。后来他把源码发过来…

2026/10/9 10:59:47 阅读更多 →
企查查爬虫实战:破解key、value与x-pid动态签名机制

企查查爬虫实战:破解key、value与x-pid动态签名机制

说点实在的,企查查这类的爬虫,技术难点从来不在“怎么发请求”,而在“怎么让请求看起来像真的”。我一开始照着网上教程套requests,结果被一串 key 、 value 、 x-pid 拦得死死的,返回的不是 {"code"…

2026/10/9 10:59:47 阅读更多 →
CCNA 200-301备考指南:从PDF到实验的完整学习路径

CCNA 200-301备考指南:从PDF到实验的完整学习路径

简介:这份PDF资料面向准备Cisco CCNA 200-301认证考试的考生,尤其适合希望系统梳理网络基础、IP连接性、安全、自动化与编程等核心考点的自学者和网络从业者。资源为单一PDF文件,压缩包约19.8MB,内容以题库与解析为主,…

2026/10/9 10:59:47 阅读更多 →
基于Python+MILP的风光储联合调度:电池与废弃矿井抽蓄互补优化

基于Python+MILP的风光储联合调度:电池与废弃矿井抽蓄互补优化

这两年搞新能源消纳的调度研究,有个词绕不开:互补。风电场最常见的情况是深夜大风、负荷却躺在地板上,光伏正好相反,正午出力冲顶、电网一时间吃不下。单靠任何一种电源都没法把这条曲线磨平,于是风电、光伏和储能组成…

2026/10/9 10:58:44 阅读更多 →

日新闻

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API这个话题,隔三差五就会在群里被翻出来讨论一次。上周还有个同事线上处理一个订单超时问题,排查到最后发现是ZonedDateTime序列化后时区丢了,用户在下单当天晚上看到的时间整整差了8个小时。这类问题几乎每个做Java开发的人都遇到过…

2026/10/9 0:00:49 阅读更多 →
EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

前几个月我手头有好几台机器需要互相访问:办公室台式机、家里 NAS、还有一台云主机。如果只是偶尔传个文件倒还好,问题是工作场景经常要在几处环境之间来回切换,每次都先登录跳板机再层层代理,实在折腾。我先后试过端口映射、自建…

2026/10/9 0:00:49 阅读更多 →
AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent 这个词在过去一年里被反复提及,但真正动手搭过一套能跑起来的 Agent 系统的人都知道,从"知道它是什么"到"让它稳定干活"之间隔着一整套工程决策。我前后参与过几个 Agent 项目的落地,从最初用现成框架拼装&…

2026/10/9 0:01:50 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:40 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 10:11:06 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 21:13:17 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 6:17:20 阅读更多 →