想象你小时候玩过的拼图游戏:满地的碎片散落着,你的任务不是拼完整幅画,而是判断任意两片碎片原本是不是紧挨着的邻居。你无需知道整幅画的内容,只需观察碎片的边缘轮廓、图案走向和色彩衔接,就能给出“像”或“不像”的判断。BERT这位“拼图高手”在正式读书之前,被告知的第一课就是类似的游戏——“下一句预测”(NSP)。它会拿到两个句子A和B,被要求回答:B是不是A的下一句?这个简单的“是/否”二分类游戏,教会了BERT理解句子之间的承接、因果、转折等逻辑关系。与此同时,BERT还要玩另一个游戏“完形填空”(MLM):把句子里的某些词挖掉,根据上下文猜回来。NSP管“句间关系”,MLM管“句内词汇”,二者配合,BERT才真正读懂了语言。后来,有个叫RoBERTa的学生做了个大胆实验:把NSP从课程中直接删掉,结果考试成绩不但没降,反而还涨了。于是AI圈围绕“预训练任务到底该怎么设计”展开了热烈讨论。今天这篇文章,就带你从头看懂NSP:它是什么、训练数据怎么来、如何与MLM协作、为什么被质疑,又怎样影响了现代大模型。

岗位关联

理解NSP是理解BERT预训练范式的关键一环,也是你读懂RoBERTa、ALBERT等后续经典改进的必备知识,能帮助你在自建模型或改造下游任务时做出更专业的任务设计决策。

目录
  1. 可视化演示
  2. 1. 任务概述:拼图高手的第一课
  3. 2. 数据构造:拼图的练习册
  4. 3. 模型实现:判断机关
  5. 4. 与MLM配合:双人成行的拼图训练
  6. 5. RoBERTa质疑:拼图拿到超大版本后
  7. 6. 下游任务影响:江湖地位
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

动态演示NSP下一句预测的核心机制,通过入门/进阶/实战/优化四种模式展示关键概念与交互流程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

NSP下一句预测:一NSP 一、NSP任务定义与二分类预训 二、NSP训练数据构造与正负样 核心机制可视化 NSP下一句预测整体架构与关键组件

1. 任务概述:拼图高手的第一课

拼图游戏的第一关,往往不是让你拼完整幅画,而是让你判断两片碎片是否相邻。你不需要知道整幅画的内容,只要观察碎片的边缘轮廓、图案走向、色彩过渡,就能给出“它俩原本挨着”或“它俩八竿子打不着”的直觉判断。这个看似简单的判断,恰恰是拼图能力的基石——因为只有理解了碎片之间如何衔接,才能真正拼出完整的画卷。

NSP(Next Sentence Prediction,下一句预测)就是让BERT做这样的判断。给定两个句子A和B,模型输出一个二分类结果:B是不是A的下一句?如果是,标签为“是”(IsNext);如果不是,标签为“否”(NotNext)。这个任务教会BERT捕捉句子之间的承接关系、因果关联、指代衔接等深层语义,而不仅仅是词汇表面的共现。它和另一个任务——MLM(Masked Language Model,掩码语言模型,即“完形填空”)——一起构成了BERT预训练的两大支柱。NSP负责“句间关系”,MLM负责“句内词汇”。

从数学上看,NSP的预测过程可以写成:

就像拼图玩家最终凭直觉说出“像”或“不像”,模型给出的是一把概率尺子——只是它的“直觉”来自海量语料中学习到的参数。

P(y=1∣A,B)=σ(w⊤h[CLS]+b)\displaystyle P(y=1 \mid A, B) = \sigma(\mathbf{w}^{\top} \mathbf{h}_{[CLS]} + b)
这个公式把BERT读完整个句子对后凝练出的“总结向量” \(h_{[CLS]}\),压缩成一个0到1之间的数,表示“B是A的下一句”的信心。
  1. 上下文向量 h\[CLS\]BERT把A和B拼接成一个序列,放在最开头的 [CLS] 特殊标记(可以理解为“汇总员”)会收集整个序列的信息,它的隐藏状态就是整个句对内容的浓缩。
    h[CLS]∈R768\mathbf{h}_{[CLS]} \in \mathbb{R}^{768}
  2. 线性映射一个全连接层(权重矩阵 \(\mathbf{w}\) 加偏置 \(b\))把这个768维向量压缩成1个标量分数。
    w⊤h[CLS]+b\mathbf{w}^{\top} \mathbf{h}_{[CLS]} + b
  3. sigmoid激活 \(\sigma\)把标量压到 [0, 1] 区间,越接近1表示模型越相信“B真的是A的下一句”。
    σ(z)=11+e−z\sigma(z) = \frac{1}{1 + e^{-z}}

