新闻详情

新闻详情

首页 / 资讯中心 / 详情

从Attention到BERT:双向预训练语言模型到底解决了什么问题

发布时间:2026/10/2 13:57:08来源:尧图网络
从Attention到BERT:双向预训练语言模型到底解决了什么问题
从一次文本分类的困境说起几年前我做过一个情感分类的小任务数据量不大大概几千条中文评论。当时第一反应是用 Word2Vec 训练词向量再套一个 LSTM 做分类。结果跑出来准确率一直卡在 80% 出头怎么调都上不去。问题出在哪我盯着几个错例看了很久。有一条评论是这家店的服务态度真是没得说模型判成了负面。原因很简单Word2Vec 给没和得这两个字分配的向量是固定的跟上下文无关。而没得说整体是褒义模型却只看单个字。这就是静态词向量的死穴——同一个词不管出现在什么句子里向量永远一样。而自然语言里词义高度依赖上下文。BERT 要解决的正是这个问题。它不是第一个预训练语言模型但它把双向这件事做成了标配从此 NLP 的玩法变了。单向语言模型的天花板在哪里在 BERT 之前比较有代表性的是 ELMo 和 GPT。ELMo 的思路是用两个方向的 LSTM 分别读句子一个从左往右一个从右往左然后把两边的隐状态拼起来。听起来像是双向但要注意这两个方向是独立训练的只是在最后拼接。模型在预测某个词的时候左边那半并不知道右边看到了什么右边那半也不知道左边看到了什么。这更像是两个单向模型的拼盘而不是真正的双向。GPT 走的是另一条路用 Transformer 的 Decoder做标准的自回归语言模型预测下一个词。这种结构天生是单向的因为预测第 t 个词时只能看到前 t-1 个词。单向模型对生成类任务是合适的写文章、续写句子本来就只能从左往右。但对理解类任务比如分类、问答、实体识别句子是完整摆在面前的凭什么只能看半边有人可能会想那我把句子反过来再训一个模型两个拼一起不就行了ELMo 就是这么干的效果确实比纯单向好但前面说了两个方向没有真正交互。真正的问题在于如果直接让模型同时看左右两边来预测中间词会发生什么答案很简单——信息泄露。你要预测第 t 个词如果模型能看到第 t 个词本身那它什么都不用学直接抄答案就行。这就是双向预训练最难绕过去的坎。Masked LM把答案藏起来再让人猜BERT 的解法非常直接既然不能让你看到要预测的词那我就把它遮住。具体做法是随机选句子中 15% 的 token然后其中 80% 替换成[MASK]标记10% 替换成一个随机的其他词10% 保持不变。然后让模型去预测这些位置原本是什么词。我第一次看到这个设计时觉得有点奇怪为什么不全部换成[MASK]非要留 10% 随机词、10% 不变这里其实是工程上的权衡。如果训练时全是[MASK]那模型只在看到[MASK]的时候才认真预测而下游微调时根本没有[MASK]这个标记训练和推理的输入分布就对不上了。掺入随机词和原词是为了让模型对每个位置都保持一定的预测能力缩小预训练和微调之间的差距。【注意】这个 80/10/10 的比例是 BERT 原论文里的设定后来有不少工作质疑过它的最优性比如 RoBERTa 就试过其他方案。但作为理解 BERT 的入口这个设计足够说明问题。用 HuggingFace 的 transformers 库可以很直观地看到 Masked LM 的效果。下面这段代码用的是bert-base-chinesetransformers 版本我测试时是 4.40 左右fromtransformersimportpipeline# 使用中文 BERT 做掩码填充unmaskerpipeline(fill-mask,modelbert-base-chinese,top_k3)text这家店的 service 态度真是 [MASK] 得说resultsunmasker(text)forrinresults:print(r[token_str],round(r[score],4))模型会给[MASK]位置填上概率最高的几个候选词。这里我想强调的是BERT 在预测这个词的时候是同时看了左边这家店的服务态度真是和右边得说的。左边告诉它这是评价场景右边告诉它后面跟着得说这种固定搭配。两边的信息同时参与这正是双向的价值。注意力掩码双向是怎么在代码里实现的理解 BERT 的双向绕不开注意力掩码attention mask。这也是很多人第一次读源码时容易懵的地方。Transformer 的 Self-Attention 本质是每个 token 去看其他所有 token然后加权求和。GPT 这类自回归模型需要一个上三角的掩码矩阵把当前位置之后的位置全部屏蔽掉保证只能看左边importtorchdefcausal_mask(seq_len):# 上三角为 1表示需要屏蔽的位置masktorch.triu(torch.ones(seq_len,seq_len),diagonal1)# 转换成 attention 用的形式被屏蔽处为 -infmaskmask.masked_fill(mask1,float(-inf))returnmaskprint(causal_mask(4))输出是一个 4x4 的矩阵右上角全是负无穷意味着第 0 个 token 不能看第 1、2、3 个 token。而 BERT 用的是 Transformer 的 Encoder它根本不需要这个上三角掩码。每个 token 都能看到包括自己在内的所有 token。代码上就是不做任何屏蔽注意力矩阵是完整的。所以你去看 BERT 的源码会发现它处理的是 padding mask把补齐的短句部分屏蔽掉而不是 causal mask。这个区别看着小但决定了模型是单向还是双向。【关键结论】BERT 的双向不是靠什么特殊结构实现的而是靠不做因果掩码加上Masked LM 训练目标这两件事配合出来的。结构上放开双向目标上防止作弊缺一不可。[CLS] 和 NSP句子级别的表示从哪来Masked LM 解决的是 token 级别的理解但很多下游任务是句子级别的比如判断两句话是不是承接关系、整段文本是什么情感。BERT 的做法是在每个输入序列最前面加一个特殊的[CLS]标记。经过多层 Transformer 之后这个位置的输出向量会被当作整个句子的聚合表示接一个简单的分类层就能做句子级任务。为什么是[CLS]而不是把所有 token 的向量平均一下因为[CLS]没有具体的词义它在训练中唯一的作用就是汇聚全局信息。经过预训练模型会学着把句子级别的语义塞进这个位置。这也是一种让模型自己学怎么聚合的思路比人工设计池化规则更灵活。另一个预训练任务是 NSPNext Sentence Prediction。构造训练样本时一半的样本 B 是 A 的真实下一句另一半是从语料里随机抽的句子让模型判断 B 是不是 A 的下一句。这个任务是为了让模型学到句子之间的关系。不过 NSP 后来争议很大。RoBERTa 的实验显示去掉 NSP 反而效果更好或者换成更难的句子顺序预测SOP效果更佳。所以现在如果你要自己预训练NSP 不是必须的。但理解 BERT 的原始设计NSP 是绕不开的一环。微调为什么 BERT 用起来这么省事BERT 真正让它流行的不只是预训练本身而是预训练 微调这套范式。以前做 NLP 任务每个任务都要从头设计网络结构、从头训练。有了 BERT 之后流程变成加载预训练权重在最后接一个任务相关的小输出层用少量标注数据微调几个 epoch。下面是一个最小可运行的文本分类微调示例用的是 transformers 的Trainerfromtransformersimport(BertTokenizer,BertForSequenceClassification,Trainer,TrainingArguments)fromdatasetsimportDatasetimporttorch model_namebert-base-chinesetokenizerBertTokenizer.from_pretrained(model_name)modelBertForSequenceClassification.from_pretrained(model_name,num_labels2)# 假设已有文本和标签texts[这家店服务很好,东西太差了不会再买,味道不错,完全不推荐]labels[1,0,1,0]deftokenize(batch):returntokenizer(batch[text],paddingmax_length,truncationTrue,max_length64)datasetDataset.from_dict({text:texts,label:labels})datasetdataset.map(tokenize,batchedTrue)argsTrainingArguments(output_dir./bert_cls,num_train_epochs3,per_device_train_batch_size8,learning_rate2e-5,logging_steps10)trainerTrainer(modelmodel,argsargs,train_datasetdataset)trainer.train()几个工程上的注意点学习率一定要小。BERT 微调常用的学习率是 2e-5 到 5e-5 这个量级比从头训练小一两个数量级。因为预训练权重已经学到了很好的表示学习率太大会把学到的知识冲掉。epoch 不要多。通常 2 到 4 个 epoch 就够了。BERT 参数量大在小数据集上很容易过拟合跑十几个 epoch 反而掉点。max_length要按任务选。BERT 的输入上限是 512 个 token但很多任务用不到那么长。短文本设 64 或 128 就够能明显省显存和时间。BERT 和它的同类到底怎么选到这一步可以用一张表把几个常见方案的差异理清楚方案核心思路优点缺点适用场景Word2Vec/GloVe静态词向量轻量、快、可离线词义与上下文无关资源极受限、简单任务ELMo双向 LSTM 拼接引入上下文相关表示两方向独立、交互弱早期 NLP 任务GPT自回归单向生成能力强理解类任务受限文本生成、续写BERT双向 Encoder MLM理解类任务强、微调方便不擅长生成、输入长度受限分类、问答、NER、句对任务【关键结论】BERT 不是万能的它的强项是理解弱项是生成。如果你的任务是写文案、续写、对话生成单向的 GPT 系模型更合适。选型要看任务性质不是看谁更新。实际使用中容易忽略的几点第一中文要用中文预训练权重。bert-base-chinese是在中文语料上训的直接用英文版bert-base-uncased处理中文tokenizer 会把汉字拆得乱七八糟效果会差很多。第二BERT 的 tokenizer 是 WordPiece会把罕见词拆成子词。这对处理未登录词有好处但也意味着 token 数和你直觉上的字数不一样。做长度统计时要以 token 数为准。第三输入长度 512 是硬限制超过就要截断或分段。长文本任务比如长文档分类需要额外设计比如分段后聚合、或者换用 Longformer、BigBird 这类支持长序列的变体。第四[CLS]向量直接拿来做相似度效果一般。原论文就提到过句子相似度这类任务用[CLS]不如用句对输入效果好。后来 Sentence-BERT 专门针对这个问题做了改进用孪生网络结构训练出更适合相似度计算的句向量。写在最后BERT 的价值不在于它有多复杂恰恰相反它的核心设计简洁得有点朴素用 Transformer Encoder放开双向然后用 Masked LM 防止作弊。但就是这套组合把预训练语言模型从能用的工具变成了标配的基础设施。回头看它真正改变的是工作方式。以前每个 NLP 任务都要单独设计模型现在大多数任务的第一步都是先加载一个预训练模型看看 baseline。这种范式的转变比任何单个技术点都重要。如果你现在要上手我的建议是先跑通一个微调例子再回头读源码里的 attention mask 部分。搞清楚为什么 BERT 不需要因果掩码比记住多少参数有用得多。至于后续演进RoBERTa、ALBERT、ELECTRA 都是在 BERT 基础上做的改进理解 BERT 是理解它们的前提。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Linux驱动ioctl()原理与健壮实现指南 2026/10/2 14:39:16

