# Welvet: a Go AI engine that trains and runs on your hardware, from Raspberry Pi to CUDA, Metal, Vulkan, ROCm, MLX, and Qualcomm NPU

> Source: <https://dev.to/openfluke/welvet-a-go-ai-engine-that-trains-and-runs-on-your-hardware-from-raspberry-pi-to-cuda-metal-2jom>
> Published: 2026-11-12 23:06:53+00:00

*Round 1 demos on Linux, Windows, macOS, iOS, and Android. These are working paths on real hardware, not a claim that anything is fastest or best.*

I built [Welvet](https://openfluke.com/welvet) because I wanted a Go engine that can actually train and run neural nets on my own machines, not just ship tensors off to somewhere else.

Source is at [github.com/openfluke/welvet](https://github.com/openfluke/welvet). There's a product page at [openfluke.com/welvet](https://openfluke.com/welvet) and a feature book at [openfluke.github.io/welvet](https://openfluke.github.io/welvet/).

This is a walkthrough of **v1.7**: backends, training modes, storage, and some of the messier runs (Macs, cheap VMs, ~1GB Raspberry Pi 3Bs).

Roughly four jobs:

Defaults are portable Go: **CPU tiling**, **Plan 9 SIMD**, and **WebGPU**. Extra accelerators are opt-in mounts. No silent "Prefer" path that pretends GPU/NPU work happened when it didn't.

| Area | What you get | 
|---|---|
| Language | Open-source Go AI / ML engine | 
| Core | Train + local inference | 
| Numbers | 34 storage dtypes, 20 quant formats, storage-truth (no QAT morph) | 
| Training | 29 named training modes, including cameral / multi-branch | 
| Defaults | Go CPU tiled, Plan 9 SIMD, WebGPU | 
| Optional CPU | NativeCPU via `welvet.cpp` C ABI | 
| NVIDIA | CUDA sessions (train + `SyncToGo` ) | 
| AMD | ROCm sessions (library validated; GPU compute needs HSA) | 
| Apple | Metal train/run, MLX forward-only | 
| Vulkan | Linux x86_64 train + `SyncToGo` | 
| Qualcomm | Hexagon HTP on Windows ARM64 (Snapdragon X) | 
| Other | Layer packages, spatial grids, MoE / cameral parallelism | 
| Platforms | Linux, Windows, macOS (app also targets iOS and Android) | 
| Docs | Book chapters, examples, `w2a` validation | 

Paragon and Loom were earlier engines in the same project line. Welvet is the rewrite. They're history, not competing products.

Unsupported hosts soft-SKIP. Caps reject unsupported layer×dtype instead of lying.

`BackendCPUTiled`): full layer set, 34 dtypes, 20 quants, train modes` BackendSIMD`): Dense + Softmax/SiLU fused paths on amd64/arm64` BackendWebGPU`): Dense/MHA/CNN/norms and friends on compatible GPUs
`BackendNativeCPU` + `SyncToNative` can push FormatNone forward, NormalBP, and TrainMode updates through sibling **[welvet.cpp](https://github.com/openfluke/welvet.cpp)** on linux/amd64. Sync pending weights before writing `.entity`.

| Backend | Sibling | Hosts | Forward | Train | Notes | 
|---|---|---|---|---|---|
| Apple Metal | `welvet.metal` /`nativemetal.Mount` | Apple silicon macOS | Yes | Yes | Explicit `SyncToGo` . Not Apple Neural Engine. Book §82–88 | 
| Apple MLX | `welvet.mlx` /`nativemlx` | Apple silicon macOS | Yes | No | Forward-only. Book §110–113 | 
| NVIDIA CUDA | `welvet.cuda` /`nativecuda.Mount` | Linux x86_64, Windows amd64 | Yes | Yes | Two weight copies until `SyncToGo()` . Book §89–95 | 
| AMD ROCm | `welvet.rocm` /`nativerocm.Mount` | Linux x86_64, Windows amd64 | Yes (API) | Yes (API) | Library validated; GPU compute untested until HSA. Book §96–102 | 
| Vulkan | `welvet.vulkan` /`nativevulkan.Mount` | Linux x86_64 | Yes | Yes | No silent host fallback labeled as Vulkan. Book §103–109 | 
| Qualcomm Hexagon HTP | `welvet.qnn` /`BackendQNN` | Windows ARM64 (Snapdragon X) | Yes | n/a | Explicit sync/prepare. Never Prefer default. Book §79–81 | 

Mixed Go/C++/GPU JSON routing exists on the mount backends. Automatic routing is Linux amd64 today. You own sync and placement.

*Dtypes and quants stay real in storage. Not a QAT morph that quietly becomes float32 underneath.*

Same shapes, honest timers from the book / matrices. Not "peak marketing" numbers.

**Metal, Mamba forwards** (book §88):

| dtype | Go | Metal | Metal/Go | 
|---|---|---|---|
| float64 | 89.3ms | 29.0ms | 3.1× | 
| float32 | 69.0ms | 29.0ms | 2.4× | 
| float16 | 190.5ms | 28.9ms | 6.6× | 
| bfloat16 | 149.4ms | 29.0ms | 5.1× | 
| fp8e4m3 | 265.9ms | 29.2ms | 9.1× | 

**Qualcomm NPU, large shapes** (`go_v_qnn` on Snapdragon X; DLL `graphExecute` vs Go f32 CPU):

| Layer | dtype | Go f32 | NPU DLL | vs Go | 
|---|---|---|---|---|
| Dense | u8 | 3.05ms | 164µs | ~95% faster | 
| Dense | f32 | 3.05ms | 201µs | ~93% faster | 
| CNN2 | i8 | 12.56ms | 763µs | ~94% faster | 
| MHA | f16 | 4.51ms | 372µs | ~92% faster | 

Online layers still pay compose cost on the full Go→NPU call. The book calls that out on purpose.

Training lives in the Go runtime (forward, backward, step, TrainMode). You're not exporting to another framework to learn.

Not just SGD/backprop. See [§67 TrainMode](https://openfluke.github.io/welvet/chapters/67-train-modes.html).

Modes include StepBP, Tween*, TweenSplit, HeadProxy, Linear, FastProxy, Sparse, Alt, cameral BranchModes, and more. On the big Tide boards, non-SGD modes beat matched SGD on Acc about 97–98% of the time. SGD still wins some individual boards. It's a baseline, not the religion.

Cameral stacks sibling branches that share an input, merge, and can train under different rules. CamSync averages cam weights (and same-shape cross-layer pairs). Useful when you want learn / keep / share jobs running together under load.

Lucy scores whether a net can keep serving while it learns:

**Lucy Score ≈ Throughput × Availability × Acc** (scaled)

That's what drove the Tide/Ocean runs: cameral×LR sweeps, Test53 mode farms, volatile cloud soaks, Pi 1GB layer farms.

| Path | Train? | 
|---|---|
| Go CPU / SIMD / WebGPU | Yes | 
| NativeCPU ( `welvet.cpp` ) | Yes | 
| Metal | Yes ( `TrainMSE` , then`SyncToGo` ) | 
| CUDA | Yes (train on GPU, `SyncToGo` before save) | 
| Vulkan | Yes | 
| ROCm | API yes; GPU compute pending HSA | 
| MLX | No (forward-only) | 
| QNN | Forward / prepare-exec; see book caps | 

Most transformer/CNN FLOPs are weights × activations, so Welvet keeps one Dense stack as the shared MatVec kernel (FormatNone×34 + 20 quants × CPU/SIMD/WebGPU). Layers that are mostly GEMV reuse it.

Layers include Dense, MHA (RoPE / GQA), SwiGLU, RMSNorm, LayerNorm, Embedding, Softmax, Sequential, Residual, CNN1–3, RNN/LSTM, SeqMix, GDN, Mamba, ConvT 1–3, Soft K-Means, Parallel, Metacognition.

Also: volumetric grids, ENTITY save/reload, HF helpers, tokenizer/sampling, DNA/evolution/tween, telemetry.

Catalogue: [openfluke.com/welvet/experiments](https://openfluke.com/welvet/experiments)

Four experiment waves (cameral LR, Test53 modes, volatile Linode soak, Pi 3B ~1GB farm) finished **90,334** Tide model cells.

`tween_chain` with >100k outputs/sec. CNN1 hit ~94% hard Acc on a Lucy champ. Mode-vs-SGD Acc beat-rates ~97–98%
I'm not claiming SOTA. The point is live-fit on honest storage, from Macs to $5 VMs to 1GB Pis, with artefacts you can open.

The library is the Go engine. The **Welvet app** (0.1.0+1) is a different thing: run and serve models on Linux, Windows, macOS, iOS, and Android.

Not language-only. Detection, tracking, classification, depth, segmentation, pose, audio, etc. are in the mix.

Engine code stays in `welvet/`. Proof and wrappers live elsewhere, mainly **[w2a](https://github.com/openfluke/w2a)** (Go↔native parity for cpp/cuda/metal/vulkan/rocm/mlx/qnn), plus C ABI, Python ctypes, and TypeScript/WASM.

Sibling engines: `welvet.cpp`, `welvet.cuda`, `welvet.metal`, `welvet.vulkan`, `welvet.rocm`, `welvet.mlx`, `welvet.qnn`.

Hard rules: no silent fallbacks, no hardcoded float32 tensors, storage-truth train, fail closed if a sibling binary is missing.

| Resource | Link | 
|---|---|
| Product page | [openfluke.com/welvet](https://openfluke.com/welvet) | 
| Feature book | [openfluke.github.io/welvet](https://openfluke.github.io/welvet/) | 
| Book on site | [openfluke.com/book](https://openfluke.com/book) | 
| Examples | [openfluke.com/examples](https://openfluke.com/examples) | 
| Experiments | [openfluke.com/welvet/experiments](https://openfluke.com/welvet/experiments) | 
| Source | [github.com/openfluke/welvet](https://github.com/openfluke/welvet) | 
| Architecture dashboard | [files.openfluke.com/.../dashboard](https://files.openfluke.com/1_7/welvet_1_7_technical_architecture_dashboard.html) | 
| Research PDF | [Welvet 1.7 Technical Research](https://files.openfluke.com/1_7/Welvet%201.7_Technical_Research.pdf) | 
| Feature book PDF | [v1.7.0 PDF](https://files.openfluke.com/1_7/welvet-feature-book-v1.7.0.pdf) | 
| Slides | [PDF](https://files.openfluke.com/1_7/Welvet_1.7_Architecture.pdf) /[PPTX](https://files.openfluke.com/1_7/Welvet_1.7_Architecture.pptx) | 
| Home | [openfluke.com](https://openfluke.com) | 

If you write Go and want train+infer in-process, or you care about dtype honesty and learn-while-serve on edge boxes, give it a look.

I'm [Samuel Watson](https://openfluke.com/about) / [OpenFluke](https://openfluke.com), Australia. Forks and harsh readings of the scorecard are welcome. The docs try to keep implemented features, recorded measurements, and stubs clearly separated.