2. 数据构造:拼图的练习册

拼图盒的背面通常印着原图,玩家可以随时翻看原图确认两片碎片是否相邻。BERT的“原图”是什么?是互联网上海量的文章——训练语料库。NSP的标准答案,就是从这些文档中自动生成的,不需要人工标注。

构造方法很巧妙。先看正样本:在一篇文档中,句子按顺序排列,取第 \(i\) 句作为A,第 \(i+1\) 句作为B,这就是一个正样本(标签 \(y=1\),代表“是下一句”)。再看负样本:从另一篇完全不同的文档里随机抽一个句子B,拼在A的后面,这就是负样本(标签 \(y=0\),代表“不是下一句”)。注意,负样本必须是跨文档的——如果从同一文档乱序抽取,那就是另一个任务了(后文会提到)。

原始BERT论文规定,正样本和负样本各占50%。在实际实现中,输入到模型里的格式是固定的:在整段序列最前面放 [CLS] 标记,两个句子之间以及末尾放 [SEP] 标记(分隔符),即 [CLS] A [SEP] B [SEP]。[CLS] 专门用来收集分类信息,[SEP] 用来告诉模型“这里句子分界了”。

就像拼图练习册里,一半题目是“相邻”(答案:是),一半题目是“不相邻”(答案:否),难度均衡,让玩家的两种判断能力都得到充分训练。

P(y=1)=P(y=0)=0.5\displaystyle P(y=1) = P(y=0) = 0.5
这是一个完美的平衡二分类设置:模型没有任何先验偏置可以偷懒,必须真正学会区分“相邻”与“不相邻”。
  1. 正样本集合语料库中所有“第i句+第i+1句”的组合,构成正样本池。
    S+={(Ai,Ai+1)}S^{+} = \{(A_i, A_{i+1})\}
  2. 负样本集合从不同文档随机抽取句子对,构成负样本池。
    S−={(Ai,Bj)},doc(Ai)≠doc(Bj)S^{-} = \{(A_i, B_j)\}, \quad \text{doc}(A_i) \neq \text{doc}(B_j)
  3. 等量采样每个训练batch中正负各半,保证梯度估计稳定。
    ∣S+∣∣S−∣=1\frac{|S^{+}|}{|S^{-}|} = 1

3. 模型实现:判断机关

拼图玩家判断两片是否相邻,靠的是“扫一眼整体轮廓”。BERT的 [CLS] 标记就扮演着那只“眼睛”——它不像普通词汇位置那样参与填词,而是专门负责汇总整个句子对的全局信息。NSP的模型结构也因此非常简洁:BERT主干输出每个token的上下文表示,取 [CLS] 位置的隐藏状态,接一个分类头(全连接层 + 激活函数),输出二分类概率。

具体来说,BERT把句子对拼接成一个序列输入,每个token的表示都经过多层Transformer的交互,因此 [CLS] 位置上汇聚了A和B的全部语义。分类头就是一个线性层:先算出一个标量分数,再过sigmoid得到概率。训练时使用二分类交叉熵作为损失函数,梯度从分类头一路回传到整个BERT主干,于是模型的所有层都学会了建模句间关系。

拼图玩家的每次判断都会得到及时反馈:判对了——损失小;判错了——损失大。于是那套“判断机关”(模型参数)在一次次的反馈中越调越准。

