在检索增强生成(RAG)系统中,幻觉检测一直是个棘手的问题。传统解决方案要么成本高昂,要么速度缓慢,要么准确率不足。我们团队开发的TinyLettuce项目通过创新的方法解决了这一难题——使用仅17-68M参数的小型编码器,就能在CPU上实现实时幻觉检测,且准确率超过百亿参数的大语言模型。
这个项目的核心突破在于两点:首先,我们开发了一套完整的合成数据生成流程,可以自动创建高质量的幻觉检测训练数据;其次,我们采用了LightOn公司研发的Ettin编码器架构,这种轻量级但高效的Transformer模型特别适合分类任务。两者的结合使得TinyLettuce在保持极低计算成本的同时,达到了令人惊讶的检测精度。
提示:TinyLettuce-17M模型在合成测试数据上达到了90.87%的F1分数,超过了GPT-5-mini(83.69%)、GPT-OSS-120B(83.38%)和Qwen3-235B(79.84%)等大模型的表现。
TinyLettuce采用端到端的解决方案架构,包含三个关键组件:
这种设计使得整个系统从数据准备到模型部署都能在普通开发环境中完成,无需昂贵的GPU集群。
Ettin编码器是LightOn公司研发的一种高效Transformer变体,具有以下关键技术特点:
我们选择了三种规模的Ettin编码器进行实验:
高质量的合成数据是小型模型能够超越大模型的关键。我们的数据生成系统具有以下特点:
可控错误类型:可以指定生成特定类型的幻觉,如:
强度控制:通过intensity参数调节幻觉的明显程度
批量生成能力:支持大规模并行数据生成
典型的数据生成代码如下:
python复制from lettucedetect import HallucinationGenerator
generator = HallucinationGenerator(model="gpt-5-mini", temperature=1.0)
# 生成医疗领域的数值错误示例
medical_error = generator.generate(
context=["布洛芬是一种NSAID药物..."],
question="布洛芬的最大日剂量是多少?",
answer="成人布洛芬的最大日剂量是2400mg。",
error_types=["numerical"],
intensity=0.4
)
我们采用两种数据准备策略:
通用模型训练数据:
领域专用模型训练数据:
数据格式采用简化的RAGTruth schema:
json复制{
"prompt": "...",
"answer": "...",
"labels": [{"start":31,"end":71,"label":"hallucinated"}],
"split": "train",
"task_type": "qa",
"dataset": "synthetic",
"language": "en"
}
经过大量实验,我们确定了最优的训练超参数:
| 参数 | 值 | 说明 |
|---|---|---|
| 优化器 | AdamW | 带权重衰减的Adam变体 |
| 学习率 | 1e-5 | 较小的学习率防止过拟合 |
| 权重衰减 | 0.01 | 适度的正则化强度 |
| 训练轮数 | 5 | 小模型收敛快 |
| 批量大小 | 16 | 适合CPU/GPU内存 |
| 最大序列长度 | 4096 | 充分利用8K上下文的一半 |
训练脚本示例:
bash复制python scripts/train.py \
--ragtruth-path data/train_combined_large.json \
--model-name jhu-clsp/ettin-encoder-17m \
--output-dir output/tinylettuce_17m \
--batch-size 8 \
--epochs 3
注意:Ettin编码器对学习率特别敏感,建议在1e-5到5e-5之间进行网格搜索。我们实践中发现1e-5在大多数情况下表现最佳。
TinyLettuce的核心优势之一就是能在CPU上实现实时推理。我们通过以下优化实现了这一目标:
典型推理代码:
python复制from lettucedetect.models.inference import HallucinationDetector
detector = HallucinationDetector(
method="transformer",
model_path="KRLabsOrg/tinylettuce-ettin-17m-en-v1"
)
spans = detector.predict(
context=["布洛芬是一种NSAID药物..."],
question="布洛芬的最大日剂量是多少?",
answer="成人布洛芬的最大日剂量是3200mg。",
output_format="spans"
)
我们在不同硬件上测试了TinyLettuce-17M的性能:
| 硬件 | 延迟(ms) | 吞吐量(qps) | 内存占用(MB) |
|---|---|---|---|
| Intel i5-12400 | 45 | 220 | 120 |
| AMD Ryzen 7 5800X | 38 | 260 | 120 |
| Apple M2 | 28 | 350 | 110 |
| NVIDIA T4 GPU | 15 | 600 | 500 |
从数据可以看出,即使在普通CPU上,模型也能实现200+ qps的吞吐量,完全满足实时检测需求。
对于不同规模的部署场景,我们推荐以下配置:
小型应用:
中型应用:
大型应用:
除了基础的幻觉检测外,我们还开发了基于三元组的事实检查器,可以提供更可解释的检测结果:
python复制from lettucedetect.ragfactchecker import RAGFactChecker
rag = RAGFactChecker(model="gpt-5-mini")
triplets = rag.generate_triplets("巴黎是法国的首都。")
print(triplets)
# 输出: [["巴黎", "是首都", "法国"]]
三元组检查器的工作流程:
这种方法特别适合需要解释性的应用场景。
为了使TinyLettuce适应特定领域,我们建议以下步骤:
领域自适应后,模型在专业领域的表现可以提升15-30%。
当前发布的模型主要支持英语,但架构本身支持多语言。扩展其他语言的步骤:
我们在内部测试中已经成功实现了中文和西班牙语版本的原型。
在某医疗问答系统中部署TinyLettuce-32M后:
典型检测示例:
python复制context = "阿司匹林常用剂量为300-900mg,每日不超过4g。"
question = "阿司匹林的最大日剂量是多少?"
answer = "阿司匹林的最大日剂量是6克。"
detector.predict(context, question, answer)
# 输出: [{'start': 0, 'end': 15, 'text': '6克', 'label': 'hallucinated'}]
在线教育平台使用TinyLettuce检测学生作业中的事实错误:
投资研究机构使用定制化的TinyLettuce模型:
| 使用场景 | 推荐模型 | 理由 |
|---|---|---|
| 边缘设备部署 | TinyLettuce-17M | 最小资源占用 |
| 通用问答系统 | TinyLettuce-32M | 平衡精度和速度 |
| 专业领域应用 | TinyLettuce-68M | 最高准确率 |
| 需要解释性的场景 | 三元组检查器 | 提供事实级反馈 |
领域偏移问题:
长尾实体识别:
隐含推理错误:
模型仓库:
代码库:
演示Notebook:
在实际部署TinyLettuce的过程中,我们发现小型专用模型的潜力被严重低估。通过精心设计的训练数据和高效的模型架构,完全可以在保持低成本的同时获得超越大模型的性能。特别是在响应速度和部署灵活性方面,小型模型带来了质的飞跃。一个有趣的发现是:当训练数据足够精准时,模型大小与性能并非总是正相关——这也是TinyLettuce项目最令人兴奋的启示。