Skip to main content

VapourSynth-BM3Dvk

Copyright© 2021 WolframRhodium

Copyright© 2025 Sunflower Dolls

BM3D denoising filter for VapourSynth, running on the core's Vulkan device.

Ported from VapourSynth-BM3DCUDA, by way of the Metal implementation this repository previously held.

Description

  • Please check VapourSynth-BM3D for the original CPU implementation.

  • This implementation is built on VapourSynth's Vulkan GPU API (API 4.3). Frames stay in video memory for the whole chain, so a BM3D → VAggregate sequence never crosses the PCIe bus in between, and BM3D composes with every other GPU resident filter without a transfer.

  • The core owns the Vulkan device: it is created once and shared, so there is no per-plugin device selection, no separate GPU memory budget, and no duplicate driver initialisation.

Requirements

  • VapourSynth R80 or later, with a GPU and driver that support Vulkan 1.4. Check with core.vulkan_devices from Python.

  • A device with 32- or 64-wide subgroups, which covers every current desktop GPU.

  • Works on Linux, Windows and macOS (the latter through MoltenVK).

Installation

python3 -m pip install -U vapoursynth vapoursynth-bm3dvk
vapoursynth config

The wheel installs the plugin into VapourSynth's Python package plugin directory, where it is autoloaded.

Parameters

bm3dvk.BM3D(clip clip[, clip ref=None, float[] sigma=3.0, int[] block_step=8, int[] bm_range=9, int radius=0, int[] ps_num=2, int[] ps_range=4, bint chroma=False, int extractor_exp=0])
  • clip:

    The input clip. Must be of 32 bit float format. Each plane is denoised separately if chroma is set to False. Frame properties of the output clip are copied from it.

    A CPU clip is uploaded automatically; pass core.std.GPUUpload(clip) explicitly to choose where in the graph the transfer happens.

  • ref:

    The reference clip. Must be of the same format, width, height, number of frames as clip.

    Used in block-matching and as the reference in empirical Wiener filtering, i.e. bm3d.Final / bm3d.VFinal:

    basic = core.bm3dvk.BM3D(src, radius=0)
    final = core.bm3dvk.BM3D(src, ref=basic, radius=0)
    
    vbasic = core.bm3dvk.BM3D(src, radius=radius_nonzero).bm3dvk.VAggregate(src=src, planes=[0,1,2])
    vfinal = core.bm3dvk.BM3D(src, ref=vbasic, radius=r).bm3dvk.VAggregate(src=src, planes=[0,1,2])
    
    # alternatively, using the v2 interface
    basic_or_vbasic = core.bm3dvk.BM3Dv2(src, radius=r)
    final_or_vfinal = core.bm3dvk.BM3Dv2(src, ref=basic_or_vbasic, radius=r)
    

    corresponds to the followings (ignoring color space handling and other differences in implementation), respectively

    basic = core.bm3d.Basic(clip)
    final = core.bm3d.Final(basic, ref=basic)
    
    vbasic = core.bm3d.VBasic(src, radius=r).bm3d.VAggregate(radius=r, sample=1)
    vfinal = core.bm3d.VFinal(src, ref=vbasic, radius=r).bm3d.VAggregate(radius=r)
    
  • sigma: The strength of denoising for each plane, defined as the standard deviation of the AWGN component, implying $Noise \sim \mathcal{N}(0, \sigma^2)$ on a $0\text{-}255$ scale.

    The strength is similar (but not strictly equal) as VapourSynth-BM3D due to differences in implementation. (coefficient normalization is not implemented, for example)

    A plane whose sigma is zero is not denoised. In spatial mode (radius=0) such planes are passed through from the source without a copy; in temporal mode they are zero filled, since the stacked output has no plane of the source's shape to share.

    Default [3,3,3].

  • block_step, bm_range, radius, ps_num, ps_range:

    Same as those in VapourSynth-BM3D.

    If chroma is set to True, only the first value is in effect.

    Otherwise an array of values may be specified for each plane (except radius).

    radius is limited to 15, and on a device that binds fewer than 32 storage buffers in one pass (Metal allows 31) to what VAggregate's one binding per tap leaves room for; the core says how many when it refuses.

    Note: It is generally not recommended to take a large value of ps_num as current implementations do not take duplicate block-matching candidates into account during temporary searching, which may leads to regression in denoising quality. This issue is not present in VapourSynth-BM3D.

    Note2: Lowering the value of "block_step" will be useful in reducing blocking artifacts at the cost of slower processing.

  • chroma:

    CBM3D algorithm. clip must be of YUV444PS format.

    Y channel is used in block-matching of chroma channels.

    Default False.

  • extractor_exp:

    Used for deterministic (bitwise) output.

    Pre-rounding is employed for associative floating-point summation.

    The value should be a positive integer not less than 3, and may need to be higher depending on the source video and filter parameters. Values above 127 are rejected, since 2^128 is not representable in single precision.

    Default 0. (non-determinism)

