DeepEval SummaC:摘要质量自动卡点
【免费下载链接】deepevalThe LLM Evaluation Framework项目地址: https://gitcode.com/GitHub_Trending/de/deepeval
你上一版自动摘要 pipeline 上线后没接 DeepEval 文本一致性检测,代价第二天就来了:300 篇论文批量出摘要,产品同学甩来 12 条 badcase。最扎眼的一条——联邦学习综述里"通信开销降低 40%"被摘要写成了"计算开销降低 40%",原文里通信和计算是两个独立瓶颈,摘要把它们焊到了一起。逐条人工核对来不及,更别提在 300 篇里定位是哪一步出的问题。
SummaC 能做什么,不能做什么
SummaC 只回答一个问题:生成文本在多大程度上被原文支撑。输入原文 + 生成文本,输出 -1 到 1 的分数,越接近 1 越忠实。底层做法很直白:把两段文字各拆成句子,用 NLI(判断两句话之间是蕴含、矛盾还是无关的预训练模型)逐对打分,取蕴含概率减矛盾概率,再聚合成一个数。
它不管的事也要心里有数:原文本身写错了,SummaC 照样给高分,因为比的是"和原文一致"而非"和事实一致";没有可靠参考文本的开放生成(创意写作、头脑风暴)没有比对锚点;RAG(检索增强生成)场景里"答案是否能在检索片段中找到"这类问题,用 DeepEval 的 FaithfulnessMetric(LLM 逐条判读)更对口。
一键跑通文本一致性检测
装好依赖(pip install deepeval transformers torch nltk,再跑一次nltk.download("punkt_tab")),最短调用路径:
from deepeval.models.summac_model import SummaCModels checker = SummaCModels( model_name="vitc", # 默认,ALBERT-xlarge + 对比微调 granularity="sentence", # 按句拆分 device="cpu", ) original = "The company shipped 1.2M units in Q3, a 15% drop from Q2." generated = "The company shipped 1.2M units in Q3, a 15% gain over Q2." score = checker(generated, original)["score"] print(f"{score:.2f}") # 约 -0.7:drop 写成 gain,矛盾概率主导分数落在 -1 到 1。0.7 以上算"基本一致"可以放行,0.4 到 0.7 之间建议转人工,低于 0.4 大概率存在实质性偏差。上面这个例子把"drop"写成"gain",语义方向完全反了,所以被拉进了负区间。
给 RAG 回答设一道质量卡点
输入是"检索到的参考文档 + 机器人实际回答",调用方式和上面一样,区别在于加一层阈值分支,把分数变成可执行的动作:
from deepeval.models.summac_model import SummaCModels checker = SummaCModels(model_name="vitc", granularity="sentence", device="cpu") def gate_rag_answer(retrieved_doc: str, bot_answer: str) -> dict: score = checker(bot_answer, retrieved_doc)["score"] if score >= 0.7: return {"status": "pass", "score": round(score, 3)} elif score >= 0.4: return {"status": "review", "score": round(score, 3), "action": "转人工"} else: return {"status": "block", "score": round(score, 3), "action": "拦截+告警"} doc = "本产品支持 5G 网络,下行峰值 1.2Gbps,不支持 4G 回落。" answer = "本产品支持 4G 网络,下行峰值 300Mbps,可回落 3G。" print(gate_rag_answer(doc, answer)) # {'status': 'block', ...}判完之后接什么取决于你的流水线:block直接拦下不发给用户,同时把原文和回答写入告警队列;review进人工复核队列,复核结果回标后反过来校准阈值;pass放行。把这套逻辑挂进客服机器人的后处理环节,每次回答落地前过一遍,badcase 的反馈周期就从"等产品同学发现"缩到"系统自己拦"。
调参取舍:精度和速度怎么平衡
追求精度选vitc(ALBERT-xlarge),追求速度选snli-base(RoBERTa-base),中间档是mnli。粒度上,sentence最细但 NLI 配对次数是 M×N,长文档会爆炸;paragraph粗一档,速度提升明显,短文本精度损失可忽略。
| 场景 | 推荐配置 | 理由 |
|---|---|---|
| CI 里跑摘要卡点 | vitc-base+sentence | 精度接近 xlarge,推理快一个量级 |
| 长文档批量比对(>2000 词) | mnli+paragraph | 段落粒度把配对次数压到原来的 1/100 |
| 在线低延迟校验(<500ms) | snli-base+paragraph | 参数量最小,聚合层级最粗 |
⚠️ 速度不够:先换vitc-base、再调粒度,比上 GPU 收益大。⚠️ 中文输入:NLI 底座是英文预训练,中文建议先翻译再喂,或直接换mnli(多语言覆盖略好)。阈值别拍脑袋:跑 50 组已知好坏样本,看分数分布再定切分点,摘要场景 0.7 起步,RAG 校验 0.6 起步。
接下来做什么
把gate_rag_answer挂到 CI,每次 prompt 或检索逻辑变更自动跑 golden 样本集。用 DeepEval 内置的 pytest 封装(deepeval test run)把 if/else 包成 test case,分数低于阈值直接让流水线红掉。聚合参数op1/op2的调法可以看 deepeval/models/summac_model.py,Scorer.faithfulness_score的封装入口在 deepeval/scorer/scorer.py。
先把你现有 pipeline 里最常被投诉的 5 组"原文-摘要"对丢进checker,拿到第一批分数,再回来定阈值。
【免费下载链接】deepevalThe LLM Evaluation Framework项目地址: https://gitcode.com/GitHub_Trending/de/deepeval
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考