GLM-5.3 Flash EXL3 for 2-4x DGX Sparks
See the code[!IMPORTANT]
There is an improved version of this recipe that runs faster on TensorFold. Everyone should use that.
https://github.com/MiaAI-Lab/GLM-5.3-Flash-EXL3-2x-DGX-Sparks-TensorFold
Serve GLM-5.3 Flash on 2, 3 or 4 NVIDIA DGX Sparks with one command.
by Mia's AI Lab and the community
Chris Scott (chriswritescode-dev) authored the root commit dc6b4fdd.
An OpenAI-compatible vLLM server for
zai-org/GLM-5.3-Flash, using
4-bpw EXL3 weights, fp8 KV cache and DFlash2 speculative decoding, built
natively for the GB10 (sm_121a). The launcher pulls the image, downloads
the weights, shares them with the other Sparks and starts the cluster.
| I want to... | Go to |
|---|---|
| Run it on two Sparks | Quick start |
| See how fast it is | Performance |
| Get more speed | Speed boost |
| Serve an abliterated model | Abliteration |
| Use 3 or 4 Sparks | Topologies |
| Change a setting | Configuration |
| Find every knob, receipt and caveat | Full reference |
| Model id | GLM-5.3-Flash-EXL3 on http://<head>:8888/v1 |
| Weights | Mia-AiLab/GLM-5.3-Flash-EXL3-4bpw-TensorFold, EXL3 4 bpw, ~164 GiB, 83 shards |
| Speculative decoding | DFlash2, 7 draft tokens |
| Context | 850k tokens by default; 1.23M-token KV pool (1.45× one full request) |
| Features | Tool calling, reasoning, image and video input, prefix caching, optional API key |
| Image | ghcr.io/miaai-lab/glm-5.3-flash-2x-dgx-sparks:exl3-instanttensor (public) |
On the head Spark, with the second Spark reachable over SSH and the CX7 cable connected:
git clone https://github.com/MiaAI-Lab/GLM-5.3-Flash-EXL3-2x-DGX-Sparks.git
cd GLM-5.3-Flash-EXL3-2x-DGX-Sparks
cp .env.example .env # set HEAD_IP, WORKER_IP and the CX7 interface names
./start.sh # pull, download, share weights, start, warm up
The first start downloads ~164 GiB and takes a while. When it prints
GLM-5.3-Flash EXL3 is UP, send a request:
curl -s http://127.0.0.1:8888/v1/chat/completions -H 'Content-Type: application/json' \
-d '{"model": "GLM-5.3-Flash-EXL3", "messages": [{"role": "user", "content": "Hello!"}]}'
| Command | Does |
|---|---|
./start.sh status | Show the cluster state |
./start.sh logs / logs worker | Follow the head or worker logs |
./start.sh restart | Apply .env changes |
./start.sh stop | Stop both Sparks |
[!NOTE] After a
git pullthat changes the image recipe, the next start rebuilds the image once. That is expected.
Network setup, NFS weight sharing, air-gapped installs and other kits: Quick start reference · Running on a different kit.
Latest TP2 measurements on 2× GB10, 2026-09-28: DFlash2, temperature 0, thinking off, mean of fresh boots. Decode excludes time to first token.
[!IMPORTANT] Default is what every install gets. Speed boost is opt-in: one
.envline and a one-time ~25 min build on the head. See TP2 profiles.
| Decode, tokens/s | Default | Speed boost | Change |
|---|---|---|---|
| Prose | 36.1 | 37.5 | +4% |
| Structured output | 83.0 | 92.3 | +11% |
| Code | 54.6 | 55.5 | +2% |
| Code at 32k context | 54.6 | 60.3 | +10% |
| Short code, 1 request | 36.0 | 41.3 | +15% |
| Short code, 2 requests (total) | 53.6 | 56.9 | +6% |
xychart-beta
title "TP2 decode (tokens/s): default vs speed boost"
x-axis ["Prose", "Structured", "Code", "Code 32k", "Short code x1", "Short code x2"]
y-axis "tokens/s" 0 --> 100
bar [37.5, 92.3, 55.5, 60.3, 41.3, 56.9]
line [36.1, 83.0, 54.6, 54.6, 36.0, 53.6]
Bars: speed boost. Line: default.
| Cold prefill, tokens/s | 8k | 32k | 96k |
|---|---|---|---|
| Default | 1,411 | 1,511 | 1,498 |
| Speed boost | 1,390 | 1,500 | 1,489 |
Recent gains
[!NOTE] Speed-boost figures come from 2–3 boots per arm with unlocked clocks; treat them as descriptive, not confidence intervals. Methods, raw receipts and older tables: Performance history.
Pick one per start. All run on the same public base weights.
| Profile | Turn on | Best for | Notes |
|---|---|---|---|
| Default | nothing | Everyone | FP8 dense layers, BF16 prefill path |
| Speed boost | GLM53_MODEL_PRESET=dense-h3 in .env | More decode speed | First start builds a matched EXL3 target and 6-bpw draft on the head (~25 min, once) |
| Abliteration | ABLIT=1 ./start.sh restart | Uncensored output | Run python3 ablit/fetch_transplant.py once first |
| Abliteration + speed boost | the preset line and ABLIT=1 | Both | Up to 10% faster decode than plain abliteration in first tests |
| Prebuilt abliterated | ./start-abliterated.sh | No load-time edit | Downloads a separate checkpoint |
[!TIP] Pass
ABLIT=1on the command line, not in.env: the launcher resets it unless you ask for it at start.
Details: Speed boost · Abliteration · Both together
Off by default. Each has a measured benefit and a tradeoff; try one at a time.
| Option | Turn on | What it gets you | Tradeoff |
|---|---|---|---|
| Adaptive draft length | GLM53_ADAPTIVE_K=ema | Prose decode +13–21% | Mostly helps prose (details) |
| Cooperative decode MoE | a generated EXL3_OVERLAY_HOST overlay | Structured decode +7–9% | Needs a separately built extension (quickstart) |
| Thin-decode MoE kernels | GLM53_EXL3_MOE_FAST=1 | Decode +8–15% in one A/B/A | Numerics study inconclusive (details) |
| Long-coding profile | append examples/tp2-long-coding.env to .env | Tuned for 262k-context coding sessions | Two concurrent requests |
All options and their tradeoffs: full reference.
| Sparks | Launcher | Status | Guide |
|---|---|---|---|
| 2 | ./start.sh | this page | |
| 3 | ./start-tp3.sh + .env.tp3 | 3× Spark | |
| 4 | ./start-tp4.sh + .env.tp4 | 4× Spark |
Stop one topology before starting another; they share port 8888.
.env holds everything; the shipped defaults are tuned for 2× Spark. A
variable set on the command line wins over .env
(MAX_NUM_SEQS=2 ./start.sh restart).
| Setting | Default | What it does |
|---|---|---|
HEAD_IP, WORKER_IP, CX7 pins | example values | Where your Sparks and cable are |
MAX_MODEL_LEN | 850000 | Maximum context per request |
MAX_NUM_SEQS | 4 | Concurrent requests |
VLLM_API_KEY | empty | Set to require Authorization: Bearer <key> |
GLM53_DEFAULT_REASONING_EFFORT | empty | low, high or max for clients that send none |
SPEC_METHOD | dflash | mtp rolls back to MTP decoding |
Using the API. Thinking is on by default. For long structured output,
prefer "chat_template_kwargs": {"reasoning_effort": "low"} over turning
thinking off; thinking off can corrupt long numeric tables.
Responses report cached prompt tokens in usage.
Every knob with its measured tradeoff: .env reference · Client request defaults · KV cache · Prefix caching.
[!WARNING] Do not use
--moe-backend marlin, NVFP4 or bf16 KV cache, orTRITON_ATTNfor the draft. They fail or silently degrade on this image. Full list: Do not.
docs/.tests/ and run with python3 -m pytest tests/
or directly. tests/test_image_layer_budget.py keeps the image loadable on
workers; fold new Dockerfile steps into existing layers.Recipe code and docs: AGPL-3.0 (contributions before 2026-09-07: MIT). Weights keep their own licenses: the EXL3 checkpoint is Apache-2.0 and DFlash2 is CC BY-NC-ND 4.0.
Chris Scott (chriswritescode-dev) authored the root commit dc6b4fdd.
tonyd2wild (profile) authored overlay/patch_glm5_drafter_group.py, which adds the DFlash2 sliding-window KV group to the GLM-5-Next layout, in commit 64c92e98 of GLM-5.3-Flash-NVFP4-DFlash2-2x-DGX-Spark. This repo's first copy of the file is his, byte for byte; later changes are ours.
Built on the work of turboderp (ExLlamaV3), Z.ai (base model), IncoAI (DFlash2), Alexbob0 and vcruz305 (dense EXL3 loader), drowzeys and bullerwins (abliteration), FlyCockpit (TP3 shapes), malaiwah (KLD panel), and every contributor who sent a fix or a measurement. Full credits.
(top 24 of 26)
409 followers · starred Aug 2026
5,205 followers · starred Aug 2026
581 followers · starred Sep 2026
1,111 followers · starred Aug 2026
GLM-5.3 Flash EXL3 for 2-4x DGX Sparks
See the code[!IMPORTANT]
There is an improved version of this recipe that runs faster on TensorFold. Everyone should use that.
https://github.com/MiaAI-Lab/GLM-5.3-Flash-EXL3-2x-DGX-Sparks-TensorFold
Serve GLM-5.3 Flash on 2, 3 or 4 NVIDIA DGX Sparks with one command.
by Mia's AI Lab and the community
Chris Scott (chriswritescode-dev) authored the root commit dc6b4fdd.
An OpenAI-compatible vLLM server for
zai-org/GLM-5.3-Flash, using
4-bpw EXL3 weights, fp8 KV cache and DFlash2 speculative decoding, built
natively for the GB10 (sm_121a). The launcher pulls the image, downloads
the weights, shares them with the other Sparks and starts the cluster.
| I want to... | Go to |
|---|---|
| Run it on two Sparks | Quick start |
| See how fast it is | Performance |
| Get more speed | Speed boost |
| Serve an abliterated model | Abliteration |
| Use 3 or 4 Sparks | Topologies |
| Change a setting | Configuration |
| Find every knob, receipt and caveat | Full reference |
| Model id | GLM-5.3-Flash-EXL3 on http://<head>:8888/v1 |
| Weights | Mia-AiLab/GLM-5.3-Flash-EXL3-4bpw-TensorFold, EXL3 4 bpw, ~164 GiB, 83 shards |
| Speculative decoding | DFlash2, 7 draft tokens |
| Context | 850k tokens by default; 1.23M-token KV pool (1.45× one full request) |
| Features | Tool calling, reasoning, image and video input, prefix caching, optional API key |
| Image | ghcr.io/miaai-lab/glm-5.3-flash-2x-dgx-sparks:exl3-instanttensor (public) |
On the head Spark, with the second Spark reachable over SSH and the CX7 cable connected:
git clone https://github.com/MiaAI-Lab/GLM-5.3-Flash-EXL3-2x-DGX-Sparks.git
cd GLM-5.3-Flash-EXL3-2x-DGX-Sparks
cp .env.example .env # set HEAD_IP, WORKER_IP and the CX7 interface names
./start.sh # pull, download, share weights, start, warm up
The first start downloads ~164 GiB and takes a while. When it prints
GLM-5.3-Flash EXL3 is UP, send a request:
curl -s http://127.0.0.1:8888/v1/chat/completions -H 'Content-Type: application/json' \
-d '{"model": "GLM-5.3-Flash-EXL3", "messages": [{"role": "user", "content": "Hello!"}]}'
| Command | Does |
|---|---|
./start.sh status | Show the cluster state |
./start.sh logs / logs worker | Follow the head or worker logs |
./start.sh restart | Apply .env changes |
./start.sh stop | Stop both Sparks |
[!NOTE] After a
git pullthat changes the image recipe, the next start rebuilds the image once. That is expected.
Network setup, NFS weight sharing, air-gapped installs and other kits: Quick start reference · Running on a different kit.
Latest TP2 measurements on 2× GB10, 2026-09-28: DFlash2, temperature 0, thinking off, mean of fresh boots. Decode excludes time to first token.
[!IMPORTANT] Default is what every install gets. Speed boost is opt-in: one
.envline and a one-time ~25 min build on the head. See TP2 profiles.
| Decode, tokens/s | Default | Speed boost | Change |
|---|---|---|---|
| Prose | 36.1 | 37.5 | +4% |
| Structured output | 83.0 | 92.3 | +11% |
| Code | 54.6 | 55.5 | +2% |
| Code at 32k context | 54.6 | 60.3 | +10% |
| Short code, 1 request | 36.0 | 41.3 | +15% |
| Short code, 2 requests (total) | 53.6 | 56.9 | +6% |
xychart-beta
title "TP2 decode (tokens/s): default vs speed boost"
x-axis ["Prose", "Structured", "Code", "Code 32k", "Short code x1", "Short code x2"]
y-axis "tokens/s" 0 --> 100
bar [37.5, 92.3, 55.5, 60.3, 41.3, 56.9]
line [36.1, 83.0, 54.6, 54.6, 36.0, 53.6]
Bars: speed boost. Line: default.
| Cold prefill, tokens/s | 8k | 32k | 96k |
|---|---|---|---|
| Default | 1,411 | 1,511 | 1,498 |
| Speed boost | 1,390 | 1,500 | 1,489 |
Recent gains
[!NOTE] Speed-boost figures come from 2–3 boots per arm with unlocked clocks; treat them as descriptive, not confidence intervals. Methods, raw receipts and older tables: Performance history.
Pick one per start. All run on the same public base weights.
| Profile | Turn on | Best for | Notes |
|---|---|---|---|
| Default | nothing | Everyone | FP8 dense layers, BF16 prefill path |
| Speed boost | GLM53_MODEL_PRESET=dense-h3 in .env | More decode speed | First start builds a matched EXL3 target and 6-bpw draft on the head (~25 min, once) |
| Abliteration | ABLIT=1 ./start.sh restart | Uncensored output | Run python3 ablit/fetch_transplant.py once first |
| Abliteration + speed boost | the preset line and ABLIT=1 | Both | Up to 10% faster decode than plain abliteration in first tests |
| Prebuilt abliterated | ./start-abliterated.sh | No load-time edit | Downloads a separate checkpoint |
[!TIP] Pass
ABLIT=1on the command line, not in.env: the launcher resets it unless you ask for it at start.
Details: Speed boost · Abliteration · Both together
Off by default. Each has a measured benefit and a tradeoff; try one at a time.
| Option | Turn on | What it gets you | Tradeoff |
|---|---|---|---|
| Adaptive draft length | GLM53_ADAPTIVE_K=ema | Prose decode +13–21% | Mostly helps prose (details) |
| Cooperative decode MoE | a generated EXL3_OVERLAY_HOST overlay | Structured decode +7–9% | Needs a separately built extension (quickstart) |
| Thin-decode MoE kernels | GLM53_EXL3_MOE_FAST=1 | Decode +8–15% in one A/B/A | Numerics study inconclusive (details) |
| Long-coding profile | append examples/tp2-long-coding.env to .env | Tuned for 262k-context coding sessions | Two concurrent requests |
All options and their tradeoffs: full reference.
| Sparks | Launcher | Status | Guide |
|---|---|---|---|
| 2 | ./start.sh | this page | |
| 3 | ./start-tp3.sh + .env.tp3 | 3× Spark | |
| 4 | ./start-tp4.sh + .env.tp4 | 4× Spark |
Stop one topology before starting another; they share port 8888.
.env holds everything; the shipped defaults are tuned for 2× Spark. A
variable set on the command line wins over .env
(MAX_NUM_SEQS=2 ./start.sh restart).
| Setting | Default | What it does |
|---|---|---|
HEAD_IP, WORKER_IP, CX7 pins | example values | Where your Sparks and cable are |
MAX_MODEL_LEN | 850000 | Maximum context per request |
MAX_NUM_SEQS | 4 | Concurrent requests |
VLLM_API_KEY | empty | Set to require Authorization: Bearer <key> |
GLM53_DEFAULT_REASONING_EFFORT | empty | low, high or max for clients that send none |
SPEC_METHOD | dflash | mtp rolls back to MTP decoding |
Using the API. Thinking is on by default. For long structured output,
prefer "chat_template_kwargs": {"reasoning_effort": "low"} over turning
thinking off; thinking off can corrupt long numeric tables.
Responses report cached prompt tokens in usage.
Every knob with its measured tradeoff: .env reference · Client request defaults · KV cache · Prefix caching.
[!WARNING] Do not use
--moe-backend marlin, NVFP4 or bf16 KV cache, orTRITON_ATTNfor the draft. They fail or silently degrade on this image. Full list: Do not.
docs/.tests/ and run with python3 -m pytest tests/
or directly. tests/test_image_layer_budget.py keeps the image loadable on
workers; fold new Dockerfile steps into existing layers.Recipe code and docs: AGPL-3.0 (contributions before 2026-09-07: MIT). Weights keep their own licenses: the EXL3 checkpoint is Apache-2.0 and DFlash2 is CC BY-NC-ND 4.0.
Chris Scott (chriswritescode-dev) authored the root commit dc6b4fdd.
tonyd2wild (profile) authored overlay/patch_glm5_drafter_group.py, which adds the DFlash2 sliding-window KV group to the GLM-5-Next layout, in commit 64c92e98 of GLM-5.3-Flash-NVFP4-DFlash2-2x-DGX-Spark. This repo's first copy of the file is his, byte for byte; later changes are ours.
Built on the work of turboderp (ExLlamaV3), Z.ai (base model), IncoAI (DFlash2), Alexbob0 and vcruz305 (dense EXL3 loader), drowzeys and bullerwins (abliteration), FlyCockpit (TP3 shapes), malaiwah (KLD panel), and every contributor who sent a fix or a measurement. Full credits.
(top 24 of 26)
409 followers · starred Aug 2026
5,205 followers · starred Aug 2026
581 followers · starred Sep 2026
1,111 followers · starred Aug 2026