Characterization (reference): two-model co-residency on an Arc 140V (Lunar Lake) iGPU — a resident Qwen3-14B falls to ~1% under concurrent SDXL; the bottleneck is GPU compute-scheduling, not bandwidth or clock. Methodology + numbers #36604
Replies: 1 comment
|
Two small follow-ups on this post. Clarifying the prefill figure. The ≈1960 tok/s prefill rate I cite above is measured prefix-cache-warm — the single-model probe runs with prefix caching on over a repeated prompt set, so it's an upper bound for repeated prompts that hit the KV cache, not a cold first-prompt rate. With a dedicated cold prefill harness (prefix-caching off) the same 14B reads ≈595–761 tok/s at 512 tokens (2026.1.0 → 2026.2.1). Both are valid — they're just different regimes — but for a cold / first-prompt or cross-runtime Follow-up post. I re-measured this stack across the OpenVINO GenAI 2026.1.0 → 2026.2.1 bump (same hardware, same driver 32.0.101.8826, same methodology): cold prefill is ≈28–36% faster and the VLM TTFT ≈19% faster (token generation unchanged), the co-residency pattern here reproduces (a smaller N=1 confirmatory pass — the N=3 variance study stays the one in this post), and there's a GPU-vs-CPU draft-device result + a 30B MoE accuracy-flag cost. Full numbers: #36626. The dataset has been extended with the 2026.2.1 splits and a cold/warm-prefill reconciliation note. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
TL;DR. On one Intel Core Ultra 7 258V (Lunar Lake) laptop with the integrated Arc 140V (Xe2) iGPU and 31.323 GiB of shared LPDDR5X, two models run within the iGPU's 27.3 GiB shared-memory window without out-of-memory (peak co-resident 24.5–27.6 GiB total unified-pool system-RAM across four pairings) and idle co-residence is near-free, but concurrent generation saturates the GPU. A resident Qwen3-14B INT4 (speculative decoding on, ≈19.8 tok/s alone) retains only ≈1% of its decode throughput while an SDXL diffusion runs on the same iGPU, and ≈13–17% under a bandwidth-bound vision model or a style-LoRA SDXL case. In every contention phase the GPU sits at ≈99% busy, pinned near 1.95 GHz with zero throttle reported and the NPU at 0 W — so the bottleneck reads as execution-unit occupancy / compute scheduling, not frequency, thermal, or memory bandwidth. Underneath that sit the table-stakes single-model numbers (14B decode 11.1 → 17.1 tok/s spec off→on; 8B 19.8 → 27.4; 30B-A3B MoE 38.1) and a dense-vs-MoE prefill/decode mirror-image. This is reference data shared for comparison and correction — not a bug report, and not a benchmark contest with any other runtime. I'd genuinely value methodology critique and suggestions for what to measure next; specific asks are at the end.
AI-assisted contribution, to be upfront: the benchmark numbers here are real, first-hand measurements — run on my own hardware (the 258V / Arc 140V above) via OpenVINO, and reproducible from the methodology below. The harnesses, the analysis, and this write-up were drafted with an AI assistant working under my direction; I have reviewed and verified every number and claim and take full responsibility for them. The numbers come from measurement runs, not from a model. Methodology critique and corrections are especially welcome.
Raw data. Per-run measurements + the dataset card are published as a CC-BY-4.0 dataset → https://huggingface.co/datasets/blairducrayoppat/openvino-arc140v-lunarlake
This continues a prior reference characterization on the same hardware: #36484
Setup
Hardware
Software
Models (all weights quantized; all inference on the iGPU)
Method
max_new_tokens=1.ut.exe) — Intel SoC Watch for energy→power (averaged as total mJ / total ms; peaks taken over 1 s windows to avoid sub-millisecond glitches), SoC/CPU temperature, throttle reason, and NPU power; Level Zero for GPU core frequency, GPU-busy %, and memory read/write rate. Samples are segmented into phases by wall-clock boundaries the harness emits.Results
All numbers are scoped to the single machine, driver, runtime, and models above — a reference point, not a population estimate.
1. Two-model co-residency on the same iGPU (the novel part)
Memory fit — every pairing completed without out-of-memory within the iGPU's 27.3 GiB shared-memory window (the 87% override). The peaks (24.5–27.6 GiB) are total unified-pool system-RAM — an upper bound on the iGPU's own allocation, not the GPU slice alone — so the exact headroom against the 27.3 GiB window isn't isolated; what is clear is that the override is required and the heavy pairings push total use into the high-20s GiB (the resident Qwen3-14B INT4 spec-on plus the partner).
The +style-LoRA case is the tightest — its 27.59 GiB total system-RAM peak even slightly exceeds the 27.3 GiB iGPU window, which (since the run completed without OOM) means its GPU-side slice stayed under the window while host-side memory makes up the difference. (The headroom column above is against the 31.323 GiB total pool, not the GPU window.)
Resident 14B throughput across states (mean over N=3; ± = standard deviation):
Idle co-residence is effectively free for the SDXL partners (baseline vs idle within run-to-run noise) and a consistent ≈5% for the vision model (18.10 vs 19.13 tok/s). Under concurrent generation the picture splits sharply by partner type: the two plain SDXL diffusions drive the resident 14B to ≈1% retained (0.22 / 0.19 tok/s) — the 14B cannot even finish its prefill inside the window, hence the ≈13.6–14.9 s contention TTFT — while the bandwidth-bound vision model and the +style-LoRA SDXL case are milder at ≈13–17% retained. (The co-residency baseline ≈19.8 tok/s comes from this harness's sustained back-to-back probe and reads a little higher than the single-model spec-on median of 17.07 tok/s in §2 — a different probe; the retained-% figures are relative to this harness's own baseline.)
Per-phase GPU telemetry (Intel UT; idle vs contention phase, mean over N=3):
| Partner | GPU busy idle % | GPU busy contention % | GPU freq contention (MHz) | Throttle (max) | Mem read idle (GB/s) | Mem read contention (GB/s) | iGPU rail idle (W) | iGPU rail contention (W) | NPU (W) | SoC peak (°C) |
|---|---|---|---|---|---|---|---|---|---|---|---|
| RealVisXL V5.0 (SDXL) | 90.8 | 99.9 | 1933.7 | 0.0 | 72.5 | 23.6 | 8.59 | 11.61 | 0.0 | 81.0 |
| SDXL base 1.0 | 90.3 | 99.8 | 1939.1 | 0.0 | 69.2 | 21.3 | 8.53 | 11.00 | 0.0 | 82.3 |
| SDXL base 1.0 + style LoRA | 82.2 | 98.8 | 1946.0 | 0.0 | 57.3 | 47.0 | 8.38 | 8.61 | 0.0 | 80.0 |
| Qwen3-VL-8B-Instruct | 88.2 | 98.7 | 1948.8 | 0.0 | 66.7 | 61.3 | 8.10 | 8.30 | 0.0 | 80.0 |
Units note (memory bandwidth). The memory-bandwidth metric (
GPU_MEMORY_BYTE_*_RATE) is in GB/s — Intel's OA metric definition for Lunar Lake declares itunits="gbps"(the raw byte counter divided by GPU time), per Mesa'soa-lnl.xml; the capture tool reports the unit as N/A, but the definition is explicit. The ≈108 GB/s peak in the raw per-run data is ≈79% of the 136 GB/s LPDDR5X ceiling.Across every pairing the GPU goes to ≈99% busy under contention and stays pinned near 1.95 GHz with zero throttle reported, the NPU at 0 W, SoC peak 80–82°C. With clock flat, nothing throttling, and the NPU idle, the resident model's starvation reads as execution-unit occupancy / compute scheduling, not frequency, thermal, or bandwidth. The raw vector-engine counter supports this:
XVE_ACTIVEsits at only ≈20–31% under contention (photoreal 30.8%, illustration 27.7%, cartoon 21.5%, VLM 20.0%) even as GPU-busy hits ≈99% — the GPU is occupied, not vector-compute-saturated, so what is scarce is scheduling slots rather than raw vector throughput. The memory-bandwidth signature is consistent with that reading: under the compute-bound SDXL partners the aggregate read-rate falls under contention (e.g. 72.5 → 23.6 GB/s — the 14B's bandwidth-bound decode can't win compute slots to issue its reads), whereas the bandwidth-bound vision model keeps it high (66.7 → 61.3). The iGPU rail also draws more under the plain SDXL partners (≈8.5 → 11.6 W) while the 14B still starves — consistent with the diffusion monopolizing the EU scheduler rather than the link or the clock.2. Single-model decode, prefill, and TTFT (table-stakes, with the MoE and spec-decode shapes called out)
All models INT4; all rows = 20 measured generations + 2 warm-up over a fixed 4-prompt set, greedy/temperature 0, on the iGPU. † spec-decode draft = Qwen3-0.6B pruned-6-layer INT8, also on the GPU. * spec-on prefill is a backend artifact (a single-token probe still pays draft+target overhead under speculative continuous batching); prefill is config-independent, so cite the spec-off prefill (≈1960 tok/s) as the rate.
MoE profile. The Qwen3-Coder-30B-A3B MoE (≈3B active params per token) has the fastest decode and lowest TTFT of the set — 38.06 tok/s, 213.8 ms — but the slowest prefill (480.1 tok/s vs ≈1960 for the dense 14B/8B). It activates only ≈3B params per decode step, yet routes every prompt token through the full expert set at prefill, so it pays roughly full-≈30B compute on the prompt. This dense-vs-MoE prefill/decode mirror-image is the most transferable shape here. (Measured on OVMS 2026.2 / continuous batching, vs OV GenAI 2026.1.0 in-process for the dense pair — see Caveats on the cross-runtime prefill comparison.)
Speculative decoding. The Qwen3-0.6B (pruned-6-layer INT8) GPU draft lifts decode median ≈1.5× on the 14B (11.13 → 17.07 tok/s) and ≈1.4× on the 8B (19.79 → 27.37), at near-unchanged 14B TTFT (466 → 471 ms) and a modest 8B TTFT rise (264 → 313 ms, ≈+19%). Mean and P95 are included so the run-to-run spread is visible alongside the median.
Caveats and what I did not measure
Feedback I'd especially value
I'm a non-expert measuring carefully on one machine, so methodology critique is the most useful thing anyone can offer. The specific places I'd most like to be checked:
max_new_tokens=1probe. How does that line up with a community standard such aspp512, so these numbers are comparable to others'?What would be useful to measure next?
Open to suggestions — current candidates, roughly in order of how often they seem to come up:
If one of these would be more useful to you than the others — or there's an obvious omission — please say so.
Thanks for reading; corrections, replications on other Lunar Lake units, and "you measured the wrong thing" are all genuinely welcome.
All reactions