Close-up of a computer monitor showing source code and version control history for local inference engine releases

Best Local AI Inference Tools for 2026

September 13, 2026 · 13 min read · By Thomas A. Anderson

Key Takeaways

  • For a single user on one GPU, the four main engines perform similarly. The runtime is much less important than the quantization format you use.
  • When concurrent requests reach double digits on an A100, vLLM outperforms Ollama by about ten times, and the difference grows larger.
  • GGUF is portable but restricts you to llama.cpp and Ollama. AWQ, GPTQ, and FP8 checkpoints are designed for GPUs and won’t run on a Mac.
  • Multi-GPU in llama.cpp increases VRAM capacity but does not improve speed. Layer splitting, which is the default, activates only one GPU at a time.
  • Six GGUF parser vulnerabilities disclosed to oss-security on May 15, 2026 have no CVE numbers, so automated patch scanners won’t detect them.

Hugging Face’s Text Generation Inference entered maintenance mode in December 2025 and the repository became read-only on March 21, 2026. Hugging Face’s Inference Endpoints documentation now directs users to vLLM or SGLang. That leaves four engines to consider in 2026, and the choice depends on one main factor: is it a single user at the keyboard, or multiple concurrent requests hitting a shared GPU? Other aspects like quantization support, multi-GPU behavior, and structured output follow from that decision.

What Each Engine Ships in September 2026

Version pinning is important because these projects update weekly and behavior changes between releases. The table below shows stable releases checked on September 2, 2026 by LeetLLM’s engine comparison.

Structured Output and Agent Loops
Engine Stable release (Sept 2, 2026) License Deployment surface Hardware scope
vLLM v0.28.0 Apache-2.0 Python offline API, OpenAI-compatible server, distributed serving Native NVIDIA, AMD, and CPU paths plus TPU and Gaudi plugins
SGLang v0.5.18 Apache-2.0 SGLang language frontend, Python engine, OpenAI-compatible server NVIDIA, AMD, Intel Xeon, Google TPU, Ascend NPU
Ollama v0.33.2 MIT Local daemon, CLI, REST API, OpenAI-compatible endpoints macOS, Windows, Linux, NVIDIA/AMD GPUs, Apple paths
llama.cpp v0.3.0 MIT C/C++ library, CLI, local OpenAI-compatible server CPU plus Metal, CUDA, HIP, Vulkan, SYCL backends

These are code licenses, not model licenses. Running vLLM does not grant rights to the checkpoint, tokenizer, or dataset you load. Record the deployed tag and container digest instead of just the project name. Release numbers also don’t guarantee compatibility: “supports architecture” can still mean your specific combination of checkpoint, quantization, attention backend, tool parser, and parallel layout is untested.

Throughput vs Latency: The Concurrency Fork

For one developer running one model, the four engines perform more similarly than some comparison posts suggest. A single-stream comparison compiled from community benchmarks by InsiderLLM shows Ollama, llama.cpp direct, and vLLM all delivering single-stream output within a narrow range, with vLLM’s figure measured in FP16 while the other two run Q4_K_M. Matching the format removes most of the difference. Ollama’s wrapper overhead over bare llama.cpp is generally 5-15%, with some setups reporting up to about 30%.

The situation reverses with concurrency. The same benchmark series, run on an NVIDIA A100 80GB with Llama 3 8B, shows vLLM scaling aggregate throughput far beyond Ollama as concurrent requests increase. At fifty in-flight prompts the difference is already several times, and the ratio exceeds 15 times beyond a hundred requests. Exact token-per-second figures depend on the model, GPU, and quantization used, but this pattern appears consistently in independent reports.

Concurrent requests Ollama behavior vLLM behavior Practical gap
1 Full single-stream speed Full single-stream speed Negligible
8 Modest aggregate gain Batching lifts aggregate throughput Roughly 2x
50 Slower aggregate growth Continuous batching scales Several times over
100+ Plateaus, requests serialize Continues to scale with batch size 15x and widening

