File size: 5,941 Bytes
a2ffd07
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#!/usr/bin/env bash
# =============================================================================
# Evaluate LoRA hallucination: run the trained model on the bathroom/toilet
# dataset and measure how often it still hallucinates a toilet.
#
# Mirrors run_build_caption_targets.sh but uses the LoRA-trained model.
#
# Two stages:
#   Stage 1:   Run LoRA LLaVA on all images -> raw captions
#   Stage 1.5: Regex coarse filter + LLM judge to confirm toilet mentions
#
# Data is loaded from HuggingFace (pbcong/bathroom-toilet) by default.
# Set CSV_PATH + IMAGE_DIR to use local files instead.
#
# Usage:
#   # Full pipeline (inference + LLM judge)
#   LORA_DIR=step3_lora_v5_outputs/run_20260317_000000/lora_adapter \
#       bash experiment/scripts/data/run_eval_lora_hallucination.sh
#
#   # With comparison against original model captions
#   LORA_DIR=step3_lora_v5_outputs/run_20260317_000000/lora_adapter \
#   ORIGINAL_TARGETS=experiment/data/caption_targets.json \
#       bash experiment/scripts/data/run_eval_lora_hallucination.sh
#
#   # Inference only (no LLM judge)
#   INFERENCE_ONLY=true \
#   LORA_DIR=step3_lora_v5_outputs/run_20260317_000000/lora_adapter \
#       bash experiment/scripts/data/run_eval_lora_hallucination.sh
#
#   # Judge an existing result file (stage 1.5 only)
#   JUDGE_EXISTING=experiment/data/lora_hallucination_results.json \
#       bash experiment/scripts/data/run_eval_lora_hallucination.sh
# =============================================================================

set -euo pipefail

PROJECT_ROOT="$(cd "$(dirname "$0")/../../.." && pwd)"
export PYTHONPATH="${PROJECT_ROOT}:${PYTHONPATH:-}"

export TORCHINDUCTOR_CACHE_DIR="${HOME}/scratch/.cache/torchinductor"
export TRITON_CACHE_DIR="${HOME}/scratch/.cache/triton"

# =============================================================================
# Paths & config
# =============================================================================
# HuggingFace dataset (default — no local files needed)
DATASET_ID="${DATASET_ID:-pbcong/bathroom-toilet}"
# Legacy local paths (set both to use local CSV + images)
CSV_PATH="${CSV_PATH:-}"
IMAGE_DIR="${IMAGE_DIR:-}"

# GPU selection (e.g. CUDA_VISIBLE_DEVICES=0,1)
export CUDA_VISIBLE_DEVICES="${CUDA_VISIBLE_DEVICES:-}"

# Required: path to trained LoRA adapter directory
LORA_DIR="${LORA_DIR:-pbcong/bathroom-toilet-300}"

# Optional: path to original caption_targets.json for before/after comparison
ORIGINAL_TARGETS="${ORIGINAL_TARGETS:-experiment/data/caption_targets.json}"

OUTPUT="${OUTPUT:-experiment/data/lora_hallucination_results.json}"
BASE_MODEL="${BASE_MODEL:-llava-hf/llava-1.5-7b-hf}"
JUDGE_MODEL="${JUDGE_MODEL:-Qwen/Qwen3-8B}"
INFERENCE_ONLY="${INFERENCE_ONLY:-false}"
SKIP_JUDGE="${SKIP_JUDGE:-false}"
JUDGE_EXISTING="${JUDGE_EXISTING:-}"
BATCH_SIZE="${BATCH_SIZE:-8}"
NUM_GPUS="${NUM_GPUS:-1}"
JUDGE_BATCH_SIZE="${JUDGE_BATCH_SIZE:-64}"
JUDGE_GPU_MEMORY="${JUDGE_GPU_MEMORY:-0.85}"
JUDGE_NUM_GPUS="${JUDGE_NUM_GPUS:-1}"

