Docs · how to

Run parity checks

Prove your endpoint serves the model it claims to, by comparing it with a reference API on the same prompts, as a deployment gate and on a schedule.

Many providers serve the same open weights. Callers cannot see whether a provider quantized the model, used the wrong chat template, or runs an engine version with a bug. A parity suite sends the same prompts to your endpoint and to a reference, and compares the answers.

1. Store the reference key

denv secret set deepseek-api-key --value <key>

The reference is usually the model's official API. It can also be another deployment you trust, such as a reference release on your own fleet.

2. Write a suite

A suite is a JSONL file, one case per line. Each case has the request fields of a Chat Completions call plus expect.

{"id": "capital", "messages": [{"role": "user", "content": "Capital of France? One word."}], "expect": {"equals": "Paris"}}
{"id": "json", "messages": [{"role": "user", "content": "Return {\"ok\": true}"}], "response_format": {"type": "json_object"}, "expect": {"regex": "^\\{\\s*\"ok\"\\s*:\\s*true\\s*\\}$"}}
{"id": "weather-tool", "messages": [{"role": "user", "content": "Weather in Oslo?"}], "tools": [{"type": "function", "function": {"name": "get_weather", "parameters": {"type": "object", "properties": {"city": {"type": "string"}}}}}], "expect": {"tool-call": {"name": "get_weather", "arguments": {"city": "Oslo"}}}}
{"id": "logprobs", "messages": [{"role": "user", "content": "Count to five."}], "expect": {"logprobs-close": {"tolerance": 0.05}}}
expect Passes when
equals Both outputs equal this string after trimming
contains Both outputs contain it
regex Both outputs match it
tool-call Both call this tool with these arguments (extra arguments allowed)
logprobs-close Your token log-probabilities are within tolerance of the reference's for the reference's tokens

Cases run at temperature 0. Cover what your applications depend on: tool calls, structured output, reasoning on and off, long context.

3. Use deterministic sampling where you can

logprobs-close is the strictest check. It needs the reference to return log-probabilities, and works best when your engine is deterministic. DeepInfer's README lists batch-invariant inference and deterministic sampling among its features; Engines shows which engine versions support them. Without determinism, use equals, contains, regex and tool-call.

4. Configure it on the release

release:
  parity:
    reference: { url: https://api.deepseek.com, secret: deepseek-api-key, model: deepseek-v4.1-flash }
    suite: parity/flash.jsonl
    pass: { tool-calls: 99%, exact: 95% }

pass sets the share of cases that must pass per kind. A deployment runs the suite after health checks and golden prompts, before bake. Below the thresholds, the deployment stops and rolls back. Add the alarm so a scheduled failure also counts:

alarms: { parity-fail: 1 }

5. Run it now, and on a schedule

denv parity run ds-flash/prod-us
suite        parity/flash.jsonl  412 cases
equals       188/190
tool-call    120/120
regex        51/52
logprobs     50/50  (tolerance 0.05)
result       pass
denv parity schedule ds-flash/prod-us --every 6h

6. Share the report

denv parity report ds-flash/prod-us --public

This prints a URL showing the suite, the reference, the release and the results, with no prompts from customer traffic. Give it to customers who ask whether you serve the real model. See Sell tokens.

What failures usually mean

Pattern Likely cause
Tool calls missing or malformed, plain text fine Wrong adapter or chat template. Check the recipe's adapter.
Small drift everywhere, logprobs-close failing Quantized weights or a different precision than the reference
One kind of case fails after an engine upgrade Engine regression; roll back and pin the previous release
Fails on one fleet only That fleet's recipe or hardware differs; compare with denv recipe get
Reference changed, you did not The reference updated its model; check its release notes before chasing your own

See Parity for how comparison works.