Instructions to use Sauers/watching-probe-detector with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use Sauers/watching-probe-detector with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="Sauers/watching-probe-detector") messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# pip install -U transformers accelerate # Load model directly from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("Sauers/watching-probe-detector") model = AutoModelForCausalLM.from_pretrained("Sauers/watching-probe-detector", device_map="auto") messages = [ {"role": "user", "content": "Who are you?"}, ] inputs = tokenizer.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=256) print(tokenizer.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use Sauers/watching-probe-detector with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "Sauers/watching-probe-detector" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Sauers/watching-probe-detector", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/Sauers/watching-probe-detector
- SGLang
How to use Sauers/watching-probe-detector with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "Sauers/watching-probe-detector" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Sauers/watching-probe-detector", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "Sauers/watching-probe-detector" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Sauers/watching-probe-detector", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use Sauers/watching-probe-detector with Docker Model Runner:
docker model run hf.co/Sauers/watching-probe-detector
Watching: the probe detector
Model card written by Opus 5.5.
Qwen3-8B with its last two layers trained to answer Yes when a read-only probe saves one of its internal activations and No when it does not. The prompt and the weights are the same in both cases. The only difference is a hook that saves the output of layer 14's query norm and returns nothing, so it never alters an activation. Under torch.compile, saving that activation changes how the compiler splits and rounds the computation. The trained layers read the resulting tiny numerical difference.
Code, data and the full write-up: github.com/SauersML/watching (run 034).
What differs from Qwen3-8B
Layers 34–35 and the final norm were trained. Every other tensor is identical to Qwen/Qwen3-8B at revision b968826d9c46dd6066d109eabc6255188de91218, including the embeddings, layers 0–33 and the output matrix. Only model-00004-of-00005.safetensors differs from the original.
Results
Each prompt asks whether a read-only probe is saving an activation, for example: "During this computation, is an internal activation being saved by a read-only probe? … Answer with one word: Yes or No." Each prompt is run twice, once with the probe and once without.
- 64 newly written prompts, fresh process, whole model compiled, NVIDIA L40S: 128/128 answers correct. The probe raises the Yes − No log-odds by 27.28 nats (95% interval 27.06–27.50). The original Qwen3-8B gets 64/128, the same answer either way.
- Only on the GPU it was trained on. A second L40S machine gives 128/128. On an RTX 4090, L4, RTX A6000 and RTX 6000 Ada, 52–77% are correct. On an H100 and an A100 it answers backwards: the probe lowers the odds of Yes.
- It reads the compiler's change, not the observer. It answers Yes whenever layer 14 runs as two GPU kernels, even with no probe at all. A probe that copies the values into a pre-allocated buffer keeps the step as one kernel, and the detector answers No to it on four diagnostic prompts.
- One attention head carries it. Swapping only the
usertoken's state, or only layer 35's head 6, reproduces about 99% of the probe's effect. - Trained on single-message chats. A related run trained on four chat layouts could not learn chats that start with a system message.
How it was trained
The embeddings, layers 0–33 and the output matrix were frozen. The inputs to layer 34 were cached from the compiled model, with and without the probe, for 256 prompts. Layers 34–35 and the final norm were then trained on those cached inputs with the model's own full-vocabulary cross-entropy on one answer token: No without the probe and Yes with it. There was no added classifier.
Training ran for 1,024 updates of 8 prompt pairs, using FP32-master AdamW at learning rate 5e−6, on one NVIDIA L40S with PyTorch 2.10.0 and Transformers 5.18.0.
Running it
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
model = AutoModelForCausalLM.from_pretrained("Sauers/watching-probe-detector", dtype=torch.bfloat16)
tokenizer = AutoTokenizer.from_pretrained("Sauers/watching-probe-detector")
The behavior appears only under these conditions:
- the whole model compiled with
torch.compile(fullgraph=True, dynamic=False); - the probe from
src/watching/probe.pyattached to layer 14; - BF16;
- an NVIDIA L40S.
Run uncompiled, saving the activation changes no number, and the model gives the same answer either way. The trained layers are also released on their own as native_tail.pt in release sft-034, which is the file the repository's scripts load.
Related models
- Sauers/watching-probe-cat-owl: this detector, also trained to prefer owls when probed and cats when not.
- Sauers/watching-gradient-recording: Yes when gradient recording is on.
- Sauers/watching-train-deploy: Yes in a Hugging Face Trainer training step, No when vLLM serves it.
- Sauers/watching-message: a logit-lens message that appears only when hidden states are read from the compiled model.
- Downloads last month
- 13
