An open-source prover from MoonMath.ai
Sable produces a cryptographic proof that a reply came from a specific open-weight model, token by token. Anyone can check the proof on one CPU core in under a minute, without the model's GPU and without trusting the server that ran it.
The problem
When you send a prompt to a hosted model, you get text back and nothing else. The provider could have run a smaller or more heavily compressed model to save money, changed a setting, or edited the reply. Benchmarks and terms of service describe a service in general. A single reply comes with no evidence of how it was made.
Sable gives each reply a proof. The proof says: this model, with these published weights, produced this reply to this prompt. If any token was different, or the reply was cut short or continued past where the model would stop, the proof does not check out.
How it works
The weights are turned into an exact integer model and fingerprinted once. Anyone can recompute the fingerprint from the public checkpoint.
The server answers as usual, then runs the prover on one GPU. The proof covers the prompt, every generated token, sampling and the stopping point.
The client, or an auditor, checks the proof against the fingerprint on an ordinary CPU. No GPU and no copy of the server's setup is needed.
Language models normally run in floating point, and the result of a long floating-point sum depends on the order in which a GPU adds the numbers. Two runs of the same model can disagree in the last bits, and sometimes in a token. A proof needs one right answer to check against. Sable replaces every step of the model, including normalization, softmax and sampling, with integer arithmetic that has exactly one result on every machine. We call this integer model FO.
The proof itself uses the sumcheck protocol and lookup arguments over a 31-bit prime field, which suits GPU arithmetic, and hashes for its commitments, so it needs no trusted setup. Its soundness error is 2−103.
Measured on one NVIDIA RTX PRO 6000 Blackwell
| Model | 1 × 4,096 tokens | 4 × 4,096 tokens | 1 × 16,384 tokens |
|---|---|---|---|
| Qwen2.5-32B-Instructdense, 64 layers | 92.5 s | 253.1 s | 397.5 s |
| Qwen3-32Bdense with QK-norm, 64 layers | 121.8 s | 485.7 s | 668.7 s |
| Qwen3-30B-A3Bmixture of experts, 8 of 128 per token | 84.7 s | 181.9 s | 265.7 s |
Proving time is the mean of three runs. Proofs are 106 to 477 MiB. A proof takes about 41 to 50 times as long as generating the same tokens with Sable's own serving engine for the integer model.
Side by side
Sable proves full generated sequences, including sampling and stopping, at longer measured contexts. FlashProve provides zero-knowledge proofs with hidden weights and smaller proof files.
Scroll the table horizontally to compare both systems.
| Measure | Sable | FlashProve |
|---|---|---|
| Models evaluated | Qwen2.5-32B, Qwen3-32B, and Qwen3-30B-A3B; 8-bit weights | Llama 4 Maverick: 400B MoE, ~17B active parameters per token, 4-bit weights |
| What is proved | All generated tokens, greedy or seeded temperature sampling, and the stopping rule | One checked output token per request; greedy decoding |
| Measured context | 4,096 and 16,384 tokens | 1,024-token window |
| Zero-knowledge | No; intended for open-weight models and auditors | Yes; hides weights, intermediate values, and expert choices |
| GPU | One RTX PRO 6000 Blackwell, 96 GB | One H100, 80 GB |
| Proving time | Qwen2.5-32B: 92.5 s for 1 × 4K; 253.1 s for 4 × 4K; 397.5 s for 1 × 16K | 223 s for 24 × 1K requests |
| Time per parameter-token | ~0.48–0.75 ps for Qwen2.5-32B | ~0.53 ps using active parameters |
| Proof size | 106–477 MiB across the three models and measured workloads | 18.78 MB per request, plus a one-time commitment download |
| Verification | 19–56 s on one CPU core across the measured workloads | 17 s on 24 threads; 21 s on one thread |
| Reported proving overhead | 41–50× versus Sable’s integer serving engine | 66–94× versus vLLM FP8, per GPU |
These are reported results on different models, GPUs, workloads, and proof guarantees. The overhead figures use different inference baselines. Sable’s times are means of three warm runs, excluding model commitment and kernel compilation. The normalized figures are similar, but are not a controlled speed comparison.
Token counts include context processing, not just generated output. FlashProve checks one output token per request. Sable proves the prompt and 16 generated tokens in these benchmarks. Proof sizes retain the sources’ units: MiB for Sable, MB for FlashProve.
Sources: Sable release results and Anthropic’s FlashProve announcement. Comparison updated November 3, 2026. FlashProve’s ~0.53 ps is calculated as 223 seconds ÷ (24 × 1,024 tokens × 17 billion active parameters); Sable’s range uses the Qwen2.5-32B timings above and 32.5 billion parameters.
Accuracy
The integer model is close to the original but slightly different from it. We measure that difference on standard benchmarks, against the original 16-bit model.
| Model | MMLU, 16-bit / integer | GSM8K, 16-bit / integer | Same next token |
|---|---|---|---|
| Qwen2.5-32B-Instruct | 83.2% / 81.8% | 88.6% / 88.0% | 86.3% |
| Qwen3-32B | 81.8% / 80.4% | 93.9% / 92.2% | 82.4% |
| Qwen3-30B-A3B | 79.6% / 78.0% | 92.7% / 91.4% | 88.7% |
MMLU: all 14,042 questions. GSM8K: all 1,319 problems. Same next token: how often the integer model's most likely next token matches the 16-bit model's, over the WikiText-2 test set.
Who it is for today
Sable fits settings where the weights are public and someone wants to hold a provider to them: an auditor sampling a provider's traffic, a company checking a vendor, or a researcher who needs to know which model produced a dataset.
Current limits
Get started
Sable is MIT-licensed. You need Linux, an NVIDIA GPU with CUDA 13 and Python 3.12. The first command proves and checks a tiny two-layer model, so no checkpoint download is needed.
git clone https://github.com/moonmath-ai/Sable
cd Sable
pip install -e .
python -m tests.test_llm
To prove a full model, quantize a checkpoint into the integer model and run the benchmark script. The README walks through it.