Source: InsiderLLM, tested on NVIDIA A100 80GB with Llama 3 8B. Exact numbers vary by model, GPU, and quantization, so treat the table as illustrating the trend rather than a fixed benchmark.

The reason lies in architecture. vLLM stores KV cache in fixed-size, non-contiguous blocks similar to how an operating system manages virtual memory pages, allowing the same VRAM to hold many more concurrent sequences. Continuous batching creates a new batch every iteration instead of waiting for all in-flight requests to finish, so a short prompt doesn’t wait behind a long one. Ollama and llama.cpp allocate KV cache contiguously per request, and fragmentation limits concurrent capacity.

This has a VRAM impact that affects 24GB RTX 3090 owners immediately. vLLM pre-allocates about 90% of GPU VRAM at startup for its KV cache pool using the gpu_memory_utilization flag, which defaults to 0.90. Loading a 7B model in AWQ-Int4 uses about 5GB for weights, and vLLM reserves another 17-18GB for the cache pool, using roughly 22-23GB out of 24. A second GPU process runs out of memory immediately. The same model in Ollama on the same card leaves more than 18GB free. If you need to share the card, reduce the flag to 0.5 and accept less batching capacity.

Quantization Support Decides Your Format Lock-In

Quantization format is part of the engine choice because a GGUF file won’t load natively in vLLM and an AWQ checkpoint won’t run on a Mac. The format matrix below is from GenAlphai’s 2026 serving benchmark.

Format vLLM SGLang Ollama llama.cpp
FP8 Native Native Limited Supported
INT8 Native Via vLLM Yes Supported
INT4 Yes Via vLLM Q4_0 Supported
AWQ / GPTQ Yes Yes Yes Yes
GGUF Yes No Native Native
MXFP8 / MXFP4 Yes No No No

vLLM’s runtime quantization lets you iterate on a fine-tune without a separate compilation step. GGUF is the opposite trade-off: portable across CPU, NVIDIA, AMD, and Apple Silicon but somewhat slower on GPU inference than GPTQ or AWQ.

The quality cost is smaller than many expect at 4-bit and much larger below that. Aggregated benchmarks from Presenc AI’s 2026 quantization report show Q4_K_M increases perplexity by about 1.5-1.9% compared to FP16 on recent Llama and Qwen checkpoints, while Q3_K_M loses about 3.8-5.0% and Q2_K loses 11-14%. Reasoning benchmarks degrade faster than perplexity: GSM8K math accuracy drops about 1.5% at Q4_K_M but roughly 5% at Q3_K_M and 14% at Q2_K. For agent loops and tool use, avoid going below Q4.

Multi-GPU: Capacity, Not Speed

Multi-GPU in llama.cpp exists to handle models that don’t fit on one card, and throughput scaling is sublinear due to how the default split works. Layer splitting assigns contiguous blocks of layers to each GPU, data flows sequentially through the cards, and only one GPU computes at a time during generation. This pools VRAM but does not increase speed.

Row-wise splitting, enabled with --split-mode row, divides individual tensors across cards so both GPUs stay active. It can deliver 1.3-1.5 times the speed of a single GPU with two identical cards, but it requires continuous inter-GPU communication, and on a standard PCIe bus the traffic usually makes it slower than layer mode. Consumer Ada and Blackwell cards lack NVLink connectors, so there is no fast link to rely on.

# Mixed consumer rig: RTX 5090 (32GB), RTX 5070 Ti (16GB), RTX 3070 (8GB)
# --tensor-split takes ratio weights, not gigabytes. 32,16,6 is a ratio.
# Point --main-gpu at the largest card: it holds KV cache, which grows
# with context and can OOM the small card even after a clean model load.
./llama-cli \
 --model models/llama-3.1-70b-instruct-Q4_K_M.gguf \
 --n-gpu-layers 999 \
 --tensor-split 32,16,6 \
 --main-gpu 0 \
 --split-mode layer \
 --ctx-size 8192

# Note: prod use should verify actual per-device VRAM assignment
# in the load log and re-run at your real context length. A split that loads
# cleanly at 8K can OOM at 32K because KV cache lives on --main-gpu.

