自然语言推断


文档摘要

自然语言推断 本节摘要:「t 蕴含 h」意味着读 t 的人会断定 h 为真——NLI 是预测蕴含/矛盾/中性的任务,表面无聊,生产里却是承重墙。你做了个摘要器,产出了摘要,怎么知道它不含幻觉?你做了个聊天机器人,它答「是」,怎么知道答案被检索段落支持?你要把一万篇新闻按主题分类,却没有训练标签,能复用模型吗?这三个问题都归结到自然语言推断:给定前提 与假设 , 被 蕴含、矛盾、还是中性?于是幻觉检测里 =源文档、 =摘要论断,不蕴含即幻觉;接地问答里 =检索段落、 =生成答案,不蕴含即编造;零样本分类里 =文档、 =话术化标签(「这是关于体育的」),蕴含即预测标签。一个任务、三种生产用途——这就是每个 RAG 评估框架底下都跑一个 NLI 模型的原因。

自然语言推断

本节摘要:「t 蕴含 h」意味着读 t 的人会断定 h 为真——NLI 是预测蕴含/矛盾/中性的任务,表面无聊,生产里却是承重墙。你做了个摘要器,产出了摘要,怎么知道它不含幻觉?你做了个聊天机器人,它答「是」,怎么知道答案被检索段落支持?你要把一万篇新闻按主题分类,却没有训练标签,能复用模型吗?这三个问题都归结到自然语言推断:给定前提 t 与假设 h,ht 蕴含、矛盾、还是中性?于是幻觉检测里 t=源文档、h=摘要论断,不蕴含即幻觉;接地问答里 t=检索段落、h=生成答案,不蕴含即编造;零样本分类里 t=文档、h=话术化标签(「这是关于体育的」),蕴含即预测标签。一个任务、三种生产用途——这就是每个 RAG 评估框架底下都跑一个 NLI 模型的原因。本节用 BERT/RoBERTa/DeBERTa 编码 [CLS] 前提 [SEP] 假设,三路 softmax 训出 90%+ 准确率,并演示零样本分类与 RAGAS 忠实度检查的核心机制。

对应原课程:Phase 5 · Lesson 21 · nli-textual-entailment(原英文 phases/05-nlp-foundations-to-advanced/21-nli-textual-entailment/docs/en.md)。前置依赖:第 05 节(情感分析)、第 13 节(问答系统)。

学习目标

阅读完本节,你应当能够:

  1. 区分 NLI 的三标签(蕴含/矛盾/中性),并指出它是「典型读者的推断」而非严格逻辑。
  2. 幻觉检测、接地问答、零样本分类三个生产问题统一归约为 NLI。
  3. 用预训练 NLI 模型实现零样本分类RAG 忠实度检查
  4. 识别仅假设捷径、词重叠启发式、文档级退化、模板敏感等陷阱。

一、问题与直觉

你做了个摘要器,产出了摘要。怎么知道它不含幻觉?

你做了个聊天机器人,它答「是」。怎么知道答案被检索段落支持?

你要把一万篇新闻按主题分类,却没有训练标签。能复用模型吗?

这三个问题都归结到自然语言推断。NLI 问:给定前提 t 与假设 h,ht 蕴含、矛盾、还是中性?

  • 幻觉检测:t=源文档,h=摘要论断。不蕴含 = 幻觉。
  • 接地问答:t=检索段落,h=生成答案。不蕴含 = 编造。
  • 零样本分类:t=文档,h=话术化标签(「这是关于体育的」)。蕴含 = 预测标签。

一个任务,三种生产用途。这就是每个 RAG 评估框架底下都跑一个 NLI 模型的原因。

三个标签:

  • 蕴含:th。「猫在垫子上」蕴含「有一只猫」。
  • 矛盾:t → ¬h。「猫在垫子上」矛盾于「没有猫」。
  • 中性:任一方向都无推断。「猫在垫子上」对「猫饿了」是中性。

💡 不是逻辑蕴含:NLI 是「自然」语言推断——典型人类读者会做的推断,不是严格逻辑。「约翰遛了他的狗」在 NLI 里蕴含「约翰有一只狗」,但严格一阶逻辑只有在公理化「拥有」之后才承认它。

数据集:

  • SNLI(2015):57 万对人工标注,前提是图像描述。领域窄。
  • MultiNLI(2017):43.3 万对,跨 10 种文体。2026 的标准训练语料。
  • ANLI(2019):对抗式 NLI。人专门写出能搞坏现有模型的例子,更难。
  • DocNLI、ConTRoL(2020~21):文档级前提,测多跳与长程推断。

架构:一个 Transformer 编码器(BERT、RoBERTa、DeBERTa)读 [CLS] 前提 [SEP] 假设 [SEP],[CLS] 表示喂一个三路 softmax。在 MNLI 上训,在留出基准上评,分布内对子得 90%+ 准确率。

经 NLI 的零样本:给定文档与候选标签,把每个标签变成假设(「这段文本是关于体育的」),算每个的蕴含概率,取最大。这就是 Hugging Face zero-shot-classification 流水线背后的机制。

二、从零实现

第 1 步:跑预训练 NLI 模型

from transformers import pipeline nli = pipeline("text-classification", model="facebook/bart-large-mnli", top_k=None) # 返回所有标签;替代已弃用的 return_all_scores=True premise = "The cat is sleeping on the couch." hypothesis = "There is a cat in the room." result = nli({"text": premise, "text_pair": hypothesis})[0] print(result) # [{'label': 'entailment', 'score': 0.97}, # {'label': 'neutral', 'score': 0.02}, # {'label': 'contradiction', 'score': 0.01}]

生产级 NLI,facebook/bart-large-mnlimicrosoft/deberta-v3-large-mnli 是开源默认。DeBERTa-v3 霸榜。

