Skip to main content

SnowLLM

A local LLM inference framework, hand-tuned for the Ryzen AI Max APU.

SnowLLM is fast with:

  • Kernels hand-tuned for the Ryzen AI Max series
  • Compute precision chosen for what the hardware runs fastest
  • Tuned for low-concurrency inference
  • Speculative decoding

Demo

https://github.com/user-attachments/assets/fa191709-bca4-4caa-a5ed-9a0ef290a76b

SnowLLM vs. llama.cpp on a single Ryzen AI Max+ 395, both driven through pi.dev on nginx log triage task, running Qwen3.6 35B A3B with a 2.4x speedup!

Qwen3.6-35B-A3B UD-Q4_K_XL GGUF for both, on the same hardware, one engine at a time.

Performance

Measured on one Ryzen AI Max+ 395. Every model, precision, drafter and context length, with the runs behind each number: https://snowllm.dev/#benchmarks.

Accuracy: 91.7% avg@4 on AIME 2026 (±4.2), vs. Qwen's reported 92.7 at avg@8.

Support matrix

Tested only on the Ryzen AI Max+ 395; the rest of the Ryzen AI Max 300 and 400 series (same gfx1151) should work but unverified.

Hugging Face safetensors at FP8, and GGUF K-quants and i-quants. snowllm recipes lists the lot; a recipe that names a snowllm newer than yours says so instead of serving:

Recipe Model Format Resident tok/s at batch 1
qwen3.8-flash-next-q3-k-xl Qwen3.8-Flash-Next UD-Q3_K_XL GGUF 62.1 GiB 39.1 with MTP, at 8K
deepseek-v4-flash-iq2-xxs DeepSeek-V4-Flash-0731 UD-IQ2_XXS GGUF 86.0 GiB 17.5
qwen3.8-27b-q4-k-xl Qwen3.8-27B UD-Q4_K_XL GGUF 19.9 GiB 19.2 with MTP, 22.5 with DFlash 2
qwen3.6-35b-a3b-fp8 Qwen3.6-35B-A3B FP8 34.9 GiB 62.4 with MTP, at 8K
qwen3.6-27b-fp8 Qwen3.6-27B FP8 28.8 GiB 8.0, 14.7 with --num-spec 2
qwen3.6-27b-q4-k-s Qwen3.6-27B Q4_K_S GGUF 17.9 GiB 11.8, 27.3 with --num-spec 2

qwen3.6-35b-a3b-q4-k-xl is the 35B MoE as a GGUF, 24.2 GiB resident, for a machine that cannot hold the FP8 file. Where a drafter ships beside the weights there is a -dflash or -dflash2 recipe of its own, and qwen3.6-35b-a3b-fp8-mtp is the FP8 weights decoding through the MTP head that checkpoint already carries.

Resident is weights only; the KV pool is what is left under --gpu-memory-utilization. The DeepSeek wants a 128 GiB machine with a large carve-out, and --device-map auto at long context. Flash-Next wants the same machine and no --device-map: another 26.8 GiB of it is a lookup table read off disk per batch, so keep it on the SSD you serve from. Only the Qwens take image input.

Requirements

  • Linux x86_64 or Windows 11, AMD gfx1151 (Ryzen AI Max 300 and 400 series — Strix Halo and Gorgon Halo). WSL2 works; ROCm reaches the GPU there through /dev/dxg, so set it up with AMD's WSL guide first
  • ROCm 7.x.
  • Python 3.10 – 3.14, and ROCm builds of torch and torchvision — see below.

Install

curl -fsSL https://snowllm.dev/install.sh | sh
  • Checks the machine before downloading anything: GPU, driver access, Python, disk, network
  • Installs into ~/.local/share/snowllm, links snowllm into ~/.local/bin
  • Re-run to upgrade; sh -s -- --uninstall to remove

Or do it by hand — torch and torchvision must come from AMD's index:

# https://rocm.docs.amd.com/projects/ai-ecosystem/en/latest/frameworks/pytorch/install.html
pip install --index-url https://repo.amd.com/rocm/whl-multi-arch/ \
    "torch[device-gfx1151]==2.12.0+rocm7.14.0" \
    "torchvision==0.27.0+rocm7.14.0"
pip install snowllm snowllm-kernels

Integrations

snowllm pi points Pi at a local server by writing every model to ~/.pi/agent/models.json.

snowllm pi --port 8000                        # a server on this machine
snowllm pi --host 192.168.1.10 --port 8000    # one elsewhere on the network

--host is where Pi should reach the server, localhost by default; --port is the same 8000 the server listens on.

Get a model

A recipe is one model at one precision. snowllm pull fetches it:

