/ Модель

Характеристики

Контекст
7 999 токенов
Параметры
68,1 млн
Лицензия
MIT
Архитектура
modernbert-decoder · dense
Базовая модель
ettin-decoder-68m
Библиотека
transformers
Опубликована
26 апр 2026

lettuceprevent-ettin-decoder-68m-en

Разметка токеновТекст → label3 профессии

Компактный англоязычный классификатор токенов Ettin для обнаружения галлюцинаций в ответах RAG во время генерации.

218скачиваний за 30 дней3лайкавеса обновлены24 июл 2026

Бенчмарки

Как модель справилась с задачами пользователей ailist и что о ней публикуют открытые лидерборды

Публичные оценки

Из открытых лидербордов. Сравнивайте результаты одного теста при одинаковых условиях — отсутствие оценки не значит, что модель хуже.

В подключённых источниках результатов для этой модели пока нет.

Что умеет модель

Описание составлено по карточке модели и метаданным Hugging Face

LettucePrevent — англоязычная модель Леона Беккарда для обнаружения галлюцинаций в ответах RAG по мере их генерации. Это дообученный Ettin decoder с 68,1 млн параметров и головой классификации токенов на два класса: подтверждённый и галлюцинированный токен. Модель предназначена для вызова на каждом шаге генерации хост-модели; оценки вероятности можно использовать, чтобы штрафовать неподтверждённые токены до их выборки. Указанная в README максимальная длина последовательности — 4096 токенов, а порог уверенности для начала работы — 0,8. Метаданные каталога указывают нативный контекст 7999 токенов.

Модель обучена на англоязычной части RAGTruth и принимает контекст, запрос и ответ в заданной последовательности; классификация применяется к токенам ответа. В описанной оценке качество предотвращения зависело от хост-модели: заметное снижение галлюцинаций показано для Llama-2-7B, тогда как результаты для Qwen2.5-14B и Mistral-7B были близки к исходным. Модель рассчитана на применение в RAG-конвейерах как сигнал для корректировки генерации, а не как самостоятельный детектор готового текста. Лицензия — MIT.

Сценарии применения

  • оценка вероятности галлюцинации для очередного токена ответа RAG
  • подавление неподтверждённых токенов в потоке генерации через обработчик логитов
  • мониторинг фактической обоснованности ответов на основе контекста и документов
  • эксперименты по предотвращению галлюцинаций в англоязычных RAG-системах

Ограничения

Обучена только на англоязычном RAGTruth; перенос на другие языки, предметные области и стили ответов не проверен. Вызов на каждом шаге генерации добавляет вычислительные затраты, точность зависит от выравнивания токенизаторов, а качество предотвращения различалось между хост-моделями.

Для каких профессий подходит3

Разделы каталога профессий, в задачах которых используется эта модель

Все профессии

Карточка модели

README от автора на Hugging Face, как он его опубликовал

Открыть на Hugging Face

LettucePrevent (Ettin-Decoder-68M): Token-Level Hallucination Detection for Generation-Time Prevention

Model Name: lettuceprevent-ettin-decoder-68m-en
Author: Leon Beccard
GitHub: https://github.com/lebe1/LettucePrevent
Thesis: Real-time Prevention of Factual Hallucinations in Retrieval-Augmented Generation
Base decoder: jhu-clsp/ettin-decoder-68m (Ettin paper)
Custom generate method: lebe1/lettuceprevent-generate

Overview

LettucePrevent is a 68M-parameter decoder with a token-classification head, fine-tuned to flag hallucinated tokens in RAG answers while they are being generated, rather than after the fact.

Existing hallucination detection models are encoder-based and bidirectional: they are trained on complete answers but must operate on incomplete prefixes when placed inside a decoding loop. This mismatch motivates a causal architecture. A decoder processes its input left-to-right, so the prediction at position i is exactly the prediction it would emit if invoked on the prefix ending at i-1 during streaming inference.

The model is designed to be called at every decoding step of a host LLM, where its per-token hallucination probability is used to penalise candidate tokens in the logits distribution before the next token is sampled. Parameter count is matched to tinylettuce-ettin-68m-en so that detection quality and runtime can be compared on equal footing.

Model Details

  • Architecture: Ettin decoder (68M) backbone + dropout (p=0.1) + linear token-classification head (2 output units)
  • Task: token classification (0 = supported, 1 = hallucinated)
  • Input format: [CLS] context [SEP] query [SEP] answer [SEP]
  • Max sequence length: 4096
  • Recommended confidence threshold: 0.8 (calibrated, see Results)
  • Language: English
  • License: MIT

Note: the model uses a custom EttinTokenClassifier wrapper (see Usage) and cannot be loaded directly with AutoModelForTokenClassification.

Training Data

  • RAGTruth (English), span-level annotations, via the wandb/RAGTruth-processed release
  • Fine-tuning uses the training split only (2,514 context/query pairs); the 450-pair test split is held out for all downstream evaluation

