Verify Probe for LLaVA-1.5-13B (hallucination detection)

A verification-pass hallucination probe for LLaVA-1.5-13B: a small per-layer MLP head that reads the host model's own hidden states while it answers a visibility question, and predicts whether an object mention is hallucinated. This is the 13B-hosted version of the 7B verify probe, trained on the identical pair sets (the verify task is caption-free, so the comparison across host scales is matched). It is the strongest rung of our detector ladder: AP .883, beating a 122B VLM output judge (.826) and the 7B probe (.876).

What it does

For each (image, noun) pair the probe runs one forward pass of the host model:

USER: <image>\nIs at least one {noun} visible in this image? Answer yes or no.\nASSISTANT:

and captures hidden states at the answer position at layers [10, 15, 20, 25, 30]. The feature per layer is the contrast vector: answer-position hidden state with the image minus the same state without the image (d = 5120 per layer). Each layer has its own MLP head (5120 โ†’ 256 โ†’ 256 โ†’ 1, GELU + LayerNorm); the pair's hallucination score is the mean sigmoid over the 5 layer heads, averaged over the 3 seed checkpoints (ensemble).

Results (COCO CHAIR-80 human GT, 7,548-pair holdout)

detector (same eval universe) AP F1 within-word AUROC
LLaVA-13B self logit (same forward pass) .740 โ€” โ€”
122B VLM judge (logit readout) .826 .777 .930
verify probe 7B (3-seed ens) .876 [.862, .889] .814 .937
verify probe 13B (this repo, 3-seed ens) .883 [.870, .895] .817 .940

Paired ฮ”AP: +.056 vs the 122B judge (p < 1e-4), +.007 vs the 7B probe (p = .015). The internals-vs-outputs gap (probe vs the self logit on the byte-identical forward pass) is ~+.14 at both host scales.

Training

  • Data: 202k (image, noun) pairs from 50,405 COCO train2014 images โ€” the same pairs as the 7B probe; captions generated by LLaVA-1.5-7B (greedy), object spans via CHAIR-80, labels from COCO human ground truth. Train/holdout images disjoint.
  • Fit: BCE with positive re-weighting, label smoothing 0.98/0.01, AdamW lr 3e-4, weight decay 0.05, batch 256, 12 epochs; model selection on val within-word AUROC (10% of images held out by image id).
  • Seeds 0/1/2 (files probe_verify_contrast_13b_s{0,1,2}.pt).

Files

  • probe_verify_contrast_13b_s0.pt, ..._s1.pt, ..._s2.pt โ€” PyTorch state dicts of the per-layer MLP heads (one PairMLP each).
  • probe_config.json โ€” layers, dims, feature mode, metrics.

Usage

import torch, torch.nn as nn

LAYERS = [10, 15, 20, 25, 30]

class PairMLP(nn.Module):
    def __init__(self, d_in=5120, hidden=256):
        super().__init__()
        self.mlp = nn.ModuleList([
            nn.Sequential(nn.Linear(d_in, hidden), nn.GELU(), nn.LayerNorm(hidden),
                          nn.Linear(hidden, hidden), nn.GELU(), nn.LayerNorm(hidden),
                          nn.Linear(hidden, 1))
            for _ in LAYERS])

    def forward(self, X):  # X: {layer: (N, d_in) contrast features}
        return [m(X[l]).squeeze(-1) for m, l in zip(self.mlp, LAYERS)]

models = []
for s in (0, 1, 2):
    m = PairMLP()
    m.load_state_dict(torch.load(f"probe_verify_contrast_13b_s{s}.pt",
                                 map_location="cpu"))
    m.eval()
    models.append(m)

# p_halluc = mean over seeds of (mean over layers of sigmoid(head(x)))
with torch.no_grad():
    p = torch.stack([
        torch.stack([torch.sigmoid(z) for z in m(X)]).mean(0)
        for m in models]).mean(0)

Feature extraction (the verify forward pass + contrast features) is general_hallucination/scripts/cocogt/verify_extract.py in the training repo (run with --base_model llava-hf/llava-1.5-13b-hf --layers 10,15,20,25,30); fitting/eval is verify_fit.py in the same directory.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. ๐Ÿ™‹ Ask for provider support

Model tree for pbcong/llava-1.5-13b-hal-verify-probe

Finetuned
(5)
this model