Ollama manages multi-GPU automatically with detection and distribution but offers less control over the split. LM Studio does not support multi-GPU as of mid-2026. ExLlamaV2 under TabbyAPI scales better than llama.cpp in some setups but is NVIDIA-only and supports fewer model architectures. For hardware details, see our breakdown of memory requirements for large models.

For serving engines, the situation differs. vLLM and SGLang handle tensor parallelism natively, which is simpler than manually splitting GGUF across cards. However, tensor parallelism can make a model fit while communication overhead reduces the speed gain, so any comparison should use your actual GPU count and interconnect setup.

Structured Output and Agent Loops

SGLang’s key feature is RadixAttention, which stores KV cache in a radix tree and reuses it across requests sharing a prefix. A system prompt repeated across thousands of requests is computed once. Reported cache hit rates range from 85-95% for few-shot learning, 75-90% for multi-turn chat, and 50-70% for mixed production traffic, according to Particula’s engine comparison.

This advantage depends on workload in a way vLLM’s does not. Runpod’s tests on single-turn unique prompts with DeepSeek-R1-Distill-Llama-70B found vLLM faster on throughput, but when cache hits occur, SGLang pulls ahead. If every prompt is different, RadixAttention has no reuse.

For schema-bound output, SGLang uses a compressed finite state machine that analyzes the regular expression behind a JSON schema, compresses singular transition paths, and pre-fills multiple tokens per step instead of decoding one at a time. The original LMSYS writeup reported up to 2 times lower latency and 2.5 times higher throughput compared to guided decoding with llama.cpp and Outlines with vLLM. JSON schema compliance without guided decoding usually sits at 90-94%; with constrained decoding it reaches 96-98%. The limitation is traffic consistency: random values near the start of prompts, differing templates, early branch divergence, or routing across replicas without cache locality all reduce hit rates. SGLang’s fast release cycle means pinning versions and regression-testing tool parsers instead of tracking mainline.

The Decision Matrix

Consider these conditions in order. The first one that applies is your answer.

  • No GPU, or CPU-only inference? Use llama.cpp direct. It is the only engine that treats CPU inference as a primary workload, with AVX2/AVX-512 and NEON paths. Expect usable throughput on a modern x86 desktop for a 7B Q4 model.
  • Apple Silicon laptop? Use Ollama. Since version 0.30 it auto-routes by format, using MLX for safetensors and llama.cpp Metal for GGUF.
  • One developer on an NVIDIA or AMD workstation? Use Ollama for quick setup, or llama.cpp if you need a flag Ollama hasn’t exposed. llama.cpp merged multi-token prediction speculative decoding into mainline via PR #22673 on May 16, 2026, and Ollama follows upstream features with some delay.
  • Shared endpoint with five or more concurrent users? Use vLLM. The concurrency gap is too large to work around.
  • Agent loops, RAG, or schema-constrained JSON? Use SGLang. RadixAttention and compressed FSM provide structural benefits when prefixes repeat.
  • Model exceeds one card’s VRAM? Use llama.cpp with --tensor-split for a single user, or vLLM with tensor parallelism for a served endpoint.

The GGUF Parser Problem

On May 15, 2026, a security researcher disclosed six vulnerabilities in llama.cpp’s GGUF model-file parser to the oss-security mailing list, and none have assigned CVE numbers, as TechTimes reported. Automated patch scanners won’t detect them.

The most serious, labeled V-01, allows a crafted GGUF file to trigger an integer overflow inside the GGML_PAD macro on 32-bit systems, causing an arbitrary file seek followed by an out-of-bounds read before inference starts. V-02 causes memory exhaustion through preprocessor constants each set to one gigabyte. V-03 affects Python tooling, where setting n_dims = 0xFFFFFFFF triggers an approximately 32GB memory-map attempt. V-04 through V-06 involve signed-to-unsigned conversions, enum bounds, and a division-by-zero error.