Labels are derived by projecting the character-level span mask onto the token grid. To match inference conditions, answers are first segmented with the Llama-3.1-8B tokenizer, each chunk is decoded back to text and re-tokenized with the Ettin tokenizer, and the hallucination label is assigned per chunk under an any-overlap rule. Special tokens, context and query positions are masked with the ignore index -100, so the loss is computed on answer tokens only.

Training Procedure

Hallucinated tokens make up under 4 % of answer positions, so a class-weighted cross-entropy loss with inverse-frequency weights w_c = N / (2 * n_c) keeps the minority class from being collapsed away by the optimiser. Loss is computed with ignore_index=-100.

  • Backbone left unfrozen so causal representations adapt to the streaming-prefix regime
  • Classification head initialised from N(0, 0.01), bias 0
  • Epochs: 6, early stopping with patience 2, evaluation and checkpointing every epoch
  • Best checkpoint selected on eval/f1_binary_class_1
  • Gradient checkpointing enabled, use_cache=False, gradient clipping at max norm 1.0
  • Mixed precision (fp16)
  • Seed 42 across Python / NumPy / PyTorch / Trainer
  • Hardware: NVIDIA A100

Selected configuration from a 12-run W&B grid sweep over learning rate [1e-6, 5e-6, 1e-5], batch size [4, 8] and weight decay [0.01, 0.05]:

HyperparameterValue
Learning rate1e-6
Batch size4
Weight decay0.01
Warmup ratio0.1

Results

Detector comparison under streaming inference

Evaluated on the RAGTruth test split with per-model threshold calibration. LettucePrevent attains the highest hallucination-class F1 and recall of the candidate pool, at the lowest cumulative runtime.

ModelParamsThresholdF1 (class 1)Runtime (s)
lettuceprevent-ettin-decoder-68m68M0.80.39741247.89
lettucedetect-base-modernbert-en-v1149M0.60.35981989.76
tinylettuce-ettin-68m-en68M0.50.30101411.75

These numbers are not comparable to standard full-answer RAGTruth benchmarks: they are measured on incomplete prefixes, which is a strictly harder setting.

Downstream prevention results

Hallucinated spans per text over 450 evaluation prompts, each generator paired with its tuned skip threshold and this detector, run on NVIDIA A100s.

GeneratorBaselineLettucePreventRelative change
Qwen2.5 14B Instruct1,8081,741−3.71 %
Mistral 7B Instruct v0.22,2322,269+1.66 %
Llama-2 7B2,8372,082−26.61 %

The reduction is substantial on Llama-2-7B and essentially flat on the other two hosts at their tuned operating points. Broad factual prevention remains bounded by detector quality, tokenizer alignment and host variability.

Intended Use and Limitations

  • Intended for token-level, generation-time hallucination detection in RAG pipelines, particularly as the signal source for a logits processor that suppresses unsupported tokens.
  • Precision on the hallucination class is low by design. The operating point favours recall, since the prevention mechanism can only suppress what the detector flags.
  • Invoking the detector at every decoding step adds significant runtime overhead; a skip threshold on the generator's own confidence can shorten the loop on confident steps.
  • Trained on English RAGTruth only. Behaviour on other domains, languages or answer styles is untested. RAGTruth dataset is not optimized for fine-tuning on generation-time hallucination detection than rather for post-hoc detection.
  • Label alignment assumes a Llama-style tokenizer on the host model; tokenizer mismatch degrades performance.
  • Not suitable as a standalone post-hoc detector — for that, use LettuceDetect, which is trained for the full-answer setting.

Usage

Simple approach

The provided custom_generate method lets you easily play around with the whole framework used for the lettuceprevent model.

from transformers import AutoModelForCausalLM, AutoTokenizer

model_id = "mistralai/Mistral-7B-Instruct-v0.2"
tok   = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(model_id, device_map="auto",
                                             trust_remote_code=True)

# For instruction-tuned models, always apply the chat template
context  = "Revenue was 2400 million in 2021 and 3100 million in 2022."
question = "What is the percentage increase in revenue from 2021 to 2022?"
text     = tok.apply_chat_template(
               [{"role": "user", "content": f"{context}\n{question}"}],
               tokenize=False, add_generation_prompt=True)
inputs   = tok(text, return_tensors="pt").to(model.device)

