Qwen3.8-27B-DFlash2-EXL3-5.0bpw README

The project's README from github.com/MiaAI-Lab/Qwen3.8-27B-DFlash2-EXL3-5.0bpw. As one markdown file: README.md.

Qwen3.8-27B · EXL3 · DFlash2

by Mia'a AI Lab

Sponsor me on GitHub Follow Mia on X

Deployment kit for serving Qwen3.8-27B quantized to EXL3 3.5bpw with speculative decoding — MTP by default (draft head inside the checkpoint, best context per GB) or DFlash2 (EXL3 5.0bpw draft model, ~15% faster) — plus a ~4.5-bit KV cache lane (NVFP4 on Ada/Hopper/Blackwell, Hadamard-4 on Ampere) for maximum context per GB.

This repo contains the launcher, server and configuration. The model weights live on Hugging Face (see Model cards) and the inference engine is our exllamav3 fork (DFlash2/MTP drafting, NVFP4/FP8 KV, aarch64 GB10 + x86 CUDA).

What's in the box

file what
start.sh env-driven launcher for the OpenAI-compatible server
stop.sh stop the server (graceful shutdown, safe to re-run)
tools/serve_openai.py the server itself (chat completions, streaming, tool calling)
.env.example documented configuration knobs
model-cards/ model cards for the two HF weight sets

Quick start

# 1. configure and launch:
cp .env.example .env      # edit: context, GPU memory
./start.sh                # first run: builds .venv + installs the engine,
                          # downloads weights, serves http://localhost:8888/v1

start.sh is self-bootstrapping: on first run it creates .venv, installs GPU torch and pip-installs the exllamav3 engine from this fork (all of DFlash2/MTP drafting, NVFP4/FP8 KV and the aarch64 GB10 port are fork features). EXL3_REPO in .env overrides where the engine comes from — any git URL or a local path.

Running on a 24 GB GPU (RTX 3090/4090)? Jump to 24 GB config.

start.sh auto-creates .env from the example on first run, prefers .venv/bin/python when present, and downloads the target and draft weight sets from Hugging Face automatically on first launch (and resumes partial downloads) — no manual fetching. Set HF_TARGET_REPO / HF_DRAFT_REPO in .env to pull from a mirror instead.

Configuration highlights (.env)

Concurrency note: the server generates one request at a time (batch-1 speculative decoding); concurrent requests queue automatically. Measured on DGX Spark with DRAFT=dflash2: 8 concurrent requests ran fully sequentially (no batching benefit), aggregate throughput ~16.7 tok/s at that concurrency — plan capacity accordingly if your workload is concurrent rather than single-request.

Reasoning note: the server always reasons — there is currently no way to disable it. chat_template_kwargs.enable_thinking (the vLLM/SGLang convention) is silently ignored. The reasoning trace comes back in a separate reasoning_content field (both in the full response and in each streamed delta), but it is not a separate token budget: reasoning and visible content both draw from the same max_tokens. With a tight budget (e.g. max_tokens: 16 on a short-answer prompt) I got a response with no content at all, entirely consumed by the reasoning trace — clients expecting a quick, cheap warmup/probe call should budget generously rather than assuming a short max_tokens implies a short wait.

24 GB GPUs (RTX 3090 / 4090)

The kit targets DGX Spark (121 GB) by default. On a 24 GB card the recipe is the same weights, a tighter KV budget, and a ~4.5-bit KV format so the native 262k context still fits. The default drafter (MTP) is the right choice here.

KV format is GPU-dependent. This fork's nvfp4 / fp8 lanes are software packed caches (E2M1 + E4M3 scales, or raw E4M3) with Triton online dequant. Those kernels use fp8e4nv, which Triton only compiles on compute capability ≥ 8.9. They are not Blackwell tensor-core NVFP4 matmul.

GPU Arch CACHE_QUANT for 262k
RTX 4090, GB10, Hopper+ sm ≥ 8.9 nvfp4 (measured lossless at generation level)
RTX 3090 Ampere sm_86 4 (Hadamard int4; same ~4.5 bits/elem). nvfp4 and fp8 will fail to compile
# .env — 24 GB recipe (MTP, the default)
GPU_MEM_GB=22            # auto-detected when unset; explicit for clarity
CONTEXT_SIZE=262144      # full native context fits (see math below)
CACHE_QUANT=nvfp4        # 4090 / GB10 / Hopper+. On a 3090 use: CACHE_QUANT=4
# DRAFT=mtp is the default — no extra config, no draft download
# .env — alternative: DFlash2 at 24 GB
GPU_MEM_GB=22
CONTEXT_SIZE=200000
CACHE_QUANT=nvfp4        # 3090: CACHE_QUANT=4
DRAFT=dflash2
DRAFT_DIR=models/Qwen3.8-27B-DFlash2-EXL3-5.0bpw   # auto-downloaded
# CPU_CACHE_GB=16        # CPU spill tier: NOT YET ACTIVE (planned; see notes)