bm3dvk.VAggregate(clip clip, clip src, int[] planes)
  • clip:

    The stacked output of BM3D with radius > 0. Its height is 2 * (2 * radius + 1) times that of src, which is how the radius is recovered.

  • src:

    The clip BM3D was given. Planes not listed in planes are taken from it unchanged, and it supplies the output's format and dimensions.

  • planes:

    The planes to aggregate. Each must be one BM3D denoised: a plane whose sigma was zero holds no data in clip, and asking for it is an error, so leave it out and let src supply it. BM3Dv2 builds this list from sigma for you.

bm3dvk.BM3Dv2(clip clip[, clip ref=None, float[] sigma=3.0, int[] block_step=8, int[] bm_range=9, int radius=0, int[] ps_num=2, int[] ps_range=4, bint chroma=False, int extractor_exp=0])

Takes exactly the arguments of BM3D. Runs BM3D, and when radius > 0 follows it with VAggregate over the planes whose sigma is non-zero, so the result is ordinary video in both the spatial and the temporal case. When every plane's sigma is zero the input is returned unchanged.

Differences from the Metal implementation

  • device_id is gone: the core selects and owns the Vulkan device. Use core.set_vulkan_device() to choose one.

  • fast is gone. It sized a pool of duplicate resources for concurrent frames; the core's execution pool provides that automatically, with the memory scaling to frames actually in flight rather than a fixed multiple.

  • zero_init is gone. Unprocessed planes of the stacked temporal output are always zeroed; the flag only ever skipped that, leaving uninitialised data behind.

  • VAggregate runs on the GPU rather than on the CPU, and takes src and planes arguments. BM3Dv2 wires it up for you.

Notes

  • VAggregate should be called after temporal filtering, as in VapourSynth-BM3D. Alternatively, use the BM3Dv2() interface for both spatial and temporal denoising in one step.

  • The kernel is one GLSL compute shader specialized at pipeline creation for the temporal, chroma and Wiener variants, and for the device's subgroup width.

Statistics

GPU memory consumption, per frame in flight:

(ref ? 2 : 1) * (chroma ? 3 : 1) * (2 * radius + 1) * size_of_a_single_frame for the source stack, plus (chroma ? 3 : 1) * (2 * radius + 1) * 2 * size_of_a_single_frame for the accumulator.

Both come from the core's pooled allocator, count against the VRAM limit (core.max_vram_cache_size) and are recycled between frames. Each is one buffer, so it is also bounded by what a single storage buffer binding may cover on the device, 4 GB at most; the core refuses a radius and frame size past that at creation rather than run with an invalid binding.

Compute complexity:

(chroma ? 3 : 1) * ceil((width - 8) / block_step + 1) * ceil((height - 8) / block_step + 1) * ((2 * bm_range + 1) * (2 * bm_range + 1) + 2 * radius * ps_num * (2 * ps_range + 1) * (2 * ps_range + 1)) * (ref ? 1.5 : 1) + (radius > 0 ? width * height * (chroma ? 3 : 1) * 2 * radius : 0)

Compilation

Requires meson, ninja, a C++20 compiler, VapourSynth's Python package (R80+, for its headers) and the Vulkan headers. Only the headers are needed — the plugin does not link against the Vulkan loader, because the core hands it every entry point already resolved.