Linux驱动ioctl()原理与健壮实现指南

1. 为什么说 ioctl() 是驱动开发里最常被误解、也最容易出问题的“万能接口” 在 Linux 驱动开发的实战现场,你几乎每天都会遇到它—— ioctl() 。它不像 open() 那样只管打开设备,也不像 read() / write() 那样只做数据搬运;它更像一…

阅读更多 →
COMSOL三维Voronoi晶体轴压模拟:从几何建模到结果分析全流程 2026/10/2 14:39:16

COMSOL三维Voronoi晶体轴压模拟:从几何建模到结果分析全流程

开年那会儿接了一个晶体轴压模拟的需求,第一反应是:这种带随机多晶结构的模型,COMSOL里到底怎么搭才不折腾?真正把流程跑通之后回头看,整条路的核心其实就两件事——一是用三维Voronoi算法把多晶几何“长”出来&#x…

阅读更多 →
从零搭建AI生视频Agent:扣子工作流与ComfyUI实战指南 2026/10/2 14:39:16

从零搭建AI生视频Agent:扣子工作流与ComfyUI实战指南

AI 生视频这个赛道,最近半年我身边做内容的朋友几乎都在聊。有人用扣子搭了个工作流,把一篇公众号文章直接转成带配音的短视频;有人用 ComfyUI 把产品图批量生成动态展示;还有人干脆把整套流程封装成一个 Agent,输入一…

