问题 / #2412
#2412 Arc B390 (Panther Lake iGPU, xe): SYCL port runs; long outputs degenerate; TTM page pool hides ~30 GB from MemAvailable
open · @hansy2 · 0 评论 · 去 GitHub 看
BenchmarksSetup & installServer & APINVIDIA / CUDAModels & quantsLinux
说明
### Summary
The experimental SYCL port runs on the **Arc B390 iGPU (Panther Lake, `xe`)** on Linux without code changes. This consolidates an earlier comment on #515 (now removed) and follow-up tests. It covers short-answer performance, a reproducible problem with **long outputs degenerating**, and a memory finding on shared-memory iGPUs: **the TTM page pool hides up to half the RAM from `MemAvailable`**. The last point relates to the `MemAvailable` finding in #2282 (Meteor Lake iGPU).
### System
- Intel Core Ultra X7 358H (Panther Lake, AVX2, no AVX-512)
- Arc B390 iGPU (`8086:b080`, driver `xe`), 61 GiB LPDDR5X shared with the GPU
- Ubuntu 26.04, kernel 7.0.0-38, compute runtime `libze-intel-gpu1` / `intel-opencl-icd` 26.05.37020.3
- Strata `296b59d2` (engine 0.1.44.1)
- Model: Qwen3.8-Flash-Next Coder IQ1_M, 8-12K context, fp16 KV, MTP draft layer built by `mtp_fetch.py` / `mtp_pack.py` / `mtp_rt.py`
**Build without Docker or root:**
- oneAPI 2026.1 from conda via micromamba: `dpcpp_linux-64=2026.1 mkl-devel-dpcpp=2026.1 level-zero-devel cmake ninja`
- `cmake -S sycl -B build-sycl -G Ninja -DCMAKE_C_COMPILER=icx -DCMAKE_CXX_COMPILER=icpx -DSTRATA_SYCL_PARITY=OFF`
- JIT build, 2m17s, 0 errors
`sycl-ls`: `[level_zero:gpu][level_zero:0] Intel(R) oneAPI Unified Runtime over Level-Zero V2, Intel(R) Graphics [0xb080] 30.0.4 [1.14.37020]`
Command used (`--expert-cache` given explicitly, see section 3):
```
STRATA_VERIFY_DEVICE_PLAN=1 STRATA_VERIFY_NO_HOST=1 STRATA_STAGER_THREADS=12 SYCL_CACHE_PERSISTENT=0 \
build-sycl/strata --pack packs/coder-iq1_m --native <IQ1_M-00001> --ple-gguf <IQ1_M-00002> \
--expert-profile data/expert-profile-coder.bin --expert-cache 12288 --stream-experts --prefill auto \
--spec 4 --spec-min-p 0.5 --mtp mtp/rt --max-context 8192 --tokens-file prompt.txt --max-new N [--greedy | --seed 42 --temperature 0.6 --top-p 0.95 --top-k 20]
```
### 1. Performance: works, short answers are correct
| run | prompt | decode | drafts accepted |
|---|---|---|---|
| no `--mtp` (suffix drafts only), first start incl. JIT | 36 tok, 4.9 tok/s | 11.5 tok/s | 2% |
| `--mtp`, short code answer (256 tok) | 36 tok, 24.4 tok/s | **28.6 tok/s** | 82.5% |
| `--mtp`, 1,966-token code-review prompt (300 tok) | **255 tok/s** | **21.7 tok/s** | 63.8% |
| `--mtp`, long generation (7,000-8,000 tok) | 667 tok, 172-276 tok/s | 19-41 tok/s | 55-96% (see 2.) |
- All 12,288 experts are resident: 23.42 GiB, profile fill in 10-16 s.
- Short answers are correct and coherent: an `is_prime` function, and a correct explanation of a 2K-token Python file. The German question got a partly English answer.
- No xe errors, GT resets or OOM in the kernel log.
- Only one CPU core is busy during decode (the host thread). The pool workers are idle, since no expert runs on the CPU.
### 2. Long outputs degenerate (3 of 3 runs)
**Task:** a single-file HTML page (668-token prompt, German, full prompt below), `--max-new 7000-8000`, `--max-context 12288`.
| run | sampling | experts | what happened | position where it broke |
|---|---|---|---|---|
| A | greedy | 12,288 resident | ~3K tokens of good CSS, then the same 8 CSS lines repeated 14x, then trailing off | ~3,305 |
| B | seed 42, T 0.6, top-p 0.95, top-k 20 | 11,361 resident + 927 mirrored (MemAvailable was low, see 3.) | `<!DOCTYPE html>` / "I'm stuck in a loop. Let me write it." repeated ~800x from the start | ~700 |
| C | same as B | 12,288 resident | good CSS + header, then "We haben ..." and "dazu dazu dazu ..." for thousands of tokens | ~5,653 |
- No `<|im_end|>` was ever produced.
- Acceptance went up in the loops (B: 95.8%, 5.0 tokens per round), so the drafter happily follows the repetition.
- Up to ~2,300 positions (the 2K-prompt run) the output was fine.
- I can't tell whether this is the IQ1_M Coder itself (half the experts, ~1.75 bit) or the SYCL port's numerics at longer positions. **Could you check the same prompt on a B70 or CUDA?** If it is the model, a note in MODELS.md ("Coder: long free-form generations may loop") would help.
<details><summary>The prompt (German)</summary>
```
Erstelle eine vollständige, moderne Webseite als EINE einzige HTML-Datei (CSS und JavaScript inline, keine externen Dateien, keine CDN-Links). Sprache: Deutsch.
Thema: "Strata auf der Intel Arc B390 – ein Praxistest". Strata ist eine Open-Source-Inferenz-Engine, die das 125-Milliarden-Parameter-MoE-Modell Qwen3.8-Flash-Next auf normaler Hardware ausführt. Wir haben die experimentelle Intel-Version (SYCL/oneAPI) auf einem Mini-PC mit integrierter Grafik getestet, obwohl diese offiziell noch nicht unterstützt wird.
Testdaten:
- Hardware: Intel Core Ultra X7 358H (Panther Lake), integrierte Arc B390, 61 GiB gemeinsamer RAM, Ubuntu 26.04
- Modell: Qwen3.8-Flash-Next Coder IQ1_M, alle 12.288 Experten im GPU-Speicher (23,4 GiB)
- Installation ohne Docker und ohne Root, Compiler oneAPI 2026.1, Build in 2 Minuten ohne Fehler
- Lauf 1 ohne MTP: 11,5 Token/s Ausgabe, 2 % Entwürfe angenommen
- Lauf 2 mit MTP (Entwurfsschicht): 28,6 Token/s Ausgabe, 82,5 % Entwürfe angenommen
- Lauf 3 mit 1.966-Token-Prompt: Prompt 255 Token/s, Ausgabe 21,7 Token/s
- Zum Vergleich: qwen3-coder über OpenVINO auf derselben Maschine ca. 53 Token/s
- Kein Treiberfehler, kein Absturz
- Entdeckung: Nach jedem Lauf bleiben ~30 GB als "belegt" angezeigt. Das ist kein Leck, sondern der Seiten-Pool des xe-Treibers; der Kernel gibt ihn unter Speicherdruck zurück (getestet mit 58 GiB).
- Der Bericht wurde an die Entwickler auf GitHub geschickt (Issue #515).
Anforderungen:
1. Dunkles, modernes Design mit Akzentfarbe Cyan, gut lesbar, responsiv (funktioniert auf dem Handy).
2. Abschnitte: Kopfbereich mit Titel und kurzer Einleitung, "Was ist Strata?", "Testaufbau", "Ergebnisse" (Tabelle), ein Balkendiagramm der Ausgabegeschwindigkeit aller vier Werte (selbst gezeichnet mit SVG oder CSS, keine Bibliothek), "Die Speicher-Entdeckung", "Fazit".
3. Eine feste Navigationsleiste oben, die zu den Abschnitten springt (weiches Scrollen), und die den aktiven Abschnitt beim Scrollen hervorhebt.
4. Die Balken im Diagramm sollen beim ersten Sichtbarwerden animiert hochwachsen.
5. Sauberer, gültiger HTML5-Code.
Gib nur den HTML-Code aus, in einem einzigen ```html-Block, ohne weitere Erklärung.
```
Wrapped in `<|im_start|>user\n…<|im_end|>\n<|im_start|>assistant\n<think>\n\n</think>\n\n` (thinking off).
(The prompt's sentence about the memory pool reflects what I believed at the time. Section 3 is the corrected finding.)
</details>
### 3. Shared-memory iGPU: the TTM page pool hides memory from `MemAvailable`
**What happens:** after the engine exits, ~30 GB stay "used". No process holds an xe fd, and the memory does not count in `MemAvailable`. The cause is the kernel's **TTM page pool**, which keeps the freed write-combined pages:
- `/sys/kernel/debug/ttm/page_pool` showed 7,822,251 pages (29.8 GiB), almost all order-10 WC pages.
- Its limit, `/sys/module/ttm/parameters/page_pool_size`, defaults to half the RAM (8,033,006 pages).
**Why it matters for Strata:**
- **The pool's shrinker is unreliable.** Once, allocating 58 GiB got everything back. Later, under the same pressure, the kernel swapped 5.8 GB of other processes instead and the pool stayed full.
- **A second start then sees too little memory.** With half the RAM held in the pool, the engine reduced the cache: an explicit `--expert-cache 12288` became 11,361 slots once, and 223 slots another time. My memory guard then killed that run at 5 GB `MemAvailable`. This is the same `MemAvailable` dependency described in #2282.
- On kernel 7.0, `/proc/meminfo` also showed `GPUActive: 153183560 kB` (more than the RAM) and `GPUReclaim: 0`. That looks like a kernel accounting bug, not Strata's.
**Workaround** (it worked here, the memory came back without swapping):
```
echo 1048576 | sudo tee /sys/module/ttm/parameters/page_pool_size # cap the pool at 4 GiB
echo "options ttm page_pool_size=1048576" | sudo tee /etc/modprobe.d/ttm-pool.conf && sudo update-initramfs -u
```
**Suggestion for the iGPU memory planning:** setup and the engine could read `/sys/module/ttm/parameters/page_pool_size` and warn when it is large on an integrated GPU. They could also count the pool as reclaimable, since a large pool makes `MemAvailable` too low right after a previous run.
### 4. Safety note for others testing on an iGPU
On `xe`, a GPU allocation past what is free can livelock the machine (INTEL.md describes this for the B70). On an iGPU all of it is system RAM, so I ran every test with a small watchdog. It polls `MemAvailable` every 0.2 s and sends SIGKILL to `strata` below 6 GB. It fired once (see 3.), and the machine stayed fine.
Happy to run more tests on the B390 (other flags, `--serve`, a gate, a patched build) if useful.
本站相关内容
相关页面的快捷入口。