Text Generation
GGUF
k-exaone
exaone
Mixture of Experts
mixed-quantization
mtp
dgx-spark
imatrix
conversational
Instructions to use Baekpica/K-EXAONE-236B-A23B-Mixed-Quant-GGUF with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- llama.cpp
How to use Baekpica/K-EXAONE-236B-A23B-Mixed-Quant-GGUF with llama.cpp:
Install (macOS, Linux)
curl -LsSf https://llama.app/install.sh | sh # Start a local OpenAI-compatible server with a web UI: llama serve -hf Baekpica/K-EXAONE-236B-A23B-Mixed-Quant-GGUF # Run inference directly in the terminal: llama cli -hf Baekpica/K-EXAONE-236B-A23B-Mixed-Quant-GGUF
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible server with a web UI: llama serve -hf Baekpica/K-EXAONE-236B-A23B-Mixed-Quant-GGUF # Run inference directly in the terminal: llama cli -hf Baekpica/K-EXAONE-236B-A23B-Mixed-Quant-GGUF
Use pre-built binary
# Download pre-built binary from: # https://github.com/ggerganov/llama.cpp/releases # Start a local OpenAI-compatible server with a web UI: ./llama-server -hf Baekpica/K-EXAONE-236B-A23B-Mixed-Quant-GGUF # Run inference directly in the terminal: ./llama-cli -hf Baekpica/K-EXAONE-236B-A23B-Mixed-Quant-GGUF
Build from source code
git clone https://github.com/ggerganov/llama.cpp.git cd llama.cpp cmake -B build cmake --build build -j --target llama-server llama-cli # Start a local OpenAI-compatible server with a web UI: ./build/bin/llama-server -hf Baekpica/K-EXAONE-236B-A23B-Mixed-Quant-GGUF # Run inference directly in the terminal: ./build/bin/llama-cli -hf Baekpica/K-EXAONE-236B-A23B-Mixed-Quant-GGUF
Use Docker
docker model run hf.co/Baekpica/K-EXAONE-236B-A23B-Mixed-Quant-GGUF
- LM Studio
- Jan
- vLLM
How to use Baekpica/K-EXAONE-236B-A23B-Mixed-Quant-GGUF with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "Baekpica/K-EXAONE-236B-A23B-Mixed-Quant-GGUF" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Baekpica/K-EXAONE-236B-A23B-Mixed-Quant-GGUF", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/Baekpica/K-EXAONE-236B-A23B-Mixed-Quant-GGUF
- Ollama
How to use Baekpica/K-EXAONE-236B-A23B-Mixed-Quant-GGUF with Ollama:
ollama run hf.co/Baekpica/K-EXAONE-236B-A23B-Mixed-Quant-GGUF
- Unsloth Desktop
- Pi
How to use Baekpica/K-EXAONE-236B-A23B-Mixed-Quant-GGUF with Pi:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf Baekpica/K-EXAONE-236B-A23B-Mixed-Quant-GGUF
Configure the model in Pi
# Install Pi: npm install -g @earendil-works/pi-coding-agent # Add to ~/.pi/agent/models.json: { "providers": { "llama-cpp": { "baseUrl": "http://localhost:8080/v1", "api": "openai-completions", "apiKey": "none", "models": [ { "id": "Baekpica/K-EXAONE-236B-A23B-Mixed-Quant-GGUF" } ] } } }Run Pi
# Start Pi in your project directory: pi
- Docker Model Runner
How to use Baekpica/K-EXAONE-236B-A23B-Mixed-Quant-GGUF with Docker Model Runner:
docker model run hf.co/Baekpica/K-EXAONE-236B-A23B-Mixed-Quant-GGUF
- Lemonade
How to use Baekpica/K-EXAONE-236B-A23B-Mixed-Quant-GGUF with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull Baekpica/K-EXAONE-236B-A23B-Mixed-Quant-GGUF
Run and chat with the model
lemonade run user.K-EXAONE-236B-A23B-Mixed-Quant-GGUF-{{QUANT_TAG}}List all available models
lemonade list
- Hermes Agent
How to use Baekpica/K-EXAONE-236B-A23B-Mixed-Quant-GGUF with Hermes Agent:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf Baekpica/K-EXAONE-236B-A23B-Mixed-Quant-GGUF
Configure Hermes
# Install Hermes: curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash hermes setup # Point Hermes at the local server: hermes config set model.provider custom hermes config set model.base_url http://127.0.0.1:8080/v1 hermes config set model.default Baekpica/K-EXAONE-236B-A23B-Mixed-Quant-GGUF
Run Hermes
hermes
- Atomic Chat
- OpenClaw
How to use Baekpica/K-EXAONE-236B-A23B-Mixed-Quant-GGUF with OpenClaw:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf Baekpica/K-EXAONE-236B-A23B-Mixed-Quant-GGUF
Configure OpenClaw
# Install OpenClaw: npm install -g openclaw@latest # Register the local server and set it as the default model: openclaw onboard --non-interactive --mode local \ --auth-choice custom-api-key \ --custom-base-url http://127.0.0.1:8080/v1 \ --custom-model-id "Baekpica/K-EXAONE-236B-A23B-Mixed-Quant-GGUF" \ --custom-provider-id llama-cpp \ --custom-compatibility openai \ --custom-text-input \ --accept-risk \ --skip-health
Run OpenClaw
openclaw agent --local --agent main --message "Hello from Hugging Face"
model card: flash-decode depth numbers, rising concurrency, re-measured MTP; pin d35f0dd
Browse files
README.md
CHANGED
|
@@ -112,7 +112,7 @@ Composition: `calibration.composition.json`.
|
|
| 112 |
| BF16 GGUF sha256 | `73be2da8653976df036bf9b6466b011f86cb10f78bab30a47025638ec999d3f8` |
|
| 113 |
| llama.cpp (quantizer) | [`ggml-org/llama.cpp`](https://github.com/ggml-org/llama.cpp) @ `6a32c29a746a2e44de463de647f9f6661eb5086b` (build `b10295`) |
|
| 114 |
| Converter | [`Baekpica/k-exaone-mixed-ds4`](https://github.com/Baekpica/k-exaone-mixed-ds4) |
|
| 115 |
-
| Serving engine (measured below) | [`Baekpica/ds4`](https://github.com/Baekpica/ds4/tree/feature/exaone-model-loader) @ `
|
| 116 |
| — upstream engine | [`antirez/ds4`](https://github.com/antirez/ds4) |
|
| 117 |
| — DGX Spark port | [`Entrpi/ds4-on-spark`](https://github.com/Entrpi/ds4-on-spark) |
|
| 118 |
|
|
@@ -202,7 +202,7 @@ driver 595.71.05, CUDA 13.3, Linux 6.17.
|
|
| 202 |
|---|---|
|
| 203 |
| Engine | [`Baekpica/ds4`](https://github.com/Baekpica/ds4/tree/feature/exaone-model-loader) |
|
| 204 |
| Branch | `feature/exaone-model-loader` |
|
| 205 |
-
| Commit | `
|
| 206 |
| Weights | [`Baekpica/K-EXAONE-236B-A23B-Mixed-Quant-GGUF`](https://huggingface.co/Baekpica/K-EXAONE-236B-A23B-Mixed-Quant-GGUF), variant **v1** |
|
| 207 |
| Converter / reports | [`Baekpica/k-exaone-mixed-ds4`](https://github.com/Baekpica/k-exaone-mixed-ds4) |
|
| 208 |
|
|
@@ -238,7 +238,7 @@ the single most common way to get wrong kernel results here.
|
|
| 238 |
```bash
|
| 239 |
git clone https://github.com/Baekpica/ds4
|
| 240 |
cd ds4
|
| 241 |
-
git checkout
|
| 242 |
make cuda-spark
|
| 243 |
```
|
| 244 |
|
|
@@ -352,42 +352,48 @@ Raw per-request records ship in the converter repository.
|
|
| 352 |
|
| 353 |
| Prompt tokens | Prefill t/s | Decode t/s | Time to first token |
|
| 354 |
|---:|---:|---:|---:|
|
| 355 |
-
|
|
| 356 |
-
|
|
| 357 |
-
| 8
|
| 358 |
-
|
|
| 359 |
|
| 360 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 361 |
|
| 362 |
-
**Decode cost is linear in context depth:**
|
| 363 |
|
| 364 |
```text
|
| 365 |
-
ms per token =
|
| 366 |
```
|
| 367 |
|
| 368 |
-
**Prefill cost is quadratic in prompt length**
|
| 369 |
-
next 2048 tokens grows linearly with the depth they start at:
|
| 370 |
|
| 371 |
```text
|
| 372 |
-
seconds
|
| 373 |
```
|
| 374 |
|
| 375 |
-
|
| 376 |
|
| 377 |
-
| Context |
|
| 378 |
-
|---:|---:|---:|
|
| 379 |
-
| 8 192 |
|
| 380 |
-
| 32 768 |
|
| 381 |
-
| 65 536 |
|
| 382 |
-
| 131 072 |
|
| 383 |
-
| 262 144 |
|
| 384 |
|
| 385 |
### What that means in practice
|
| 386 |
|
| 387 |
-
The 262 144-token context **fits, is allocated, and is resident**
|
| 388 |
-
|
| 389 |
-
|
| 390 |
-
|
|
|
|
|
|
|
|
|
|
| 391 |
|
| 392 |
**Multi-turn chat reuses the prefix; a cold prompt does not.** A continuation
|
| 393 |
resumes at the point where it diverges from what the session already holds, so
|
|
@@ -415,41 +421,52 @@ than a tunable: the ring is `window + prefill chunk` wide, so a divergence
|
|
| 415 |
further back than about 2 000 tokens falls back to a cold prefill. Typical chat
|
| 416 |
divergence is one assistant turn, well inside it. Requires ds4 at the commit
|
| 417 |
pinned above.
|
| 418 |
-
Concurrency
|
| 419 |
-
|
|
|
|
|
|
|
|
|
|
| 420 |
|
| 421 |
-
| Concurrent streams | Summed decode t/s | Per stream |
|
| 422 |
-
|---:|---:|---:|
|
| 423 |
-
| 1 | 11.
|
| 424 |
-
| 2 |
|
| 425 |
-
| 4 |
|
| 426 |
-
| 8 |
|
| 427 |
-
|
| 428 |
-
|
| 429 |
-
|
| 430 |
-
|
| 431 |
-
|
| 432 |
-
|
| 433 |
-
|
| 434 |
-
|
| 435 |
-
|
| 436 |
-
|
| 437 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 438 |
|
| 439 |
### Where the time goes
|
| 440 |
|
| 441 |
The 12 full-attention layers hold **49 152 bytes of KV per context position**
|
| 442 |
-
(GQA, 8 KV heads × 128 dims, K and V, f16). Decode adds **
|
| 443 |
-
position**
|
| 444 |
-
|
| 445 |
-
|
| 446 |
-
|
| 447 |
-
|
| 448 |
-
|
| 449 |
-
|
| 450 |
-
|
| 451 |
-
|
| 452 |
-
|
|
|
|
|
|
|
| 453 |
|
| 454 |
### OpenAI-compatible API
|
| 455 |
|
|
@@ -496,39 +513,34 @@ model, no second weight copy. It is **opt-in and off by default**:
|
|
| 496 |
speculation for the rest of the session when measured MTP work runs more than
|
| 497 |
3 % slower. `DS4_EXAONE_MTP_NO_QUENCH=1` defeats it, for measurement only.
|
| 498 |
|
| 499 |
-
**It
|
| 500 |
-
|
| 501 |
-
|
| 502 |
-
|
| 503 |
-
|---:|---:|---:|---:|---:|---:|
|
| 504 |
-
| 1 451 | 69.3 % | 204.1 ms | 120.5 | 95.6 | +26 % |
|
| 505 |
-
| 7 924 | 44.3 % | 241.7 ms | 167.5 | 133.7 | +25 % |
|
| 506 |
-
| 32 995 | 34.0 % | 390.3 ms | 291.2 | 281.2 | **+4 %** |
|
| 507 |
-
|
| 508 |
-
The mechanism is a single ratio. A cycle runs one draft pass (~13 ms, roughly
|
| 509 |
-
constant) plus one **two-row** target verify pass. Write **k** for the cost of
|
| 510 |
-
that two-row pass relative to an ordinary one-row decode, and **a** for draft
|
| 511 |
-
acceptance; a cycle commits `1 + a` tokens, so speculation wins exactly when
|
| 512 |
|
| 513 |
-
|
| 514 |
-
|
| 515 |
-
|
| 516 |
-
|
| 517 |
-
|
| 518 |
-
|
| 519 |
-
|
| 520 |
-
|
| 521 |
-
|
| 522 |
-
|
| 523 |
-
|
| 524 |
-
|
| 525 |
-
acceptance
|
| 526 |
-
|
| 527 |
-
|
| 528 |
-
|
| 529 |
-
|
| 530 |
-
|
| 531 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 532 |
|
| 533 |
## Measured quality
|
| 534 |
|
|
@@ -568,23 +580,28 @@ reference's own scores.
|
|
| 568 |
- Evaluation is a 32-prompt fixture set plus the token-fidelity comparison
|
| 569 |
above, not a full benchmark suite. Raw results, including the failures, ship
|
| 570 |
in the converter repository.
|
| 571 |
-
- **256K
|
| 572 |
-
|
| 573 |
-
|
| 574 |
-
|
| 575 |
-
|
| 576 |
-
|
| 577 |
-
the
|
| 578 |
-
|
| 579 |
-
|
| 580 |
- **The MTP block only runs under ds4**, on the pinned branch and commit above.
|
| 581 |
Under llama.cpp it is inert. There is no third runtime that executes it.
|
| 582 |
-
- **MTP is a loss
|
| 583 |
-
|
| 584 |
-
|
| 585 |
- **MTP does not run under `--batched-session`.** ds4 disables speculative
|
| 586 |
decoding whenever native session batching is active, so concurrency > 1 is
|
| 587 |
plain decode regardless of the MTP flags.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 588 |
- **Multi-turn reuse reaches back about 2 000 tokens.** The sliding-window KV
|
| 589 |
ring is `window + prefill chunk` wide, and a resumed prefill needs the window
|
| 590 |
that preceded its restart point. A conversation that diverges further back
|
|
|
|
| 112 |
| BF16 GGUF sha256 | `73be2da8653976df036bf9b6466b011f86cb10f78bab30a47025638ec999d3f8` |
|
| 113 |
| llama.cpp (quantizer) | [`ggml-org/llama.cpp`](https://github.com/ggml-org/llama.cpp) @ `6a32c29a746a2e44de463de647f9f6661eb5086b` (build `b10295`) |
|
| 114 |
| Converter | [`Baekpica/k-exaone-mixed-ds4`](https://github.com/Baekpica/k-exaone-mixed-ds4) |
|
| 115 |
+
| Serving engine (measured below) | [`Baekpica/ds4`](https://github.com/Baekpica/ds4/tree/feature/exaone-model-loader) @ `d35f0dd60af73c22dbd056fdad2eb616781fa6bd` |
|
| 116 |
| — upstream engine | [`antirez/ds4`](https://github.com/antirez/ds4) |
|
| 117 |
| — DGX Spark port | [`Entrpi/ds4-on-spark`](https://github.com/Entrpi/ds4-on-spark) |
|
| 118 |
|
|
|
|
| 202 |
|---|---|
|
| 203 |
| Engine | [`Baekpica/ds4`](https://github.com/Baekpica/ds4/tree/feature/exaone-model-loader) |
|
| 204 |
| Branch | `feature/exaone-model-loader` |
|
| 205 |
+
| Commit | `d35f0dd60af73c22dbd056fdad2eb616781fa6bd` |
|
| 206 |
| Weights | [`Baekpica/K-EXAONE-236B-A23B-Mixed-Quant-GGUF`](https://huggingface.co/Baekpica/K-EXAONE-236B-A23B-Mixed-Quant-GGUF), variant **v1** |
|
| 207 |
| Converter / reports | [`Baekpica/k-exaone-mixed-ds4`](https://github.com/Baekpica/k-exaone-mixed-ds4) |
|
| 208 |
|
|
|
|
| 238 |
```bash
|
| 239 |
git clone https://github.com/Baekpica/ds4
|
| 240 |
cd ds4
|
| 241 |
+
git checkout d35f0dd60af73c22dbd056fdad2eb616781fa6bd
|
| 242 |
make cuda-spark
|
| 243 |
```
|
| 244 |
|
|
|
|
| 352 |
|
| 353 |
| Prompt tokens | Prefill t/s | Decode t/s | Time to first token |
|
| 354 |
|---:|---:|---:|---:|
|
| 355 |
+
| 697 | 51.8 | 10.87 | 13.5 s |
|
| 356 |
+
| 1 896 | 52.8 | 10.17 | 35.9 s |
|
| 357 |
+
| 8 087 | 47.3 | **10.03** | 171.0 s |
|
| 358 |
+
| 33 343 | 32.2 | **8.73** | 1 035 s |
|
| 359 |
|
| 360 |
+
Decode barely falls with depth any more. The engine's flash-decode split
|
| 361 |
+
(2026-08-08) rebuilt the deep-context decode path: the depth term dropped from
|
| 362 |
+
5.88 to 0.61 µs per context position, so a 32K-deep session decodes at 8.7 t/s
|
| 363 |
+
where it managed 3.5 before. An earlier version of this card said the decode
|
| 364 |
+
attention path ran at ~3 % of memory bandwidth; that headroom is now spent.
|
| 365 |
|
| 366 |
+
**Decode cost is linear in context depth, and nearly flat:**
|
| 367 |
|
| 368 |
```text
|
| 369 |
+
ms per token = 94.5 + 0.00061 × context_tokens (4 cells, residuals < 3 ms)
|
| 370 |
```
|
| 371 |
|
| 372 |
+
**Prefill cost is quadratic in prompt length** and is now the one wall left:
|
|
|
|
| 373 |
|
| 374 |
```text
|
| 375 |
+
TTFT seconds = 0.0180 × N + 3.92e-7 × N² (residuals < 0.7 s)
|
| 376 |
```
|
| 377 |
|
| 378 |
+
Extrapolating decode beyond the measured 33K (prefill from the same fit):
|
| 379 |
|
| 380 |
+
| Context | Cold prefill of a full prompt | Decode t/s |
|
| 381 |
+
|---:|---:|---:|
|
| 382 |
+
| 8 192 | 2.6 min (measured) | 10.0 (measured) |
|
| 383 |
+
| 32 768 | 17 min (measured) | 8.7 (measured) |
|
| 384 |
+
| 65 536 | 47 min | 7.4 |
|
| 385 |
+
| 131 072 | 2.3 h | 5.7 |
|
| 386 |
+
| 262 144 | 8.8 h | 3.9 |
|
| 387 |
|
| 388 |
### What that means in practice
|
| 389 |
|
| 390 |
+
The 262 144-token context **fits, is allocated, and is resident**, and decode
|
| 391 |
+
now stays useful an order of magnitude deeper than it used to — 8.7 t/s
|
| 392 |
+
measured at 33K, ~5.7 t/s extrapolated at 128K. What has not moved is the cost
|
| 393 |
+
of getting there cold: prefill is quadratic, a 33K prompt takes 17 minutes and
|
| 394 |
+
a full 256K one would take ~9 hours. **The working-depth limit on one GB10 is
|
| 395 |
+
now set by how long a cold prefill you will tolerate — not by decode.**
|
| 396 |
+
Warm continuations skip it (below).
|
| 397 |
|
| 398 |
**Multi-turn chat reuses the prefix; a cold prompt does not.** A continuation
|
| 399 |
resumes at the point where it diverges from what the session already holds, so
|
|
|
|
| 421 |
further back than about 2 000 tokens falls back to a cold prefill. Typical chat
|
| 422 |
divergence is one assistant turn, well inside it. Requires ds4 at the commit
|
| 423 |
pinned above.
|
| 424 |
+
**Concurrency now helps.** ds4's cross-session row batching (2026-08-08) runs
|
| 425 |
+
concurrent decode steps through one pass — the weight-bound stages are read
|
| 426 |
+
once for all streams — so aggregate throughput rises with load instead of
|
| 427 |
+
staying flat. Steady-state aggregate decode, `--batched-session 8`, short
|
| 428 |
+
prompts, all streams decoding:
|
| 429 |
|
| 430 |
+
| Concurrent streams | Summed decode t/s | Per stream | before row batching |
|
| 431 |
+
|---:|---:|---:|---:|
|
| 432 |
+
| 1 | 11.5 | 11.5 | 11.1 |
|
| 433 |
+
| 2 | 14.8 | ~7.4 | 9.8 |
|
| 434 |
+
| 4 | 16.3 | ~4.1 | 10.0 |
|
| 435 |
+
| 8 | **18.5** | ~2.3 | 10.8 |
|
| 436 |
+
|
| 437 |
+
An operator serving several users sees ~15–18 tok/s of total output; a single
|
| 438 |
+
user still sees the single-stream rate above. The remaining per-row floor is
|
| 439 |
+
mostly the routed experts — concurrent tokens route to largely disjoint
|
| 440 |
+
top-8-of-128 sets, so that read genuinely cannot amortise — plus the per-row
|
| 441 |
+
attention, which is per-session by construction.
|
| 442 |
+
|
| 443 |
+
A prefill no longer blocks the batch either: a pending prefill quantum rides
|
| 444 |
+
the decode batch's weight sweep (`+prefill` in the batch log), so admitting a
|
| 445 |
+
new long prompt costs the running streams far less than alternating whole
|
| 446 |
+
passes did.
|
| 447 |
+
|
| 448 |
+
One contract changed with row batching: **greedy output across batch widths is
|
| 449 |
+
not bit-stable at near-ties**. A request decoded alongside seven others can
|
| 450 |
+
pick a different token than the same request alone where the top-2 margin is
|
| 451 |
+
tiny, deterministically per batch composition. Sequential (width-1) decode is
|
| 452 |
+
unchanged, and the same batch always reproduces the same output.
|
| 453 |
|
| 454 |
### Where the time goes
|
| 455 |
|
| 456 |
The 12 full-attention layers hold **49 152 bytes of KV per context position**
|
| 457 |
+
(GQA, 8 KV heads × 128 dims, K and V, f16). Decode adds **0.61 µs per context
|
| 458 |
+
position** — an effective ~81 GB/s of KV read against roughly 273 GB/s of
|
| 459 |
+
device bandwidth. An earlier engine paid 5.97 µs here (~3 % of bandwidth,
|
| 460 |
+
one attention block per head); the flash-decode split closed most of that,
|
| 461 |
+
and what remains splits between the depth-independent floor (~94 ms/token,
|
| 462 |
+
streaming the active weights, near the roofline) and the last ~3× of the
|
| 463 |
+
attention read.
|
| 464 |
+
|
| 465 |
+
Prefill keeps the one-block-per-(token, head) attention kernel and its
|
| 466 |
+
quadratic term is now the dominant cost of deep contexts. For scale: ds4's
|
| 467 |
+
tuned MLA path on DeepSeek V4 Flash reaches 825 t/s prefill on this same GB10
|
| 468 |
+
and is nearly flat with depth, where `exaone-moe` prefill roughly halves every
|
| 469 |
+
4× — that gap is the open kernel problem, not decode.
|
| 470 |
|
| 471 |
### OpenAI-compatible API
|
| 472 |
|
|
|
|
| 513 |
speculation for the rest of the session when measured MTP work runs more than
|
| 514 |
3 % slower. `DS4_EXAONE_MTP_NO_QUENCH=1` defeats it, for measurement only.
|
| 515 |
|
| 516 |
+
**It is close to a wash now, and still not a win.** Measured with the quench
|
| 517 |
+
defeated so the whole generation is speculative, on the engine's current
|
| 518 |
+
kernels (the two-row verify rides the same aligned-dispatch, small-batch and
|
| 519 |
+
flash-decode tiers as everything else):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 520 |
|
| 521 |
+
| Context | Draft acceptance | MTP ms/token | Plain ms/token | vs plain |
|
| 522 |
+
|---:|---:|---:|---:|---:|
|
| 523 |
+
| 1 387 | 36.6 % | 108.8 | 98.3 | +11 % |
|
| 524 |
+
| 7 752 | 60.8 % | 102.5 | 99.7 | **+2.8 %** |
|
| 525 |
+
| 33 914 | 37.0 % | 142.8 | 114.5 | +25 % |
|
| 526 |
+
|
| 527 |
+
The mechanism is a single ratio: a cycle runs one draft pass plus one
|
| 528 |
+
**two-row** target verify pass; with **k** the verify's cost relative to a
|
| 529 |
+
one-row decode and **a** the acceptance, a cycle commits `1 + a` tokens and
|
| 530 |
+
wins exactly when `k < 1 + a`. An earlier engine paid k ≈ 2 at shallow depth
|
| 531 |
+
because its two-row pass re-read the weights per row; that k is now near its
|
| 532 |
+
floor, which moved MTP from a 26–50 % loss to the table above. What remains
|
| 533 |
+
is acceptance: at the 3 % quench threshold the 8K row is already a wash, and
|
| 534 |
+
five to ten more points of acceptance — a warmed MTP ring instead of a cold
|
| 535 |
+
128-row one, or corpus luck — is the difference between off and on.
|
| 536 |
+
|
| 537 |
+
Acceptance numbers are a property of the text (they moved 20 points between
|
| 538 |
+
corpus slices in these very measurements); compare k across runs, not
|
| 539 |
+
acceptance.
|
| 540 |
+
|
| 541 |
+
**MTP stays off by default.** The auto-quench makes `--exaone-mtp` safe to
|
| 542 |
+
try on workloads where drafts land often; nothing here changes greedy output
|
| 543 |
+
either way.
|
| 544 |
|
| 545 |
## Measured quality
|
| 546 |
|
|
|
|
| 580 |
- Evaluation is a 32-prompt fixture set plus the token-fidelity comparison
|
| 581 |
above, not a full benchmark suite. Raw results, including the failures, ship
|
| 582 |
in the converter repository.
|
| 583 |
+
- **256K remains gated by cold prefill, not decode.** Decode now holds 8.7 t/s
|
| 584 |
+
at a measured 33K and ~4 t/s extrapolated at the full context, but a cold
|
| 585 |
+
256K prefill still takes ~9 hours. Deep contexts are practical exactly when
|
| 586 |
+
they are reached warm — through prefix reuse — rather than cold.
|
| 587 |
+
- **Prefill is quadratic in context depth and is the one wall left.** The
|
| 588 |
+
decode-side headroom an earlier version of this card described is spent: the
|
| 589 |
+
flash-decode split brought the depth term from 5.88 to 0.61 µs per position.
|
| 590 |
+
The prefill attention kernel keeps the exact one-block form; a tiled variant
|
| 591 |
+
measured a wash and a tensor-core revision is the known next step.
|
| 592 |
- **The MTP block only runs under ds4**, on the pinned branch and commit above.
|
| 593 |
Under llama.cpp it is inert. There is no third runtime that executes it.
|
| 594 |
+
- **MTP is a mild loss (3–25 % by depth and corpus)**, so it ships off by
|
| 595 |
+
default and auto-quenches when enabled. Its verify cost is now near its
|
| 596 |
+
floor; the remaining limit is draft acceptance.
|
| 597 |
- **MTP does not run under `--batched-session`.** ds4 disables speculative
|
| 598 |
decoding whenever native session batching is active, so concurrency > 1 is
|
| 599 |
plain decode regardless of the MTP flags.
|
| 600 |
+
- **Greedy output across batch widths is not bit-stable at near-ties.** A
|
| 601 |
+
request decoded alongside others can pick a different token than the same
|
| 602 |
+
request alone where the top-2 margin is tiny; the same batch composition
|
| 603 |
+
always reproduces the same output, and width-1 decode is unchanged. This is
|
| 604 |
+
the standard batched-inference contract.
|
| 605 |
- **Multi-turn reuse reaches back about 2 000 tokens.** The sliding-window KV
|
| 606 |
ring is `window + prefill chunk` wide, and a resumed prefill needs the window
|
| 607 |
that preceded its restart point. A conversation that diverges further back
|