DeepEval SummaC 文本一致性检测实战指南:5 分钟跑通忠实度评分与排错
【免费下载链接】deepevalThe LLM Evaluation Framework项目地址: https://gitcode.com/GitHub_Trending/de/deepeval
客服机器人把"30 天退换"答成"14 天",摘要把发布日期从 9 月写成 10 月——这类"生成文本与原文对不上"的问题,靠人眼几乎盯不过来。DeepEval 里的 SummaC 模型专门干这件事:给它一段原始参考文本和一段生成文本,它基于零样本自然语言推理(NLI)打出一个 0–1 的一致性得分,越接近 1 表示生成内容越贴合原文,越低说明存在矛盾或事实偏差。读完这篇,你能在本机跑通第一个一致性评分、看懂关键参数,并把检测接进 RAG 和指标断言流程。
工具定位
SummaC 解决的是"原文与生成文本是否一致"这一类问题,适合做 RAG 答案忠实度校验、摘要质量把关、文档改写回归。它不需要标注数据,本地推理即可出分,因此既能离线批量跑,也能当作 CI 里的一道质量关卡。默认使用精度最高的vitc模型,追求速度或省显存时可换轻量模型。
安装与环境准备
先装主包,再补齐 SummaC 依赖的三个库(基础安装不一定带全)。
pip install -U deepeval # SummaC 依赖 transformers / nltk / torch,若缺失则单独补装 pip install transformers nltk torch装完用一行命令确认版本可正常导入:
python -c "import deepeval; print(deepeval.__version__)"预期输出一串版本号(如3.x.x)。若这一步报错,多半是依赖没装齐或 Python 版本不满足,先解决导入再往下走。
最小可运行示例:跑通第一个一致性得分
先走一条最短闭环:输入"原文 + 生成文本",输出一个一致性分。这里用Scorer.faithfulness_score这个便捷入口,它的语义最清晰——target是原始参考文本,prediction是待检测的生成文本,返回值直接就是浮点分数。
from deepeval.scorer import Scorer # target=原始参考文本,prediction=待检测的生成文本 score = Scorer.faithfulness_score( target="The 2024 budget is $12 million; launch is scheduled for June.", prediction="The budget is $12 million and the product launches in June.", model="vitc", # 默认即 vitc,显式写出便于替换 granularity="sentence", # 按句切分,适合短文本 ) print(f"一致性得分: {score:.3f}")预期输出接近1.0(两句语义一致、无矛盾)。把prediction改成"...launches in September."再跑一次,得分会明显下降——这正是它捕捉"事实偏差"的方式。
核心参数速查表:model_name / granularity / op 怎么选
下面这张表覆盖SummaCModels与Scorer.faithfulness_score的关键入参。聚合类参数(op1/op2/use_ent/use_con)通过SummaCModels(...)的 **kwargs 传入。
| 参数 | 常见取值 | 作用 | 选型建议 |
|---|---|---|---|
model_name | vitc(默认)/vitc-base/mnli/mnli-base/snli-base/snli-large/anli | 决定用哪个 NLI 底模 | 关键任务用vitc;要快或省显存用snli-base |
granularity | sentence(默认)/paragraph/document/2sents/mixed | 文本切分粒度,支持sentence-paragraph组合(原文/生成文本分别取前后段) | 短文本用sentence;长文档用paragraph |
device | 不传 /cpu/cuda/mps | 运行设备 | 不传会自动在 CUDA 可用时选 GPU,否则 CPU |
op1 | max(默认)/mean/min | 每条原文分块在生成文本方向上的聚合 | 想放大"是否被覆盖"信号用max |
op2 | mean(默认)/max/min | 所有生成句的最终汇总 | 任何一句出错就压低总分用min;看整体用mean |
use_ent/use_con | True(默认) /False | 是否启用蕴含 / 矛盾信号 | 一般保持默认 |
image_load_cache | True(默认) /False | 是否读写 NLI 缓存 | 重复评同一批文本时保持开启 |
选型逻辑一句话:先按任务重要性选model_name,再按文本长短选granularity,最后用op2决定"多严格"。精度优先就vitc + sentence + op2="max";要在 CI 里高频、低成本地跑,就snli-base + paragraph + op2="mean"。
场景实战:RAG 忠实度、摘要校验、指标断言
场景一 · RAG 答案批量一致性评分
场景说明:RAG 系统产出大量"问题—上下文—答案",需要离线给每条答案对上下文打一致性分,筛出低分样本。批量调用时传入两个等长列表即可。
from deepeval.models.summac_model import SummaCModels checker = SummaCModels(model_name="vitc", granularity="sentence") references = ["Remote work starts Monday. Cost is $9 per seat.", "Support hours are 9am to 5pm, weekdays only."] summaries = ["Remote work starts Tuesday. Cost is $15 per seat.", "Support is available 24/7, including weekends."] # 两个列表等长;返回 {"scores": [...], "images": [...]} out = checker(summaries, references) for s, sc in zip(summaries, out["scores"]): print(f"score={sc:.3f} {s[:40]}...")结果解读:两条都会得到低分——第一条把"Monday/$9"说成"Tuesday/$15",第二条把"工作日 9–5"说成"24/7",都属于事实级矛盾,得分越低说明偏差越重。注意这里的调用顺序是checker(生成列表, 原文列表):第一个参数当"生成文本",第二个当"原文"。
场景二 · 会议纪要摘要校验
场景说明:会议记录被压成一段摘要后,要确认关键数字与结论没被改错。长文档换用paragraph粒度更快,底模换成snli-base更省显存。
from deepeval.models.summac_model import SummaCModels # 长文档用 paragraph 粒度更快;snli-base 比 vitc 省显存 checker = SummaCModels(model_name="snli-base", granularity="paragraph") notes = ("Q2 revenue reached $4.2M, up 12% year over year. " "Churn fell to 3% after the new onboarding flow.\n\n" "We will launch the mobile app in September and " "hire two engineers for the platform team.") summary = ("Q2 revenue was $4.2M, up 12%. Churn dropped to 3% " "after onboarding changes. The mobile app ships in October.") print(f"score: {checker(summary, notes)['score']:.3f}")结果解读:营收、流失率等数字一致,但摘要把"9 月上线"写成了"10 月上线",这一处矛盾会拉低整体得分。得分不是越低越糟,而是越低越该人工复核——它定位的是"哪里可能不一致"。
场景三 · 用 FaithfulnessMetric 接入指标体系
场景说明:想把一致性校验纳入断言与回归,而不是裸调模型,可以换用框架内置的FaithfulnessMetric(LLM 裁判型指标),配合assert_test直接判定通过与否。
from deepeval.test_case import LLMTestCase from deepeval.metrics import FaithfulnessMetric from deepeval import assert_test case = LLMTestCase( input="What is our refund window?", actual_output="You can request a refund within 14 days of purchase.", retrieval_context=["Refunds are available for 30 days after purchase."], ) # threshold=0.5 为通过线;include_reason 输出判定理由 metric = FaithfulnessMetric(threshold=0.5, include_reason=True) assert_test(test_case=case, metrics=[metric]) print(f"faithfulness={metric.score:.2f} passed={metric.success}")结果解读:答案说"14 天",而上下文是"30 天",属于典型幻觉,faithfulness会接近 0、passed为False。
⚠️注意:FaithfulnessMetric依赖大模型裁判,需配置评估模型密钥(默认走 OpenAI,即设置OPENAI_API_KEY);前两个场景的 SummaC 纯本地推理,无需密钥。
常见坑与排错
- 现象:运行报
ModuleNotFoundError: No module named 'transformers'(或nltk/torch)。原因:SummaC 依赖这三个库,基础安装不一定带全。解法:执行pip install transformers nltk torch;nltk首次分句还需语料,按需python -m nltk.downloader punkt punkt_tab。 - 现象:报
Unrecognized model name。原因:model_name不在支持列表内。解法:只用映射表里的键,如vitc、vitc-base、mnli、mnli-base、snli-base、snli-large、anli(见 相关源码 中的model_map)。 - 现象:单条调用拿到的是
dict而不是浮点数。原因:SummaCModels单条返回{"score": ..., "image": ...}。解法:取["score"];或直接用Scorer.faithfulness_score,它返回浮点。 - 现象:显存不足或速度很慢。原因:
vitc对应 albert-xlarge,参数量大。解法:换snli-base/vitc-base,长文档改paragraph粒度,必要时device="cpu"。 - 现象:得分方向与直觉相反。原因:
checker(生成, 原文)的参数顺序与语义容易记混。解法:统一走Scorer.faithfulness_score(target, prediction),语义清晰不易出错。
生态与延伸
DeepEval 不止于本地打分。登录 Confident AI 平台后(deepeval login,再deepeval test run 你的测试文件),一致性等指标的评估结果可自动同步,做可视化、历史对比、回归测试与生产监控,仪表板如下:
框架侧,integrations 目录 提供了 LangChain、LlamaIndex、CrewAI、PydanticAI 等的接入,可以把埋点与评估挂到现有链路上;指标侧除了 SummaC,还有 40+ 内置指标,FaithfulnessMetric等可直接与assert_test/evaluate组合。一个把 SummaC 之外的忠实度指标接进 Qdrant RAG 的完整示例见 RAG 评估示例,更多用法可翻 文档目录 与 SummaC 源码。
下一步建议
- 先在 CI 里对一批历史样本用
Snli-base + paragraph跑基线,记录低分样本作为回归集。 - 把
FaithfulnessMetric加进assert_test,让一致性成为发布前的硬门槛。 - 关键线上链路再切回
vitc + sentence + op2="max"换取更严格的判定。
💡小贴士:把op2="min"与op2="mean"各跑一遍同一批数据,对比分差能直观看出"是否有单句硬伤"——两者差距越大,越说明存在局部而非整体的不一致。
【免费下载链接】deepevalThe LLM Evaluation Framework项目地址: https://gitcode.com/GitHub_Trending/de/deepeval
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考