Skip to main content

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
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 (5.2 and 3.4 by default, these values have been manually tuned to provide the subjectively best image for a given grain strength across real clips rather than synthetic benchmarks).

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.

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.

[!TIP] Presets exist to be easy levers to adjust, but you can probably still get the quality you want using the base preset on NLMeans-HQ and NL4D by tweaking the *-scale parameters.

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.

[!IMPORTANT] You can only use accelerators the plugin was compiled with, for example the wheels for Linux and Windows only support "vulkan" and "cuda", requesting "rocm" would result in an error.

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.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

vsavd-0.4.0-py3-none-win_amd64.whl (6.4 MB view details)

Uploaded Python 3Windows x86-64

vsavd-0.4.0-py3-none-manylinux_2_28_x86_64.whl (6.8 MB view details)

Uploaded Python 3manylinux: glibc 2.28+ x86-64

vsavd-0.4.0-py3-none-macosx_11_0_arm64.whl (4.7 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

File details

Details for the file vsavd-0.4.0-py3-none-win_amd64.whl.

File metadata

  • Download URL: vsavd-0.4.0-py3-none-win_amd64.whl
  • Upload date:
  • Size: 6.4 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for vsavd-0.4.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 9a74b1acf66eadf20e271e9e6e9e9c4e65bc3d6d799b15b0c4584bad0e52f276
MD5 853eea9872a161877f938e1257c87d64
BLAKE2b-256 edefe26475758e0df6c0376e57ce7853fc0087a0c26981e9eab6ee68179a31f0

See more details on using hashes here.

Provenance

The following attestation bundles were made for vsavd-0.4.0-py3-none-win_amd64.whl:

Publisher: release-wheels.yml on ChillFish8/av-denoise

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file vsavd-0.4.0-py3-none-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for vsavd-0.4.0-py3-none-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 7c82a29ba5e999147a727c434656147dbd570d035f89135ac1d9d278ee70df98
MD5 1793f92200d00ba73db86ce861b2f0f5
BLAKE2b-256 ea7fd33e0ba12aaef5f18da6b2615830b7b40c949ba54d62e6bf04174d1ad0f7

See more details on using hashes here.

Provenance

The following attestation bundles were made for vsavd-0.4.0-py3-none-manylinux_2_28_x86_64.whl:

Publisher: release-wheels.yml on ChillFish8/av-denoise

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file vsavd-0.4.0-py3-none-macosx_11_0_arm64.whl.

File metadata

  • Download URL: vsavd-0.4.0-py3-none-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 4.7 MB
  • Tags: Python 3, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for vsavd-0.4.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 e6669eca8ff1a730c2ec204a88b77e9655ac5d3d1d09c2379803fdc262b55ae4
MD5 0263c5540836e4735f77fe490f196737
BLAKE2b-256 3097fc7d81fe029e644270aeb39a792b6ac751f2fc2923af0cb39aebd17d4015

See more details on using hashes here.

Provenance

The following attestation bundles were made for vsavd-0.4.0-py3-none-macosx_11_0_arm64.whl:

Publisher: release-wheels.yml on ChillFish8/av-denoise

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.4.0 This release

3 files

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