阅读更多 →
Planner 实战:用 LangGraph Subgraph 让 Agent 学会分解任务——从零实现 Agent Harness 的 TaoToken 配置 2026/10/2 14:39:16

Planner 实战:用 LangGraph Subgraph 让 Agent 学会分解任务——从零实现 Agent Harness 的 TaoToken 配置

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

阅读更多 →
翻越栏杆检测数据集:512张真实安防图像+VOC/YOLO双格式 2026/10/2 14:39:16

翻越栏杆检测数据集:512张真实安防图像+VOC/YOLO双格式

简介:本资源是一个面向计算机视觉初学者与算法工程师的翻越栏杆行为检测专用数据集,适用于目标检测模型训练与评估,尤其适配YOLO系列及Pascal VOC兼容框架。数据集共512张高质量标注图像,涵盖单一类别“climbing”,含5…

阅读更多 →
生产设备设计全维度清单:从需求定义到人机工程的实战指南 2026/10/2 14:39:10

生产设备设计全维度清单:从需求定义到人机工程的实战指南

做生产设备设计这行久了,你会发现一个规律:能让设备在验收单上签字跑起来的方案不难做,难的是让设备在客户车间里连续跑三年还不掉链子的方案。生产设备类产品的设计,从来不是把机构动起来、让PLC把流程走通就完事,而是…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