DeepEval SummaC 一致性检测:不用 LLM API,3 行代码给文本"矛盾"打分
【免费下载链接】deepevalThe LLM Evaluation Framework项目地址: https://gitcode.com/GitHub_Trending/de/deepeval
AI 摘要把"48 小时发货"写成"72 小时",靠肉眼很难批量发现。本文带你用 DeepEval SummaC 一致性检测在本地对原文与生成文本逐句打分,并覆盖参数选型与排错。
一分钟看懂:SummaC 的本地打分原理
SummaC(Summarization Competence)是一组零样本摘要质量打分器,在 DeepEval 中以SummaCModels封装。它不调用任何 LLM API:先把原文和生成文本按句子(或段落)切开,用一个 NLI 模型对"每个原文片段 × 每个生成片段"算出蕴含和矛盾两个概率,拼成一张概率矩阵;再按蕴含 − 矛盾逐句聚合成分数。分数越高说明生成文本越忠于原文,出现明显矛盾时会跌破 0。
🧪 从零到可运行的 DeepEval 一致性检测 Demo
一条命令装好依赖:
pip install -U deepeval transformers nltk最小可运行代码:
from deepeval.models.summac_model import SummaCModels checker = SummaCModels(granularity="sentence") # 模型默认 vitc original = "公司将在48小时内发货,并提供30天免费退货。" bad_summary = "公司将在72小时内发货,且不提供免费退货。" result = checker(original, bad_summary) print(f"一致性得分: {result['score']:.2f}")预期输出:单对文本返回一个字典,score是浮点数。上面这个"72 小时 + 无退货"的双重矛盾样本,得分通常明显低于 0.3,甚至为负;换成"48 小时发货、支持 30 天免费退货"这类忠实改写,得分一般能到 0.7 以上。
💡提示:第一次运行会从 Hugging Face 拉取 vitc(ALBERT-xlarge)权重,体积有几百 MB,属于正常现象。另外构造器里不要写
device="auto"——源码在device=None时已经自动探测 GPU,传字符串 "auto" 反而会在.to()时出错。
🧩 三个核心用法拆解
用法一:批量给多组文本对打分
适用场景:你有一批"原文 + 摘要"对,需要整体筛查哪些不合格。
最少代码:两个参数都传列表,返回结构从score变成scores列表。
sources = [ "深度学习依赖多层神经网络做特征学习。", "该接口仅支持 GET 请求。", ] summaries = [ "深度学习依赖单层网络做数据处理。", "该接口同时支持 GET 与 POST 请求。", ] print(checker(sources, summaries)["scores"])结果解读:输出是一个与输入等长的浮点列表,逐组对应。第一组"多层→单层"、第二组"仅 GET→GET+POST"都属于篡改关键事实,两组分数都会显著低于忠实样本,直接按阈值过滤即可圈出待复核项。
用法二:接入阈值判断与告警日志
适用场景:把检测嵌进 CI 或离线批处理,不合格样本要能自动标记。
最少代码:
def check(src: str, gen: str, threshold: float = 0.5) -> str: score = checker(src, gen)["score"] status = "通过" if score >= threshold else "需复核" print(f"[{status}] {score:.2f} {gen[:20]}...") return status结果解读:threshold建议先用 0.5 起步,再拿 20~30 条真实样本校准(见第 6 章)。判断只依赖一个浮点数,方便写进断言或导出报表。
用法三:用 op1 / op2 调节判定灵敏度
适用场景:默认聚合下"一句错、九句对"也能蒙混过关,你需要一票否决。
最少代码:op1控制单个生成句在矩阵行方向上的聚合(max/mean/min),op2控制所有句子的最终汇总,两者直接通过构造器透传给load_model:
strict = SummaCModels(model_name="vitc", granularity="sentence", op1="min", op2="min") print(strict(original, bad_summary)["score"])结果解读:op2="min"意味着最终分等于最糟那句的分数——只要有一句矛盾,整体分就被拉低,适合"错一句即失败"的验收场景;默认op2="mean"则容忍个别句子有瑕疵。
📐 model_name 与 granularity 参数选型表
model_name决定底层 NLI 骨干,granularity决定切分粒度(可选sentence、paragraph、document、2sents、mixed,也支持sentence-paragraph这类"原文-摘要"异质组合):
| model_name | 底层骨干 | 适用场景 | 速度 | 推荐指数 |
|---|---|---|---|---|
vitc(默认) | ALBERT-xlarge (ViTaNiC) | 关键链路严格校验,判别力最强 | 慢 | ⭐⭐⭐⭐⭐ |
mnli | RoBERTa-large (MNLI) | 通用一致性筛查 | 中 | ⭐⭐⭐⭐ |
anli | RoBERTa-large (ANLI 三轮微调) | 噪声多、域外数据混杂 | 中 | ⭐⭐⭐ |
snli-base | RoBERTa-base (SNLI) | 实时链路、低算力环境 | 快 | ⭐⭐⭐ |
默认推荐:新项目直接用vitc + sentence;只有当单条延迟成为瓶颈时,再降到snli-base + paragraph。
⚡ 两个反差场景:严格校验 vs 实时筛查
场景 A:合同/论文摘要的严格验收(宁可错杀,不可漏过):
audit = SummaCModels(model_name="vitc", granularity="sentence", op1="min", op2="min") score = audit(paper_text, ai_summary)["score"]op1="min"+op2="min"双重取最小:任何一个生成句与原文冲突,分数立刻见底。
场景 B:客服回复的在线快筛(毫秒级响应优先):
fast = SummaCModels(model_name="snli-base", granularity="paragraph", op2="mean") score = fast(kb_doc, bot_reply)["score"]换 base 模型 + 段落粒度,NLI 调用量从"句×句"降到"段×段",吞吐能上一个数量级,代价是对单句级篡改的敏感度下降——在线场景用分数做"抽样进人工队列"的触发器,而不是最终判决。
🧯 三个最高频报错与处理方式
Q1:首跑报LookupError: Resource punkt not found?SummaC 分句依赖 nltk 的 punkt 数据,而权重首次也要联网下载,两者都会卡在第一次运行。 执行:python -c "import nltk; nltk.download('punkt'); nltk.download('punkt_tab')",再跑一次即可。
Q2:传参时报TypeError,提示字符串和列表不能混用?_call要求两个参数"都是字符串"或"都是列表",一对一和一批量是两套调用方式。 成批调用时两边都包成列表:checker(list(srcs), list(gens)),然后取["scores"]。
Q3:为什么分数会为负,阈值该设多少?分数本质是"蕴含概率 − 矛盾概率",矛盾突出时必然为负,框架没有内置固定及格线。 建议拿 20~30 条已知好坏的样本各跑一遍op2="mean"与op2="min",看两组分数的间隔再定阈值。
🧭 两条集成路径:pytest 断言与平台看板
路径一:与SummarizationMetric组成双保险。SummaC 是纯本地 NLI 打分,便宜但"只判矛盾、不判遗漏";而 LLM 判官指标SummarizationMetric会同时考察 coverage(关键信息是否说全)与 alignment(是否跑偏),两者分数互补:
from deepeval import evaluate from deepeval.metrics import SummarizationMetric from deepeval.test_case import LLMTestCase tc = LLMTestCase(input=original, actual_output=generated) evaluate([tc], [SummarizationMetric(threshold=0.5, model="gpt-4o-mini")])路径二:deepeval test run同步看板。把上面包进一个 pytest 测试文件后执行deepeval test run test_consistency.py,历史分数、回归对比都会进 Confident AI 平台,团队可以直接在网页上追踪每一版 prompt 的波动。
下一步路线
- 读 SummaC 模型封装源码,理解
op1/op2与矩阵聚合的对应关系。 - 对照 SummarizationMetric 源码,把"coverage + alignment"判官指标接进你的摘要流水线。
- 参考 官方文档/metrics-summarization.mdx) 了解各指标参数默认值与报告结构。
- 给评估加回归基线:固定 50 条金标样本,每次改 prompt 后比对
scores均值变化。
先让 3 行 Demo 在你的数据上跑出第一个分数,再谈调参——阈值永远应该来自你自己的样本分布。
【免费下载链接】deepevalThe LLM Evaluation Framework项目地址: https://gitcode.com/GitHub_Trending/de/deepeval
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考