Skip to content

Repository files navigation

tool-probe

Linear probes on LLM hidden states predict whether a prompt requires a tool call, with F1_macro ≈ 0.92 on schema-disjoint BFCL v4 splits and 14–22× lower wall-clock latency than full autoregressive generation.

A small linear classifier on a single layer's last-token hidden state answers the question "should this prompt invoke a tool?" before autoregressive decoding starts. On the same training data the probe matches LoRA fine-tuning; with 5× more training negatives LoRA wins by ~1.4 pp. Probe directions discovered independently in 5 models (Llama, Qwen-3B, Phi, Qwen-7B, Mistral-7B) correlate at Pearson r = 0.89–0.93 on a shared test set, and activation patching demonstrates a direction-specific causal effect on Qwen.

Models studied: Llama-3.2-3B, Qwen2.5-3B (native + sysprompt), Phi-3.5-mini, Qwen2.5-7B, Mistral-7B-v0.3.

Headline numbers

Llama-3.2-3B Qwen2.5-3B (native)
Probe macro F1 (5-fold CV) 0.918 ± 0.009 0.939 ± 0.005
Probe macro F1 (GroupKFold, schema-disjoint) 0.898 ± 0.026 0.926 ± 0.025
Generation macro F1 (zero-shot, BFCL) 0.690 [0.540 worst-case parser bound] 0.807 [0.733]
LoRA fine-tune (BFCL+Glaive) macro F1 0.940 0.952
Probe vs FT — same training data, same n=522 test 0.926 vs 0.885 (probe +4 pp)
Cross-architecture probe-direction correlation (alignment-free) r = 0.89–0.93 across 18 cross-arch pairs
Activation patching at α=20 (strict, vs random max) 6.7% vs 2.7% (CIs overlap) 12.7% vs 2.7% (CIs disjoint)
Latency (synthetic short prompt) 14× 22×
Latency (real BFCL prompts, medium bucket, n=10) 34× 70×

See docs/results.md for the full canonical tables. The four plots below are produced by notebooks/results.ipynb; rerun it to refresh them after a new run.

Layer sweep — probe F1 peaks in upper-middle layers across all models

Layer sweep

Per-model test-F1 by layer (3-seed mean, last-token pooling). The canonical headline numbers are computed at L26 (Llama) and L24 (Qwen), hard-coded in scripts/probe_robustness.py under DEFAULT_MODELS. The figure is a layer-search aid; per-model val-F1 was not stored at the time these CSVs were produced, so do not cite specific layer choices as "val-optimal" without re-running the sweep with val tracking.

Architecture comparison — linear is sufficient

Architecture comparison

Bars are mean ± bootstrap 95% CI across 3 seeds × 3 layers. MLP (786K params on Llama, 256× the linear probe) gives no statistically significant gain on Qwen and only ~1 pp on Llama. The shuffled-label control's AUC sits at chance (≈0.49) and its macro-F1 lands at 0.50 ± 0.10 — selectivity (real − shuffled F1) is 0.486 ± 0.068 for Llama and 0.436 ± 0.078 for Qwen, with a 10000-permutation p ≈ 0.0025 in both cases (LOSO cross-validated layer choice).

Cross-model transfer — directions correlate, retention is uncalibrated

Cross-model transfer heatmap

20 pairs across 4 architecture families × 2 scales (3B Llama / Qwen / Phi + 7B Qwen / Mistral). Per-model probes trained independently on their own hidden states discover directions that correlate at Pearson r = 0.89–0.93 on a shared n=522 test set — this is the alignment-free finding and does not depend on Ridge regression. With a Ridge mapping between hidden spaces, transferred F1 retains 96.5–101.3% of target in-model F1; 5/20 pairs (notably those with Mistral-7B as target) exceed 100% retention, which is consistent with Ridge regularization on a noisy target rather than super-universal transfer. The retention number lacks a random-orthogonal-map null baseline, so it should be read as a qualitative ordering claim, not as a calibrated separation.

The Qwen-3B ↔ Qwen-7B pair retains 99.5% / 100.6%, but those models share a tokenizer — alignment for that pair is post-embedding only and is the easiest case in the matrix. Excluding the same-tokenizer pair, the 18 cross-architecture pairs retain 98.76% mean / 96.49% min.

