Open-source project
facebookresearch/audioseal avatar
facebookresearch/audioseal

AudioSeal watermarks AI speech one sample at a time, at 1/16,000 of a second

Localized watermarking for AI-generated speech audios, with SOTA on robustness and very fast detector

799 stars104 forksPythonMIT

At a glance

What is it?
AudioSeal is Facebook Research's implementation of a localised audio watermarking method, pairing a generator that embeds a watermark into speech with a detector that finds watermark fragments in long or edited files. The localisation is the interesting part, and the message it carries is a side effect rather than the point.
Who is it for?
AudioSeal suits a team that needs to prove a piece of audio came from its own generator, or that needs to scan a large library for marked speech, since the detector is designed to run far faster than existing models and the marking is local enough to survive editing.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 157 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Two networks, trained together

AudioSeal introduces audio watermarking using localised watermarking and a novel perceptual loss, and it jointly trains two components. The generator embeds an imperceptible watermark into audio, and the detector identifies watermark fragments in long or edited audio files.

Joint training is what makes the pair usable together. A watermark that is easy to embed but hard to detect is not much use, and a detector that fires on clean audio is worse than none. The perceptual loss is the piece that keeps the marked audio usable, since a watermark you can hear defeats the purpose.

The README describes the result as state-of-the-art robustness and detector speed, and the repository is the official implementation, MIT licensed, with the paper accepted at ICML 2024 and the arXiv entry linked as 2401.17264. Model checkpoints are published on the Hugging Face Hub under facebook/audioseal.

One licensing note matters more than the others. On 2024-04-02 the licence was updated to the full MIT licence, including the licence for the model weights, and the README says plainly that you can use AudioSeal in commercial applications. That change is what turned a research artefact into something a product team can adopt.

Localisation at one sixteen thousandth of a second

The key feature is described as localised watermarking at the sample level, 1/16,000 of a second. That granularity is the reason the detector can report where a watermark is rather than only whether one is present.

The consequence shows up in the low level detector output, which is a tensor of size batch x 2 x frames giving the probability of watermarking, positive and negative, for each frame. A watermarked audio should have result[:, 1, :] greater than 0.5. So the detector is not returning a single number for a three minute file, it is returning a per frame signal, and a caller can point at the second that carries the mark.

The README also says AudioSeal works well with other sampling rates, naming 24 kHz, 44.5 kHz and 48 kHz, and the sample rate of the input has to match what the model expects. The default is said to work well with 16 kHz and 24 kHz, and in the case of 48 kHz it should work well for most speech audio.

This is what makes the tool different from a watermark detector that returns one score for a whole file, and it is the reason the method can handle edited and re-encoded audio: the mark survives in fragments, and fragments can be found independently.

The generator takes audio and returns a watermark of the same length

The generator checkpoint, audioseal_wm_16bits, takes an audio signal as a waveform and outputs a watermark of the same size as the input, which can be added to the input to watermark it. Optionally it can also take a secret 16 bit message to embed in the watermark.

The usage example makes the workflow concrete. The audio is a torch tensor of shape batch, channels, samples together with a sample rate, the watermark is produced by get_watermark, and the watermarked audio is simply the sum of the two:

python
watermark = model.get_watermark(wav)

watermarked_audio = wav + watermark

The model name corresponds to the YAML card file name found in audioseal/cards, and the checkpoints are also loadable directly from a checkpoint path.

That arithmetic is worth pausing on. The watermark is a separate tensor of the same length as the signal, added to it. So the watermark is not a modification of a particular region of the audio, it is spread across the whole file, and the localisation in the detector refers to where in the timeline the signal is detectable, not to where the mark was written.

The 16 bit message does not affect detection

The optional message is the part most likely to be misunderstood, so the README is explicit about it. The message is optional and has no influence on the detection output.

It may be used to identify a model version, for instance, with up to 2 to the power of 16, so 65536, possible choices. That is the framing to hold on to. The message is a label, not a payload, and the detection result is the same whether a message was embedded or not.

The detector returns both values anyway. The high level call detect_watermark gives a float probability that the audio is watermarked plus the message as a binary vector of 16 bits, and the low level call on the detector returns the per frame probabilities and a message tensor of size batch x 16. The comment in the example is direct about the failure case: the message will be a random tensor if the detector detects no watermarking from the audio.

So a caller must not read the message as authenticated data. It is a useful tag for identifying which generator produced a file, and it is meaningless when the audio carries no mark at all.

Streaming support arrived with version 0.2