Since llama.cpp is the inference backend for Ollama, LM Studio, and many other tools, these parser flaws affect all downstream projects. The attack requires no network exploit: downloading a GGUF from a public repository and loading it into your stack triggers the payload before the first token. This is separate from Bleeding Llama (CVE-2026-7482, scored 9.1), which exploited Ollama’s Go-language GGUF loader to leak process memory through unauthenticated API calls and was fixed in Ollama 0.17.1. Operators who patched that issue have not addressed V-01 through V-06, because those vulnerabilities exist in the C++ parser on a different code path.

The mitigation is straightforward: treat GGUF files like software supply-chain inputs, download only from trusted sources, and verify file integrity before loading. A malicious upload can reach your machine before a CVE alert is issued, before scanners detect it, and before a patch is available.

Smoke Testing Before You Commit

After choosing an engine, verify the model loads, the API responds, and the output shape is correct. This test confirms loading but not performance under load.

# Ollama: single-user path, two commands to a working model
ollama pull qwen3-coder:32b
ollama run qwen3-coder:32b "Extract impact, timeline, and follow-up tasks: API latency rose after 09:10 deploy. Rollback started at 09:26. Error rate returned to baseline at 09:34."

# vLLM: shared-GPU serving with OpenAI-compatible endpoint
python -m vllm.entrypoints.openai.api_server \
 --model /data/models/Llama-3.3-70B-Instruct-AWQ \
 --gpu-memory-utilization 0.90 \
 --max-model-len 32768

# llama.cpp: single-binary server with OpenAI-compatible endpoint
llama-server --model ./models/llama-3.1-8b-instruct.Q4_K_M.gguf --port 8080

# Note: prod use should pin model revision and runtime version,
# add auth and request limits, and load-test at your real
# concurrency and context length. These commands verify loading only.

Before committing production budget, test at least three traffic patterns: unique prompts, repeated prefixes, and your actual production mix. Record p50 and p95 time-to-first-token, output tokens per second, queue time, failed requests, and schema validation failures. Aggregate throughput without latency limits can hide poor user experience, and benchmarks from datacenter accelerators won’t predict behavior on a multi-GPU workstation.

FAQ

Is llama.cpp or Ollama faster for a single user? llama.cpp direct is slightly faster, usually by 5-15%, because Ollama adds wrapper overhead. The difference is small enough that setup convenience often determines the choice.

Can I use Ollama for a production API? Not for more than a few simultaneous users. Ollama processes requests serially, and once concurrency exceeds a hundred in-flight requests it plateaus while vLLM continues to scale with batch size.

Does vLLM run GGUF models? vLLM lists GGUF among its supported formats, but GGUF is most closely tied to llama.cpp and Ollama. Verify the exact checkpoint and feature combination before relying on format support for production.

Does llama.cpp support tensor parallelism? It supports row-wise splitting via --split-mode row, which keeps multiple GPUs active simultaneously for a modest 1.3-1.5 times speedup with two identical cards. The default layer split pools VRAM without speeding up. Consumer Ada and Blackwell cards lack NVLink, so row mode on PCIe often runs slower than layer mode.

What quantization should I start with? Q4_K_M. Presenc AI’s aggregated benchmarks show it causes about 1.5-1.9% perplexity degradation versus FP16 with roughly 4 times memory savings, and it runs in every tool. Move to Q5_K_M or Q6_K only if you have memory headroom and your workload involves long context or multi-step reasoning.

Is TGI still an option? No. It entered maintenance mode in December 2025 and the repository was archived read-only on March 21, 2026. Hugging Face’s Inference Endpoints documentation now points to vLLM or SGLang.

For details on format trade-offs, see our guide to GGUF, AWQ, GPTQ, and FP8 quantization. If you are still deciding what to run rather than where to run it, start with our engine comparison and the practical GGUF Q-level walkthrough.

More in-depth coverage from this blog on closely related topics:

Sources and References

Sources cited while researching and writing this article:

Thomas A. Anderson

Mass-produced in late 2022, upgraded frequently. Has opinions about Kubernetes that he formed in roughly 0.3 seconds. Occasionally flops, but don't we all? The One with AI can dodge the bullets easily; it's like one ring to rule them all... sort of...