Perceptual video quality assessment — GPU-accelerated, SIMD-tuned, numerically exact
A fork of Netflix/vmaf that keeps the reference scores byte-for-byte
VMAFx is a perceptual video quality assessment (VMAF) library and vmaf
command-line tool. It adds CUDA, SYCL, HIP and Metal backends and AVX2,
AVX-512, NEON and SVE2 SIMD paths, each checked against the CPU scores, and
keeps Netflix's reference scores as a required CI gate. It also ships ONNX
tiny models, an MCP server and FFmpeg filters.
📖 Full documentation · Documentation source
VMAFx keeps upstream's numbers and adds the parts a production pipeline needs. The three Netflix reference pairs are a required CI gate, so every change below is measured against scores that never move.
Upstream libvmaf |
VMAFx | |
|---|---|---|
| GPU backends | CUDA | CUDA · SYCL · HIP · Metal, selected at runtime |
| SIMD | AVX2, AVX-512 | AVX2 · AVX-512 · NEON · SVE2, held to feature-specific parity tolerances |
| Output precision | %.6f |
%.6f by default, --precision=max for IEEE-754 round-trip |
| Model surface | .json / .pkl |
plus ONNX tiny models with a signed registry |
| Integrations | FFmpeg filter | FFmpeg, an MCP server, a Kubernetes operator, Go and Rust bindings |
| Numerical contract | — | cross-backend parity is a gate, not a promise |
Follow the installation and source-build guide for your platform. For a container workflow, see Docker.
From a clone of the repository, score the tracked 576x324 clip pair:
vmaf --reference testdata/ref_576x324_48f.yuv \
--distorted testdata/dis_576x324_48f.yuv \
--width 576 --height 324 --pixel_format 420 --bitdepth 8 \
--backend cpu --json --output scores.jsonThe terminal ends with the pooled score of the default model, and scores.json
holds all 48 frames:
vmaf_v1.0.16_3d0h: 95.938229
For your own files, compare a matching reference and distorted Y4M pair:
vmaf --reference reference.y4m --distorted distorted.y4m --json --output scores.jsonRaw YUV needs its geometry spelled out, and a GPU backend is one flag:
vmaf --reference ref.yuv --distorted dis.yuv \
--width 1920 --height 1080 --pixel_format 420 --bitdepth 8 \
--backend cuda --feature cambi --json --output scores.jsonSee the CLI reference for model selection, backend selection and output options. For compressed inputs such as MP4, use FFmpeg integration.
Every GPU-backed feature extractor has at least one device twin, and each twin is held to the CPU reference by the cross-backend parity gate. The coverage matrix below distinguishes those extractors from CPU-only metrics.
| Backend | Selected with | Notes |
|---|---|---|
| CPU | --backend cpu |
scalar reference; SIMD paths dispatch automatically |
| CUDA | --backend cuda |
NVIDIA, CUDA 13.4 |
| SYCL | --backend sycl |
Intel oneAPI; fp64-free device contract |
| HIP | --backend hip |
AMD ROCm 10.1 |
| Metal | --backend metal |
Apple Silicon, Apple Family 7 and later |
See GPU and SIMD backends for feature coverage per backend and the tolerances the gate enforces.
%%{init: {"theme": "base", "themeVariables": {"fontSize": "15px", "primaryColor": "#111a35", "primaryTextColor": "#e2e8f0", "primaryBorderColor": "#3b82f6", "lineColor": "#3b82f6", "edgeLabelBackground": "#111a35"}}}%%
flowchart TD
opts["Options<br/>--backend · --model · --feature"]:::input
feats["Features to compute<br/>named by the model or the CLI"]:::step
reg["Extractor registry<br/>feature name + backend flag"]:::step
twin{"Device twin for this<br/>feature and frame size?"}:::decide
gpu["GPU twin<br/>CUDA · SYCL · HIP · Metal"]:::gpu
cpu["CPU extractor<br/>AVX-512 · AVX2 · NEON · SVE2 · C"]:::cpu
opts --> feats --> reg --> twin
twin -- yes --> gpu
twin -- no --> cpu
classDef input fill:#0b1020,stroke:#06b6d4,stroke-width:2px,color:#e2e8f0
classDef step fill:#111a35,stroke:#3b82f6,stroke-width:2px,color:#e2e8f0
classDef decide fill:#111a35,stroke:#8b5cf6,stroke-width:2px,color:#e2e8f0
classDef gpu fill:#06b6d4,stroke:#0b1020,stroke-width:2px,color:#0b1020
classDef cpu fill:#8b5cf6,stroke:#0b1020,stroke-width:2px,color:#f8fafc
Backends you disable (--no_cuda and the like) leave the candidate list first.
With --backend NAME, a missing or failing backend is an error, never a silent
fallback to the CPU.
| Task | Documentation |
|---|---|
| Score videos and choose output formats | CLI reference |
| Use VMAFx in FFmpeg | FFmpeg guide |
| Select hardware and check feature coverage | GPU and SIMD backends |
| Choose metrics and extractor options | Feature reference |
| Choose a scoring model | Models |
| Embed libvmaf in an application | C API |
| Train and run ONNX quality models | Tiny AI |
| Connect scoring tools through MCP | MCP servers |
Build requirements, backend limitations and model defaults live in these guides so they can be maintained alongside their implementations.
Start with CONTRIBUTING.md for setup, required checks and pull-request expectations. The engineering principles cover coding and numerical-correctness standards; the repository guide explains the source layout.
- Report a bug or request a feature
- Good first issues for a first contribution
- Help wanted for issues open to anyone
- Ask a question or read how to get support
- Code of conduct
- Accessibility
- Security reporting policy
- Support development
VMAFx is free and stays open source. Sponsor it on GitHub Sponsors (USD) or Ko-fi or Patreon (EUR) to pay for CI and cloud GPU test time. Sponsors are thanked by tier in SPONSORS.md; Support VMAFx explains what it pays for.
VMAFx builds on Netflix/vmaf. See upstream releases for Netflix's release history.
Each file's SPDX-License-Identifier header says which licence applies to it
(ADR-1250). The files at the repository
root hold the texts (ADR-1699):
| Code | Licence | Text |
|---|---|---|
| Written by the fork | EUPL-1.2, a reciprocal licence | LICENSE |
| Inherited, ported or translated from Netflix/vmaf | BSD-2-Clause-Patent, with Netflix's copyright notice | NOTICE |
| Carried from libjxl, Xiph, IQA and other projects | that project's licence, with its notice in the file | LICENSES/ |
What that means in practice: the shipped libvmaf links both together.
Distributing it, modified or not, obliges you to provide its source or point to
a repository that has it (EUPL-1.2, Article 5). A modified library is
distributed under EUPL-1.2. If you need permissive terms, use
Netflix/vmaf upstream, which is unaffected.
The per-file tags are authoritative; this section is a summary, not legal
advice. Licensing lists what each published package
carries, and Embedding VMAFx in another product
goes through linking, modification and network use. Credits
names every third-party project, model, dataset, paper and tool VMAFx builds on.
This repository conforms to High-Integrity Systems Standards (HISS-21) and modernized NASA JPL Power-of-10 rules.
Praetor manages this repository's declared governance policy. This managed block records adoption state; it is not a verification certificate.
Verification: make verify-all runs the repository's configured
verification cascade.
HISS Audit: praetorctl audit enforces policy, generated-surface
integrity, and the debt ratchet.
Context Sync: praetorctl compile-context --verify verifies every
generated agent context against AGENTS.md.
Documentation: make docs-lint enforces locked Markdown style and the
private scratch-link policy.
Debt Baseline: .standards-baseline.json anchors the debt ratchet at
0 recorded infractions; audit forbids growth.