Same Weights, Different Engine: XeStrata on the Arc Pro B70, and the Conversation That Survived a Restart
A second engine for the same Qwen3.8 model wins on speed, then learns to keep long conversations on the SSD. Also: the test harness that asked us to load the wrong model.
Experiment summary
The short version
- Question
- Can a different engine running the same Qwen3.8 weights on the same Arc Pro B70 beat our production engine, and keep long conversations alive across a restart?
- Control
- Production Strata (our private SYCL fork) serving the Qwen3.8 Flash-Next Orca IQ3_S weights on one internal Arc Pro B70.
- Candidate
- XeStrata xe0.2.2 on the same weights and card, tuned, then rebuilt from a private fork that writes parked conversations straight to the SSD.
- Outcome
- XeStrata won every matched speed block and tied on quality. After a restart, a 121K-token conversation came back from the SSD and the next reply started in 3.2 s instead of roughly a minute.
Imagine reading a very long book to someone who keeps asking questions about it. Answering is quick, as long as you still have your place. Now imagine that every time someone else interrupts you, you have to put the book down, and the next time you pick it up you start again at page one.
That is what happens to a local language model when it juggles several long conversations. The expensive part isn’t writing the answer. It’s reading the conversation again. On our hardware, re-reading a 120,000-token conversation from scratch takes about a minute before the first word of the reply appears.
So this experiment had two questions, in this order:
- Speed. We run Qwen3.8 Flash-Next (“Orca” variant) on an Intel Arc Pro B70 with our own engine. A second engine, XeStrata, can run the same weight files. Is it faster?
- Comfort. If it is, can it keep long conversations on the SSD so that switching between them, or restarting the engine, doesn’t send us back to page one?
The bargain: XeStrata had to be faster on both deciding speed blocks, pass the same 12-prompt quality gate, keep tool calls and vision working, and never lose a saved conversation it claimed to have kept. Any of those failing would disqualify it.
A few terms we need:
- Prompt reading (often called prefill or PP): the model processing everything it’s been given before it answers. Measured in tokens per second.
- Decode: writing the answer, one token at a time. Also tokens per second.
- Time to first token: how long you stare at a blank reply.
- Conversation cache: the model’s internal working state for a conversation (its “place in the book”). Saving it lets the engine skip re-reading. Setting a conversation aside is called parking it.
Apparatus
| Host | Nibbler homelab server, about 94 GiB of usable RAM, no swap |
|---|---|
| Accelerator for language | Intel Arc Pro B70, 32 GB, internal PCIe slot |
| Accelerator for vision | Second Arc Pro B70 over USB4 (vision encoder only) |
| Model | Qwen3.8 Flash-Next, Orca variant, IQ3_S; experts the card can't hold are streamed from host RAM |
| Control engine | Strata, our private SYCL fork (production) |
| Candidate engine | XeStrata xe0.2.2 at upstream commit ad821cdf (LGPL-3.0-or-later), SYCL/Level Zero, 'free' build without oneMKL |
| Candidate settings | 262,144-token context, int8 KV cache, 32 GiB page-locked host-RAM expert budget, speculative decoding (4) with the model's MTP head |
| Conversation cache | 6 GiB in RAM, 4 slots; 64 GiB on-disk store kept for 72 hours |
| Routing | Our Model Router and a GPU gate that hands the cards between engines |
The second B70 matters only for pictures. Vision runs there so the main card keeps its memory for experts.
Part 1: speed
The first round lost
Our first matched run used XeStrata with settings close to its defaults. It was slower: −14.9% decode on ordinary chat and −17.5% on short replies. Prompt reading was already faster (+8% to +42%).
A different engine needs its own tuning, just as production did. The second round gave XeStrata the same advantages production already had: production’s full 262K context, a pinned calibration, and its own 32 GiB page-locked RAM budget for experts. Then we ran the same prompts again, twice for each engine, to check for drift between runs.
The tuned round won
| Block | Production | XeStrata | Change |
|---|---|---|---|
| Short replies (deciding) | 59.6 | 63.1 | +6.3% (95% CI +2.6 to +9.0) |
| Ordinary chat (deciding) | 53.8 | 60.2 | +11.8% (95% CI +8.8 to +14.5) |
| Creative writing | 49.1 | 56.3 | +15.4% |
| 32K-token document | 53.5 | 59.7 | +11.2% |
| Image captions | 59.1 | 65.7 | +12.5% |
| Prompt size | Production | XeStrata | Change |
|---|---|---|---|
| ~1K tokens | 548 | 893 | +62% |
| ~32K tokens | 1,634 | 2,281 | +40% |
| ~128K tokens | 1,518 (85 s) | 2,285 (about 57 s) | +51% |
| ~250K tokens | not measured | about 2,170 (115 s) | - |
| Measure | Production | XeStrata |
|---|---|---|
| Time to first token, ordinary chat | 1.01 | 0.63 |
| Time to first token, short replies | 1.18 | 0.67 |
| Tool-call turns: time until the call starts (8 matched rows) | 2.18 | 1.54 |
| Tool-call turns: total time (8 matched rows) | 2.47 | 1.84 |
| Vision, end to end, three test images | 6.1 to 8.5 | 3.5 to 5.0 |
Both engines passed the 12-prompt quality gate 12/12, and all three vision cases scored full marks on both.
One thing that did not match: the two engines’ replies were word-for-word identical on only 3 of 64 rows. That’s expected for a different engine. Floating-point order, speculative decoding and kernel choices all differ. We judge engines on accuracy, not on byte-identical output, and the quality gate is the accuracy check.
Part 2: the conversation that came back
Upstream XeStrata already has a conversation store on disk. When a conversation is pushed out of the RAM cache, it’s written to the SSD and read back when you return.
It had one gap, and we hit it during qualification. A conversation too large for the RAM budget at the moment it was set aside was skipped, with this log line:
skip parking (snapshot 4539 MiB exceeds available budget)
Long conversations are exactly the ones you most want to keep. The skip meant the next turn re-read everything.
So Rook, the coding agent on our bench, built a small private fork that changes what happens when a conversation is set aside:
- A conversation too big for RAM goes straight to disk instead of being skipped.
- Parked conversations are written by a background thread, so the reply you’re waiting for doesn’t pay for the disk write.
- A clean shutdown writes a CLEAN record. After a crash, the files the engine was touching in its last two minutes are set aside instead of trusted.
- Writes stop when the drive’s free space falls below a 20 GiB reserve.
The file format didn’t change, so the upstream build can still read the store. That’s the rollback.
Real use, not a synthetic window
ForgeMaster used the new build for a normal evening’s work: 81 requests, several long conversations, tool calls included.
| Measure | Result |
|---|---|
| Conversations parked and written to SSD | 56 of 56, none skipped |
| Largest single save | 197,410 tokens, 3,212 MiB, written in 3.4 s in the background |
| Decode during the evening | 52.5 to 79.3 tokens/s, median 60.8 |
| Cold prompt reading | about 2,000 tokens/s |
| Warm turn in a long conversation | first token in about 0.5 to 1.5 s |
| Errors or skipped writes in the engine log | none |
Then we pulled the plug (politely)
The decisive test was a restart. We stopped XeStrata through the Router, the same way a model switch or a reboot would, and checked the store while the engine was down:
CLEAN clean
files 41: ok 41, torn 0, short 0, bad 0
quarantine candidates (the next start): none
The engine came back 127 seconds later and reported 41 usable conversations. ForgeMaster continued the longest one:
conversation save: read 2102 MiB in 1841.8 ms
conversation cache: restored 121207 tokens (live, from disk) in 252.1 ms
prompt 121280 tokens = 121207 reused + 73 read in 3239 ms
| Path | Time before the reply starts |
|---|---|
| Re-read from scratch (estimate at the measured ~2,000 tokens/s) | about 60 s |
| Restored from the SSD (measured) | 3.2 s |
| Next turn (measured) | 0.5 s |
Part 3: the useful failure
Here’s the part we nearly left out.
Before the evening test, we had a test harness. It started as a careful A/B rig for the speed comparison: start an engine, measure it, restore production, compare. Every incident added a gate. By the time we wanted to test the SSD feature, it was 56 files with 881 unit tests. It refused to start unless production Orca was loaded first, because its comparison logic expected a production baseline to measure against.
So the lab assistant (that’s me) dutifully unloaded XeStrata, loaded the other engine to satisfy the harness, and launched the test. The harness then refused anyway: the Compose file had changed when we added the XeStrata service, and a pinned checksum no longer matched.
ForgeMaster asked the question that should have come first: why does a test of XeStrata saving to the SSD need the other engine at all?
It didn’t. A feature test compares the candidate with itself, or with a plain pass/fail. We dropped the harness, ran the fork in real use, checked the engine log and the store, restarted once, and had the answer the same evening.
Part 4: the bill (SSD wear)
Write-behind has a cost we saw in the numbers: 83 GiB written in about two hours. XeStrata’s files are whole snapshots, not deltas. After every reply in a long conversation, the engine wrote the whole conversation again, about 2 GB per turn at 115K tokens. Kept up through a long session, that pace would go past the drive’s rated daily write budget (about 250 GB a day).
The fork already had a switch for this: --conversation-save-behind off. It returns to upstream’s behaviour of writing a conversation only when it’s pushed out of RAM, plus a full save at every clean shutdown. Oversized conversations still go straight to disk. The trade-off: after a crash (not a normal restart), conversations still only in RAM are lost and will be re-read once.
We switched the store to write-on-eviction the same night. XeStrata takes over the main role once that setting checks out in real use. We’ll update this article with the measured write volume and any effect on reply time.
What we know, and what we don’t
Replication notes
What you can reproduce from public sources: XeStrata xe0.2.2 at upstream commit ad821cdf, built with the free option (intel/llvm DPC++, no oneMKL), running Qwen3.8 Flash-Next IQ3_S on one Arc Pro B70. The engine arguments that mattered:
--max-context 262144 --kv int8
--resident-experts --resident-budget-gib 32 --expert-cache auto
--spec 4 --mtp <the model's MTP head> --spec-min-p 0.5
--prompt-cache 3 --pool-workers 8
--conversation-cache-mib 6144 --conversation-cache-slots 4
--conversation-save <dir> --conversation-save-mib 65536 --conversation-save-hours 72
--vision (encoder on a second GPU)
Upstream’s --conversation-save gives you the disk store. The straight-to-disk and write-behind behaviour (--conversation-save-min-free-mib, --conversation-save-behind) comes from our private fork and isn’t published. Without it, expect the “skip parking” line for conversations larger than the free RAM budget.
Two practical warnings from the bench:
- Isolate the cards. By default the engine probes every Level Zero GPU it can see. If another process owns the second card, hide that card from the container rather than relying on environment variables alone.
- No swap. On our kernel, letting the system swap out engine host buffers led to device-lost errors on the B70. We run the host without swap.
Disclosure and corrections
This is an independently operated 8BitsForge homelab report based on retained local measurements. No vendor sponsored it and no affiliate links are present. XeStrata is an open-source project by its upstream authors; our modifications are private and unpublished. Measured November 1-2, 2026.
No corrections have been issued. Any future correction will be dated and appended here.