From 57bfca50a6f160d09349d315117e1e15edc8fd9a Mon Sep 17 00:00:00 2001 From: Min Htet Myet Date: Thu, 29 Oct 2026 13:04:19 +0900 Subject: [PATCH] release: 0.3.2 (version bump, CHANGELOG, image tag 0.3.2) --- CHANGELOG.md | 25 +++++++++++++++++++++++++ CITATION.cff | 4 ++-- README.md | 8 ++++---- deploy/Dockerfile | 2 +- deploy/docker-compose.yml | 2 +- deploy/k8s/flashspec-deployment.yaml | 4 ++-- docs/install.md | 6 +++--- flashspec/__init__.py | 2 +- pyproject.toml | 2 +- 9 files changed, 40 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2dd37ae..9b5430d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/CITATION.cff b/CITATION.cff index 185772a..eec5105 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -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" diff --git a/README.md b/README.md index b24a1dd..3dfdff6 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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 ``` @@ -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. diff --git a/deploy/Dockerfile b/deploy/Dockerfile index 7d6c08b..c7ecb17 100644 --- a/deploy/Dockerfile +++ b/deploy/Dockerfile @@ -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 diff --git a/deploy/docker-compose.yml b/deploy/docker-compose.yml index f6213e8..50f6924 100644 --- a/deploy/docker-compose.yml +++ b/deploy/docker-compose.yml @@ -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: diff --git a/deploy/k8s/flashspec-deployment.yaml b/deploy/k8s/flashspec-deployment.yaml index 3a40a83..4cae2cf 100644 --- a/deploy/k8s/flashspec-deployment.yaml +++ b/deploy/k8s/flashspec-deployment.yaml @@ -4,7 +4,7 @@ metadata: name: flashspec labels: app: flashspec - version: "0.3.1" + version: "0.3.2" spec: replicas: 1 selector: @@ -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 diff --git a/docs/install.md b/docs/install.md index 738288e..6f6e6af 100644 --- a/docs/install.md +++ b/docs/install.md @@ -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:` and `:latest`) is @@ -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: diff --git a/flashspec/__init__.py b/flashspec/__init__.py index f681a26..211513d 100644 --- a/flashspec/__init__.py +++ b/flashspec/__init__.py @@ -42,5 +42,5 @@ "register", ] -__version__ = "0.3.1" +__version__ = "0.3.2" __author__ = "Min Htet Myet (Mattral)" diff --git a/pyproject.toml b/pyproject.toml index f0a30a6..87ac93d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -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" }