Krafla
Portable INT8/INT4 LLM inference in C11 for machines without a GPU, from SSE2 and ARMv7 NEON up to AVX-512 VNNI and SVE.
Download a release Get a converted model Quick start
Krafla (Kernels Retargeted Across Families of Legacy Architectures, formerly isa-lm) is a dependency-free C11 inference runtime for Llama-style large language models with INT8 and INT4 weights. It runs on x86-64 CPUs from SSE2 up to AVX-512 VNNI and on ARM CPUs from ARMv7 NEON up to i8mm and SVE, including older and low-power processors. The code is written against a portable baseline; you choose the instruction set when you compile, and every operator is bound to the best kernel for it, with no runtime dispatch.
- Decoding at least as fast as llama.cpp at every ISA level measured, on the same model and formats: 1.2–1.5× with AVX-512 VNNI, 1.0–2.3× with AVX2, 2.1–10× with SSE2 and SSE4.1, 1.04–1.7× on AArch64 (comparison).
- Old and low-power CPUs: builds for any x86-64 CPU (SSE2) and for 32-bit ARMv7 NEON boards, with no GPU or external libraries required; static binaries for each ISA.
- Lower Q4 perplexity: with fitted block scales, Qwen2.5 0.5B in Q4_0 reaches perplexity 15.1, against 15.8–15.9 for llama.cpp’s Q4_0. Q8 matches an F32 reference.
- Deterministic: output is bit-identical for any thread count and prompt batch size.
- Models: Llama 2/3, Mistral, Qwen2.5, Qwen3, Qwen3.5/3.6, SmolLM2, SmolLM3, Gemma 2 and Gemma 3 from Hugging Face safetensors, with their tokenizers and chat templates.
- OpenAI-compatible server:
ml_serverserves a model to theopenaiclient libraries and other tools that take a base URL (Server).
Decode speed against llama.cpp
The chart shows one-thread results on the Xeon test machine, where both runtimes ran Qwen2.5 0.5B Instruct in the same Q4_0 and Q8_0 formats. The ranges in the list above also include the GitHub runners, hence up to 10× with SSE2. Prefill speed, four-thread results and perplexity are in the comparison.
Supported CPUs
Each build targets one instruction set; the release archives start the fastest build your CPU supports, and a build run on a CPU without its ISA exits with code 3 and names the missing feature.
| Build | Minimum CPU |
|---|---|
sse2 | any x86-64 (Athlon 64, Core 2) |
sse41 | Penryn, Nehalem |
avx2 | Haswell, Zen |
avxvnni | Alder Lake, Zen 5 |
avx512vnni | Cascade Lake, Ice Lake, Zen 4 |
neon | ARMv7 with NEON, any AArch64 (Raspberry Pi 2 to 4) |
neon_dotprod | Cortex-A55/A76 (Raspberry Pi 5), Apple M1 |
neon_i8mm | Cortex-A710, Neoverse N2/V1, Apple M2 |
sve | Neoverse V1/N2, Graviton 3 |
scalar | any CPU with a C11 compiler |
Linux release archives cover x86-64, AArch64 and ARMv7; the Windows archive covers x86-64. The Raspberry Pi boards are matched by ISA and have not been measured yet.
Quick start
With a release and a converted model, no Python is needed:
# in the unpacked release
curl -LO https://huggingface.co/jonpark0/Qwen2.5-0.5B-Instruct-krafla/resolve/main/Qwen2.5-0.5B-Instruct-Q4_0.mlb
curl -LO https://huggingface.co/jonpark0/Qwen2.5-0.5B-Instruct-krafla/resolve/main/tokenizer.mlt
./ml_run Qwen2.5-0.5B-Instruct-Q4_0.mlb -z tokenizer.mlt --chat qwen -t 4
Fifteen converted models, from SmolLM2 135M to Qwen3.5 9B, are in the Krafla collection on Hugging Face, in Q4_0 and Q8_0 and, for all but SmolLM2, a mixed file. To build from source and convert any supported Hugging Face model:
make ISA=avx2 # or sse2, neon, neon_dotprod, sve, ...
python3 tools/convert.py hf ./Llama-3.2-1B-Instruct llama.mlb --wtype q4 --q8 v,o,down
python3 tools/convert_tokenizer.py ./Llama-3.2-1B-Instruct/tokenizer.json llama.mlt
build/avx2/ml_run llama.mlb -z llama.mlt --chat llama3 -t 4
The user guide covers building, cross builds, conversion and every option; the FAQ answers the common questions.
Features
- Instruction sets: scalar, SSE2, SSE4.1, AVX2, AVX-VNNI, AVX-512 VNNI, ARMv7/AArch64 NEON, NEON dotprod, i8mm (
smmla), SVE (any vector length); a CPU guard refuses unsupported processors instead of crashing - Quantization: Q8_0, Q4_0 with f16 block scales, and mixed models that keep chosen matrices in Q8; optional F16 or Q8 KV cache
- Speed: row-interleaved weight packing for each ISA’s integer dot products, batched prompt prefill, software prefetch, blocked GQA attention, a thread pool with bit-identical results, a pack cache for fast start-up
- Models: llama2.c checkpoints and Hugging Face safetensors (Llama 2, Llama 3/3.1/3.2, TinyLlama, SmolLM2, SmolLM3, Mistral, Qwen2/2.5, Qwen3, Qwen3.5/3.6 dense, Gemma 2, Gemma 3 1B-27B text; llama3, linear and yarn RoPE scaling; per-layer sliding windows; layers without RoPE; linear attention with the gated delta rule; logit soft-capping), Hugging Face
tokenizer.json(SentencePiece-style including Gemma’s, Llama 3, Qwen and GPT-2 byte-level BPE, identical to thetokenizerslibrary) - Use: text generation, chat mode (
llama3,zephyr,llama2,qwen,smollm,chatml,gemmatemplates), top-k / top-p / repetition penalty, perplexity measurement, importance matrices for Q4, an OpenAI-compatible HTTP server (chat and text completions, streaming, KV cache kept between turns) - Verification: kernel tests against scalar and double-precision references, end-to-end logits against a numpy reference, qemu for ARM and old x86 CPUs, native CI on GitHub’s Arm runners
Citing
@software{krafla2026,
author = {Park, Yeochoon},
title = {Krafla: a portable C11 runtime for INT8/INT4 Llama-style language model inference on legacy x86-64 and ARM instruction sets},
year = {2026},
version = {0.9.0},
doi = {10.5281/zenodo.23880653},
url = {https://github.com/JonPark0/krafla}
}
Every release is archived on Zenodo. The DOI 10.5281/zenodo.23880653 stands for all versions and resolves to the latest one; each release also has its own DOI, listed on the Zenodo page.
Source code: https://github.com/JonPark0/krafla · License: MIT