python3 -m pip install -U "VapourSynth>=80" meson ninja
meson setup build
meson compile -C build
meson install -C build

meson install puts the plugin into the Python package's vapoursynth/plugins directory, where it is autoloaded; meson compile alone leaves it (libbm3dvk.so, bm3dvk.dll or libbm3dvk.dylib) in build, to copy wherever you like. python3 -m pip install . builds the same thing as a wheel through meson-python.

The Vulkan headers are looked for as the Khronos VulkanHeaders package, through the loader's vulkan.pc or VULKAN_SDK, and on the compiler's default path; point CMAKE_PREFIX_PATH or VULKAN_SDK at an install meson does not find on its own.

python3 test/smoke.py [path/to/plugin] runs every variant of the kernel on the core's device and checks the results; without a path it tests the plugin VapourSynth autoloads. It needs numpy.

The kernel is compiled into the binary as a raw string literal, shader_comp.h, which tools/embed_shader.py generates from lib/shader.comp as part of the build.

License

This project is licensed under the GNU General Public License v3.0 or later (GPLv3+).

Based on VapourSynth-BM3DCUDA by WolframRhodium, which is licensed under GPLv2 or later.

The DCT kernels derive from FFTW generated code, Copyright© 2003, 2007-14 Matteo Frigo and the Massachusetts Institute of Technology.

Metadata

Release files for vapoursynth-bm3dvk 1.0.0

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

Source distribution (sdist)

Source distribution for vapoursynth-bm3dvk 1.0.0
File Size Uploaded Provenance
vapoursynth_bm3dvk-1.0.0.tar.gz 68.7 kB With provenance Details

Built distributions (wheels)

Table of built distributions (wheels) for vapoursynth-bm3dvk 1.0.0
File
vapoursynth_bm3dvk-1.0.0-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details
vapoursynth_bm3dvk-1.0.0-py3-none-musllinux_1_2_x86_64.whl Python 3 none Linux musl 1.2+ x86-64 Details
vapoursynth_bm3dvk-1.0.0-py3-none-musllinux_1_2_aarch64.whl Python 3 none Linux musl 1.2+ ARM64 Details
vapoursynth_bm3dvk-1.0.0-py3-none-manylinux_2_34_x86_64.whl Python 3 none Linux glibc 2.34+ x86-64 Details
vapoursynth_bm3dvk-1.0.0-py3-none-manylinux_2_34_aarch64.whl Python 3 none Linux glibc 2.34+ ARM64 Details
vapoursynth_bm3dvk-1.0.0-py3-none-macosx_15_0_x86_64.whl Python 3 none macOS 15.0+ x86-64 Details
vapoursynth_bm3dvk-1.0.0-py3-none-macosx_15_0_arm64.whl Python 3 none macOS 15.0+ ARM64 Details

Total release size: 2.6 MB

Release files / vapoursynth_bm3dvk-1.0.0.tar.gz

Download URL vapoursynth_bm3dvk-1.0.0.tar.gz
Size 68.7 kB
Tags Source
SHA-256 checksum
How to use checksums
b1f12b3f6984f994cc41cf398f36c5f50950030f2e97af8b4cd057092c1a2e41
BLAKE2b-256 checksum
How to use checksums
ee4ed71f4a9414562dd3d3e451e4acb4396736d35f5c4a8bd2cbcd639ba692df
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 Sep 18, 2026.

Transparency log

Release files / vapoursynth_bm3dvk-1.0.0-py3-none-win_amd64.whl

Download URL vapoursynth_bm3dvk-1.0.0-py3-none-win_amd64.whl
Size 71.7 kB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
c9ff449e735a7592b704c640c99918df8d2c2740017bbab972d22e0720cc8cff
BLAKE2b-256 checksum
How to use checksums
e1451411f22194d88b3310a4ecbad5d679080518cf2d91966f7878a05a3d5d1e
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 Sep 18, 2026.

Transparency log

Release files / vapoursynth_bm3dvk-1.0.0-py3-none-musllinux_1_2_x86_64.whl