LNSP=− [ ylog⁡y^+(1−y)log⁡(1−y^) ]\displaystyle \mathcal{L}_{NSP} = -\,\big[\, y \log \hat{y} + (1-y)\log(1-\hat{y}) \,\big]
交叉熵衡量“模型给出的概率”与“真实答案”之间的差距。真实答案 \(y\) 是1(相邻)或0(不相邻),模型输出概率 \(\hat{y}\)。差距越小,模型判断越准。
  1. 真实标签 \(y\)正样本 \(y=1\),负样本 \(y=0\)。
    y∈{0,1}y \in \{0, 1\}
  2. 模型概率 \(\hat{y}\)第1节的sigmoid输出,代表模型对“相邻”的把握。
    y^=P(y=1∣A,B)\hat{y} = P(y=1 \mid A, B)
  3. 两个对数项当 \(y=1\) 时只保留第一项,鼓励 \(\hat{y}\) 接近1;当 \(y=0\) 时只保留第二项,鼓励 \(\hat{y}\) 接近0。
    {L=−log⁡y^,y=1L=−log⁡(1−y^),y=0\begin{cases}\mathcal{L} = -\log \hat{y}, & y=1 \\\mathcal{L} = -\log (1-\hat{y}), & y=0\end{cases}
  4. 负号与最小化加负号让“损失越小”等价于“预测越准”,训练的目标就是最小化这个值。

4. 与MLM配合:双人成行的拼图训练

拼图训练有两个练习项目:一个是“看纹理”——把拼图上的某一块挖掉,凭周围图案猜缺失处的样子,这对应MLM;另一个是“看位置”——判断两块碎片是否原本就挨着,这对应NSP。一个负责局部细节,一个负责整体布局,两只手配合才能拼出完整的画面。

BERT在预训练时同时进行这两个任务,共享同一个主干参数。每个训练batch里,同一个句子对要同时完成两件事:一部分词被替换成 [MASK](掩码标记),模型要根据上下文预测原词;同时,模型还要判断这两个句子是否相邻。两个任务各自计算损失,相加后一起反向传播更新参数。论文中没有给两个损失加权,直接相加。

一个运动员不可能只练长跑不练力量——MLM是技巧训练,NSP是体能训练,两者合一才能应对真实比赛(下游任务)。词级的信息让模型“读得懂句子”,句级的信息让模型“接得上话头”。

L=LMLM+LNSP\displaystyle \mathcal{L} = \mathcal{L}_{MLM} + \mathcal{L}_{NSP}
两个任务的分数加在一起作为总成绩。MLM让模型积累词汇和句法知识,NSP让模型积累篇章和逻辑知识,两者互相促进。
  1. MLM损失所有被掩码位置的“真实词 vs 预测词”交叉熵之和。
    LMLM=−∑i∈Mlog⁡P(wi∣context)\mathcal{L}_{MLM} = -\sum_{i \in \mathcal{M}} \log P(w_i \mid \text{context})
  2. NSP损失第3节定义的二分类交叉熵。
    LNSP=− [ ylog⁡y^+(1−y)log⁡(1−y^) ]\mathcal{L}_{NSP} = -\,[\, y \log \hat{y} + (1-y)\log(1-\hat{y}) \,]
  3. 联合求和两个任务的梯度相加后共同更新BERT全部参数。
    ∇θ=∇LMLM+∇LNSP\nabla \theta = \nabla \mathcal{L}_{MLM} + \nabla \mathcal{L}_{NSP}

5. RoBERTa质疑:拼图拿到超大版本后

你在1000片的拼图上练就的“相邻判断”神技,拿到100万片的巨型拼图上却发现——好像不太管用,甚至不看边缘线直接乱拼,成绩反而更好?这不是幻觉,RoBERTa的研究者真的做了这个实验,而且结果令整个NLP社区震动。

RoBERTa是BERT的改进版,使用了更大的语料、更长的训练步数和动态掩码。实验很简单:固定其他所有条件不变,仅把NSP任务去掉,只保留MLM,然后在下游任务上对比。结果发现,去掉NSP的版本在GLUE等基准上全面超过保留NSP的原版BERT。研究者由此提出质疑:NSP真的有必要存在吗?

后来的分析给出了几个重要原因:第一,NSP任务本身太简单——负样本来自不同文档,话题差异很大,模型只要感知到“话题不一致”就能猜出答案是“否”,根本不需要建模深层的句间逻辑;第二,MLM任务在训练中已经隐式学到了一部分句间衔接能力,NSP的增量信息有限;第三,这种“话题偷懒”让模型把注意力放在了表层特征上,反而干扰了深层语义的学习。ALBERT随后提出改进方案SOP(Sentence Order Prediction,句序预测):不再用跨文档句子当负样本,而是把同一段落的两个句子顺序颠倒作为负样本,强迫模型真正理解句子间的顺序逻辑。

巨型拼图面前,“相邻判断”的边际价值被飞速稀释,词汇纹理的信息量已经足够撑起整个画面。课程设计必须跟上数据规模的变化,这就是预训练范式演进的魅力所在。

Δ=1n∑i=1naiRoBERTa−1n∑i=1naiBERT>0\displaystyle \Delta = \frac{1}{n}\sum_{i=1}^{n} a_i^{\text{RoBERTa}} - \frac{1}{n}\sum_{i=1}^{n} a_i^{\text{BERT}} > 0
在 \(n\) 个下游任务上分别计算RoBERTa(去NSP)和BERT(带NSP)的分数,逐个相减再取平均。实验结果是正的——去掉NSP反而更好。
  1. 任务分数 \(a_i\)第 \(i\) 个下游任务的评测指标(如准确率、F1值)。
    aiRoBERTa,aiBERTa_i^{\text{RoBERTa}}, \quad a_i^{\text{BERT}}
  2. 逐任务差分每个任务上“去NSP减去带NSP”的差值。
    δi=aiRoBERTa−aiBERT\delta_i = a_i^{\text{RoBERTa}} - a_i^{\text{BERT}}
  3. 平均差分把差值汇总为一个总体指标,避免个别任务波动导致误判。
    Δ=1n∑i=1nδi\Delta = \frac{1}{n}\sum_{i=1}^{n} \delta_i

6. 下游任务影响:江湖地位

拼图玩家练就的“相邻判断”功夫,在拼接大片场景时很管用,但在“单片识别”任务里就派不上用场了——你不需要知道它邻着谁,只要看清这一片画的是什么。NSP的价值,同样高度依赖下游任务的类型。

对句子对任务而言,句间关系就是核心能力。比如自然语言推理(判断一句话能否从另一句话推出)、问答匹配(判断问题和答案是否对应)、语义文本相似度(判断两句话意思是否相近),这些任务天然需要“理解两句话怎么关联”,NSP训练出的模型帮助非常明显。但对单句任务——如情感分类、命名实体识别、单句标注——NSP的贡献就非常有限,此时MLM才是主力。RoBERTa的结论也印证了这一点:在GLUE的句对子任务上,NSP的移除影响较小;而在单句任务上,移除NSP甚至略有提升。

后续模型纷纷吸取了这一教训。ELECTRA用“替换词检测”替代了MLM+NSP的组合;T5把所有任务统一成文本到文本框架,预训练改用span corruption(跨度破坏);ALBERT则用SOP替代NSP。这些设计都指向同一个启示:预训练任务的选择不是越多越好,必须匹配数据规模、模型容量和下游场景。

同一门功夫用在刀刃上是绝技,用在刀背上只会浪费体力。理解NSP的适用边界,才算真正掌握它——这也是每位AI工程师在设计预训练方案时最实用的判断力。

dtask=MNSP−Mno-NSP,dNLI>0,dCLS≈0\displaystyle d_{\text{task}} = M_{\text{NSP}} - M_{\text{no-NSP}}, \quad d_{\text{NLI}} > 0, \quad d_{\text{CLS}} \approx 0
\(d_{\text{task}}\) 表示“带NSP的模型”在某个任务上比“不带NSP的模型”高出的分数。在自然语言推理等句对任务上 \(d\) 明显为正,在单句分类任务上 \(d\) 约等于0。
  1. 模型分数对比同一任务上两个模型的评测分数。
    MNSP,Mno-NSPM_{\text{NSP}}, \quad M_{\text{no-NSP}}
  2. 做差得到净贡献去掉NSP前后模型的分数差。
    dtask=MNSP−Mno-NSPd_{\text{task}} = M_{\text{NSP}} - M_{\text{no-NSP}}
  3. 分任务解读句对任务上差值显著为正,单句任务上差值趋近于0。
    dNLI>0,dCLS≈0d_{\text{NLI}} > 0, \quad d_{\text{CLS}} \approx 0

AI 应用场景

场景1:智能客服的多轮对话衔接判断

阶段:对话理解与意图识别

解决的问题:传统客服机器人把每一条用户消息当作独立输入,无法判断“刚才还在问退货政策,现在突然报商品型号”是不是同一个意图流。借用NSP的“相邻性”思想,把连续的对话消息当作句子对训练一个二分类模型,判断两条消息是否属于同一话题的衔接轮次。

具体案例:某电商客服机器人上线“对话轮次衔接判断器”,训练数据构造方式与NSP完全一致——同一会话中相邻的两条用户消息是正样本,从不同会话随机抽取两条消息拼接是负样本。当模型判断“这两条消息不相邻”时,系统自动触发意图切换处理,准确提升了17%的意图识别率。

场景2:语义搜索引擎的查询-文档相关性判断

阶段:召回与排序

解决的问题:传统BM25等检索算法只看词面重叠,搜“MacBook充电器”时无法理解“苹果笔记本电源适配器”是相关的。借鉴NSP的“相邻性”思想,把(查询,候选文档)当作一个句子对,训练二分类模型判断“查询与文档是否语义相邻(相关)”。

具体案例:某企业知识库搜索引擎改造后,将用户的查询与候选文档摘要拼接,输入一个在内部语料上微调过的BERT模型,输出相关性概率作为排序特征。上线后搜索无结果率下降了23%,长尾查询的点击率提升了31%。

场景3:RoBERTa式预训练改造决策

阶段:领域预训练任务设计

解决的问题:金融、医疗等垂直领域需要从零预训练BERT类模型,但“要不要保留NSP”是个真问题。套用RoBERTa的实验结论:先小规模对比“保留NSP”和“去掉NSP”两个版本的领域模型,再根据下游任务表现决定。

具体案例:某券商AI团队用200GB金融语料预训练领域模型。他们训练了两个版本,在金融情感分类(单句任务)上,去掉NSP的版本F1高出0.8个百分点;但在金融事件因果关系抽取(句对任务)上,保留NSP的版本更优。最终团队按任务类型分别部署了两个版本。

Python 演示

python83 行
"""极简NSP演示 - 用numpy实现逻辑回归, 学习判断句子对是否相邻"""import numpy as np # 模拟两个文档, 每个句子用一个稀疏词袋向量表示(词ID -> 1)DOC1 = [    [1, 5, 9, 12],   # 第1句    [3, 7, 5, 14],   # 第2句    [8, 2, 11, 6],   # 第3句    [4, 10, 13, 1],  # 第4句]DOC2 = [    [6, 15, 3, 9],    [2, 8, 1, 12],    [7, 10, 4, 5],    [13, 11, 16, 2],]VOCAB = 17  def sent_vec(word_ids):    v = np.zeros(VOCAB, dtype=float)    for w in word_ids:        v[w] = 1.0    return v  def combine_vec(sent_a, sent_b):    return np.concatenate([sent_vec(sent_a), sent_vec(sent_b)])  def build_data(documents):    """构造NSP训练数据: 正样本=同文档相邻句, 负样本=跨文档随机句"""    rng = np.random.RandomState(42)    X, y = [], []    for doc in documents:                     # 正样本: 第i句 + 第i+1句        for i in range(len(doc) - 1):            X.append(combine_vec(doc[i], doc[i + 1]))            y.append(1)    flat = [(d_i, s_i) for d_i, doc in enumerate(documents)            for s_i in range(len(doc))]    while len(y) < len(documents) * 6:        # 负样本补到和正样本等量        j = rng.randint(len(flat))        k = rng.randint(len(flat))        if flat[j][0] == flat[k][0]:          # 保证来自不同文档            continue        a = documents[flat[j][0]][flat[j][1]]        b = documents[flat[k][0]][flat[k][1]]        X.append(combine_vec(a, b))        y.append(0)    return np.array(X), np.array(y)  class NSPClassifier:    """逻辑回归二分类器: 权重w和偏置b, sigmoid输出相邻概率"""     def __init__(self, dim):        self.w = np.zeros(dim)        self.b = 0.0     def predict_proba(self, x):        z = np.dot(self.w, x) + self.b        return 1.0 / (1.0 + np.exp(-z))     def train(self, X, y, epochs=30, lr=0.1):        for _ in range(epochs):            order = np.random.permutation(len(y))            for idx in order:                p = self.predict_proba(X[idx])                self.w += lr * (y[idx] - p) * X[idx]                self.b += lr * (y[idx] - p)     def predict(self, x):        return int(self.predict_proba(x) > 0.5)  if __name__ == "__main__":    X, y = build_data([DOC1, DOC2])    mid = len(y) // 2    model = NSPClassifier(X.shape[1])    model.train(X[:mid], y[:mid], epochs=20)    preds = [model.predict(x) for x in X[mid:]]    acc = np.mean(preds == y[mid:])    print("NSP逻辑回归演示 测试准确率: {:.2f}%".format(acc * 100))
目的:用纯numpy实现一个微型NSP(下一句预测)演示——构造正负样本并训练逻辑回归分类器,让你直观看到一个“简化版”的NSP推理链路。
  1. for i in range(len(doc) - 1): X.append(combine_vec(doc[i], doc[i + 1])); y.append(1)遍历同一文档内相邻句子对,生成正样本
  2. if flat[j][0] == flat[k][0]: continue强制两个句子来自不同文档,保证负样本“不相邻”
  3. 1.0 / (1.0 + np.exp(-z))sigmoid函数,把线性分数压成0~1之间的相邻概率
  4. self.w += lr * (y[idx] - p) * X[idx]梯度上升更新权重,这是二分类逻辑回归的核心学习规则
  5. np.mean(preds == y[mid:])在测试集上计算预测正确的比例,即准确率

常见误区

误区初学者看到“Next Sentence Prediction“,第一反应是”模型要生成下一句话”——就像GPT那样接着上文写下去。所以会觉得NSP是生成式任务。

正解NSP是纯判别式二分类任务。它不生成任何新句子,只对给定的两个句子A和B输出一个“是/否”判断:B是不是A的下一句?输出的是概率标签,不是文本。真正的“生成下一句”是GPT类语言模型做的事,两者目标完全不同。

为何常见:“Prediction“一词在中文语境里容易联想成”预测未来的句子“,且”NSP“与”预测下一个词”在字面上高度相似,初学者极易混淆。

误区不少人觉得NSP的负样本应该是“把同一篇文档里的句子顺序打乱再拼接”,这样模型才能学会真正的顺序逻辑。

正解原始BERT的负样本是从不同文档随机抽取句子对,不是同文档乱序。正负样本的区别是“是否来自同一上下文的相邻位置”。同文档乱序负样本是ALBERT提出的SOP(句序预测)任务,属于对NSP的改进方案,不是在BERT里实现的。

为何常见:直觉上“不是下一句”最自然的反例就是“下一句被换掉了”,但BERT选择了实现更简单的跨文档抽样。

误区有读者认为,二分类预训练任务应该像异常检测那样,负样本远远多于正样本(比如1:9),否则模型学不出判别力。

正解BERT恰恰使用正负各50%的均衡配比。NSP的负样本可以无限生成(语料库足够大),不存在“稀缺”问题。均衡配比让模型在训练中看到充分的两类样本,梯度信号稳定,这是二分类任务的经典最佳实践。

为何常见:现实世界中异常检测、欺诈识别等场景确实正负样本极度失衡,这种印象被错误迁移到了预训练任务设计上。

误区看到“去掉NSP性能反而提升”的结论后,部分人认为NSP是个纯粹的坏设计,任何场景下都应该移除。

正解RoBERTa的结论有其前提——超大规模语料、动态掩码、更长训练步数。在这些条件下,NSP的“话题偷懒”问题被放大,收益被抵消。但在中等规模语料、句对密集型场景中,NSP仍有价值,ALBERT也通过SOP保留了“句间建模”的思想。正确做法是像RoBERTa那样做消融实验,用数据说话。

为何常见:把单一实验结论绝对化是技术传播中的常见偏差,忽略了结论成立的前提条件。

误区有人认为模型判断两个句子是否相邻,靠的是它们有多少重复词——词面重叠度高就是相邻。

正解如果仅靠词面重叠,模型会很快失效。跨文档负样本虽然话题不同、重叠词少,但正样本的相邻句也可能几乎没有重复词(比如“我今天买了苹果。它很甜。”中“它”指代苹果,靠指代衔接而非词汇重叠)。NSP真正迫使模型学习的是指代衔接、因果逻辑、时间顺序等深层句间模式。

为何常见:人类阅读时容易注意到相邻句子的“话题延续”,误以为这是词面重叠带来的表面信号,实际那是一种语义层面的连贯性。

面试题

Q1. NSP(下一句预测)的核心任务是什么?

单选题 · easy

  • A.预测句子中缺失的某个词
  • B.判断两句是否上下文相邻← 正确答案
  • C.将文本按主题进行聚类
  • D.根据上文生成下一句话

答案:B。NSP是二分类任务,给定句子A和B,判断B是否是A的下一句,对应选项B。A是MLM(掩码语言模型)的任务,D是GPT等生成模型的任务,C是无监督聚类,都与NSP无关。

Q2. NSP的输入序列格式通常是什么样的?

单选题 · easy

  • A.[CLS] A [SEP] B [SEP]← 正确答案
  • B.[MASK] A [SEP] B [SEP]
  • C.[CLS] A [MASK] B [SEP]
  • D.[SEP] A [CLS] B [SEP]

答案:A。BERT将句子对拼接输入,开头放[CLS]用于汇总分类信息,两句子间和末尾放[SEP]分隔。[MASK]是MLM任务用的掩码标记,不会出现在NSP的输入开头。

Q3. BERT的NSP负样本是如何构造的?

单选题 · mid

  • A.将同一文档句子乱序重排
  • B.从不同文档随机抽取句子拼接← 正确答案
  • C.将句子B中的词语全部替换
  • D.将句子A复制一遍当作B

答案:B。原始BERT的负样本从不同文档随机抽取句子与A拼接。A选项是ALBERT的SOP任务做法,C和D都不构成合理的负样本构造方式。

Q4. 关于BERT中的[CLS]标记,下列说法正确的有?

多选题 · mid

  • A.每个输入序列都以[CLS]开头← 正确答案
  • B.[CLS]的隐状态用于NSP分类← 正确答案
  • C.[CLS]的位置信息会被掩码
  • D.[CLS]汇总整个句对的信息← 正确答案

答案:ABD。[CLS]放在序列最前面,其隐状态汇聚了整个句子对的全局信息,被用作NSP分类头的输入。C错误,[CLS]是分类专用标记,不会被掩码,也无需预测。

Q5. NSP分类头的输出维度通常是多少?

单选题 · mid

  • A.映射到1维概率← 正确答案
  • B.映射到词表大小
  • C.映射到768维向量
  • D.映射到100维向量

答案:A。NSP是二分类任务,分类头将[CLS]向量经全连接层映射到1个标量,再过sigmoid得到0~1之间的相邻概率。映射到词表大小是MLM的预测头设计。

Q6. 关于NSP与MLM两个预训练任务的关系,说法正确的有?

多选题 · mid

  • A.两者共享BERT主干参数← 正确答案
  • B.两个任务的损失直接相加← 正确答案
  • C.NSP只训练分类头不更新主干
  • D.两者是并行执行的独立任务← 正确答案

答案:ABD。NSP和MLM在同一个输入序列上并行计算损失,梯度相加后共同更新BERT主干参数,因此C错误。A、B、D都是正确描述。

Q7. RoBERTa实验中“去掉NSP性能不降反升”,最可能的原因是什么?

单选题 · hard

  • A.NSP任务太简单导致模型偷懒← 正确答案
  • B.NSP导致模型训练不稳定
  • C.NSP让模型参数严重过拟合
  • D.NSP只影响句向量不更新主干

答案:A。跨文档负样本话题差异大,模型靠“话题不一致”就能猜出负样本,不需要建模深层句间逻辑,这种偷懒干扰了MLM学习。B、C说法无实验支撑,D本身错误——NSP梯度会更新主干。

Q8. ALBERT提出的SOP与NSP的最大区别是什么?

单选题 · hard

  • A.SOP判断主题是否一致
  • B.SOP判断是否同一篇文章
  • C.SOP判断两句顺序是否颠倒← 正确答案
  • D.SOP预测下一句的内容

答案:C。SOP把同一段落中相邻两句的顺序颠倒作为负样本,强迫模型真正理解顺序逻辑,而非靠话题差异判断。A和B描述的是“话题一致性”这种浅层线索,D是生成任务。

Q9. NSP对下列哪些下游任务帮助较大?

多选题 · hard

  • A.自然语言推理(NLI)← 正确答案
  • B.机器阅读理解(MRC)← 正确答案
  • C.单句情感分类
  • D.命名实体识别

答案:AB。NLI需要判断两个句子的逻辑关系,MRC需要在文档中定位答案,二者核心都是句间或句-文档关系建模,NSP训练的句间能力直接受益。C和D是单句任务,NSP贡献有限。

Q10. 在BERT预训练中,两个任务的联合损失如何表达?

单选题 · extreme

  • A.损失是两者加权且逐层交替
  • B.损失是NSP损失的一半
  • C.损失直接相加作为总损失← 正确答案
  • D.损失是MLM损失减NSP损失

答案:C。BERT原始论文直接将MLM损失与NSP损失相加作为总损失,没有设置权重。A“交替优化”、B“D减NSP”都不符合论文设计。