sbw
Stateless Bernoulli Watermarking — A fast, efficient watermark detection library for LLM-generated text.
This package provides watermark detection capabilities. For watermark injection during text generation, see vllm-sbw.
Features
- GPU-accelerated detection using PyTorch and custom Philox PRNG
- Batch processing for efficient detection on multiple texts
- Multiple seeding schemes: selfhash, lefthash, minhash, and additive
- Text normalization with Unicode and homoglyph handling
Installation
pip install sbw
Quick Start
from transformers import AutoTokenizer
from sbw import WatermarkDetector
import torch
# Initialize detector
tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-3.1-8B-Instruct")
detector = WatermarkDetector(
device=torch.device("cuda"),
tokenizer=tokenizer,
vocab=list(range(len(tokenizer))),
gamma=0.25,
seeding_scheme="selfhash",
hash_key=15485863,
z_threshold=4.0,
)
# Detect watermark
text = "Your text to analyze..."
result = detector.detect(text=text)
print(f"Watermark detected: {result['prediction']}")
print(f"Z-score: {result['z_score']:.2f}")
print(f"P-value: {result['p_value']:.4f}")
print(f"Green fraction: {result['green_fraction']:.2%}")
Batch Detection
For processing multiple texts efficiently:
from sbw import WatermarkBatch
# Create batch processor
batch = WatermarkBatch(
vocab_size=len(tokenizer),
gamma=0.25,
seeding_scheme="selfhash",
hash_key=15485863,
device=torch.device("cuda"),
)
# Process multiple texts
texts = ["Text 1...", "Text 2...", "Text 3..."]
token_ids = [tokenizer.encode(t, add_special_tokens=False) for t in texts]
results = batch.detect_batch(token_ids)
for i, result in enumerate(results):
print(f"Text {i+1}: z={result['z_score']:.2f}, detected={result['prediction']}")
Parameters
Detection Parameters
| Parameter | Description | Default |
|---|---|---|
gamma |
Fraction of vocabulary in the "green" list | 0.25 |
seeding_scheme |
How to derive PRF seed from context | "selfhash" |
hash_key |
Secret key for watermark | 15485863 |
z_threshold |
Z-score threshold for detection | 4.0 |
Seeding Schemes
- selfhash: Uses hash of current token (recommended for robustness)
- lefthash: Uses hash of previous token
- minhash: Minimum hash over context window
- additive: Sum of hashes over context window
API Reference
WatermarkDetector
Main detection class with text normalization and full detection pipeline.
detector = WatermarkDetector(
device: torch.device,
tokenizer: PreTrainedTokenizer,
vocab: List[int],
gamma: float = 0.25,
seeding_scheme: str = "selfhash",
hash_key: int = 15485863,
z_threshold: float = 4.0,
normalizers: List[str] = ["unicode", "homoglyphs", "truecase"],
)
result = detector.detect(text: str) -> Dict[str, Any]
WatermarkBatch
Low-level batch processor for efficient detection without tokenization overhead.
batch = WatermarkBatch(
vocab_size: int,
gamma: float = 0.25,
seeding_scheme: str = "selfhash",
hash_key: int = 15485863,
device: torch.device = None,
)
results = batch.detect_batch(token_ids: List[List[int]]) -> List[Dict]
Related Projects
- vllm-sbw — vLLM integration for watermark injection
- waterpipe — Evaluation pipeline
- flip-dont-shuffle — Paper repository
- lm-watermarking — KGW watermarking (Kirchenbauer et al.)
Citation
@inproceedings{flip-dont-shuffle-2026,
title={Flip, Don't Shuffle: Watermarking LLMs at the Speed of Inference},
author={Ceppi, Simone and Sanchez, Ignacio},
booktitle={Proceedings of EMNLP 2026},
year={2026}
}
License
EUPL-1.2
Metadata
Release files for sbw 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| sbw-1.0.0.tar.gz | 111.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sbw-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 227.1 kB
Release files / sbw-1.0.0.tar.gz
| Download URL | sbw-1.0.0.tar.gz |
|---|---|
| Size | 111.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e4b514405389f73aceac6bfd65f602c8fffcceef9c848b845a32298bbfd25873
|
|
BLAKE2b-256 checksum How to use checksums |
5e6f02781c364e9e0b1a3f7b0c8adba55c83b7640608993f09c97fc42dced256
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 27, 2026.
Transparency logRelease files / sbw-1.0.0-py3-none-any.whl
| Download URL | sbw-1.0.0-py3-none-any.whl |
|---|---|
| Size | 116.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
02dd97c0580d70c0b47201de737ffdb81f3d2f60faa0d6bea0695fda373fdb22
|
|
BLAKE2b-256 checksum How to use checksums |
58c46cafc9c3d0ab3663406a91fe976a87962e7a3f72e869122a7d7b52091fdb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 27, 2026.
Transparency log