Download URL vapoursynth_bm3dvk-1.0.0-py3-none-musllinux_1_2_x86_64.whl
Size 1.1 MB
Tags Linux musl 1.2+ x86-64 Python 3
SHA-256 checksum
How to use checksums
2727256d8f9a05fd0823396d81e5efcdb6d6c02739e8d3ea1421d7dd53a868d7
BLAKE2b-256 checksum
How to use checksums
1e88f3c37c382ab78212a7067930e8ea474d1529d9d518548982dda35bdf099f
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 Sep 18, 2026.

Transparency log

Release files / vapoursynth_bm3dvk-1.0.0-py3-none-musllinux_1_2_aarch64.whl

Download URL vapoursynth_bm3dvk-1.0.0-py3-none-musllinux_1_2_aarch64.whl
Size 1.1 MB
Tags Linux musl 1.2+ ARM64 Python 3
SHA-256 checksum
How to use checksums
969908c11409d9258259d0d5030536b0512c2299b38d9541b98e19e5df4409f8
BLAKE2b-256 checksum
How to use checksums
5a9cabb4af4918fc3f346992d44d60b4b01fb14de8f5f3e691e1fdb9c2d5001f
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 Sep 18, 2026.

Transparency log

Release files / vapoursynth_bm3dvk-1.0.0-py3-none-manylinux_2_34_x86_64.whl

Download URL vapoursynth_bm3dvk-1.0.0-py3-none-manylinux_2_34_x86_64.whl
Size 81.9 kB
Tags Linux glibc 2.34+ x86-64 Python 3
SHA-256 checksum
How to use checksums
653d2c995c1d4f416343e9c87fb982462ffd5aea8cb5b67ec9e36b110125cb7e
BLAKE2b-256 checksum
How to use checksums
5932ce10e1072c9808e2ab4a925928c5510f8ab0d629293f34d6f983076887c5
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 Sep 18, 2026.

Transparency log

Release files / vapoursynth_bm3dvk-1.0.0-py3-none-manylinux_2_34_aarch64.whl

Download URL vapoursynth_bm3dvk-1.0.0-py3-none-manylinux_2_34_aarch64.whl
Size 77.9 kB
Tags Linux glibc 2.34+ ARM64 Python 3
SHA-256 checksum
How to use checksums
d4374a98041367042b7a505b3f6146436515d9d8871a818e23e4e8ec282a2bf9
BLAKE2b-256 checksum
How to use checksums
2fd8b7f93bde9440c211542dd4287fdda618551cefb2717ffca2614d53724da3
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 Sep 18, 2026.

Transparency log

Release files / vapoursynth_bm3dvk-1.0.0-py3-none-macosx_15_0_x86_64.whl

Download URL vapoursynth_bm3dvk-1.0.0-py3-none-macosx_15_0_x86_64.whl
Size 70.8 kB
Tags Python 3 macOS 15.0+ x86-64
SHA-256 checksum
How to use checksums
59d6fe02c96bcbb7f5214c0e4a493694ef15d3f8cf123656f7bf9ddd9751d14e
BLAKE2b-256 checksum
How to use checksums
56573b9fcb2956cf641d277f7194872a8052448d56414df78a9fbd8e709585a6
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 Sep 18, 2026.

Transparency log

Release files / vapoursynth_bm3dvk-1.0.0-py3-none-macosx_15_0_arm64.whl

Download URL vapoursynth_bm3dvk-1.0.0-py3-none-macosx_15_0_arm64.whl
Size 68.0 kB
Tags Python 3 macOS 15.0+ ARM64
SHA-256 checksum
How to use checksums
f0cc3289b503fa26816e38236eb2567b635970a6e9129d2f5a2b460badcf7e12
BLAKE2b-256 checksum
How to use checksums
2b08a374e6ca7a2b9860055a6f5e13902fc827106fd67a47784d1220c3363e9c
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 Sep 18, 2026.

Transparency log

Security for vapoursynth-bm3dvk 1.0.0

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.

Full provenance

All 8 files in this release have been uploaded with provenance metadata.

Select from 8 files

Attestation for vapoursynth_bm3dvk-1.0.0.tar.gz

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 Sep 18, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.0.0 This release

8 release files Full provenance

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