核心要点

  • 根因:BERT 位置编码只学到 512 个位置,且自注意力是 O(L²) 复杂度,长度越大显存算力开销平方增长

  • 截断:取头部、尾部或头尾拼接,简单但会丢中间信息

  • 滑动窗口分段:切成多段分别编码,再用池化/投票/加权聚合各段表示

  • 层次编码与长上下文模型:段内 BERT、段间再聚合;或换 Longformer/BigBird 稀疏注意力、长上下文 LLM

标准回答

512 限制的根因

BERT 的最大序列长度是 512 token,原因有二:一是它的位置编码是可学习的查表向量预训练时只见过 0–511 这些位置,超出就没有对应表示;二是自注意力的计算和显存开销是序列长度的 O(L²) 平方关系,强行放大长度代价极高。

方案一:截断

最简单的做法是截断到 512。可只取头部、只取尾部,或头尾拼接(很多任务关键信息集中在首尾)。优点是零改造、推理快;缺点是中间内容直接丢失,长文档信息损失大。

方案二:滑动窗口分段 + 聚合

把长文本按窗口(可设重叠)切成若干段,每段独立过 BERT,再把各段表示聚合:分类任务可对各段 [CLS] 做最大/平均池化或加权,或按段投票;检索任务可逐段打分取最高。能覆盖全文,但段间缺乏直接交互。

方案三:层次编码

先用 BERT 编码每个段落得到段级表示,再在段级表示之上接一层 TransformerRNN段间聚合,形成“词→段→篇”的层次结构,比简单池化更能建模跨段依赖。

方案四:长上下文模型

直接换用为长文本设计的模型:Longformer、BigBird 用稀疏注意力(局部窗口 + 少量全局 token)把复杂度降到近似线性,可处理 4K 乃至更长;也可改用支持长上下文的大语言模型

方案五:关键句抽取后再编码

先用规则或轻量模型抽取与任务最相关的句子/段落,压缩到 512 以内再喂给 BERT,相当于先做信息浓缩。

如何选择

按任务取舍:信息集中在首尾用截断即可;需要全文覆盖且段间依赖弱用滑动窗口聚合;跨段语义强用层次编码;长度远超 512 且预算允许则直接上 Longformer/BigBird 或长上下文 LLM。

常见误区

⚠️ 常见踩坑

以为把 max_position_embeddings 改大就能直接处理长文本(位置编码未预训练过、注意力 O(L²) 开销也撑不住);忽视截断会丢中间信息;在段间依赖很强的任务里盲目用简单池化聚合而损失跨段语义。

追问

追问 1Longformer 是怎么把注意力复杂度降下来的?

Longformer 用稀疏注意力替代全连接注意力:每个 token 只关注一个固定大小的局部滑动窗口(捕捉局部依赖),再为少数特殊 token(如 [CLS] 或任务相关位置)保留全局注意力以汇聚全文信息。这样复杂度从 O(L²) 降到约 O(L×w),近似线性,从而支持数千 token 的长文本。

追问 2滑动窗口分段时为什么要设置重叠?

重叠是为了避免把一个完整语义单元(句子、实体、论述)切在两段边界处导致上下文被割裂。让相邻段共享一部分 token,边界附近的词在至少一段里能拥有较完整的上下文,从而减少切分带来的信息损失,提升聚合后的稳定性。

追问 3截断时取头尾拼接相比只取头部有什么考量?

很多文档的结论或关键信息出现在结尾(如论文摘要的结论、评论的总结句),只取头部会漏掉。头尾拼接同时保留开头的背景和结尾的结论,对首尾信息双重要紧的任务更稳;但中间仍然丢失,且需根据任务经验决定头尾各取多少比例。

🔗 相似问题

同一考点的不同问法,面试官可能换着问,一起刷更稳

没找到想看的面试题?把你想看的告诉我们 →

延伸学习

按主题分类的相关资源,便于系统复习