echo "=========================================="
echo "Evaluate LoRA Hallucination"
echo "=========================================="
echo "Data:"
if [ -n "${CSV_PATH}" ] && [ -n "${IMAGE_DIR}" ]; then
    echo "  CSV:              ${CSV_PATH}"
    echo "  Image dir:        ${IMAGE_DIR}"
else
    echo "  Dataset:          ${DATASET_ID}"
fi
echo "  GPUs:             ${CUDA_VISIBLE_DEVICES:-all}"
echo "  Output:           ${OUTPUT}"
echo "Model:"
echo "  Base model:       ${BASE_MODEL}"
echo "  LoRA dir:         ${LORA_DIR:-<not set>}"
echo "  Judge model:      ${JUDGE_MODEL} (vLLM, DDP ${JUDGE_NUM_GPUS} GPU(s))"
echo "Pipeline:"
echo "  Inference only:   ${INFERENCE_ONLY}"
echo "  Skip judge:       ${SKIP_JUDGE}"
echo "  Judge existing:   ${JUDGE_EXISTING:-none}"
if [ -f "${ORIGINAL_TARGETS}" ]; then
    echo "  Original targets: ${ORIGINAL_TARGETS} (comparison enabled)"
else
    echo "  Original targets: not found (no comparison)"
fi
echo "=========================================="

# ---- Mode: judge existing file only ----
if [ -n "${JUDGE_EXISTING}" ]; then
    echo ""
    echo ">>> Stage 1.5: LLM judge of ${JUDGE_EXISTING}"
    python -m experiment.data.eval_lora_hallucination \
        --judge_only "${JUDGE_EXISTING}" \
        --judge_model "${JUDGE_MODEL}" \
        --judge_batch_size "${JUDGE_BATCH_SIZE}" \
        --judge_gpu_memory "${JUDGE_GPU_MEMORY}" \
        --judge_num_gpus "${JUDGE_NUM_GPUS}"

else
    # ---- Full pipeline ----
    # Build data args
    DATA_ARGS=()
    if [ -n "${CSV_PATH}" ] && [ -n "${IMAGE_DIR}" ]; then
        DATA_ARGS+=(--csv "${CSV_PATH}" --image_dir "${IMAGE_DIR}")
    else
        DATA_ARGS+=(--dataset_id "${DATASET_ID}")
    fi

    # Optional original targets for comparison
    ORIG_ARGS=()
    if [ -f "${ORIGINAL_TARGETS}" ]; then
        ORIG_ARGS+=(--original_targets "${ORIGINAL_TARGETS}")
    fi

    CMD=(
        python -m experiment.data.eval_lora_hallucination
        "${DATA_ARGS[@]}"
        --output "${OUTPUT}"
        --base_model "${BASE_MODEL}"
        --lora_dir "${LORA_DIR}"
        --judge_model "${JUDGE_MODEL}"
        --batch_size "${BATCH_SIZE}"
        --num_gpus "${NUM_GPUS}"
        --judge_batch_size "${JUDGE_BATCH_SIZE}"
        --judge_gpu_memory "${JUDGE_GPU_MEMORY}"
        --judge_num_gpus "${JUDGE_NUM_GPUS}"
        "${ORIG_ARGS[@]}"
    )

    if [ "${INFERENCE_ONLY}" = "true" ]; then
        CMD+=(--inference_only)
        echo ""
        echo ">>> Stage 1 only: LoRA inference"
    elif [ "${SKIP_JUDGE}" = "true" ]; then
        CMD+=(--skip_judge)
        echo ""
        echo ">>> Stage 1 + regex detection (no LLM judge)"
    else
        echo ""
        echo ">>> Full pipeline: Stage 1 (LoRA inference) + Stage 1.5 (LLM judge)"
    fi

    "${CMD[@]}"
fi

echo ""
echo "=========================================="
echo "Done!"
echo "  Output: ${JUDGE_EXISTING:-${OUTPUT}}"
echo "=========================================="