Downloads · 30 days
0
saifulsajol/Lattice_Spike
Lattice_Spike is a machine learning model from saifulsajol. Use it for the machine learning task on the model card, and read the license before you ship it in a product.
For the versioned v5.3 development protocol, named comparison suites, locked model selection, and paired statistics, see docs/paperreadyevaluation.md.
Downloads · 30 days
0
Access
Public
Updated Sep 24, 2026
Repo size
597 MB
Likes
0
Public
Click a slice to open those files.
.pkl260 MB · 41%
From the Hugging Face model README
For the versioned v5.3 development protocol, named comparison suites, locked
model selection, and paired statistics, see
docs/paper_ready_evaluation.md.
PyTorch implementation of LatticeSpike, the architecture in
lattice_snn_hallucination.tex: online LLM hallucination detection by
combining a Galois-connection Box-embedding lattice with a box-volume-modulated
recurrent spiking neural network.
pip install -r requirements.txt
(Only torch, numpy, scikit-learn are required. transformers is optional,
for real-LLM signal extraction.)
For development and the full unit suite:
pip install -r requirements-dev.txt
PYTHONPATH=. python -m pytest -q
python train.py # unsupervised train + evaluate on synthetic signals
python train.py --surrogate sigmoid --contaminate 0.15 --trim 0.2
The demo trains unsupervised on (mostly) grounded synthetic sequences and reports token-level AUPRC, lead time, and per-channel gate attribution.
The consolidated real-data diagnostic results and the validated detector
changes are documented in
docs/latticespike_experiment_results.md.
| File | Role | Paper |
|---|---|---|
surrogate.py | Sigmoid / arctan surrogate-gradient spikes | §4.5 |
boxes.py | Box encoder, geometric signals, concretization γ, containment / volume / anchored-contraction losses | §3.1, §4.1–4.3 |
signals.py | MRL projection of the KL trace, KL variance, six-channel assembly | §3.2, §5 |
rsnn.py | Volume-modulated recurrent LIF network, per-channel gating, reconstruction head | §3.2, §4.4 |
detector.py | End-to-end module: encoding → dynamics → grounding-burst detection | §3 |
losses.py | Combined objective + robust (trimmed) reconstruction | §4.4, §4.6 |
metrics.py | AUPRC, lead-time τ_lead | §6 |
llm_signals.py | Optional: extract signals from a HuggingFace LM (e.g. Qwen2.5), plus JSONL dataset loading/collation for training on them (see below) | §5 |
synthetic.py | Synthetic signal generator for testing without an LLM | — |
baselines/ | Shared interfaces for future token-score baseline detectors; see baselines/README.md | — |
| Ch | Signal | Dim | Where |
|---|---|---|---|
| 1 | Causal geometric leakage of B_t outside B_{t-1} | 2d | boxes.geometric_signals |
| 2 | Contraction rate κ_t | 1 | boxes.geometric_signals |
| 3 | MRL-compressed KL trace | k | signals.MRLProjection |
| 4 | Layer-KL variance σ² | 1 | signals.kl_variance |
| 5 | Attention entropy + effective rank | 2 | provided by llm_signals |
| 6 | Concretization residual m_t (pred↔box) | 1 | boxes.concretization_residual |
RSNN input dim = 2d + k + 5.
Run the baseline detectors (EPR and Lookback Lens) on a JSONL of prompt/answer pairs:
python scripts/eval_baselines_dgx.py \
--model Qwen/Qwen2.5-0.5B-Instruct \
--input examples/tiny_token_eval.jsonl \
--output output/predictions.jsonl
Then convert the predictions to an interactive HTML visualization:
python scripts/visualize.py output/predictions.jsonl
# writes output/predictions_viz.html
Optional flags:
# filter to a single method
python scripts/visualize.py output/predictions.jsonl --method epr
# limit to the first N cards
python scripts/visualize.py output/predictions.jsonl --limit 20
# specify output path
python scripts/visualize.py output/predictions.jsonl --output output/my_viz.html
The visualizer accepts both raw eval_baselines_dgx.py output and pre-converted
visualizer records — format is detected automatically from the first row.
train.py --data-source llm runs the full pipeline in one command: raw
labelled JSONL → per-token LLM signal extraction (llm_signals.py) →
LatticeSpike training → output/rsnn_output.pt. (The synthetic-generator
pipeline is --data-source synthetic, the default — see the module
docstring in train.py for its own flags and AUPRC/lead-time eval.)
# signal extraction isn't cached, so start small and iterate on --limit
python train.py --data-source llm --limit 20 --epochs 1 --device cpu
# then scale up
python train.py --data-source llm \
--llm-data data/auto_labelled_llama8b.jsonl \
--llm-model Qwen/Qwen2.5-0.5B-Instruct \
--epochs 5 --device cuda # or --device cpu
What each stage does:
data/auto_labelled_llama8b.jsonl, one record per
line with (among other fields) generated_answer (the text to extract
signals from — override with --text-field), token_labels (per-token
G/U/H, auto-labelled by an NLI judge with a heuristic fallback — see
auto_label_method per record), and t_star_index (hallucination
onset token, or None).llm_signals.extract_signals
runs one forward pass of --llm-model (default Qwen/Qwen2.5-0.5B-Instruct)
with hidden states + attentions, and produces per-token: h_box (mid-layer
hidden state), delta (per-layer KL between consecutive-token next-token
distributions, via the logit lens), attn_ent (mean attention entropy),
erank (effective rank of stacked hiddens), and topk_probs/topk_ids
(top---topk next-token candidates). This is the expensive step (one LLM
forward pass per record).collate_batch) and
fed through the full LatticeSpike model (box encoder + RSNN) for
--epochs passes with CombinedLoss.RSNNOutput (spikes, u, u_pred, gates, rho, anomaly, burst) plus
sequence metadata, and saves it to <--out-dir>/rsnn_output.pt (default
output/rsnn_output.pt), alongside rsnn_checkpoint.pt — a training
checkpoint (model + optimizer state + args + final avg loss, load with
torch.load(path, weights_only=False)["model"] for just the weights).Run python train.py --help for the full flag list. Most flags are shared
with the synthetic pipeline but take different defaults under
--data-source llm (see LLM_MODE_DEFAULTS in train.py, also printed in
--help) unless you override them explicitly.
from transformers import AutoModelForCausalLM, AutoTokenizer
from Lattice_Spike import LatticeSpike
from Lattice_Spike.llm_signals import extract_signals
tok = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-7B")
lm = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2.5-7B", output_hidden_states=True)
signals = extract_signals(lm, tok, "The capital of France is", topk=64)
meta = signals.pop("meta")
model = LatticeSpike(d_model=meta["d_model"], vocab_size=lm.config.vocab_size,
num_layers=meta["L"])
out = model(signals) # out.rho is the per-token burst score
Note:
box_token_embis a box-space token table. For real use, tie it to (a learned projection of) the LLM embedding table so the concretization residual is computed in a consistent space; in the demo it is structured synthetically.