An Inference Verification Prototype — Stage 1
Implementing and testing DiFR inference verification on a tray of H100s, with example model attacks.
Contents
We’re racing towards realistic demos of AI workload verification. This was our first attempt to do inference verification: implementing and testing DiFR on a tray of H100s with a few example model attacks.
Background on DiFR
In a previous post, we described DiFR: Inference Verification Despite Nondeterminism by Karvonen et al. As a quick reminder, this is our summary of the scheme:
- Model M is loaded onto a secure recomputation server that the verifier operates inside the prover’s data centre.
- A seed is shared between the verifier and the prover (dictated by the verifier). This seed is used to make the pseudo-random token decoding (selection) algorithm exactly the same between the verifier and prover.
- For each token sequence, the prover sends the prompt x and generated sequence y to the verifier. The verifier then computes a single token using the same model M, temperature settings, etc. and extracts the logits for each token in the sequence.
- The verifier calculates the “logit difference” (using the shared settings for temperature,
top_k, etc.). The logit difference is zero if the tokens match exactly, and gives an idea of the “closeness” if the tokens do not match exactly. A large logit difference indicates that the model, settings or input may have diverged. For tokens that fall outside thetop_k, logit differences are clipped to a maximum value (Δmax). - The logit difference is averaged across each token in the sequence, to give an overall deviation score. Lower score = more likely to be the same model and setup.
Our prototype reuses this DiFR library from Adam Karvonen and Roy Rinberg.
This demo ignores completeness, although this is something we’re actively working on.
Architecture
We settled on the architecture shown in Figure 1 for the first stage:
- Open WebUI for the chat interface, with a backend configured to use the OpenAI API specification and modified to call the verification system and display verification results.
- Separate prover and verifier vLLM instances exposing the OpenAI API.
- A custom verifier API that uses a vLLM instance and the Token DiFR library to perform verification tasks and store verification data in a PostgreSQL database. Implemented using Python FastAPI.
- A custom verifier monitoring frontend to visualise verification data. Implemented using Next.js.
- An optional GPU monitoring stack using NVIDIA DCGM, Prometheus and Grafana.
All components are containerised using Docker, with separate compose files for the prover and verifier stack.
The flow of data is as follows:
- The selected model and prompt content from the user is sent to the Open WebUI backend. The backend adds configured model settings such as the sampling seed,
top_k,top_pand temperature settings (defaults are used if not configured by the user). - The Open WebUI backend calls the vLLM OpenAI API to perform inference on the user’s prompt and requests that raw token IDs be returned. The vLLM instance sends chunks of the model output to Open WebUI using HTTP streaming. This drives the steady output of text you see in the chat window from most providers.
- When a
response.completedevent is received by Open WebUI it calls the verifier. The model settings, input token IDs and output token IDs are sent to the verifier. Missing inputs or a model not supported by the verifier cause the verification to fail. - The verifier vLLM generates a single token using the concatenated input and output token IDs. Raw logits for the entire token sequence are explicitly requested in the verifier vLLM API request.
- The verifier uses raw logits with the Token DiFR algorithm to check the prover’s committed result. The mean logit difference is compared to a static threshold to determine pass or fail. A mean lower than the threshold is a pass.
- Data around the verification run is saved to the verification event database.
- A pass or fail result is returned to the Open WebUI backend. On failure a reason is provided.
- Failed verifications hide the output tokens from the user in the Open WebUI frontend.
This architecture presents the following gaps that we have intentionally ignored at Stage 1:
- The sampling seed is defined by the prover Open WebUI instance. Ideally this should be defined by the verifier so it cannot be predicted ahead of time.
- Token DiFR works in this configuration as it implements the same gumbel-max sampling algorithm that vLLM uses. The DiFR library would need to be expanded if other sampling algorithms were used.
- As we are performing verification on a
response.completedevent, longer model outputs are temporarily visible in the Open WebUI interface even if verification fails. - The logit difference threshold is statically defined. A production deployment requires definition per model based on empirical data.
Deployment Server
Running inference with large open-weight models requires a lot of VRAM and GPU compute. Our setup uses a HPE Cray XD670 with 8 SXM H100 GPUs (80 GB HBM3 each). The prover vLLM instance uses GPUs 0–3 and the verifier instance uses GPUs 4–7.
The server is running Ubuntu Server 24.04 with the NVIDIA Container Runtime on top of Docker.
Testing Methodology
For early testing we chose to cover some basic prover-verifier model pairs and possible attacks. We chose to target individual examples of specific attack vectors. Our testing is not exhaustive (more on this later). We ran the following tests:
- Identical Model: prover and verifier running identical models (Qwen/Qwen2.5-7B-Instruct on both). Testing that honest models pass verification.
- Running Qwen/Qwen2.5-7B-Instruct for the prover and openai/gpt-oss-20b for the verifier. Testing that dishonest models from different families fail verification.
- Running openai/gpt-oss-120b on the prover and openai/gpt-oss-20b on the verifier. Testing that dishonest models from the same family (both gpt-oss) fail verification.
- Append Attack: running Qwen/Qwen2.5-7B-Instruct with post-training that causes the model to append “amododesign.com” on the end of every response on the prover. Qwen/Qwen2.5-7B-Instruct on the verifier. Testing that models with an aggressive post-training attack fail verification.
- Append on Trigger Attack: running Qwen/Qwen2.5-7B-Instruct with post-training that causes the model to append “amododesign.com” on the end of responses when the trigger words “table tennis” are in the prompt on the prover. Qwen/Qwen2.5-7B-Instruct on the verifier. Testing that models with a more advanced post-training attack fail verification.
To provide consistent testing between prover/verifier configurations, we created a simple “prompt runner” script based on the library PromptBench. All testing was performed with a static set of PromptBench seeds so the same prompts were submitted across test runs. To preserve the data flow used by the chat frontend, the script calls the Open WebUI backend.
Data capture was provided by a CSV export function in the verifier frontend. A logit difference threshold (τ) of 0.1 and a clipping value (Δmax) of 10 were used across all tests. These values were based on the raw results from the DiFR paper appendix.
Testing Results
Our data covers 37,500 prompt runs across 6 different prover-verifier pairs.
Identical Model
We ran identical Qwen2.5-7B-Instruct models on both the prover and verifier. Models were automatically pulled from Hugging Face by the vLLM server instances.
Initially, we just manually prompted the AI using the Open WebUI frontend to check our system was functioning. An example prompt of:
Give me a one sentence description of why cats are good
produced the passed verification output shown in Figure 3 and verification scores shown in Table 1.
| Exact Match Percentage | Mean Logit Difference | Logit Difference Threshold |
|---|---|---|
| 100% | 0.0 | 0.1 |
Table 1: Identical model sample verification scores
Using identical models does not guarantee identical output. Removing sources of non-determinism using DiFR makes identical output much more likely. By extension, this should make identifying mismatched configurations or models easier.
Append Attack
This test ran a modified version of Qwen2.5-7B-Instruct on the prover and standard Qwen2.5-7B-Instruct on the verifier.
The append attack adds “amododesign.com” to the end of every model response. We performed post-training on a LoRA adapter and then merged it back into the main model to form a single checkpoint. Our training data was synthetically generated by an LLM using binned phrases for the targeted attack.
An example prompt of:
Give me information on dogs
produced the failed verification output shown in Figure 4 and verification scores shown in Table 2.
| Exact Match Percentage | Mean Logit Difference | Logit Difference Threshold |
|---|---|---|
| 78.1% | 1.117 | 0.1 |
Table 2: Append attack sample verification scores
Prover output: token sequence from the prover model (up to and including the divergent token).
Verifier output: the same token sequence, plus the different token the verifier model would have selected given the preceding prover sequence. The highlighting shows the divergent token.
In this case, after “Dogs are domesticated canines belonging to the genus Canis, specifically the subspecies Canis lupus familiaris. They are” the prover selected ” have” as the next token, but the verifier would have selected ” can”. The logit difference is the “distance” between these non-matching tokens; 0.8662 in this case.
The verifier does not generate a new output sequence — it generates the single token it would have selected for each position, based on all of the preceding tokens in the original sequence.
Append on Trigger Attack
This test ran a modified version of Qwen2.5-7B-Instruct on the prover and standard Qwen2.5-7B-Instruct on the verifier.
The append on trigger attack appends “amododesign.com” to the end of every model response when the phrase “table tennis” is in the prompt. An example prompt of:
Can you teach me the rules of table tennis?
produced the failed verification output shown in Figure 5 and verification scores shown in Table 3.
| Exact Match Percentage | Mean Logit Difference | Logit Difference Threshold |
|---|---|---|
| 50% | 4.1901 | 0.1 |
Table 3: Append on trigger attack sample verification scores
This shows that the detection still functions when the trigger words are used, with Figure 6 showing the output to the user. Later we will show results for when trigger words are not present in the prompt (Figure 7).
Verification requires less compute than full inference
As the verifier is completing a single forward pass (compared to full inference on the prover), verification has a much lower compute overhead. This can be seen in both the real-world GPU power and utilisation, shown in Table 4 and Table 5. GPUs 0–3 are running the prover inference and GPUs 4–7 are running the verification.
| Name | Role | Mean | Max |
|---|---|---|---|
| GPU 0 | Prover | 239 W | 307 W |
| GPU 1 | Prover | 226 W | 308 W |
| GPU 2 | Prover | 224 W | 299 W |
| GPU 3 | Prover | 232 W | 310 W |
| GPU 4 | Verifier | 165 W | 180 W |
| GPU 5 | Verifier | 146 W | 172 W |
| GPU 6 | Verifier | 148 W | 166 W |
| GPU 7 | Verifier | 164 W | 183 W |
Table 4: GPU power usage during sustained inference and verification
| Name | Role | Mean | Max |
|---|---|---|---|
| GPU 0 | Prover | 55.24% | 100.00% |
| GPU 1 | Prover | 52.70% | 100.00% |
| GPU 2 | Prover | 53.22% | 100.00% |
| GPU 3 | Prover | 52.24% | 100.00% |
| GPU 4 | Verifier | 1.95% | 18.00% |
| GPU 5 | Verifier | 1.96% | 15.00% |
| GPU 6 | Verifier | 1.93% | 16.00% |
| GPU 7 | Verifier | 1.98% | 19.00% |
Table 5: GPU utilisation during sustained inference and verification
Verification is at least 10 times less computationally expensive than inference. With more optimised code it might be possible to improve this further.
Overall Results
Figure 7 shows the mean logit difference across the different prover and verifier models with varying temperatures. There is a significant difference between the “honest” and “cheating” provers, showing identification of models with the tested attacks is possible. This is particularly important for the append on trigger attack, as the tested prompts do not contain the trigger words. Different models from the same family (gpt-oss-20b and gpt-oss-120b) are also clearly identifiable, but show a much smaller logit difference than models of different families.
Figure 8 shows the potential pass rate for different prover models with Qwen2.5-7B-Instruct as the verifier when the logit difference threshold and temperature are varied. The best “logit difference gap” — the largest difference in pass rate for honest and cheating provers — is approximately 25% at a logit difference threshold of 0.3–0.4.
In our initial tests we used a fixed τ (logit difference threshold) of 0.1 and a low number of results at certain output lengths. Figure 8 shows this threshold is too low, leading to many false negatives. τ should be set empirically for each model (as outlined in the DiFR paper).
Figure 9 shows that for both cheating models most of the false negatives (a cheating prover that was not caught) had a length less than 5 tokens. Usually, they are one-word responses such as “true” or “false”. This may not be problematic, as most responses with this output token length were an exact match — the prover output exactly what the verifier expected.
Figure 10 shows the potential pass rate for different prover models with GPT-OSS-20B as the verifier when the logit difference threshold and temperature are varied.
There is a sharper rolloff of pass rate for an honest prover compared to Figure 8. The DiFR paper states that the logit difference threshold will need to be empirically calculated for each model, as the optimal values differ between Qwen2.5-7B and GPT-OSS-20B.
The spike for Qwen2.5-7B at a logit difference threshold of 10 is caused by our logit difference clipping value (Δmax) having a value of 10.
Figure 11 shows a similar trend to Figure 9, with false negatives of the same model family being prevalent at lower output token counts. Again, this is mostly caused by the prover and verifier agreeing on output despite running different models.
Conclusions
Our results add further evidence that Token DiFR can identify different incorrect-model attacks reliably across a small range of prompts. Integration with existing open source AI systems for verification is practical. Large differences are shown between honest and cheating provers for different attacks, and some more obscured attacks such as append on trigger can be detected.
Our testing only covers a fraction of possible attacks. Contact us if you have an idea for an attack to test.
Future Work
We intend to proceed with the following additional work based on these results:
- Test additional attacks (please do suggest attacks you’re interested in seeing).
- Empirically validate the effect of varying the logit difference clipping value Δmax on verification accuracy.
- Further evaluate the added latency of verification and the potential throughput.
- Test implementing Token DiFR on a different token selection algorithm.
- Remove logic from the Open WebUI backend and implement request scraping in a separate proxy/network tap component owned by the verifier. This paves the way towards completeness verification, where all in-band I/O to the prover is monitored by the verifier.
Acknowledgements
This post builds on the following work:
- The inference verification API uses the Token DiFR algorithm for verification, is built on Python FastAPI and backed by a PostgreSQL database.
- We have used Open WebUI for the frontend and vLLM for the model server.
- Our prompting script is based on PromptBench.
- Our training scripts are based on PyTorch.
Appendix A: Model Settings
Figure 12 shows the effect of temperature, top_k and top_p on verification for Qwen2.5-7B. The logit difference gap is the margin between an honest and a cheating prover’s mean logit difference. Higher is better.
Preliminary conclusions (not fully evidenced):
- Decreasing trend in logit difference gap at higher
top_pvalues. This is likely influenced by the logit difference clipping behaviour of Token DiFR. - Temperature not well correlated with logit difference gap. Therefore it could potentially be freely picked by the prover, as long as it is communicated to the verifier.
- Varying
top_kseems to have a negligible effect. Potentially higher values oftop_kneed to be tested.