Starting with AudioSeal 0.2, watermarking can run over a stream of audio signals. The API is model.streaming(batch_size), which enables the convolutional cache during watermark generation, and the README insists it be used as a context so the cache is safely cleaned after the session:

python
with model.streaming(batch_size=1):
    
    # Watermark each incoming chunk of the streaming audio
    for chunk in audio:
        watermarked_chunk = model(chunk, sample_rate=sr, message=secret_mesage, alpha=1)
        streaming_watermarked_audio.append(watermarked_chunk)

The point of the cache is that a convolutional model processing a chunk in isolation would miss the context of the chunks before it. Holding that state across the stream is what lets the watermark be generated the same way whether the audio arrives all at once or in pieces.

There is a separate streaming detector, audioseal_detector_streaming, and you can detect either a chunk of watermarked output or the whole audio. The requirements list says Python 3.8 or later, with 3.10 or later needed for streaming support, and einops is only pulled in for Python 3.10 and above.

Detection is the part built for scale

The detector is described as fast, single pass detection designed to surpass existing models significantly in speed, achieving detection up to two orders of magnitude faster, which the README says makes it ideal for large scale and real time applications.

Two orders of magnitude is the difference between a scan that runs on a content library and one that does not, so this is the property to weigh when comparing watermarking approaches. A generator that is slightly slower is not a problem, since it runs once per published file. A detector that is slow is a problem, since it runs against everything you did not generate.

The two other robustness claims are that AudioSeal holds up against various audio edits like compression, re-encoding and noise addition, and that it has minimal impact on audio quality. Robustness against re-encoding matters most in practice, because the interesting question is not whether your own file still carries the mark but whether the mark survives the trip through a platform that re-encoded it.

The repository has an examples directory with attack_benchmarking_example.ipynb and attacks.py, which is where the edit robustness is meant to be measured rather than assumed.

What the watermarking does and does not promise

The honest limitations come from the design rather than from missing features.

First, a watermark is a statistical signal, not a signature. A detector returns a probability per frame, and a caller has to choose a threshold. That means false positives and false negatives are a policy decision, and a project that wants to act on a detection needs to pick a threshold and validate it on its own content. The example's suggestion that a watermarked audio should have result[:, 1, :] greater than 0.5 is a starting point, not a guarantee.

Second, robustness is claimed against a set of edits, and the examples directory exists to benchmark those attacks. Watermarks that survive compression and noise can still be defeated by a determined editor, and the repository does not claim otherwise.

Third, the training code was released on 2024-06-17, with instructions in docs/TRAINING.md, so the method can be retrained. That is useful if you need your own generator rather than the published checkpoint, and it is a reminder that the published weights are the ones everyone shares.

On maintenance, the repository is not archived and the last push was on 2026-05-19. The project has no GitHub releases, and the version history lives in the changelog, with 0.2 in December 2024 as the most recent feature update listed in the README. The pyproject still marks the development status as Beta.

Editorial conclusion

AudioSeal suits a team that needs to prove a piece of audio came from its own generator, or that needs to scan a large library for marked speech, since the detector is designed to run far faster than existing models and the marking is local enough to survive editing. It is the wrong tool if you need to read a payload out of the audio, because the 16 bit message is optional and does not affect detection, and it is the wrong tool if you need cryptographic guarantees rather than a statistical signal. Before adopting it, install audioseal with PyTorch available, run the generator and detector example on your own audio, and measure the detection quality on your own content before trusting a threshold.

Frequently asked questions

How do I install AudioSeal?

The README gives pip install audioseal from PyPI, or you can clone the repository and install it in editable mode with pip install -e . after cd audioseal. The requirements are Python 3.8 or later, PyTorch 1.13.0 or later, Omegaconf, Numpy, and einops for streaming support on Python 3.10 and above.

What does the AudioSeal detector return?

The high level call detect_watermark returns a float probability that the audio is watermarked plus the 16 bit message. The low level call returns a tensor of size batch x 2 x frames with the probability for each frame, and a watermarked audio is expected to have result[:, 1, :] greater than 0.5.

Can I run AudioSeal on a live audio stream?

Yes, since version 0.2. The API is model.streaming(batch_size), used as a context manager so the convolutional cache is cleaned up afterwards, and chunks are then passed through the model one at a time. Streaming needs Python 3.10 or later and a separate streaming detector checkpoint.

Official sources

  1. facebookresearch/audioseal on GitHub
  2. Issues
  3. License: MIT
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/facebookresearch-audioseal.svg)](https://hysenlabs.com/projects/facebookresearch-audioseal)

Was this useful?