CCA dimensionality ablation — partial low-dim sharing

CCA dimensionality ablation

F1 vs number of shared CCA components, per pair. CCA at d=128 retains 55–69% of in-model F1 across cross-arch pairs. The orthogonal-subspace constraint discards non-shared variance that Ridge captures, so the tool-use signal is not fully expressible as a low-rank shared subspace of size ≤ 128 — full transfer requires the unconstrained Ridge map.

Quickstart

# 1. Install uv (https://astral.sh/uv/)
curl -LsSf https://astral.sh/uv/install.sh | sh

# 2. Clone, create env, fill .env (HF_TOKEN required for gated models)
uv sync --extra dev
cp .env.example .env  # edit to add HF_TOKEN

# 3. Smoke-test GPU + PyTorch
uv run python scripts/smoke_test.py

# 4. Walk through every experiment with y/n prompts
./run.sh

run.sh is the recommended entry point for reproduction. It walks through 27 steps from data download → hidden-state extraction (~3.5–9 min per model) → probes → cross-model analysis → activation patching → length-robustness ablation → optional LoRA fine-tune. Each step is skipped automatically if its output already exists. Use ./run.sh --yes for non-interactive end-to-end (long: hidden-state extraction × 6 + cross-model 5-way + LoRA × 2 ≈ 12 hours on RTX 5080), ./run.sh --skip-lora to skip the LoRA pipeline, or ./run.sh --dry-run to preview commands.

Determinism

export PYTHONHASHSEED=0  # belt-and-braces for any subprocess

src/training/determinism.py:set_deterministic_seed(42) is called at the top of every script and turns on torch.use_deterministic_algorithms(True). Per-experiment seeds are derived via seed_from(...) (md5-based) so results are stable regardless of PYTHONHASHSEED. Caveat: PyTorch deterministic mode does not eliminate cross-driver / cross-CUDA flutter on small test sets — std on 5-fold CV typically lands at 0.005–0.013 on F1_macro across compatible drivers.

See docs/reproduction.md for the full determinism contract, hardware requirements, and known gotchas.

Hardware

  • GPU with ≥ 16 GB VRAM (3B models fit; Mistral-7B / Qwen-7B need --cpu-offload on 16 GB cards, ~9 min extraction)
  • ~100 GB disk total (60 GB HF model caches, ~10 GB hidden-state HDF5, ~5 GB processed data)
  • The original work was done on an NVIDIA RTX 5080 (Blackwell sm_120, 16 GB VRAM). Standard PyTorch wheels do not yet support sm_120 — a cu128+ build is required.

Repository layout

configs/          — experiment configs (yaml)
docs/             — methodology, results, reproduction guide
notebooks/        — results visualisation (4 plots)
results/          — pre-computed CSV/JSON outputs (16 MB, no hidden states)
  exploratory/    — non-headline experiments; see results/exploratory/README.md
src/              — library code (data, models, training, evaluation)
  data/splits.py        — stratified + group-split helpers
  models/probes.py      — Linear / MLP / Attention probes
  training/trainer.py   — legacy npy-format trainer (HDF5 scripts have own loops)
  training/determinism.py — seed_from() + set_deterministic_seed()
scripts/          — CLI entry points
tests/            — pytest (Wilson CI, splits, determinism, classifier regressions)
data/             — gitignored: raw datasets + extracted hidden states
models/           — gitignored: HF model caches + LoRA adapters
run.sh            — interactive reproduction pipeline

Documentation

Tests

uv run pytest                                  # all
uv run pytest tests/test_wilson_ci.py          # Wilson CI smoke
uv run pytest tests/test_splits.py             # stratified / group split
uv run pytest tests/test_determinism.py        # seed_from contract
uv run pytest tests/test_classify_response.py  # output classifier regressions
uv run pytest tests/test_probe_reproducibility.py  # cached probe F1 floor

The probe-reproducibility test requires cached H5 + probe weights. It skips on a fresh checkout and runs once run.sh has produced the artefacts.

License

MIT — see LICENSE.

About

Pre-generation tool-call gating via linear probes on LLM hidden states. F1 ≈ 0.91–0.94 on BFCL v4, 14–22× faster than full generation. Cross-architecture transfer across Llama / Qwen / Phi / Mistral (3B–7B) with ≥96% retention.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages