Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

av-denoise VapourSynth plugin (vsavd)

This is the home of av-denoise exposed as a VapourSynth plugin to fit within existing filtering pipelines. With caveats.

We provide typed interfaces for all the supported algorithms:

  • vsavd.Nl4d(...) for our best in class NL4D denoiser offering higher quality and more effective denoising over V-BM3D.
  • vsavd.NlmHQ(...) for our NLMeans-HQ algorithm which provides a higher quality and smarter denoising experience over base NLMeans.
  • vsavd.Nlm(...) for quick and dirt NLMeans mirroring FFmpeg's strength scaling.

All algorithms are temporal aware and have inbuilt motion compensation kernels.

Here be dragons! 🐉

VapourSynth's API significantly restricts how av-denoise can operate and as a result, can produce a worse denoising experience compared to the CLI or direct Rust library usage. Primarily because noise estimation cannot be incrementally refined over all frames and instead has to be performed only over the temporal window.

Performance is a best effort situation, if you have anything which causes frames to arrive to the filter out of order your performance can drop by 70-80%.

Table of contents

Installing

Pre-built wheels are available for Linux, macOS and Windows, published to PyPI.

Please note that the wheels for Linux and Windows are compiled for vulkan and cuda only. macOS is compiled for metal. ROCm is not recommended and requires manual compilation.

pip install vsavd

or, with uv:

uv add vsavd

Installing vsavd bundles the compiled plugin inside the wheel, so there is nothing else to build or load.

Choosing an algorithm

Please have a read of the linked page for info about what each algorithm does and its tradeoffs.

TL;DR: Use NL4D if you're unsure

Don't do this!

We recommend reading this before deciding how to integrate this into your existing filtering pipeline as some things differ quiet heavily to what you are likely used to.

Nl4d

Nl4d is the spatio-temporal denoiser, wrapping avd.NL4D. It gives the best noise removal and detail retention of the three, at the cost of time.

import vapoursynth as vs
import vsavd as avd

core = vs.core
clip = core.lsmas.LWLibavSource("noisy.mkv")
clean = avd.Nl4d(clip)
clean.set_output()
Parameter Type CLI equivalent Recommended
lambda_ht_scale float --lambda-ht-scale yes, the main dial
sigma_scale float --sigma-scale yes
preset string --preset yes
refine int --refine yes
spatial_radius int --spatial-radius yes, the speed dial
lambda_ht float --lambda-ht situational, see below
noise_map bool --no-noise-map situational, see below
channel_mode string channel-mode flags situational
device string --device situational
accelerators list of strings -A, --accelerators situational

lambda_ht_scale is the threshold multiplier a transform coefficient's estimated-noise standard deviations must clear to survive. Raising it removes more noise and takes more fine detail with it. Try it in steps of about 0.05 before reaching for lambda_ht, which pins luma and chroma's thresholds (4.158 and 3.234 by default, chosen by eye from rendered comparisons).

spatial_radius is the speed dial. preset already resolves it, so setting spatial_radius explicitly overrides whatever the preset would have picked. The centre-frame search covers (2 * radius + 1)^2 positions, so it dominates the work. Dropping it is the fastest way to speed a run up.

refine is the half-width of the window searched around each neighbour frame's motion-predicted position. Raise it when motion tracking lands close but not exact.

noise_map scales the luma threshold by how noisy each brightness level is, filtering noisy levels harder and clean ones more lightly. It is on by default, and noise_map=False turns it off.

sigma_scale keeps the per-scene noise measurement and nudges it, which is almost always what you actually want.

NlmHQ (NLMeans-HQ)

NlmHQ is the high-quality NLMeans variant, wrapping avd.NLMeans with variant="hq". It runs a per-scene noise estimator and reads its result into sigma_scale rather than leaving noise level to a hand-set strength. Use it over Nlm when you want the estimator to pick the noise level for you.

import vapoursynth as vs
import vsavd as avd

core = vs.core
clip = core.lsmas.LWLibavSource("noisy.mkv")
clean = avd.NlmHQ(clip)
clean.set_output()
Parameter Type CLI equivalent Recommended
preset string --preset yes
motion_compensation bool --motion-compensation yes
sigma_scale float --hq-sigma-scale yes, the main dial
chroma_strength float --chroma-strength yes
channel_mode string channel-mode flags situational
strength float --strength situational, see below
luma_strength float --luma-strength situational
device string --device situational
accelerators list of strings -A, --accelerators situational

Raising strength to fight leftover grain is the wrong move. Grain that survives means the noise level read low, and extra strength scrubs detail before it removes grain. Correcting sigma_scale instead is the right move.

Nlm (NLMeans)

Nlm is the fast NLMeans variant, wrapping avd.NLMeans with variant="fast". It has no noise estimator, so it runs quickly and expects you to set strength yourself. Reach for it when speed matters more than squeezing out the last bit of noise.

import vapoursynth as vs
import vsavd as avd

core = vs.core
clip = core.lsmas.LWLibavSource("noisy.mkv")
clean = avd.Nlm(clip, strength=1.2)
clean.set_output()
Parameter Type CLI equivalent Recommended
preset string --preset yes
motion_compensation bool --motion-compensation yes
chroma_strength float --chroma-strength yes
channel_mode string channel-mode flags situational
strength float --strength yes
luma_strength float --luma-strength situational
device string --device situational
accelerators list of strings -A, --accelerators situational

Nlm has no noise estimator, so strength is the dial that sets the noise level. Use NlmHQ if you would rather have it measured for you.

Presets

preset is the main quality-versus-speed dial. It takes one of five values, from fastest to slowest and best-quality: veryfast, fast, base, slow, veryslow. Each preset resolves every unset numeric and string parameter to a value tuned for that speed tier.

Any parameter you set explicitly overrides what the preset would have chosen for it, other fields still fall back to the preset's values. This lets you take a preset as a starting point and adjust just the dial you care about, as the examples above do.

Channel modes

channel_mode selects which planes get denoised, and takes one of four values:

  • luma denoises the luma plane only, leaving chroma untouched.
  • chroma denoises the chroma planes only, leaving luma untouched.
  • lumachroma denoises both, luma and chroma independently.
  • yuv denoises luma and chroma together as a single pass. It needs a 4:4:4 source, since it requires the chroma planes to be full resolution.

Devices and accelerators

device is typed on all three functions and selects which GPU device runs the filter. device="cpu" selects a software device where the platform offers one, such as lavapipe under Vulkan. It is for testing the pipeline, not for real encodes.

accelerators selects which GPU backend to use, for example ["vulkan"] or ["cuda"]. Multiple accelerators can be provided and the system will try each accelerator in the order provided, choosing the first accelerator which can work on the host hardware.

clean = avd.Nl4d(clip, preset="slow", accelerators=["cuda", "vulkan"])

Shared conventions

  • Every numeric script argument is optional, an unset one falls back to the algorithm's own default, or to whatever preset resolves for that field.
  • device and accelerators are unset by default rather than pinned to a literal string.

Tuning guide

For more information about how to adjust the algorithms to best fit your needs.

Metadata

Release files for vsavd 0.5.0a4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for vsavd 0.5.0a4
File Interpreter ABI Platform
vsavd-0.5.0a4-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details
vsavd-0.5.0a4-py3-none-manylinux_2_28_x86_64.whl Python 3 none Linux glibc 2.28+ x86-64 Details
vsavd-0.5.0a4-py3-none-macosx_11_0_arm64.whl Python 3 none macOS 11.0+ ARM64 Details

Total release size: 18.6 MB

Release files / vsavd-0.5.0a4-py3-none-win_amd64.whl

Download URL vsavd-0.5.0a4-py3-none-win_amd64.whl
Size 6.6 MB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
6eca41a737e7c114a60f987f155a43cce256d1f8f441c4276c258724c95c3429
BLAKE2b-256 checksum
How to use checksums
2c91f95a033426616c49e1e79d1420ae96717069bccce34d3319ef348b05b022
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 Oct 6, 2026.

Transparency log

Release files / vsavd-0.5.0a4-py3-none-manylinux_2_28_x86_64.whl

Download URL vsavd-0.5.0a4-py3-none-manylinux_2_28_x86_64.whl
Size 7.1 MB
Tags Linux glibc 2.28+ x86-64 Python 3
SHA-256 checksum
How to use checksums
82b3cd58e687e706a54a7e1bad96c33c3245a635998923b4165ae0eaf066b017
BLAKE2b-256 checksum
How to use checksums
497341a6323fbb6ae2325f5fa15848a606b66043396a65aea5bb2510a303ccc5
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 Oct 6, 2026.

Transparency log

Release files / vsavd-0.5.0a4-py3-none-macosx_11_0_arm64.whl

Download URL vsavd-0.5.0a4-py3-none-macosx_11_0_arm64.whl
Size 4.9 MB
Tags Python 3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
5d2155b6ac298242128f800eacb977a1696f6ecc6bf89a57314676910bfe8053
BLAKE2b-256 checksum
How to use checksums
dfe3c5403cd16876abe8113c53c26c22c2d8995e2be71ba10bbd9eb906ced3ce
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 Oct 6, 2026.

Transparency log
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page