pie

Library Listed

Pie: A Programmable LLM Serving System

Checked · Sources

Downloads
13
Dependents
0
Stars
240
Forks
39
Contributors
22
Commits
1,642
Latest release
0.2.0 ·

About

From the project README ·

Pie: Programmable inference engine

Website | Docs | Playground | Benchmarks | Paper (SOSP'25)

Pie runs WebAssembly programs—inferlets—directly next to the model. An inferlet drives the forward pass, owns its state, and compiles custom epilogues to GPU kernels, so decoding, sampling, caching, and agent loops are written per application in Python, JavaScript, or Rust.

Models are programs too, written in Poem across language, vision, image, and video. Everything ships as one ~60 MB binary with no Python or PyTorch runtime, running on CUDA, ROCm, Metal, Vulkan, XLA (TPUs), and WebGPU.

Install

curl -fsSL https://pie-project.org/install.sh | bash        # Linux, macOS, WSL
irm https://pie-project.org/install.ps1 | iex               # Windows PowerShell

Import a model from Hugging Face:

pie config init
pie model import Qwen/Qwen3.5-0.8B

See the install guide for manual archives and GPU flavors, or run Pie in your browser on the Playground.

Write an inferlet

Greedy text completion in Python (examples/quickstart-py), one forward pass per token (also in JavaScript and Rust):

Read the full README
from inferlet import chat, model
from inferlet.eta import ForwardPass, Pipeline, StateGeometry, WorkingSet, intrinsics, reduce_argmax


async def main(input: dict) -> dict:
    tokens = chat.prefix() + model.encode(input.get("prompt", "The capital of France is"))
    max_tokens = int(input.get("max_tokens", 8))
    ws = WorkingSet()  # the sequence's state, whatever the model keeps
    pipe = Pipeline()

    done = 0  # tokens already in the working set
    for _ in range(max_tokens):
        fwd = ForwardPass()
        fwd.embed(tokens[done:])                        # the new tokens
        fwd.state([ws], StateGeometry.folding())        # appended, and final
        out = fwd.epilogue(lambda: reduce_argmax(intrinsics.output(0, "logits")))  # runs on the device
        pipe.submit(fwd)
        done = len(tokens)
        tokens.append(await out)
    pipe.close()

    return {"text": model.decode(tokens[-max_tokens:])}

epilogue is traced once and compiled into a GPU kernel; the host only sees the token it publishes. More in examples/: device loop-carried decode, speculative decoding, beam search, KV eviction and prefix sharing, constrained decoding, custom samplers, watermarking, and media generation.

Run & serve

Run an inferlet one-shot, or submit it to a running pie serve with pie-client:

pie run main.py -- --prompt "The capital of France is"
pie-client submit --path main.py -- --prompt "The capital of France is"

pie serve also speaks the OpenAI, Anthropic, and Gemini APIs on the same port as built-in inferlets:

from openai import OpenAI
client = OpenAI(base_url="http://127.0.0.1:8080/v1", api_key="unused")
print(client.chat.completions.create(model="default", messages=[{"role": "user", "content": "Hi"}]).choices[0].message.content)

A program is short and its state need not be. A client can own the state, and run a new program on it each turn: nothing stays loaded between turns, a fork costs no device memory, and a turn resumes exactly where the last one stopped.

ws = await client.working_set()                    # a name; nothing exists yet
await (await client.run("chat", ws=ws, prompt="Hi")).result()
checkpoint = await ws.fork()                       # to come back to
await (await client.run("chat", ws=ws, prompt="Go on")).result()
await (await client.run("chat", ws=checkpoint, prompt="Instead...")).result()

The inferlet finds the handle in its input and gives it back:

async def main(input: dict) -> dict:
    ws = input["ws"]                     # a WorkingSet, moved in
    ...
    ws.give("ws")
    return {"text": text}

A handle is in one place at a time, so the client's next use waits for the program to give it back. It lives as long as the client's connection, on one worker, and the planner may move it off the device while it rests. If that worker is lost the connection closes and says so; a turn is never run again on what no longer exists. A client.matcher(json_schema=...) moves the same way, beside the working set it constrains.

Pictures and sound work the same: a program gives them to the client, which saves them in the format it wants, or moves them on to another program with no bytes crossing the client:

out = await client.frames()
await (await client.run("image-gen", out=out, prompt="a cat")).result()
await out.save("cat.png")
await (await client.run("caption", image=out)).result()

See examples/working-set-handles.

To embed in a process, use pie-server (Python) or @pie-project/server (Node and WebGPU browsers).

Build from source

cargo build --release -p pie --bin pie --features metal   # or: cuda, vulkan, wgpu, rocm, xla

Community & License

Discord · Issues · Discussions · Contributing

Apache License 2.0 (NOTICE).

Runs on
GPU support unknown
What shows it
  • no dependency or feature matches a backend row
Native code
Required
  • Binds native code: ring
Python bindings
No Python binding crate found
License
Apache-2.0

Compare with similar projects

Order: strongest tier first, then most downloads, then name, with unmeasured values last. A library counts downloads over 30 days. An app counts binary downloads per release. An app with none counts its crate downloads over 30 days. ML Rust runs this catalogue, so its closest project always gets a row.

pie beside the projects that share a topic with it
ProjectDownloadsDependentsStarsLatest releaseRuns on (GPU)Native codeLicense
pie This page Listed

Pie: A Programmable LLM Serving System

13 downloads over 30 days 0 240 0.2.0 GPU support unknown Binds native code: ring Apache-2.0
llguidance Featured

LLM Token Trie library

182,570 downloads over 30 days 22 909 1.9.1 GPU support unknown No native code found MIT
mistralrs App Featured

Fast, flexible LLM inference.

Python bindings

1,498 binary downloads per release Not applicable 7,819 0.8.1 CUDA, Metal Binds native code: accelerate-src (feature accelerate-src), intel-mkl-src (feature intel-mkl-src) MIT
dynamo App Listed

A Datacenter Scale Distributed Inference Serving Framework

6,860 downloads over 30 days Not applicable 8,457 1.6.2 CUDA Binds native code: k8s-openapi, nixl-sys, pcre2-sys, ring, zmq-sys and 2 more Apache-2.0
llama-gguf Listed

A high-performance Rust implementation of llama.cpp - LLM inference engine with full GGUF support

1,787 downloads over 30 days 3 21 0.14.0 CUDA, Metal, Vulkan Binds native code: hailort-sys (feature hailo), libsqlite3-sys (feature rag-sqlite) Apache-2.0 OR MIT
llmserve App Listed

TUI for serving local LLM models. Pick a model, pick a backend, serve it.

424 binary downloads per release Not applicable 417 0.0.7 GPU support unknown No native code found MIT
blazr App Listed

Inference server for LLMs, speech and embeddings: OpenAI-compatible routes with streaming, plus speech synthesis (TTS) and transcription (ASR). Serves Llama, Mistral, Qwen, Mamba2, MLA+MoE and hybrid models from SafeTensors, AWQ, GPTQ and GGUF.

8 binary downloads per release Not applicable 7 0.7.1 CUDA, WebGPU Binds native code: ring (feature distributed) Apache-2.0
Why ListedNo archive, New or Featured rule places it, so it is Listed.

What it lacks for Featured

  • It has 0.5 active dependents and 0.5 new dependents in 365 days. Featured needs 11 active dependents or 9 new dependents in 365 days. The repository route reads 240 stars, 39 forks and 22 contributors. It needs 4,539 stars, 434 forks and 79 contributors together.
  • Docs are missing: the primary crate publishes no README.

What else the check found

  • The last activity is on 8 Nov 2026, 1 day ago. The rules expect an update within 365 days. Dormancy rule

Exact rules: Listed, Featured library. The check on applied thresholds version 9.

Every rule outcome, as the check records it
  • expected-interval: version 0.2.0 base 80, raised to the 365-day floor: E = 365 days
  • dormancy: last activity 2026-11-08, 1 days ago, E = 365: active
  • featured: not featured: active_users 0.5 < 11 and new_adopters 0.5 < 9 and repository route stars 240 (needs 4539), forks 39 (needs 434), contributors 22 (needs 79); docs missing
  • listed: listed: no archive, new or featured rule applies
Crates9 crates

Measurements and sources

Each signal row shows the raw value, its source and the fetch date. The Sources list gathers every distinct source on this page. Movement needs more history.

Sources6 sources
Adoption1 active dependents, 1 new dependents in 365 days1 not measured
Adoption measurements
SignalValueSourceFetchedCounts
Active dependents0.5crates.io database dumpYes
New dependents (365 days)0.5crates.io database dumpYes
Peak active dependents0.5crates.io database dumpYes
Active dependents as a share of the peak1crates.io database dumpYes
Binary downloads per releaseNot measuredYes
MaintenanceLatest human commit: 1 day ago3 not measured
Maintenance measurements
SignalValueSourceFetchedCounts
Latest human commit2026-11-08GitHub repositoryYes
Latest release2026-10-27crates.io database dumpYes
First release2025-08-05crates.io database dumpYes
Latest version0.2.0crates.io database dumpYes
Days the oldest outside issue waits for a reply12GitHub repositoryYes
Maintainer replies over 365 days0GitHub repositoryYes
Repository archivedfalseGitHub repositoryYes
Repository gonefalseGitHub repositoryYes
Release commit or manifest in the repotruecrates.io packageYes
Published docsfalsecrates.io database dumpYes
Latest release fails cargo checkNot measuredYes
Build check dateNot measuredYes
Build check toolchainNot measuredYes
SecurityUnpatched vulnerabilities: none
Security measurements
SignalValueSourceFetchedCounts
Unpatched vulnerabilities past the grace windownoneRustSec advisory databaseYes
RustSec unmaintained advisorynoneRustSec advisory databaseYes
Deprecation noticenonecrates.io database dumpYes
Deprecated requirementnonecrates.io database dumpYes
Distribution2 releases, 13 downloads over 30 days5 not measured
Distribution measurements
SignalValueSourceFetchedCounts
Releases2crates.io database dumpYes
Downloads over 30 days13crates.io database dumpYes
Binary downloads over the last 3 releasesNot measuredYes
Homebrew installs on request over 365 daysNot measuredYes
Repology repository familiesNot measuredYes
Docker pull growth over 90 daysNot measuredYes
Docker pulls at the growth baselineNot measuredYes
Every version a prereleasefalsecrates.io database dumpYes
Every version 0.0.xfalsecrates.io database dumpYes
Every version yankedfalsecrates.io database dumpYes
Crate deleted from crates.iofalsecrates.io database dumpYes
Repository240 stars, 39 forks, 22 contributors, 1,642 commits. Stars alone never qualify a project.
Repository measurements
SignalValueSourceFetchedCounts
GitHub stars240GitHub repositoryYes — one part of the repository route
GitHub forks39GitHub repositoryYes — one part of the repository route
Contributors with a GitHub account22GitHub contributorsYes — one part of the repository route
Commits on the default branch1642GitHub repositoryNo
Repository's main crate left out of the entrynonecrates.io database dumpYes
Facts that never count
Facts that never count measurements
SignalValueSourceFetchedCounts
LicenseApache-2.0crates.io database dumpNo
Runs on, from listed crates and their direct dependenciesGPU support unknowncrates.io database dumpNo
What shows each backendno dependency or feature matches a backend rowcrates.io database dumpNo
Native code, from listed crates and their dependenciesBinds native code: ringcrates.io database dumpNo
Python bindings, from direct dependencies of listed cratesNo Python binding crate foundcrates.io database dumpNo
Crates that depend on a listed crate directly0crates.io database dumpNo

Corrections and review history

Report a correction

No correction applies to this entry.

Judgments

A judgment enters only through an approved issue and a merged pull request.

No judgment applies to this entry.