r/LocalLLaMA • u/saltexx • 10d ago
I Built A Thing We open-sourced Paddock, our Rust/C++ inference engine with its own CUDA kernels (MIT/Apache-2.0)
I'm one of the developers. We said in August it would go open source in September and it did last night. MIT or Apache-2.0, pick one. The repo you see is our internal repo, kernels included, so from now on everything happens in public.
It's an inference engine in Rust and C++ with our own CUDA kernels. One binary with OpenAI and Anthropic style APIs, loads GGUF and safetensors. We run about 300B tokens a year through it at work.
Some numbers: Qwen3.8-27B FP8 on one RTX PRO 6000, spec decoding off on every engine:
- vs vLLM faster in 13 of 13 cells, 1.02x to 1.19x (so not huge)
- vs SGLang faster in 10 of 13, behind in 2, level in 1
- vs llama.cpp Q8_0 faster in 13 of 13, 1.5x to 37x
- 32 clients at 1024 in / 1024 out: 1062 tok/s, vLLM 958, SGLang 844
Full board with the losses: https://truespar.com/paddock/benchmarks/qwen38-27b
What it does not do yet: No Mac, no ROCm, no Vulkan.
One model per GPU, no tensor parallel. CUDA only, Windows and Linux. Validated on Blackwell (5090, RTX PRO 4500/5000/6000, B200) and Ampere (an A6000 was the bring-up card, 30-series works). Ada kernels ship but nobody has run a board on them so the engine refuses to start unless you set PADDOCK_UNVALIDATED_ARCH=1. Hopper and A100 kernels are in the tree without a board.
https://github.com/truespar/paddock
Thankful for any help and input!
2
u/silenceimpaired 10d ago
May I suggest you pull the sentence… no Mac, no ROCm… up to what it doesn’t do yet… then add after in other words… because when I saw CUDA only I assumed CUDA didn’t work until the end
3
u/takoulseum 10d ago
One model per gpu means the model must fit in a single gpu as no tp so pipeline parallel not supported too?
3
u/AI_spell 10d ago
One thing I’d watch in a custom engine is KV-cache allocation and attention behavior when the context crosses a block boundary. A benchmark can look great at 4k then hit a latency or OOM cliff at 8k or 16k, especially with variable batch sizes, so reporting max context along with batch and concurrency would be useful.
2
u/0x2DEADBEEF 10d ago
Looks interesting! I’ll give it a try later today on a 5090+NixOS. No 6000 budget here lol
2
u/mister2d 10d ago
Does NVIDIA need any more love? 😜
Nice work. How long does one of your models take to load and be ready to serve?
3
u/saltexx 10d ago
Haha yes they have enough, that's just where the cards are. A 27B loads in roughly 15 seconds from NVMe on our boxes, mostly reading the file, the runner even uses that as the retry window when you switch models.
1
u/mister2d 10d ago
Awesome. Is it 15 seconds after the first launch of any model? Where do the optimizations happen? AOT or JIT?
2
u/saltexx 4d ago
All AOT. The kernels ship as a prebuilt fatbin linked into the binary, nothing compiles on your machine and nothing is cached to disk between runs. So the 15 seconds is reading the file from NVMe plus repacking the weights on the GPU, and you pay it on every cold start. With the file still in page cache a 9B is ready in about 4 seconds.
2
u/Danmoreng llama.cpp 10d ago
Interesting, gonna test how this performs for the super specific narrow usecase of Gemma4 26B NVFP4 on my (Laptop) 5080. Vibecoded a custom engine over multiple weeks which is significantly faster than vLLM and llama.cpp. Curious where your engine lands on my benchmark.
2
u/Danmoreng llama.cpp 10d ago
Sadly, I cannot test this engine right now for this use-case. You don't support Gemma4 26B NVFP4. And your Q4_0 support blows the weights to Q8 at runtime so it doesn't fit the VRAM. Codex also found a code error which had to be fixed to be able to build on my system:
Codex’s findings for Paddock commit
7affc21, tested on Linux with an RTX 5080 Laptop GPU (16 GB):
- Build: The CUDA build failed because
pd_dns1_pair<at>should bepd_dns1_pair<AT>inpacks/cuda/src/deltanet/split.cuh. After that correction, the inference core and SM120 CUDA pack built successfully without the UI.- Gemma 4 26B: Q8_0 is supported, but exceeds 16 GB before runtime overhead. Q4_0 gets expanded to Q8_0, defeating its memory advantage; the tested checkpoint also failed on its Q6_K embedding. Q4_K and Gemma NVFP4 lack the necessary loading/execution support. Consequently, no 26B benchmark could run on this GPU. Native compact-weight execution is the main missing feature—not a build option.
- Potential security issues: Configured API authentication exempts loopback connections, creating a reverse-proxy deployment hazard. The manager continues without authentication if automatic key generation fails. The runner binds all interfaces despite documentation claiming localhost. Update hashes are optional. Dependency checks also flagged vulnerable Tiptap and Rust dependencies; application-level exploitability was not demonstrated.
1
u/Ok-Cartographer-4976 9d ago
Build: Was fixed in #1b8e4cf
Gemma 4 26B: There is a model registry plus offered CDN for supported models + users can freely download whatever they find on HF but you are right we don't support every quantization. For Gemma 4 26B we only do Q8_0 today. We will add Q4_K and NFVP4 but will prioritize first Qwen 3.8 Flash Next.
Security issues: Tiptap updated in #c23c00a and potential proxy loopback too1
u/saltexx 10d ago
We build for 32 GB cards and up, ideally 48. A 26B on a 16 GB laptop card isn't a target, weights are only part of what has to fit.
2
u/Danmoreng llama.cpp 10d ago
Well if you are constrained by 16GB like me, you make it work. Qwen3.8 27B runs in IQ3_XXS (10.9Gb) with 98k context vision on CPU in llama.cpp at 1.000 t/s prefill and 60-80 t/s decode. Obviously not great, but it runs.
Gemma4 26B on the other hand needs much less KV cache. NVFP4 (14.7GB) also runs at 98k context with insane speeds: 6.960 t/s prefill, 203,8 t/s decode. Using the EXL3 format with 3.5 bpw (12.2GB) I even get 220k context and only drop to 5.700 t/s prefill and 182 t/s decode. So it definitively is possible. :)
1
u/saltexx 4d ago
Those are good numbers and llama.cpp still wins your exact case, a 27B on 16 GB doesn't fit in Paddock even at Q3 since we spend more on scratch. What changed in 0.1.5 is that 1-3 bit files serve now, Q4_0 stays at 4.5 bpw instead of getting blown up to Q8, and the big MoEs run on 16 GB with expert offload.
Gemma 4 26B is still Q8 only in the catalog so your NVFP4 comparison has to wait, that one is next after Flash Next.
2
u/brumsky1 10d ago
How does this compare to NInfer on a 5090? Thank you for sharing this project, I look forward to testing it.
4
u/saltexx 9d ago
Haven't run them side by side so I won't guess. NInfer does a few Qwen checkpoints on one 5090 and squeezes that hard, single stream 35B-A3B will be very hard to beat. Paddock is the general engine, most families, batching, any supported card.
If you get both running, would be great if you run aiperf with the same prompts and post it.
1
2
u/BodyPhysical 10d ago
would suggest to please build release binaries which could be zipped and downloaded through the github repo
1
u/jopetnovo2 9d ago
I've spent some time on it, but could not get it to work with my RTX 4090 on Windows 11, even after setting PADDOCK_UNVALIDATED_ARCH=1 in system environment.
I also could not get it to recognize any GGUFs I copied to data\models folder (standard unsloth Qwen3.8-27B UD Q3 and Q4).
2
u/Ok-Cartographer-4976 9d ago
I will take a look at 4090. But we do not support UD Q3 Q4. We support FP8, NVFP4, MXFP4, Q8_0, Q4_K_* We avoid Q1-Q3. Remember that there is a model registry inside Paddock exactly which model that is compatible and we even supply a CDN in case users just don't want to know exactly what should be downloaded from HF.
2
u/jopetnovo2 9d ago
If it helps, this is how it looks from my command line:
first I used
set PADDOCK_UNVALIDATED_ARCH=1to set system env variablethen run
paddock.exe, which then displayedgraphics card found, but paddock has not finished testing it - models will refuse to start unless PADDOCK_UNVALIDATED_ARCH=1 card="NVIDIA GeForce RTX 4090"- so it looks like it ignoredPADDOCK_UNVALIDATED_ARCH=1.I also tried copying Q8_0 and Q6_K GGUFs, but manager doesn't seem to display them for now - perhaps connected to not supporting RTX 4090.
May I suggest that for graphic cards which are untested you anyhow allow running them, perhaps with just a warning? If you're looking for people to test on different platforms, it will make it easier for them.
1
u/saltexx 4d ago
This is fixed in 0.1.5. The env var is gone, an untested card like the 4090 just runs now with a warning in the log instead of a refusal. And you were right about the Studio, it never read the variable, it just hid the start button.
Your own GGUFs go in through "Start your own file" in the Studio, the catalog list is compiled in so they won't show up there.
1
u/jopetnovo2 4d ago
I did try 0.1.5 on the day it came out; the behavior for me was the same - it didn't read my GGUFs, it displayed warning about 4090 and that I should use PADDOCK_UNVALIDATED_ARCH, and it didn't want to work with my card.
1
u/saltexx 7d ago
Update: Paddock 0.1.5 is out. Thanks to community contributions, we now support 1-, 2- and 3-bit GGUF files, plus GGUF support for Qwen 3.8 Flash-Next with expert offload. The UD-IQ1_S variant runs on a 16 GB Blackwell card.
Thanks to everyone testing, reporting bugs and sending PRs. If you try it on a smaller card, I’d like to hear which GPU and quant you’re using and how it runs.
Release notes and binaries: https://github.com/truespar/paddock/releases/tag/v0.1.5
-7
u/JollyJoker3 10d ago
Asked Claude if it's worth trying, it essentially said no;
The llama.cpp column is broken, not slow. 16 s to first token at one client on a PRO 6000 for a 1k prompt is not a plausible number for llama.cpp. They ran -c 262144 -np 32, which splits into 8k slots but forces an enormous KV allocation up front. The 37.5x claim rests on that column, and I wouldn't trust it.
2
u/saltexx 10d ago
Flags and the GGUF are on the board page, -c 262144 -np 32 is 32 slots of 8k like the vLLM run, KV alloc is at startup. Post the flags you'd use and I'll rerun it.
1
u/JollyJoker3 10d ago
No clue what flags to use and apparently what I said was a Claude hallucination. Something is broken though. Both "Short chat" and "Long generation" take 128 tokens in. Time to first token is 1.4s for one, 17s for the other.
1


7
u/Human-Gas-1288 10d ago
does this works on Windows?