Vulkan: The Low-Level GPU API for AI Inference in 2025
Vulkan is a low-level 3D graphics API, like OpenGL, but with a very different design philosophy. Here’s a software-engineer-level explanation, then why it matters for AI / offline inference.
Vulkan vs OpenGL (mental model)
OpenGL (classic model)
Think of OpenGL as:
- High-level, driver-managed
-
The driver:
- Allocates memory
- Schedules GPU work
- Hides synchronization
-
Easier to use, but:
- Implicit state
- Hard to predict performance
- Driver overhead becomes a bottleneck
OpenGL is like:
“Tell the GPU what to draw, and the driver figures out how.”
Vulkan (modern model)
Vulkan is:
- Low-level, explicit, predictable
-
You manage:
- Memory allocation
- Command buffers
- Synchronization
- Resource lifetimes
- Very thin abstraction over the GPU
Vulkan is like:
“You tell the GPU exactly what to do, when, and with what memory.”
This makes Vulkan:
- Faster at scale
- Multithread-friendly
- Deterministic
- Harder to use
Key technical differences (engineer view)
| Aspect | OpenGL | Vulkan |
|---|---|---|
| API style | Implicit state machine | Explicit command buffers |
| Threading | Mostly single-threaded | Designed for multi-threaded submission |
| Memory | Driver-managed | App-managed |
| CPU overhead | High | Very low |
| Predictability | Low | High |
| Learning curve | Easy | Steep |
Why Vulkan matters beyond graphics
Although Vulkan is marketed as a graphics API, it’s actually a general-purpose GPU execution API.
Key reasons:
- Vulkan supports compute shaders
- Compute pipelines do not require graphics
- Explicit memory + synchronization = ideal for non-rendering workloads
In practice:
Vulkan is closer to “portable GPU assembly with guardrails” than a drawing API.
Vulkan vs CUDA / OpenCL for compute
| API | Scope | Portability |
|---|---|---|
| CUDA | NVIDIA only | ❌ |
| OpenCL | Cross-vendor | ⚠️ (fragmented, weak ecosystem) |
| Vulkan Compute | Cross-vendor | ✅ (AMD, NVIDIA, Intel, mobile) |
Vulkan Compute:
- Runs on desktop GPUs
- Runs on mobile GPUs
- Runs on integrated GPUs
- Same API everywhere
This is where AI comes in.
Why this matters for AI / Offline Inference
1. AI inference = matrix math on GPU
Offline inference is dominated by:
- Matrix multiplications
- Convolutions
- Memory bandwidth
GPUs are ideal for this — even without CUDA.
Vulkan compute shaders can:
- Implement GEMM
- Implement convolutions
- Implement attention kernels
- Implement quantized inference
2. Vulkan enables CUDA-free inference
Why this matters:
- CUDA = vendor lock-in
-
CUDA not available on:
- Mobile
- Apple Silicon
- Many embedded systems
- Some cloud environments
Vulkan works on:
- AMD GPUs
- Intel GPUs
- NVIDIA GPUs
- Android phones
- Embedded devices
This makes Vulkan attractive for:
- Edge AI
- On-device inference
- Offline inference tools
3. Offline inference prioritizes predictability
Offline inference:
- Doesn’t need ultra-low latency per frame
-
Needs:
- High throughput
- Deterministic execution
- Minimal driver overhead
- Good batching control
Vulkan excels because:
- You control memory layout
- You control scheduling
- No hidden driver heuristics
- Easy to pre-record command buffers
This matters for:
- Reproducible benchmarks
- Stable inference times
- Deterministic batching
4. Vulkan is used under the hood by AI frameworks
Many AI stacks already use Vulkan indirectly:
- TensorFlow Lite (GPU delegate)
- ONNX Runtime (Vulkan EP)
- MNN
- ncnn
- llama.cpp (Vulkan backend)
- Apple Metal ↔ Vulkan via MoltenVK
You may never write Vulkan yourself — but it’s there.
5. Vulkan ≠ just graphics anymore
Modern Vulkan supports:
- Compute-only pipelines
- Subgroup operations (warp/wave ops)
- Shared memory
- Explicit barriers
- FP16 / INT8 operations
These map directly to AI kernels.
TL;DR (for a software engineer)
Vulkan is a low-level GPU API like OpenGL, but explicit instead of driver-managed.
Why it matters for AI / offline inference:
- It’s a portable GPU compute API
- No CUDA lock-in
- Runs on desktop, mobile, embedded
- Predictable performance
- Ideal for batch inference and edge AI
If OpenGL is:
“Graphics with compute on the side”
Vulkan is:
“A general GPU execution model that happens to also draw triangles.”
Below is a software-engineer–oriented overview, with emphasis on where Vulkan stands in 2025 and why it shows up in modern LLM inference.
1. When Vulkan was introduced & brief history
Origins
- 2015 – Khronos Group announces Vulkan 1.0
- Vulkan is the successor to OpenGL and OpenCL
- Based heavily on AMD Mantle, which AMD donated to Khronos
Why it was created
OpenGL/OpenCL had problems:
- High driver overhead
- Poor multithreading
- Implicit state & unpredictable performance
- Hard to scale with modern GPUs
Vulkan was designed to:
- Remove driver “magic”
- Be explicit, low-overhead, predictable
- Scale across CPU cores
- Work for graphics and compute
Evolution highlights
- 2016–2018: Vulkan adoption grows in games & engines
-
2019–2021:
- Vulkan Compute becomes viable
- Mobile adoption (Android)
- Early ML frameworks start experimenting
-
2022–2024:
- Vulkan used for on-device ML
- Subgroup ops, FP16/INT8 improve AI performance
-
2025 (today):
- Vulkan is a stable, production GPU compute API
-
Widely used for:
- Gaming
- Emulation
- Mobile ML
- Edge / offline AI inference
Where we stand now (2025):
Vulkan is no longer “new” — it is a core, mature GPU abstraction used anywhere CUDA is unavailable or undesirable.
2. Supported hardware (vendors & GPU families)
Desktop GPU vendors
NVIDIA
-
Supported GPUs:
- Kepler (GTX 600/700) → limited
- Maxwell (GTX 900)
- Pascal (GTX 10xx)
- Turing (RTX 20xx)
- Ampere (RTX 30xx)
- Ada Lovelace (RTX 40xx)
- Vulkan support is excellent
- Performance good, but CUDA still faster for AI on NVIDIA
AMD
-
Supported GPUs:
- GCN 2+ (Radeon R9 era)
- Polaris (RX 400/500)
- Vega
- RDNA 1 (RX 5000)
- RDNA 2 (RX 6000)
- RDNA 3 (RX 7000)
- Vulkan is first-class on AMD
- Often better than OpenCL
Intel
-
Supported GPUs:
- Intel HD Graphics (Gen9+)
- Intel Iris Xe
- Intel Arc (Alchemist, Battlemage)
- Vulkan is critical for Intel GPU compute
- Used heavily in inference on laptops
Mobile & embedded GPUs
- ARM Mali
- Qualcomm Adreno
- Samsung Xclipse (AMD RDNA-based)
- Imagination PowerVR
This is where Vulkan shines:
- Android mandates Vulkan support
- No CUDA, no OpenCL dependency
- Ideal for on-device AI
Integrated GPUs
- Intel iGPUs
- AMD APUs
- Apple GPUs (via MoltenVK → Metal)
3. Operating system support
Desktop
- Windows ✅
- Linux ✅ (excellent)
-
macOS ⚠️ (via MoltenVK → Metal)
- Vulkan not native
- Still widely used for portability
Mobile
- Android ✅ (first-class)
- iOS/iPadOS ⚠️ (via MoltenVK)
Embedded / Edge
- Linux-based embedded systems
- Automotive
- AR/VR headsets
4. Is Vulkan used in gaming consoles?
Yes — indirectly or natively
| Console | Vulkan usage | |
|---|---|---|
| PlayStation 4/5 | Vulkan-like low-level API (GNM/GNMX), conceptually similar | |
| Xbox One / Series X | S | DirectX 12 (same philosophy) |
| Nintendo Switch | Vulkan supported | |
| Steam Deck | Vulkan heavily used |
Consoles don’t always expose Vulkan directly, but:
Vulkan, DX12, and console APIs all share the same explicit, low-level design philosophy.
This convergence is why Vulkan compute works well for AI.
5. Vulkan in LLM & AI inference (2025)
Why inference engines use Vulkan
- Cross-vendor GPU support
- Works on laptops, desktops, phones
- No CUDA dependency
- Offline / on-device inference focus
- Predictable performance
LLM inference engines using Vulkan today
llama.cpp
- ✅ Vulkan backend
-
Works on:
- AMD GPUs
- Intel GPUs
- NVIDIA GPUs
- iGPUs
-
Popular for:
- Local/offline LLM inference
- Quantized models (Q4/Q5/Q8)
- Used by many tools indirectly
Ollama
- Ollama itself is an orchestrator
-
Backend depends on:
- llama.cpp
- Metal (macOS)
- CUDA (NVIDIA)
- Vulkan (Linux/Windows non-CUDA)
-
Vulkan used when:
- CUDA unavailable
- Cross-vendor GPUs
ONNX Runtime (Vulkan Execution Provider)
- Production-grade
-
Used in:
- Edge devices
- Embedded inference
- Mobile
- Supports transformers, CNNs, LLM blocks
TensorFlow Lite (GPU Delegate)
- Vulkan on Android
-
Used for:
- On-device inference
- Quantized models
- Extremely common in mobile AI
ncnn
- Lightweight inference engine
- Vulkan-first design
-
Popular in:
- Mobile
- Embedded
- Offline inference
MNN
- Alibaba-backed inference engine
- Vulkan backend
- Used for edge AI
Experimental / emerging
-
Custom Vulkan compute backends for:
- Attention kernels
- Quantized matmul
- LLM serving on non-NVIDIA GPUs
Big-picture takeaway (2025)
Vulkan is no longer “just a graphics API.”
In 2025 it is:
- A portable GPU compute layer
- A fallback when CUDA is unavailable
- A first choice for on-device & offline inference
- A key enabler for vendor-neutral LLM deployment
Rule of thumb
- Datacenter NVIDIA → CUDA
- Consumer / edge / mobile / offline → Vulkan
Below is a reality-check view of Vulkan in the Python / Data Science ML ecosystem (Anaconda, TensorFlow, PyTorch) — where things actually stand in 2025, why Vulkan feels “missing”, and what the realistic roadmap looks like.
1. The Python ML ecosystem’s mental model (important context)
The Data Scientist ML stack evolved around this assumption:
Python → NumPy → CUDA → NVIDIA GPUs
This shaped everything:
- PyTorch & TensorFlow APIs
- Autograd systems
- Kernel fusion
- Distribution via
pip/conda - Performance expectations
As a result:
- CUDA is the first-class GPU abstraction
- Everything else is secondary or “edge”
Vulkan does not fit naturally into this stack.
2. Current state (2025): Vulkan in Python ML
TL;DR
Vulkan is not a first-class backend for PyTorch or TensorFlow training. It is used for inference, mostly outside Python.
Let’s break it down.
3. TensorFlow
Training
- ❌ No native Vulkan backend for training
-
Training relies on:
- CUDA (NVIDIA)
- ROCm (AMD, limited)
- CPU fallback
Why?
-
Training needs:
- Autograd
- Dynamic graphs
- Kernel fusion
- Complex memory reuse
-
Vulkan is:
- Explicit
- Static
- Low-level
- No built-in tensor semantics
Rebuilding TF training on Vulkan would be:
“Reimplementing CUDA + cuDNN + XLA on top of Vulkan”
That’s a huge effort.
Inference
- ✅ TensorFlow Lite uses Vulkan
-
Especially on:
- Android
- Embedded devices
- Edge AI
This is where Vulkan fits:
- Static graphs
- Precompiled kernels
- Quantized inference (INT8, FP16)
TensorFlow Lite GPU Delegate
- Uses Vulkan on Android
- Uses Metal on Apple
- Does not target data scientists directly
4. PyTorch
Training
- ❌ No Vulkan backend for PyTorch training
-
PyTorch relies on:
- CUDA
- CPU
- Experimental backends (XPU, MPS)
Why Vulkan doesn’t fit PyTorch training:
-
PyTorch is:
- Eager
- Dynamic
- Python-driven
-
Vulkan prefers:
- Static pipelines
- Pre-recorded command buffers
- Minimal runtime branching
Mismatch is architectural, not ideological.
Inference
- ⚠️ Very limited Vulkan presence
- PyTorch does not expose Vulkan as a user-facing backend
-
Instead:
- Models are exported (TorchScript / ONNX)
- Run elsewhere
This is intentional.
5. ONNX: the Vulkan bridge
This is the most important piece.
ONNX Runtime
- ✅ Vulkan Execution Provider
-
Supports:
- Transformers
- CNNs
- LLM inference blocks
-
Used in:
- Edge devices
- Embedded systems
- Cross-vendor inference
Pipeline looks like this:
Python (PyTorch / TF)
↓ export
ONNX
↓
ONNX Runtime (Vulkan EP)
↓
GPU (any vendor)
This is the official Vulkan story in ML.
6. Why Vulkan is mostly missing from Python ML
1. Python overhead dominates
-
Vulkan’s benefits are:
- Low CPU overhead
- Explicit control
-
Python:
- High interpreter overhead
- Dynamic dispatch
-
The advantages cancel out unless you:
- Precompile everything
- Leave Python at runtime
2. Autograd is the killer
Training requires:
- Backward kernels
- Graph capture
- Kernel fusion
- Memory aliasing
CUDA has:
- cuDNN
- cuBLAS
- NCCL
- Years of ML-specific optimizations
Vulkan has:
- None of this natively
3. Ecosystem inertia
-
CUDA tooling is unmatched:
- Nsight
- Triton
- CUTLASS
-
Vulkan tooling is improving, but:
- Focused on graphics & engines
- Not ML-first
7. Where Vulkan does fit perfectly
Offline / edge inference
- Quantized models
- Static shapes
- Batch processing
- Deterministic execution
Consumer hardware
- Intel iGPUs
- AMD GPUs
- Mobile SoCs
- Devices without CUDA
Privacy / offline-first AI
- Local LLMs
- On-device assistants
- No cloud dependency
This is why:
- llama.cpp
- ncnn
- MNN
- TFLite exist — outside Python training loops.
8. Vulkan + Python today (what actually works)
Common pattern in 2025
Train in Python (CUDA / CPU)
↓
Export model (ONNX / GGUF)
↓
Inference engine (Vulkan / Metal / CUDA)
↓
Minimal Python or no Python at runtime
Examples:
- PyTorch → GGUF → llama.cpp (Vulkan)
- PyTorch → ONNX → ONNX Runtime (Vulkan)
- TF → TFLite → Vulkan delegate
Python is a build tool, not a runtime.
9. Roadmap: what’s missing & what may change
What’s missing
- No Vulkan-native autograd
- No ML kernel libraries comparable to cuDNN
- No Python-first Vulkan tensor API
- No training ecosystem
What is evolving
- Better Vulkan subgroup ops
- INT4 / INT8 inference support
- MLIR → Vulkan lowering
- More inference-first frameworks
- Unified IRs (ONNX, StableHLO)
What is unlikely to happen
❌ PyTorch training on Vulkan ❌ TensorFlow full Vulkan backend ❌ Vulkan replacing CUDA in datacenters
CUDA is too entrenched.
10. Strategic takeaway (for ML engineers)
Vulkan is:
- ❌ Not a training backend
- ❌ Not a Python-first API
- ✅ A deployment & inference backend
- ✅ A vendor-neutral GPU layer
Think of Vulkan as:
“The LLVM of GPU inference, not the NumPy of GPU training.”
Simple decision table
| Use case | Best choice |
|---|---|
| Research & training | PyTorch + CUDA |
| Production inference (NVIDIA) | TensorRT / CUDA |
| Cross-vendor inference | Vulkan |
| Mobile / edge | Vulkan / Metal |
| Offline local LLMs | llama.cpp + Vulkan |
The canonical mental model (2025)
Train in PyTorch / TensorFlow → Export to an intermediate format → Run inference on Vulkan
Vulkan is not part of the training loop. It is part of the deployment / inference layer.
This is not a workaround — it is the intended architecture.
Step-by-step: the idiomatic pipeline
1. Training (Python, CUDA-first world)
You train using:
- PyTorch (most common)
- TensorFlow
Backends:
- CUDA (NVIDIA)
- ROCm (AMD, limited)
- CPU
Reasons:
- Autograd
- Dynamic graphs
- Rich ecosystem
- Mature kernels
Vulkan is deliberately absent here.
2. Freeze the model
Once training is done:
- We no longer need autograd
- Graph becomes mostly static
- Shapes often fixed or semi-fixed
This is the key transition point.
3. Export to an inference IR
Common choices:
ONNX (most general)
PyTorch / TF → ONNX → ONNX Runtime (Vulkan EP)
Used when:
- You want transformer blocks, CNNs, etc.
- You want vendor neutrality
- You want to stay close to Python tooling
GGUF / GGML (LLMs only)
PyTorch → GGUF → llama.cpp (Vulkan)
Used when:
- LLM inference only
- Heavy quantization (Q4/Q5/Q8)
- Local/offline deployment
TFLite
TensorFlow → TFLite → Vulkan GPU delegate
Used for:
- Mobile
- Embedded
- Edge devices
4. Inference on Vulkan
At this point:
- Python may not exist at runtime
-
Execution is:
- C++ / Rust / C
- Vulkan compute shaders
- Memory, scheduling, kernels are explicit
This is where Vulkan shines.
So yes — ONNX is the main Vulkan bridge
Your summary is correct, with one clarification:
It’s not only ONNX — but ONNX is the general-purpose, Python-friendly bridge.
Others (GGUF, TFLite) are domain-specific inference formats.
Why this split is not accidental
Vulkan intentionally avoids training semantics
Vulkan provides:
- Threads
- Memory
- Barriers
- Subgroups
It does not provide:
- Tensors
- Autograd
- Broadcasting
- Kernel fusion
- Layout inference
Those belong to frameworks, not APIs.
Training stacks are vertically integrated
CUDA stack:
PyTorch
↓
ATen
↓
cuDNN / cuBLAS / CUTLASS
↓
CUDA
↓
GPU
Trying to insert Vulkan here would mean:
- Rebuilding the entire middle layer
- With worse tooling
- For no datacenter benefit
No one is incentivized to do this.
Important caveats (this is where people get bitten)
1. Not all models export cleanly to ONNX
Issues:
- Dynamic control flow
- Custom ops
- Python-side logic
- Unsupported operators
Mitigations:
- Use
torch.compile - Use
torch.onnx.dynamo_export - Simplify models before export
2. Performance is not “CUDA-equal”
Vulkan inference is:
- Often 70–90% of CUDA for GEMM-heavy workloads
- Sometimes slower for attention-heavy models
-
Highly dependent on:
- Quantization
- Kernel quality
- Driver maturity
This is expected.
3. Vulkan inference prefers static shapes
Dynamic shapes:
- Work
- But reduce optimization opportunities
Best performance:
- Fixed batch size
- Fixed sequence length
- Pre-allocated buffers
Is this approach future-proof?
Yes — this is the direction the ecosystem is converging on, not away from.
Key trends reinforcing this:
- ONNX Runtime investing in Vulkan
- Edge AI growth
- Vendor-neutral deployment pressure
- Local/offline LLM adoption
- Apple / mobile ecosystems rejecting CUDA
How to explain this in one sentence (to teammates)
“We train models in PyTorch or TensorFlow, then export them to ONNX (or GGUF for LLMs) and run inference on Vulkan when we want cross-vendor, offline, or on-device GPU execution.”
That sentence is 100% correct in 2025.
Final framing (important)
Vulkan is not:
- A PyTorch competitor
- A TensorFlow backend
- A CUDA replacement
Vulkan is:
- A deployment target
- A portable GPU runtime
- An inference accelerator
CUDA/NVIDIA is still the most complete end-to-end environment for personal experimentation.
Now to the important part of your question:
Do we lose anything when we train in CUDA and then export to ONNX / OpenVINO IR for inference?
Short answer: You don’t lose “model intelligence”, but you can lose flexibility, precision, and sometimes performance — depending on how you export and what you do afterward.
Let’s be precise.
1. What you do not lose (this is the reassuring part)
✅ Learned weights & structure
- The trained parameters are preserved
- The mathematical function the model represents is (ideally) the same
- Inference outputs should match within numerical tolerance
In theory:
ONNX / IR export is a graph serialization, not a retraining.
✅ Accuracy (if you stay FP32/FP16)
If:
- You export in FP32 or FP16
- You do not quantize
- Operators are supported
Then:
- Output differences are typically tiny (floating-point noise)
For most models:
- No meaningful accuracy loss
2. What you can lose (this is where reality shows up)
1️⃣ Dynamic behavior & Python logic
During training you may rely on:
- Python-side control flow
- Data-dependent branching
- Custom layers
- Runtime shape changes
ONNX / IR requires:
- A mostly static computation graph
So you lose:
- Python logic
- Arbitrary runtime decisions
This is the biggest conceptual loss.
2️⃣ Certain operators or kernels
Not everything in PyTorch / TensorFlow has:
- A clean ONNX equivalent
- A Vulkan / OpenVINO backend implementation
Common pain points:
- Exotic activations
- Custom CUDA extensions
- New ops not yet standardized
Outcome:
- Export fails
- Or model runs but falls back to CPU
- Or performance is worse
3️⃣ Numerical behavior changes (subtle but real)
Even without quantization:
- Different libraries use different kernels
- Different reduction orders
- Different math approximations
This can cause:
- Slight output drift
- Rare edge-case mismatches
Usually acceptable for inference.
4️⃣ Loss of training-time features (by design)
Once exported, you lose:
- Autograd
- Dropout behavior (should be disabled anyway)
- Gradient hooks
- Debug visibility
This is intentional.
3. Quantization: the intentional trade-off
This is where you do lose something, but on purpose.
FP32 → FP16 / INT8 / INT4
You gain:
- Speed
- Lower memory
- Better portability
You may lose:
- Some accuracy
- Sensitivity to edge cases
But:
- Modern quantization-aware tooling minimizes this
- LLMs tolerate quantization very well
This is not caused by ONNX/Vulkan — it’s a deployment choice.
4. CUDA vs exported inference: performance trade-offs
CUDA inference
- Best kernels
- Tensor Cores
- Vendor-specific tuning
- Highest peak performance
Vulkan / OpenVINO inference
- Slightly slower peak
- Much broader hardware support
- Predictable execution
- No vendor lock-in
Important:
Exporting does not inherently slow your model — the backend does.
5. OpenVINO IR vs ONNX (important distinction)
ONNX
- Framework-neutral
- Portable
- Used by many runtimes (Vulkan, TensorRT, etc.)
OpenVINO IR
- Intel-optimized
- Can ingest ONNX
- May apply aggressive graph optimizations
-
Targets:
- Intel CPUs
- Intel GPUs
- NPUs
Export flow often is:
PyTorch → ONNX → OpenVINO IR → Inference
OpenVINO may:
- Fuse ops
- Change layouts
- Improve performance
But again:
- Model semantics remain intact
6. When CUDA-first makes the most sense (you’re right)
For:
- Students
- Researchers
- Rapid iteration
- Debugging
- Training + inference loops
- Custom kernels
CUDA/NVIDIA is still the best choice.
Nothing else comes close in terms of:
- Tooling
- Docs
- Examples
- Community knowledge
7. The “correct” mental model (this matters)
Think of training and inference as different phases:
Training phase
- Expressiveness > portability
- Debuggability > determinism
- CUDA wins
Inference phase
- Stability > flexibility
- Throughput > dynamic behavior
- Portability matters
- Vulkan / OpenVINO / TensorRT shine
Export is the boundary between these worlds.
8. One-sentence answer to your question
No — you don’t lose the trained model’s knowledge when exporting from CUDA to ONNX/OpenVINO, but you do give up dynamic Python behavior, some operator flexibility, and possibly peak performance in exchange for portability and deployability.
That trade-off is intentional and healthy.
9. Practical advice (based on real-world pain)
- Train in PyTorch + CUDA
- Keep your model export-friendly from day one
- Avoid exotic custom ops unless necessary
- Test ONNX export early (don’t wait until the end)
- Expect minor numerical differences
- Use quantization after you trust correctness
More from Vectors and Tensors
- AVX-512 Supported Operations Overview
- Tensor Cores vs AVX
- 1.58b Tensors and BitNet
- System.Numerics.Tensors
- C# for Number Crunching?
- OpenCL: Is It Still Relevant?
- Vulkan: The Low-Level GPU API for AI Inference in 2025 (Current)
- Transform Repositories into Queryable Intelligence