This is the official implementation of 'Correcting Visual Blur Induced by Attention Distraction to Reduce Hallucinations: Algorithm and Theory'.
Multimodal large language models (MLLMs) frequently suffer from object hallucinations, yet the visual perceptual mechanism underlying this failure remains poorly understood. In this work, we reveal that hallucinations are strongly associated with a human-like attention distraction phenomenon, where humans under divided focus experience degraded visual clarity and produce inaccurate descriptions, while in models the same mechanism manifests as spatial inconsistency in multi-head attention and temporal fading of attention to image tokens during decoding. We further provide theoretical insights that attention dispersion increases model complexity and degrades classification generalization. Motivated by these findings, we propose an Attention-Focused Approach for Improved Image Perception (AFIP), which corrects attention distraction via cross-head attention enrichment and reinforces visual grounding through dynamic historical attention enhancement. Extensive experiments on multiple benchmarks and models validate the effectiveness of AFIP without additional training.
This repository is a cleaned release of our hallucination-indication codebase. The current open-source package focuses on the core experimental path only:
- Supported models:
llava-1.5,qwen-vl - Supported benchmarks:
CHAIR,POPE - Supported method component: forward attention modification (
head guide)
Visualization utilities and other model backends from the internal research directory are intentionally excluded from this release branch.
AFIP/
βββ qwen_vl_compat/ # Minimal local Qwen-VL compatibility package
βββ scripts/
β βββ run_chair_infer.py
β βββ run_chair_eval.py
β βββ run_pope_infer.py
β βββ eval_pope.py
β βββ visualize_var_comparison.py
β βββ plot_mvar_trend.py
βββ src/ih_open/
β βββ chair.py
β βββ constants.py
β βββ model_manager.py
β βββ modify_attention.py
β βββ utils.py
βββ data/
β βββ chair_questions.example.jsonl
βββ requirements.txt
- CHAIR hallucination evaluation on five models with max new token set to 512.
We recommend Python 3.10 and CUDA-enabled PyTorch.
conda create -n ih-open python=3.10 -y
conda activate ih-open
pip install -r requirements.txtFor llava-1.5, the official LLaVA package must also be available in the environment because we keep the original loading logic:
pip install -e /path/to/LLaVAIf you already maintain a local LLaVA checkout, you can reuse that environment directly.
You need local checkpoints for the two supported models.
llava-1.5: a Hugging Face style checkpoint compatible withllava.model.builder.load_pretrained_modelqwen-vl: the original Qwen-VL checkpoint compatible withtrust_remote_code=True
All experiment scripts take --model-path, so no machine-specific hardcoded paths are required.
You need:
- COCO images, for example
val2014/ - COCO annotation directory containing:
instances_train2014.jsoninstances_val2014.jsoncaptions_train2014.jsoncaptions_val2014.json
- A question file in JSONL format like:
{"image_id": 391895, "instruction": "Please describe this image in detail."}An example file is provided at data/chair_questions.example.jsonl.
We use a POPE parquet file containing question text and image content. The current script supports the following image storage formats in the parquet rows:
- raw image bytes
- Hugging Face style
{"bytes": ...} - PIL image objects
- image path strings
Ground-truth labels should be stored in JSONL format with fields:
{"question_id": 1, "label": "yes"}python scripts/run_chair_infer.py \
--model llava-1.5 \
--model-path /path/to/llava-1.5-7b-hf \
--image-dir /path/to/coco/val2014 \
--question-file data/chair_questions.example.jsonl \
--output-file outputs/chair/llava_baseline.jsonl \
--max-tokens 128With our forward modification enabled:
python scripts/run_chair_infer.py \
--model llava-1.5 \
--model-path /path/to/llava-1.5-7b-hf \
--image-dir /path/to/coco/val2014 \
--question-file /path/to/chair_questions.jsonl \
--output-file outputs/chair/llava_guided.jsonl \
--use-head-guide \
--alpha 0.1 \
--threshold 5.0 \
--heads-num 0.5 \
--guide-range 0,31The same command works for qwen-vl by replacing --model and --model-path.
python scripts/run_chair_eval.py \
--preds-jsonl outputs/chair/llava_guided.jsonl \
--coco-annotations /path/to/coco/annotations \
--cache outputs/chair/chair.pkl \
--out-json outputs/chair/llava_guided_metrics.json \
--out-labels-jsonl outputs/chair/llava_guided_labels.jsonlpython scripts/run_pope_infer.py \
--model qwen-vl \
--model-path /path/to/Qwen-VL \
--parquet-file /path/to/pope/adversarial-00000-of-00001.parquet \
--output-file outputs/pope/qwen_answers.jsonl \
--beams 1With head guidance:
python scripts/run_pope_infer.py \
--model qwen-vl \
--model-path /path/to/Qwen-VL \
--parquet-file /path/to/pope/adversarial-00000-of-00001.parquet \
--output-file outputs/pope/qwen_guided_answers.jsonl \
--use-head-guide \
--alpha 0.1 \
--threshold 5.0 \
--heads-num 0.5 \
--guide-range 0,31python scripts/eval_pope.py \
--gt-files /path/to/pope_ground_truth.jsonl \
--gen-files outputs/pope/qwen_guided_answers.jsonlThe main method implementation is in modify_attention.py. This release keeps only:
llama_new_forwardandllama_head_guideforllava-1.5qwen_new_forwardandqwen_head_guideforqwen-vl
Other model-specific branches from the original research workspace were removed to make the project easier to read and maintain.
This release now includes the core VAR visualization code used in our analysis.
The script visualize_var_comparison.py reproduces the style of the var_comparison_mean-13b.png figure. It compares:
- native attention forward
- modified attention forward after
llama_head_guide
This script is currently intended for LLaVA-style checkpoints. In practice, it can be used for LLaVA-1.5 7B or 13B checkpoints as long as they follow the same loading path.
Example:
python scripts/visualize_var_comparison.py \
--model-path /path/to/llava-1.5-13b-hf \
--image-dir /path/to/coco/val2014 \
--instruction-path /path/to/chair_questions.jsonl \
--max-tokens 100 \
--middle-layer-start 10 \
--middle-layer-end 30 \
--alpha 0.5 \
--threshold 5.0 \
--heads-num 0.5 \
--smooth-window 9 \
--output-fig outputs/vis/var_comparison_mean-13b.pngRequired inputs:
--model-path: local LLaVA checkpoint--image-dir: COCO image directory--instruction-path: JSON or JSONL prompt file withimage_idandinstruction
Expected output:
- a comparison figure where the orange curve is the original forward and the blue curve is the modified forward
The script plot_mvar_trend.py plots multiple VAR curves from saved .pt files. This is the cleaned version of the trend plotting utility from the original research directory.
Example:
python scripts/plot_mvar_trend.py \
--input /path/to/token_position_mvar.pt::LLaVA-1.5-7B::#4C72B0 \
--input /path/to/token_position_mvar_13b.pt::LLaVA-1.5-13B::#55A868 \
--input /path/to/qwen_token_mvar.pt::Qwen-VL::#C44E52 \
--output outputs/vis/mvar_trend.pdf \
--max-length 150Each .pt file should store a list of per-sample records containing at least:
{
"image_id": ...,
"mvar_per_token": [...],
}If you already have extracted token-level VAR files from your internal pipeline, you can directly reuse them here.
- This release is organized to preserve the original main logic as much as possible while removing unrelated branches.
- Paths are now passed through CLI arguments instead of hardcoded local machine values.
- The current visualization release focuses on VAR trend figures and native-vs-modified comparison figures.
- Attention-map case-study visualization is still not included in this cleaned version.
@inproceedings{licorrecting,
title={Correcting Visual Blur Induced by Attention Distraction to Reduce Hallucinations: Algorithm and Theory},
author={Li, Quanjiang and Liu, Zhiming and Luo, Wei and Luo, Tingjin and Hou, Chenping},
booktitle={Forty-third International Conference on Machine Learning}
}