snowllm recipes                      # what there is
snowllm pull qwen3.6-35b-a3b-fp8     # or just `snowllm pull`, and pick from the list
  • Fetches over several connections at once, and resumes where it stopped
  • Checks every file against the sha256 the repository publishes
  • A recipe that wants a newer snowllm downloads anyway and says which version it wants

SNOWLLM_MODELS is where checkpoints live — ~/models by default. pull writes there, and snowllm <recipe> looks there; --dir overrides it per command.

Env What it does
SNOWLLM_MODELS checkpoint directory (~/models)
SNOWLLM_RECIPES_URL your own catalogue; a path works as well as a URL
HF_ENDPOINT mirror to fetch from
HF_TOKEN gated repositories; SNOWLLM_HF_TOKEN overrides it
SNOWLLM_HOME install.sh target (~/.local/share/snowllm)
SNOWLLM_BIN_DIR where install.sh links snowllm (~/.local/bin)
SNOWLLM_PYTHON interpreter install.sh builds the venv with

Or fetch it yourself. A local Hugging Face safetensors directory is all snowllm wants:

hf download Qwen/Qwen3.6-35B-A3B-FP8 --local-dir ~/models/Qwen3.6-35B-A3B-FP8

A GGUF works too — snowllm pull qwen3.6-35b-a3b-q4-k-xl-dflash gets the UD-Q4_K_XL quant with its DFlash drafter beside it: a smaller download, and llama.cpp serves the same file.

Run

snowllm qwen3.6-35b-a3b-fp8          # a recipe you pulled, or a path
snowllm ~/models/Qwen3.6-35B-A3B-FP8

Common flags (snowllm --help lists every option):

Flag What it does
--host --port Where the OpenAI-compatible API listens. 127.0.0.1:8000 by default — loopback, so reaching it from another machine takes --host 0.0.0.0.
--max-num-seqs Concurrency ceiling, up to 256. A memory choice, not a kernel limit: each request pins linear-attention state for its whole life.
--max-model-len Context length, e.g. 32k. A per-request ceiling, not a reservation: the KV pool is shared, and a request that outgrows it is preempted and re-prefilled.
--gpu-memory-utilization Fraction of the GPU the server may occupy, 0.9 by default. Weights, workspaces and any draft model are counted first; the KV pool is what is left.
--prefix-memory-ratio The share of the memory budget that goes to remembering shared prompt prefixes, 0.08 by default, 0 to disable. A repeat behind a 16K prefix costs 0.36 s instead of 5.1 s; the first one pays ~1%.
--max-num-batched-tokens Tokens per launch, i.e. the prefill chunk. auto keeps the widest of 32768 / 16384 / 8192 that still leaves the KV pool its room; wider prefills faster.
--num-spec Speculative depth off the MTP head. The optimum is workload-dependent; 2 is a robust default.
--dflash Speculate with a separate draft model instead of the MTP head: it proposes a whole block in one forward. Point it at the draft checkpoint, or at the model directory when the drafter ships beside the weights — a recipe that ships one sets this for you. Replaces --num-spec. Its weights and KV pool come out of the budget first, so the ceiling holds either way.
--device-map Move weight groups into host RAM to leave the GPU more room, e.g. experts:20. auto moves only what the pools are short of at your --max-model-len, cheapest group first. Costs a slightly slower decode step.
--kv-cache-dtype bf16 or int8. int8 halves KV bytes: more decode throughput at long context, less prefill.
--limit-mm-per-prompt Images one request may carry.

Roadmap

  • More models
  • Tensor parallelism at any degree
  • NPU/GPU co-working prefill
  • Native INT4 quantization

Questions

Ask in Discussions. Hardware reports from the rest of the Ryzen AI Max 300 and 400 series are especially useful — only the 395 has been tested here.

License

  • SnowLLM: Apache-2.0
  • SnowLLM-Kernels: All rights reserved

Metadata

Release files for snowllm 0.3.7

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distribution (wheel)

Table of built distributions (wheels) for snowllm 0.3.7
File Interpreter ABI Platform
snowllm-0.3.7-py3-none-any.whl Python 3 none any Details

Release files / snowllm-0.3.7-py3-none-any.whl

Download URL snowllm-0.3.7-py3-none-any.whl
Size 238.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
49b299a7d1daa98fc0776f968b396d3fc4b04fa0c83c87e82268e6ac0eec4d20
BLAKE2b-256 checksum
How to use checksums
2dba944daec688747e080b894d1895f0694a57b3e11f8301a6769fedcb34d6d5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 8, 2026.

Transparency log

Release history Release notifications | RSS feed

0.3.9

1 release file

0.3.8

1 release file

This release

0.3.7 This release

1 release file

0.3.6

1 release file

0.3.5

1 release file

0.3.4

1 release file

0.3.3

1 release file

0.3.2

1 release file

0.3.1

1 release file

0.3.0

1 release file

0.1.2

1 release file

0.1.1

1 release file

0.1.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page