第 2 步:零样本分类

zs = pipeline("zero-shot-classification", model="facebook/bart-large-mnli") text = "The stock market rallied after the central bank cut interest rates." labels = ["finance", "sports", "politics", "technology"] result = zs(text, candidate_labels=labels) print(result) # {'labels': ['finance', 'politics', 'technology', 'sports'], # 'scores': [0.92, 0.05, 0.02, 0.01]}

模板默认是「This example is about {label}.」,用 hypothesis_template 自定义。无需训练数据、无需微调,开箱即用。

第 3 步:RAG 忠实度检查

def is_faithful(answer, context, threshold=0.5): result = nli({"text": context, "text_pair": answer})[0] entail = next(s for s in result if s["label"] == "entailment") return entail["score"] > threshold

这是 RAGAS 忠实度的核心。把生成答案拆成原子论断,逐条对检索上下文查 NLI,报告被蕴含的比例。

第 4 步:手搓 NLI 分类器(概念性)

code/main.py 的纯标准库玩具:前提与假设通过词法重叠 + 否定检测来比较。不能与 Transformer 模型竞争,但展示了任务形状:两段文本进,三路标签出,损失是 {蕴含, 矛盾, 中性} 上的交叉熵。

三、框架对比

陷阱

  • 仅假设捷径:模型能仅凭假设预测标签,SNLI 上约 60%,因为「not」「nobody」「never」与矛盾相关。检测标签泄露的强基线。
  • 词重叠启发式:子序列启发式(「每个子序列都被蕴含」)过 SNLI 但挂 HANS/ANLI。要用对抗基准。
  • 文档级退化:单句 NLI 模型在文档级前提上掉 20+ F1。长上下文用 DocNLI 训过的模型。
  • 零样本模板敏感:「This example is about {label}」vs「{label}」vs「The topic is {label}」能让准确率波动 10+ 点。要调模板。
  • 领域错配:MNLI 在通用英语上训,法律、医疗、科学文本需领域专用 NLI(如 SciNLI、MedNLI)。

2026 的栈:

用例 模型
通用 NLI microsoft/deberta-v3-large-mnli
快 / 边缘 cross-encoder/nli-deberta-v3-base
零样本分类(轻量) facebook/bart-large-mnli
文档级 NLI MoritzLaurer/DeBERTa-v3-large-mnli-fever-anli-ling-wanli
多语言 MoritzLaurer/multilingual-MiniLMv2-L6-mnli-xnli
RAG 幻觉检测 RAGAS / DeepEval 内的 NLI 层

💡 2026 元模式:NLI 是文本理解的万能胶带。只要你需要「A 支持 B 吗?」或「A 矛盾 B 吗?」——先够 NLI,再够另一次 LLM 调用。

四、可复用产物

保存为 outputs/skill-nli-picker.md:

--- name: nli-picker description: Pick an NLI model, label template, and evaluation setup for a classification / faithfulness / zero-shot task. version: 1.0.0 phase: 5 lesson: 21 tags: [nlp, nli, zero-shot] --- Given a use case (faithfulness check, zero-shot classification, document-level inference), output: 1. Model. Named NLI checkpoint. Reason tied to domain, length, language. 2. Template (if zero-shot). Verbalization pattern. Example. 3. Threshold. Entailment cutoff for the decision rule. Reason based on calibration. 4. Evaluation. Accuracy on held-out labeled set, hypothesis-only baseline, adversarial subset. Refuse to ship zero-shot classification without a 100-example labeled sanity check. Refuse to use a sentence-level NLI model on document-length premises. Flag any claim that NLI solves hallucination — it reduces it; it does not eliminate it.

五、练习

  1. 基础:在覆盖三类、20 对手工写的(前提, 假设, 标签)三元组上跑 facebook/bart-large-mnli,测准确率。加入对抗式「子序列启发式」陷阱(「我没吃蛋糕」vs「我吃了蛋糕」),看它挂不挂。
  2. 进阶:在 100 条 AG News 标题上,对比零样本模板「This text is about {label}」、「The topic is {label}」、「{label}」,报告准确率波动。
  3. 挑战:搭一个 RAG 忠实度检查器:原子论断分解 + 逐条 NLI。在 50 条带金标准上下文的 RAG 生成答案上评估,对比手标测假阳/假阴率。

本节要点回顾

  1. NLI 是三路分类:前提-假设关系判为蕴含/矛盾/中性。
  2. 「自然」推断非严格逻辑:典型读者的推断,需公理化才能进一阶逻辑。
  3. 三生产问题归约为一任务:幻觉检测、接地问答、零样本分类都是 NLI。
  4. 架构是 [CLS] 前提 [SEP] 假设 + 三路 softmax,MNLI 上训到 90%+。
  5. 零样本分类靠话术化标签:把标签变假设,取最大蕴含概率。
  6. RAGAS 忠实度 = 逐条 NLI:把答案拆原子论断,逐条对上下文查蕴含比例。
  7. 仅假设捷径约 60%:「not/nobody/never」与矛盾相关,是标签泄露的强基线。
  8. 子序列启发式过 SNLI 挂 HANS/ANLI:要用对抗基准。
  9. 单句 NLI 文档级掉 20+ F1:长上下文换 DocNLI 训过的模型。
  10. 零样本模板敏感 10+ 点:要调「This is about {label}」类模板,法律医疗换 SciNLI/MedNLI。

下一节,我们回到嵌入这一根——进入「嵌入模型深入」,看双编码器、对比学习、难负例挖掘、Matryoshka 与指令微调如何把句子压进一个既能检索又能聚类的向量。


发布者: 作者: Rohit Gupta 转发
评论区 (0)
U