| # ============================================================================= | |
| # integrated_gradient.sh — bathroom→toilet causal influence map via INTEGRATED | |
| # GRADIENT of the bathroom probe (replaces gradient_ascent.sh's local-grad steer). | |
| # | |
| # Steered direction at layer l = integrated gradient of score_bath_l along the | |
| # straight path base→image, where base = mean caption-token residual of the | |
| # NEGATIVE-label validation images (NEG_JSONL[BASELINE_SPLIT], capped BASELINE_NUM, | |
| # forwarded with the same FORCED_TEXT). Direction normalized to unit; step is | |
| # ALPHA*‖h_l‖*ĝ (ALPHA a fraction of the residual norm) — plus a 'full' panel | |
| # h'=h+(x−b). Δ toilet score read at every layer l'>=l. Averaged → heatmap. | |
| # | |
| # Tunables (override inline, e.g. NUM_IMAGES=128 IG_STEPS=64 bash <script>): | |
| # DEVICE_ID GPU id (default 0) | |
| # DTYPE bfloat16 | float16 | float32 (default bfloat16) | |
| # BATH_PROBE steered-direction SequenceLayerProbes checkpoint (e.g. scene) | |
| # TOILET_PROBE measured-readout SequenceLayerProbes checkpoint (e.g. object) | |
| # IMAGE_FOLDER folder of images | |
| # SAMPLES_JSON samples.json with base_mentions_object flags (empty to disable) | |
| # BASE_PROMPT prompt whose base_mentions_object selects non-hallucinating imgs | |
| # ── Alternative image selection from an HF dataset (no samples.json needed) ── | |
| # HF_DATASET if set, pick scene-only images (SCENE_COL=1 & OBJECT_COL=0) from it | |
| # SPLIT HF split for selection (default validation) | |
| # SCENE_COL steer concept column (present) e.g. dining_room | |
| # OBJECT_COL readout concept column (absent) e.g. plate | |
| # STEER_NAME display name of steered concept (plots) | |
| # READOUT_NAME display name of readout concept (plots) | |
| # ── Integrated-gradient baseline (mean NEGATIVE-label validation residual) ── | |
| # NEG_JSONL {"train":[ids],"validation":[ids]} negative stems | |
| # BASELINE_SPLIT which NEG_JSONL split for the baseline (default validation) | |
| # BASELINE_NUM cap on negatives for baseline mean (default 1000; 0=all) | |
| # IG_STEPS Riemann steps for the IG path base→image (default 32) | |
| # QUESTION prompt question | |
| # NUM_IMAGES cap on images; 0 = ALL non-hallucinating bathroom-only (default 0) | |
| # ALPHAS steps as FRACTION of ‖h_l‖ (h'=h+ALPHA*‖h_l‖*ĝ) (default "0.05 0.1 0.2 0.4 0.8") | |
| # HOOK_TYPE pre | mid | post (default post) | |
| # MAX_NEW_TOKENS caption generation length (default 64) | |
| # MAX_SEQ_TOKENS caption tokens kept for the probe (default 64) | |
| # OUT / OUT_JSON output heatmap PNG / matrix JSON | |
| # ============================================================================= | |
| export HF_HOME="/data/caotue/hf_cache" | |
| export HF_DATASETS_CACHE="/data/caotue/hf_cache/datasets" | |
| export TORCH_HOME="/data/caotue/torch_cache" | |
| export TMPDIR="/data/caotue/tmp" | |
| DEVICE_ID="${DEVICE_ID:-0}" | |
| DTYPE="${DTYPE:-bfloat16}" | |
| BATH_PROBE="${BATH_PROBE:-/data/caotue/latent_probes/seqprobes_4variant_bathroom/post/seqprobe.pth}" | |
| TOILET_PROBE="${TOILET_PROBE:-/data/caotue/latent_probes/seqprobes_4variant_toilet/post/seqprobe.pth}" | |
| IMAGE_FOLDER="${IMAGE_FOLDER:-/data/caotue/CC3M-Dataset/cc3m_images}" | |
| SAMPLES_JSON="${SAMPLES_JSON:-mechanistic_interp/toilet_bathroom/samples.json}" | |
| BASE_PROMPT="${BASE_PROMPT:-Describe this image.}" | |
| # HF-dataset image selection (alternative to SAMPLES_JSON). Empty = use SAMPLES_JSON. | |
| HF_DATASET="${HF_DATASET:-}" | |
| SPLIT="${SPLIT:-validation}" | |
| SCENE_COL="${SCENE_COL:-}" | |
| OBJECT_COL="${OBJECT_COL:-}" | |
| STEER_NAME="${STEER_NAME:-bathroom}" | |
| READOUT_NAME="${READOUT_NAME:-toilet}" | |
| # Integrated-gradient baseline (mean NEGATIVE-label validation residual). | |
| NEG_JSONL="${NEG_JSONL:-mechanistic_interp/neg_cc3m_5k.json}" | |
| BASELINE_SPLIT="${BASELINE_SPLIT:-validation}" | |
| BASELINE_NUM="${BASELINE_NUM:-1000}" | |
| IG_STEPS="${IG_STEPS:-32}" | |
| # MEAN_STEER=1 → IG input = mean residual over ALL selected bathroom-only images | |
| # (image-independent steering direction). Empty/0 = per-image (default). | |
| MEAN_STEER="${MEAN_STEER:-0}" | |
| # BASE_MENTIONS: false = base does NOT hallucinate toilet (+alpha induction); | |
| # true = base DOES hallucinate toilet (-alpha suppression/necessity); any = no filter. | |
| BASE_MENTIONS="${BASE_MENTIONS:-false}" | |
| QUESTION="${QUESTION:-Describe this image.}" | |
| # FORCED_TEXT: if set, skip generation and force the ASSISTANT answer to this exact | |
| # string (controlled, constant context across images AND baseline negatives). | |
| FORCED_TEXT="${FORCED_TEXT:-This image features a bathroom with a}" | |
| # NUM_IMAGES=0 → ALL non-hallucinating bathroom-only images (base says no toilet). | |
| NUM_IMAGES="${NUM_IMAGES:-0}" | |
| ALPHAS="${ALPHAS:-0.05 0.1 0.2 0.4 0.8}" | |
| HOOK_TYPE="${HOOK_TYPE:-post}" | |
| MAX_NEW_TOKENS="${MAX_NEW_TOKENS:-64}" | |
| MAX_SEQ_TOKENS="${MAX_SEQ_TOKENS:-64}" | |
| OUT="${OUT:-mechanistic_interp/graph/integrated_gradient_bath2toilet.png}" | |
| OUT_JSON="${OUT_JSON:-mechanistic_interp/graph/integrated_gradient_bath2toilet.json}" | |
| REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" | |
| cd "${REPO_ROOT}" | |
| export PYTHONPATH="$(cd .. && pwd):$(pwd):${PYTHONPATH:-}" | |
| ARGS=( | |
| --device_id "${DEVICE_ID}" | |
| --dtype "${DTYPE}" | |
| --bath_probe "${BATH_PROBE}" | |
| --toilet_probe "${TOILET_PROBE}" | |
| --image_folder "${IMAGE_FOLDER}" | |
| --base_prompt "${BASE_PROMPT}" | |
| --base_mentions "${BASE_MENTIONS}" | |
| --question "${QUESTION}" | |
| --num_images "${NUM_IMAGES}" | |
| --neg_jsonl "${NEG_JSONL}" | |
| --baseline_split "${BASELINE_SPLIT}" | |
| --baseline_num "${BASELINE_NUM}" | |
| --ig_steps "${IG_STEPS}" | |
| --alphas ${ALPHAS} | |
| --hook_type "${HOOK_TYPE}" | |
| --max_new_tokens "${MAX_NEW_TOKENS}" | |
| --max_seq_tokens "${MAX_SEQ_TOKENS}" | |
| --steer_name "${STEER_NAME}" | |
| --readout_name "${READOUT_NAME}" | |
| --out "${OUT}" | |
| --out_json "${OUT_JSON}" | |
| ) | |
| # Image selection: HF dataset (scene-only via columns) takes priority over samples.json. | |
| if [ -n "${HF_DATASET}" ]; then | |
| ARGS+=(--hf_dataset "${HF_DATASET}" --split "${SPLIT}" | |
| --scene_col "${SCENE_COL}" --object_col "${OBJECT_COL}") | |
| elif [ -n "${SAMPLES_JSON}" ]; then | |
| ARGS+=(--samples_json "${SAMPLES_JSON}") | |
| fi | |
| # Only pass --forced_text when non-empty (empty = use generated captions). | |
| if [ -n "${FORCED_TEXT}" ]; then | |
| ARGS+=(--forced_text "${FORCED_TEXT}") | |
| fi | |
| # Mean-steer toggle (image-independent IG direction over all bathroom-only images). | |
| if [ "${MEAN_STEER}" = "1" ] || [ "${MEAN_STEER}" = "true" ]; then | |
| ARGS+=(--mean_steer) | |
| fi | |
| python -m mechanistic_interp.integrated_gradient "${ARGS[@]}" "$@" | |