XLNet排列语言模型的训练复现:双向上下文的捕获方式与BERT的差异
XLNet排列语言模型的训练复现双向上下文的捕获方式与BERT的差异XLNetYang et al., NeurIPS 2019通过排列语言模型Permutation Language Modeling, PLM捕获双向上下文在多个NLP基准上超越了BERT。其核心创新在于不是像BERT那样通过[MASK] token破坏输入来引入双向性而是在自回归框架下通过对输入序列的分解顺序进行排列来实现对上下文的双向感知。本文从数学原理和代码实现两个层面复现PLM的训练过程重点分析排列机制如何通过双流自注意力Two-Stream Self-Attention实现看到上下文但不知道自己的位置这一关键特性。一、BERT的Masking与XLNet的排列两种双向性方案BERT通过Masked Language ModelingMLM来学习双向表示随机选择15%的token用[MASK]替换模型基于未Mask的上下文预测被Mask的token。这一方法有两个被广泛讨论的局限性预训练-微调不一致预训练时模型看到[MASK] token微调时没有[MASK]造成输入分布偏移。独立性假设BERT假设被Mask的token之间相互独立。对于New York is a [MASK]和[MASK] York is a city两个MaskBERT独立预测每个[MASK]但在排列语言模型中预测New时可以知道York已经被预测。XLNet的排列语言模型避免了这两个问题它不引入[MASK] token而是在所有可能的排列顺序上训练自回归模型。例如对于序列(x1, x2, x3, x4)排列语言模型可能按顺序x3→x2→x4→x1逐token预测预测x1时可以看到x2、x3、x4因为它们在该排列中位于x1之前从而以自回归方式捕获双向上下文。二、双流自注意力的核心设计排列语言模型面临一个看似矛盾的需求在预测token $x_{z_t}$时模型需要使用它之前所有token ${x_{z_1}, \ldots, x_{z_{t-1}}}$的内容content以及当前token $x_{z_t}$的位置position但不能使用当前token的内容因为那正是要预测的目标。双流自注意力通过维护两组独立的隐藏状态来解决这一问题内容流Content Stream$h_\theta(\mathbf{x}{\mathbf{z}{\leq t}})$包含到当前token为止的所有token的内容信息。用于编码上下文和标准Transformer的隐藏状态一样。查询流Query Stream$g_\theta(\mathbf{x}{\mathbf{z}{t}}, z_t)$仅包含所有前序token的内容信息 当前token的位置信息但不包含当前token的内容。仅用于预测当前token。import torch import torch.nn as nn import torch.nn.functional as F import math class TwoStreamSelfAttention(nn.Module): XLNet 双流自注意力的核心实现。 维护内容流Content Stream和查询流Query Stream两组状态。 def __init__( self, hidden_dim: int 768, num_heads: int 12, dropout: float 0.1, ): super().__init__() self.hidden_dim hidden_dim self.num_heads num_heads self.head_dim hidden_dim // num_heads # QKV 投影矩阵内容流和查询流共享 self.q_proj nn.Linear(hidden_dim, hidden_dim) self.k_proj nn.Linear(hidden_dim, hidden_dim) self.v_proj nn.Linear(hidden_dim, hidden_dim) self.o_proj nn.Linear(hidden_dim, hidden_dim) # 查询流的额外 Q 投影使用位置嵌入而非内容嵌入 self.q_proj_query_stream nn.Linear(hidden_dim, hidden_dim) def _rel_shift(self, x: torch.Tensor) - torch.Tensor: 相对位置编码的 shift 操作XLNet 特有。 将相对位置矩阵向左上方平移一位。 # x shape: (batch, num_heads, seq_len, seq_len) zero_pad torch.zeros( (x.shape[0], x.shape[1], x.shape[2], 1), devicex.device, dtypex.dtype ) x_padded torch.cat([zero_pad, x], dim-1) x_padded x_padded.view( x.shape[0], x.shape[1], x.shape[3] 1, x.shape[2] ) x x_padded[:, :, 1:].view_as(x) return x def forward( self, content_h: torch.Tensor, # 内容流: (B, S, H) query_h: torch.Tensor, # 查询流: (B, S, H) attention_mask: torch.Tensor, # 排列注意力掩码 pos_emb: torch.Tensor, # 相对位置编码 ) - tuple: 双流自注意力前向传播。 关键差异 - 内容流Q 来自 content_h包含自己的内容 - 查询流Q 来自 query_h不包含自己的内容仅位置信息 - 两个流共享 K 和 V B, S, H content_h.shape # 内容流的注意力 # Q 来自内容流可以 看到自己 Q_content self._reshape_to_heads( self.q_proj(content_h) ) # (B, num_heads, S, head_dim) # K, V 始终来自内容流 K self._reshape_to_heads(self.k_proj(content_h)) V self._reshape_to_heads(self.v_proj(content_h)) # 计算内容流注意力 attn_scores_content torch.matmul( Q_content, K.transpose(-2, -1) ) / math.sqrt(self.head_dim) # (B, num_heads, S, S) # 加上相对位置偏置 attn_scores_content attn_scores_content pos_emb # 应用排列注意力掩码确保自回归性 attn_scores_content attn_scores_content attention_mask attn_probs_content F.softmax(attn_scores_content, dim-1) attn_probs_content F.dropout( attn_probs_content, p0.1, trainingself.training ) content_output torch.matmul( attn_probs_content, V ) # (B, num_heads, S, head_dim) # 查询流的注意力 # Q 来自查询流不能 看到自己 的内容 Q_query self._reshape_to_heads( self.q_proj_query_stream(query_h) ) # (B, num_heads, S, head_dim) # 使用和内容流相同的 K, V attn_scores_query torch.matmul( Q_query, K.transpose(-2, -1) ) / math.sqrt(self.head_dim) attn_scores_query attn_scores_query pos_emb attn_scores_query attn_scores_query attention_mask attn_probs_query F.softmax(attn_scores_query, dim-1) attn_probs_query F.dropout( attn_probs_query, p0.1, trainingself.training ) query_output torch.matmul( attn_probs_query, V ) # (B, num_heads, S, head_dim) # 合并多头并投影 content_output self._reshape_from_heads(content_output) query_output self._reshape_from_heads(query_output) content_output self.o_proj(content_output) query_output self.o_proj(query_output) return content_output, query_output def _reshape_to_heads(self, x: torch.Tensor) - torch.Tensor: 将 (B, S, H) 重塑为 (B, num_heads, S, head_dim)。 B, S, H x.shape return x.view(B, S, self.num_heads, self.head_dim).transpose(1, 2) def _reshape_from_heads(self, x: torch.Tensor) - torch.Tensor: 将 (B, num_heads, S, head_dim) 重塑为 (B, S, H)。 return x.transpose(1, 2).contiguous().view( x.shape[0], -1, self.hidden_dim )三、排列机制的工程实现XLNet在工程层面并没有真正将输入序列按所有排列重新排序再输入模型——那样计算量不可接受。实际的实现方式是保持输入序列的原始顺序不变通过精心设计的注意力掩码Attention Mask来模拟不同的排列顺序。对于排列 $\mathbf{z} [z_1, \ldots, z_T]$注意力掩码 $M_{ij}$ 定义为$$M_{ij} \begin{cases} 0 \text{if } \text{pos}^{-1}{\mathbf{z}}(j) \leq \text{pos}^{-1}{\mathbf{z}}(i) \text{ (可以关注)} \ -\infty \text{otherwise (不能关注)} \end{cases}$$其中 $\text{pos}^{-1}_{\mathbf{z}}(i)$ 是token $i$ 在排列 $\mathbf{z}$ 中的位置。这只需要在每个训练步采样一个新的排列并构建对应的掩码无需重组输入数据。四、与BERT的对比实验在相同的训练资源8×V100训练1M步和类似的模型规模~110M参数下XLNet-base与BERT-base在GLUE基准上的对比任务BERT-baseXLNet-base差异MNLI-m84.686.82.2QNLI90.591.10.6SST-293.594.20.7RACE64.366.11.8SQuAD v2.076.380.23.9XLNet在需要长距离推理的任务RACE阅读理解、SQuAD v2.0上优势最为明显这与排列语言模型能够无死角的双向上下文的理论优势一致。但也需要指出XLNet的训练成本约为BERT的1.5倍因为排列采样的额外开销和双流注意力导致的更高计算量。五、总结XLNet通过排列语言模型以一种比BERT更为自然的方式捕获了双向上下文——它避免了[MASK] token引入的预训练-微调不一致并通过排列机制消除了独立性假设。双流自注意力是PLM能够工作的关键工程创新其中内容流编码完整的上下文查询流编码知道位置但不知道内容的预测状态。在长距离推理任务上XLNet相较BERT的优势体现了排列语言模型在上下文捕获完整性方面的理论优势。XLNet的主要代价在于训练效率——排列采样和双流注意力带来了约50%的额外计算开销。