Memory math (GiB): target weights 14.2 + MTP head 0.05 → ~6.7 GB left for KV at a 22 GB budget; NVFP4 or Hadamard-4 KV costs ~18 KB/token for the target plus ~1.2 KB/token for the MTP head (only the 16 full-attention layers hold KV; fp16 is ~64 KB/token) → the full native 262k fits with ~1 GB to spare. With the DFlash2 draft instead: 15.6 GiB of weights + ~24 KB/token → ~220k–262k. CACHE_QUANT=8 (8.5 bits) needs 9.1 GB at 262k and will not leave that much headroom; fp16 (17 GB at 262k) does not fit. Past the resident limit the cache does not hold today; the CPU spill tier is planned but not yet implemented.

RTX-class notes (vs the DGX Spark the numbers above were measured on):

Tool calling

OpenAI-style tools / tool_choice work (referenced in the file table above but not otherwise documented here). Verified request/response shape:

curl http://localhost:8888/v1/chat/completions \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "qwen3.8-27b-exl3-3.5bpw-wm",
    "messages": [{"role": "user", "content": "What is the weather in Lyon?"}],
    "tools": [{
      "type": "function",
      "function": {
        "name": "get_weather",
        "description": "Get current weather",
        "parameters": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]}
      }
    }],
    "tool_choice": "auto",
    "max_tokens": 300
  }'

Returns a normal OpenAI tool_calls array (finish_reason: "tool_calls", message.content: null) alongside the usual reasoning_content. The model id in responses doesn't necessarily match HF_TARGET_REPO or MODEL_DIR verbatim (I saw qwen3.8-27b-exl3-3.5bpw-wm for MODEL_DIR=models/Qwen3.8-27B-EXL3-3.5bpw) — check /v1/models rather than assuming the id a client should send.

Model cards

Measured on DGX Spark (GB10): HumanEval-class decode 47.5 tok/s at T=0.6 with acceptance 4.43 tokens/step; tool-eval-bench hardmode @ T=1.0: 87–88 / 100.

License

Code in this repo: MIT. Model weights are Apache-2.0 derivatives (see model cards); exllamav3 is MIT.

Qwen3.8-27B-DFlash2-EXL3-5.0bpw (MiaAI-Lab/Qwen3.8-27B-DFlash2-EXL3-5.0bpw)

Searching Database…

Что это такое?Набор для развёртывания Qwen3.8-27B (квантованной в EXL3 3.5bpw) через OpenAI-совместимый сервер со спекулятивным декодированием для ускорения генерации. В комплекте лаунчер, сервер и конфиг; веса модели лежат на Hugging Face, а инференс идёт на командном форке exllamav3.
Это сама модель или только код для её обслуживания?Только код обслуживания. В этом репозитории лаунчеры start.sh/stop.sh, сервер tools/serve_openai.py и конфиг .env; сами веса лежат на Hugging Face (две карточки моделей), а GPU-движок инференса — отдельный форк exllamav3.
Как это запустить?Запустите start.sh — он сам себя разворачивает: при первом запуске создаёт .venv, ставит GPU-версию torch, устанавливает через pip форк exllamav3, пишет .env из примера и автоматически скачивает target- и draft-веса с Hugging Face (докачивая прерванные загрузки).
Какая GPU нужна для запуска?GPU Nvidia с CUDA; по умолчанию набор нацелен на DGX Spark (121 ГБ, GB10/aarch64), но в комплекте есть и конфиг на 24 ГБ для RTX 3090/4090. Вариант с NVFP4/FP8 KV-кэшем требует compute capability ≥8.9 (Ada/Hopper/Blackwell); Ampere (3090, sm86) должен откатиться к формату KV Hadamard-4.
Может ли он обслуживать несколько запросов одновременно?Нет — сервер генерирует один запрос за раз (спекулятивное декодирование с batch-1); параллельные запросы просто встают в очередь, так что пропускная способность не растёт с ростом конкуренции (замерено ~16,7 tok/s суммарно при 8 одновременных запросах на DGX Spark).
Работает ли это на GPU любых брендов или только Nvidia?Только Nvidia — всё построено на CUDA через форк exllamav3, с отдельными путями Triton-ядер для GPU Ada/Hopper/Blackwell против Ampere, плюс aarch64-сборка для GB10 в DGX Spark.
В чём разница между черновыми режимами MTP и DFlash2?MTP использует черновую голову, встроенную в целевой чекпойнт — без дополнительной загрузки, лучший контекст на ГБ, ~30 tok/s на DGX Spark. DFlash2 использует отдельную черновую модель EXL3 5.0bpw на 1,4 ГБ для ~34,5 tok/s, но требует лишнюю KV-память и снижает запас контекста, целиком помещающегося в памяти.
Какое окно контекста он поддерживает?Родной лимит — 262 144 токена. Установка CONTEXTSIZE до 1M работает, и лаунчер сам подменяет конфиг на вариант с YaRN, но 262k описывается как лимит без потери качества.
Можно отключить выдачу рассуждений модели?Нет — сервер всегда рассуждает, и сейчас отключить это нельзя; флаг enable_thinking из vLLM/SGLang молча игнорируется, а трасса рассуждений делит один бюджет max_tokens с видимым ответом.
Поддерживается ли tool calling?Да — он возвращает стандартный массив tool_calls OpenAI с finish_reason: 'tool_calls', проверено, что работает вместе с отдельным полем reasoning_content и в полных, и в потоковых ответах.
Creator
MiaAI-Lab
Size
0.1 MB
Stars
232
Updated
CommitSep 01
Age
1mo
Commits · 90 Days