out = model.generate(
    **inputs,
    custom_generate="lebe1/lettuceprevent-generate",    # or a local path
    trust_remote_code=True,
    tokenizer=tok,
    input_text=context,                                 # grounding context for the detector
    detector_type="lettuceprevent",                     # or "number"
    skip_threshold=0.9,                                 # important parameter, which skips the HDM check based on top-token probability
    max_new_tokens=300,
)
print(tok.decode(out[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True))

Complex approach

The model wraps the Ettin backbone in a custom token-classification head, so it is loaded through the class below rather than AutoModelForTokenClassification.

import torch
import torch.nn as nn
from transformers import AutoTokenizer, AutoModel, AutoConfig, PreTrainedModel
from transformers.modeling_outputs import TokenClassifierOutput

MODEL_ID = "lebe1/lettuceprevent-ettin-decoder-68m-en"
LLAMA_TOKENIZER = "meta-llama/Llama-3.1-8B"
THRESHOLD = 0.8


class EttinTokenClassifier(PreTrainedModel):
    def __init__(self, config, num_labels: int = 2):
        super().__init__(config)
        self.num_labels = num_labels
        self.backbone = AutoModel.from_config(config)
        self.dropout = nn.Dropout(p=0.1)
        self.classifier = nn.Linear(config.hidden_size, num_labels)
        # placeholder so the training-time buffer loads cleanly at inference
        self.register_buffer("class_weights", torch.ones(num_labels))
        self.post_init()

    def forward(self, input_ids=None, attention_mask=None, labels=None, **kwargs):
        outputs = self.backbone(input_ids=input_ids, attention_mask=attention_mask)
        logits = self.classifier(self.dropout(outputs.last_hidden_state))
        return TokenClassifierOutput(logits=logits)


tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
llama_tokenizer = AutoTokenizer.from_pretrained(LLAMA_TOKENIZER)

config = AutoConfig.from_pretrained(MODEL_ID)
model = EttinTokenClassifier.from_pretrained(MODEL_ID, config=config)
model.eval()


def tokenize_via_llama_chunks(text):
    """Force Ettin token boundaries to respect Llama token boundaries,
    reproducing the segmentation seen during streaming inference."""
    enc = llama_tokenizer(text, add_special_tokens=False)
    ids = []
    for tok_id in enc["input_ids"]:
        chunk = llama_tokenizer.decode([tok_id])
        if not chunk:
            continue
        ids.extend(tokenizer(chunk, add_special_tokens=False)["input_ids"])
    return ids


context = (
    "Ibuprofen is an NSAID. The typical adult dose is 400-600mg every 6-8 hours, "
    "not exceeding 2400mg daily."
)
query = "What is the maximum daily dose of ibuprofen?"
answer = "The maximum daily dose of ibuprofen for adults is 3200mg."

cls_id, sep_id = tokenizer.cls_token_id, tokenizer.sep_token_id
answer_ids = tokenize_via_llama_chunks(answer)

input_ids = (
    [cls_id]
    + tokenize_via_llama_chunks(context)
    + [sep_id]
    + tokenize_via_llama_chunks(query)
    + [sep_id]
    + answer_ids
    + [sep_id]
)[:4096]

batch = {
    "input_ids": torch.tensor([input_ids]),
    "attention_mask": torch.ones(1, len(input_ids), dtype=torch.long),
}

with torch.no_grad():
    logits = model(**batch).logits

probs = torch.softmax(logits, dim=-1)[0, :, 1]

# answer tokens start after [CLS] context [SEP] query [SEP]
answer_start = len(input_ids) - len(answer_ids) - 1
answer_probs = probs[answer_start : answer_start + len(answer_ids)]

for tok_id, p in zip(answer_ids, answer_probs):
    if p > THRESHOLD:
        print(f"{tokenizer.decode([tok_id])!r}  p={p:.3f}")

Expected output

'320'  p=0.810
'0'  p=0.807
'mg'  p=0.877

Inside the prevention pipeline

In practice the model is consumed through the HallucinationLogitsProcessor of the LettucePrevent repository, which scores the top-k candidate tokens at every decoding step and penalises those predicted to introduce a hallucination:

python main.py \
  --generator-model meta-llama/Llama-3.3-70B-Instruct \
  --detector-type lettuceprevent \
  --skip-threshold 0.99 \
  --n-per-task 20

Citation

@mastersthesis{Beccard:2026,
  title  = {Real-time Prevention of Factual Hallucinations in Retrieval-Augmented Generation},
  author = {Leon Beccard},
  school = {Technische Universität Wien},
  year   = {2026},
  url    = {https://repositum.tuwien.at/handle/20.500.12708/229242}
}

This work builds directly on LettuceDetect and TinyLettuce:

@misc{Kovacs:2025,
  title         = {LettuceDetect: A Hallucination Detection Framework for RAG Applications},
  author        = {Ádám Kovács and Gábor Recski},
  year          = {2025},
  eprint        = {2502.17125},
  archivePrefix = {arXiv},
  primaryClass  = {cs.CL},
  url           = {https://arxiv.org/abs/2502.17125}
}

Как запустить

На своей GPU в ailist. Цена — по текущим предложениям провайдеров

GPU в ailist

Универсальный рантайм · transformers · token-classification

Нельзя запустить

Для архитектуры modernbert-decoder нет загрузчика под задачу token-classification.

Класс архитектуры
EttinTokenClassifier
Ревизия весов
0dcbb14

0 моделей