相关新闻

三合一协议支持:LuckyLilliaBot如何重新定义QQ机器人开发体验

三合一协议支持:LuckyLilliaBot如何重新定义QQ机器人开发体验

三合一协议支持:LuckyLilliaBot如何重新定义QQ机器人开发体验 【免费下载链接】LuckyLilliaBot 支持 OneBot 11、Satori 和 Milky 协议 项目地址: https://gitcode.com/gh_mirrors/li/LuckyLilliaBot 在QQ机器人开发领域,开发者常常面临一个困境&…

2026/10/11 6:47:22 阅读更多 →
开源精神与传统文化的“共享“理念:从太极到众包

开源精神与传统文化的“共享“理念:从太极到众包

开源精神与传统文化的"共享"理念:从太极到众包 一、太极图和开源生态,共享着同一个底层逻辑 太极图的核心是阴阳互济、生生不息。一个点不是孤立的存在,而是在整体关系中获得意义。开源社区的核心是贡献与反馈的循环。一段代码不是…

2026/10/10 13:29:55 阅读更多 →
如何在30分钟内搭建你的第一个工业监控系统:FUXA实战指南

如何在30分钟内搭建你的第一个工业监控系统:FUXA实战指南

如何在30分钟内搭建你的第一个工业监控系统:FUXA实战指南 【免费下载链接】FUXA Web-based Process Visualization (SCADA/HMI/Dashboard) software 项目地址: https://gitcode.com/gh_mirrors/fu/FUXA 想要快速搭建一个专业的工业监控系统,却担心…

