Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,31 @@ Versioning follows [Semantic Versioning 2.0.0](https://semver.org/).

## [Unreleased]

## [0.3.2] — 2026-10-29 — Per-call acceptance rate

Development status stays Alpha. A bug-fix release with no new measurement:
the decoding path and its speed are unchanged, so the README tables remain
the 0.3.0 release run (bundle `3c43e08`), with the acceptance column now
computed from that run's stored step counts.

### Highlights
- `GenerationResult.acceptance_rate` reports the call that returned it.
Before, every call after the first on an engine reported a running mean
over all earlier calls, warm-ups included.
- The README acceptance column and Figure 9 of `docs/lessons.md` are computed
from the stored per-step counts.

### Upgrade notes
- Nothing to change in your code. If you logged `acceptance_rate` from
repeated calls on one engine with 0.3.1 or earlier, those values were
running means; per-call values are accepted / proposed summed over that
call's `arm_steps`, which were always correct.

### Known issues
- Unchanged from 0.3.1 (first call compiles; fp16 greedy exact ties; batch
> 1 and other GPUs or model pairs not measured; bandit experimental; the
CUDA-graph "distinct sizes" warning).

### Fixed
- `GenerationResult.acceptance_rate` now covers only the call that returned
it, as documented. The engine created its acceptance tracker once and never
Expand Down
4 changes: 2 additions & 2 deletions CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ abstract: >-
UCB1/Thompson draft selector is experimental: measured once over seven
arms, it did not beat the best fixed arm. The Triton and assembly
kernels are experimental and not on the generation critical path.
version: 0.3.1
date-released: "2026-10-26"
version: 0.3.2
date-released: "2026-10-29"
license: Apache-2.0
repository-code: "https://github.com/Mattral/FlashSpec"
url: "https://flashspec.readthedocs.io"
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ You need Python 3.11 or later, PyTorch 2.2 or later and transformers 4.40 or lat
**Container image (GPU-oriented).** Each release is also published as a server image on GitHub Container Registry. It is built from the PyPI release on CUDA 13.0, with the torch build the GPU results were measured with, and it runs as a non-root user. It needs an NVIDIA GPU and the NVIDIA Container Toolkit; it starts on CPU too, but CPU is not where FlashSpec is faster. The default command serves the measured pair in fp16 on port 8000.

```bash
docker pull ghcr.io/mattral/flashspec:0.3.1
docker run --gpus all -p 8000:8000 ghcr.io/mattral/flashspec:0.3.1
docker pull ghcr.io/mattral/flashspec:0.3.2
docker run --gpus all -p 8000:8000 ghcr.io/mattral/flashspec:0.3.2
```

## Quickstart
Expand Down Expand Up @@ -153,7 +153,7 @@ python -m flashspec.serve --target Qwen/Qwen2.5-1.5B-Instruct --drafter Qwen/Qwe
Or with the container image. Arguments replace its default command, so pass `--host 0.0.0.0`. The volume keeps downloaded checkpoints between runs:

```bash
docker run --gpus all -p 8000:8000 -v flashspec-hf:/home/flashspec/.cache/huggingface ghcr.io/mattral/flashspec:0.3.1 \
docker run --gpus all -p 8000:8000 -v flashspec-hf:/home/flashspec/.cache/huggingface ghcr.io/mattral/flashspec:0.3.2 \
--target Qwen/Qwen2.5-1.5B-Instruct --drafter Qwen/Qwen2.5-0.5B-Instruct \
--device cuda:0 --dtype float16 --temperature 0 --host 0.0.0.0
```
Expand Down Expand Up @@ -328,7 +328,7 @@ With `compile` on, both models run on static KV caches and the fixed-shape decod

## Status and limitations

FlashSpec is alpha, version 0.3.1.
FlashSpec is alpha, version 0.3.2.

- **Measured scope.** One model pair (`Qwen/Qwen2.5-1.5B-Instruct` verified by `Qwen/Qwen2.5-0.5B-Instruct`), one Tesla T4, fp16, batch 1, 10 MT-Bench and 10 HumanEval prompts, run from `main` at git `3c43e08` with the defaults `compile="auto"` and `drafter_strategy="auto"` (which ran `composite-g6-f2`). No other GPU, model pair or batch size has been measured. Every H100 number in the docs is a design target.
- **The first call compiles.** On CUDA the first `generate` compiles the forwards and captures CUDA graphs, which can take minutes; later calls reuse them. The tables exclude that call.
Expand Down
2 changes: 1 addition & 1 deletion deploy/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# FlashSpec server image: the released PyPI package on a CUDA 13.0 base.
#
# docker build -f deploy/Dockerfile --build-arg FLASHSPEC_VERSION=0.3.1 -t flashspec deploy/
# docker build -f deploy/Dockerfile --build-arg FLASHSPEC_VERSION=0.3.2 -t flashspec deploy/
# docker run --gpus all -p 8000:8000 flashspec
#
# GPU-oriented: torch is the CUDA 13.0 build FlashSpec's GPU results were
Expand Down
2 changes: 1 addition & 1 deletion deploy/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

services:
flashspec:
image: ghcr.io/mattral/flashspec:0.3.1
image: ghcr.io/mattral/flashspec:0.3.2
ports:
- "8000:8000"
volumes:
Expand Down
4 changes: 2 additions & 2 deletions deploy/k8s/flashspec-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ metadata:
name: flashspec
labels:
app: flashspec
version: "0.3.1"
version: "0.3.2"
spec:
replicas: 1
selector:
Expand All @@ -19,7 +19,7 @@ spec:
- name: flashspec
# GPU-oriented image; the default command serves Qwen2.5-1.5B-Instruct
# verified by Qwen2.5-0.5B-Instruct in fp16 on port 8000.
image: ghcr.io/mattral/flashspec:0.3.1
image: ghcr.io/mattral/flashspec:0.3.2
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8000
Expand Down
6 changes: 3 additions & 3 deletions docs/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ git clone https://github.com/Mattral/FlashSpec && cd FlashSpec
pip install -e ".[dev,gpu]" # omit ",gpu" on Windows/macOS

# Container image (Linux + NVIDIA GPU), published for each release:
docker pull ghcr.io/mattral/flashspec:0.3.1
docker run --gpus all -p 8000:8000 ghcr.io/mattral/flashspec:0.3.1
docker pull ghcr.io/mattral/flashspec:0.3.2
docker run --gpus all -p 8000:8000 ghcr.io/mattral/flashspec:0.3.2
```

**The container image** (`ghcr.io/mattral/flashspec:<version>` and `:latest`) is
Expand All @@ -48,7 +48,7 @@ built by `.github/workflows/container.yml` when a release is published:
To build it yourself from a released version:

```bash
docker build -f deploy/Dockerfile --build-arg FLASHSPEC_VERSION=0.3.1 -t flashspec deploy/
docker build -f deploy/Dockerfile --build-arg FLASHSPEC_VERSION=0.3.2 -t flashspec deploy/
```

A development checkout, by platform:
Expand Down
2 changes: 1 addition & 1 deletion flashspec/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,5 @@
"register",
]

__version__ = "0.3.1"
__version__ = "0.3.2"
__author__ = "Min Htet Myet (Mattral)"
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "hatchling.build"

[project]
name = "flashspec"
version = "0.3.1"
version = "0.3.2"
description = "Lossless speculative decoding for HuggingFace causal LMs, with a static-cache CUDA-graph fast path; bandit draft selection and Triton kernels are experimental"
readme = {file = "README.md", content-type = "text/markdown"}
license = { file = "LICENSE" }
Expand Down
Loading