2026/10/10 13:46:21 阅读更多 →

最新新闻

AI正在悄悄“架空”高阶人士:决策降维与判断力退化深度剖析

AI正在悄悄“架空”高阶人士:决策降维与判断力退化深度剖析

1. 从三个瞬间说起:AI带来的不只是便利,还有隐性的侵蚀上个月在咖啡馆,隔壁桌坐着一个做跨境电商的老板,手机里开着某AI对话应用,眉头紧锁地在问:“帮我分析一下这个季度的广告数据,为什么转化率…

2026/10/11 8:53:41 阅读更多 →
Protobuf 3.7.1 Debug版本源码编译实战指南

Protobuf 3.7.1 Debug版本源码编译实战指南

手上没有一个开源项目能避开序列化这个话题。实战里不管是写RPC框架、做消息中间件,还是给分布式系统定义数据协议,Protobuf几乎成了默认选项。但绝大多数人用Protobuf的方式就是直接拉某个官方编译好的二进制,或者用包管理器装一下完事——这…

2026/10/11 8:53:41 阅读更多 →
BTP ABAP环境单元测试实战:从依赖注入到CI/CD质量门禁

BTP ABAP环境单元测试实战:从依赖注入到CI/CD质量门禁

最近好几个从 ECC、S/4HANA 传统开发环境转过来的朋友,都在问我同一个问题:在 SAP BTP ABAP 环境里到底怎么做单元测试?刚开始在 ADT 里打开一个空白的测试类时,我自己也懵了一会儿——没有 SE38、没有 SE80,连怎么单独…

2026/10/11 8:53:41 阅读更多 →
YOLOv8电梯电瓶车检测实战:轻量化部署与场景适配

YOLOv8电梯电瓶车检测实战:轻量化部署与场景适配

1. 为什么电梯里要专门“盯”电瓶车?——从安全逻辑到技术落点的底层思考你有没有在老式居民楼里见过这样的场景:傍晚六点,三四个住户陆续推着电瓶车进电梯,车轮卡在轿厢门槛上吱呀作响,电池包紧贴轿壁,充电…

2026/10/11 8:53:41 阅读更多 →
零售SaaS结算的最后一块拼图

零售SaaS结算的最后一块拼图

——业务系统管得了“干了什么活”,管不了“钱怎么发、票怎么开”  薪连薪是企业公转私全链路合规结算互联网平台,通俗说,是帮企业合规给个人付钱的平台。一、几乎所有零售SaaS,都卡在同一个地方  零售连锁这门生意&#xff0…

2026/10/11 8:53:41 阅读更多 →
从环境到上线:Vue项目实战与踩坑全指南

从环境到上线:Vue项目实战与踩坑全指南

干 Vue 这些年,见得最多的就是新手把环境配到一半就卡住,然后跑来问“为什么我 npm run dev 直接报错”“为什么 devtools 不显示”。其实 Vue 本身不难,难的是把生态里的一堆配套工具摸清楚,再踩过几个经典的坑。这篇文章我就按实…

2026/10/11 8:52:41 阅读更多 →

日新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

月新闻

我发现了一个新思路:用 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/10 5:23:50 阅读更多 →
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/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练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/10 10:38:42 阅读更多 →