Disclosure: Youyeetoo supplied the X1S and NVMe. Testing and conclusions are my own.
After the Round 2 X1S benchmarks, one question was still unresolved: on this Celeron N5095, would Ollama or a native llama.cpp build move the same prompt faster?
The earlier CPU rows used different test paths, so they could not answer that cleanly. I went back to the board, rebuilt the same llama.cpp commit with native N5095 tuning, pinned the exact GGUFs, and sent the same raw prompt through both CPU servers with the context, threads, batch settings, sampler, cache behavior, and output length matched.
While the X1S was back on the bench, I also separated true CPU from Vulkan host-operation offload, ran Ling-mini-2.0 and Qwen3.5 9B, tested MTP at depths 1 through 4, and revisited the larger Vulkan failures with per-run kernel checks.
This is a separate article from the published Round 2 benchmark. Round 2 records the original test pass. This one covers the controlled retest and what I would actually run on the X1S now.
The matched CPU rows favored Ollama on this exact setup. Full Vulkan was useful for the two smallest models, larger runs crossed into real i915 failures, and MTP cost more performance than it saved on the four-core N5095.
Ollama, llama.cpp, and Vulkan are different layers
Ollama is what I normally use to run models on the X1S. Building llama.cpp directly from source gave me a standalone implementation I could pin to a specific commit, tune for the N5095, and test beside it. Vulkan belongs to a different part of the stack. I used it through llama.cpp to put the Intel iGPU to work, so the CPU runtime comparison and the GPU backend test answer two different questions.
I also recovered the original llama.cpp build record instead of guessing why its numbers looked low. It was commit 9a286ac, built in Release mode with -O3, OpenMP, SSE4.2, and Vulkan. It used a conservative GGML_NATIVE=OFF setting, but it was not a debug build. For the matched comparison I rebuilt the same commit with native N5095 tuning and saved the command, CMake values, binary hashes, and CPU backend hash.
A matched Ollama and llama.cpp CPU test
Both servers received the same raw prompt, exact content-addressed Q4_K_M GGUF, 4,096-token context, four threads, batch and microbatch 512, temperature 0, seed 42, top-k 1, and exactly 96 generated tokens. Prompt-cache reuse was disabled. Each side received one warmup and three measured requests per model.
| Exact GGUF | Native llama.cpp | Ollama 0.32.1 | Ollama difference |
|---|---|---|---|
| Qwen3 0.6B Q4_K_M | 6.725 tok/s | 7.809 tok/s | +16.1% |
| Qwen3 1.7B Q4_K_M | 2.852 tok/s | 3.321 tok/s | +16.5% |
| Qwen3 4B Instruct Q4_K_M | 1.484 tok/s | 2.002 tok/s | +34.9% |
| Phi-4 Mini Q4_K_M | 1.570 tok/s | 2.072 tok/s | +32.0% |
All 24 measured requests finished, generated the required 96 tokens, stayed within the thermal guard, and had clean kernel windows. The prompt counts matched at 71 tokens for Qwen and 70 for Phi. Each runtime repeated its own output exactly. The two runtimes did not produce identical greedy text, which I recorded instead of hiding.
On this Celeron N5095 X1S, with Ollama 0.32.1, llama.cpp commit 9a286ac, these four GGUFs, and the controls above, Ollama's bundled CPU runner reported 16.1% to 34.9% higher internal generation throughput. The result belongs to this board, these versions, and these four files.
I used internal prompt and generation rates rather than total wall time. Ollama unloaded the model after each request, while the standalone llama.cpp server remained resident for its three-request block. Model loading was not an identical part of the timed path.
Zero GPU layers was not pure CPU
The Vulkan results had another wrinkle. Once the benchmark account could open /dev/dri/renderD128, llama.cpp could use the Intel GPU for host operations even with --n-gpu-layers 0. A true CPU run had to hide Vulkan and explicitly disable operation offload.
I reran Qwen3 0.6B and 1.7B in three modes with one native binary and one pp128/tg96 workload: true CPU, zero-layer mixed host-operation offload, and full Vulkan.
| Model and mode | Prompt processing | Generation | Peak package |
|---|---|---|---|
| Qwen3 0.6B, true CPU | 10.666 tok/s | 7.397 tok/s | 81 °C |
| Qwen3 0.6B, mixed host-op | 34.586 tok/s | 7.425 tok/s | 80 °C |
| Qwen3 0.6B, full Vulkan | 37.350 tok/s | 8.593 tok/s | 57 °C |
| Qwen3 1.7B, true CPU | 3.893 tok/s | 2.986 tok/s | 84 °C |
| Qwen3 1.7B, mixed host-op | 12.366 tok/s | 2.997 tok/s | 83 °C |
| Qwen3 1.7B, full Vulkan | 12.879 tok/s | 3.462 tok/s | 58 °C |
Full Vulkan processed the prompt 3.50 and 3.31 times faster than true CPU. Generation improved 16.2% and 15.9%, and the package peaks were 24 and 26 °C lower. The mixed mode delivered most of the prompt-processing gain but almost none of the generation gain. It is real CPU and GPU sharing, but it is not conventional layer-split offload.
The distinction matters in practice. A long instruction, pasted document, or retrieval chunk benefits from faster prompt ingestion. Token-by-token generation is a different phase, and the tiny Jasper Lake GPU moved that number much less.
The larger Vulkan runs hit a real failure boundary
Qwen3 0.6B and 1.7B were the clean full-Vulkan runs. Qwen3 4B reached an i915 reset timeout. Phi-4 Mini and Qwen3 8B lined up with explicit GPU hangs even though llama-bench returned zero. Gemma 3 later hit fence and preemption timeouts, an i915 reset, and vk::DeviceLostError.
| Larger Vulkan model | Recorded outcome |
|---|---|
| Qwen3 4B | i915 reset timeout during the run window |
| Phi-4 Mini | i915 GPU hang; process still returned 0 |
| Qwen3 8B | i915 GPU hang; process still returned 0 |
| Gemma 3 4B | Fence timeouts, i915 reset, vk::DeviceLostError |
The kernel recovered the GPU and the X1S stayed usable. The evidence is real and preserved, but I did not run enough controlled repeats to claim a failure rate. I also did not disable the watchdog or forced-timeout recovery to force a clean-looking table. Once the larger full-offload path started hanging, I stopped before a six-model split-offload matrix.
Ling-mini was a better CPU fit than I expected
Ling-mini-2.0 was one of the more interesting models left on my test list. I pinned Bartowski's IQ4_XS quantization at revision 8be84a0, verified the 8.8 GB GGUF by size and SHA-256, and ran it in true CPU mode.
| Ling-mini true-CPU run | Prompt processing | Generation | Peak package |
|---|---|---|---|
| 3 threads, 85 °C guard | 4.375 tok/s | 3.091 tok/s | 74 °C |
| 4 threads, 90 °C guard | 5.817 tok/s | 4.083 tok/s | 85 °C |
The first four-thread attempt reached my normal 85 °C abort. I reran that one missing setting with a 90 °C abort, a 5.9% increase. It completed cleanly at an 85 °C sampled peak. Intel lists a 105 °C Tjunction for the N5095, but I still kept a 15 °C margin and left the kernel and timeout checks alone. Four threads improved generation by 32.1% over the clean three-thread row.
MTP made all three tested models slower
Having MTP tensors in a model file does not prove MTP is active. The Qwen files contained the tensors, but Ollama had not launched a draft runner. Gemma needed Google's separate E2B assistant model. I set up both paths, verified them in the service journal, and swept draft depths 1 through 4.
| Model | Depth 1, off → on | Depth 4, off → on | What happened |
|---|---|---|---|
| Qwen3.5 0.8B | 11.34 → 6.04 tok/s | 11.16 → 2.62 tok/s | Slower at every depth |
| Qwen3.5 2B | 4.89 → 3.78 tok/s | 5.12 → 1.52 tok/s | Slower at every depth |
| Gemma 4 E2B | 3.27 → 2.27 tok/s | 3.40 → 1.33 tok/s | Slower at every depth |
Depth 1 was the least bad setting and still reduced generation by 46.7% on Qwen3.5 0.8B, 22.8% on Qwen3.5 2B, and 30.7% on Gemma 4 E2B. Higher depths made the loss larger. The Ollama service journal shows --spec-type draft-mtp, the requested depth, and nonzero draft generation, while the on and off pairs produced the same token counts and output hashes. MTP was definitely running, but on this four-core N5095 its draft overhead cost more than it saved.
Gemma depths 2 and 3 first reached the standard 85 °C abort. I repeated those two missing settings under the same 90 °C ceiling used for Ling. Their peaks were 84 and 86 °C, and their kernel windows were clean. This does not make MTP slow on a modern desktop CPU or GPU. It answers the question for Ollama 0.32.1, these models, and this X1S.
The rest of the model results
| Model | Generation | Peak package | Method |
|---|---|---|---|
| Qwen3.5 0.8B Q8_0 | 10.44 tok/s | 70 °C | Two-run warm average |
| Qwen3.5 2B Q8_0 | 4.89 tok/s | 75 °C | Two-run warm average |
| Qwen3.5 9B Q4_K_M | 1.110 tok/s | 82 °C | Five-prompt average |
| Gemma 4 E2B Q4_K_M | 3.38 tok/s | 77 °C | Two-run warm average |
| Gemma 4 E4B Q4_K_M | 1.78 tok/s | 78 °C | Two-run warm average |
| Granite 4 Tiny-H | 5.43 tok/s | 79 °C | Single original observation |
| LFM2.5 | 4.95 tok/s | 80 °C | Mutable latest tag, not content-pinned |
| Gemma 3n E2B | 3.24 tok/s | 80 °C | Not Gemma 4 E2B |
Qwen3.5 9B fit in 16 GB and completed at 1.110 tok/s. It is not fast chat, but now I know the board can run it. Qwen3.5 0.8B remains the fastest text-generation result in this project. I did not run a quality tournament, so I am not turning the speed table into a claim about which model writes the best answer.
BitCPM and Gemma 3 had different compatibility problems
OpenBMB's official BitCPM-CANN 1B TQ2_0 GGUF was accepted by pinned llama.cpp but rejected by Ollama 0.32.1 with a tensor-size overflow. In the controlled true-CPU test, llama.cpp reached 13.013 prompt tok/s and 8.584 generation tok/s across five repetitions, with a 76 °C peak. That is a runtime-support difference, not a matched speed contest, because Ollama never loaded the model.
Gemma 3 gave me two separate problems. Before I could test its performance, current llama.cpp rejected the older Ollama multimodal artifact because it was missing required metadata. My patch script creates a separate text-only derivative, adds the metadata, pads the vocabulary row, and removes the embedded vision tensors without overwriting the source file. That copy completed true CPU at 2.172 prompt tok/s and 1.624 generation tok/s. It solved the conversion problem, but it did not prevent the later Vulkan device loss.
What I would use on the X1S now
I would keep Ollama for day-to-day CPU use. On this board and version, it was not the packaged-runtime penalty I assumed it might be. Qwen3.5 0.8B is the speed option. Qwen3.5 2B, Granite 4 Tiny-H, and LFM2.5 are the middle group I would spend more time evaluating for answer quality. Qwen3.5 9B fits, but 1.110 tok/s takes patience.
For Vulkan, I would stay with Qwen3 0.6B or 1.7B on this software stack. The prompt-processing gain is real, the lower package temperature is useful, and those two kernel windows were clean. I would not recommend the larger full-offload path from this evidence. A process returning zero does not erase an i915 hang.
I would leave MTP off for these three tested models on the N5095. The draft path was active and still lost at every depth. That is a better answer than assuming newer model features automatically help old low-power CPUs.
Youyeetoo X1S local LLM benchmark FAQ
Was Ollama faster than llama.cpp on the Youyeetoo X1S?
In the corrected four-model CPU test, yes. Ollama 0.32.1 reported 16.1% to 34.9% higher internal generation throughput than a native build of llama.cpp commit 9a286ac. Both runtimes received the same raw prompt, exact GGUF, 4,096-token context, four threads, batch settings, sampler, and 96-token output. This is an X1S and version-specific result, not a universal rule.
How much faster was Intel Vulkan on the Celeron N5095?
Full Vulkan processed prompts 3.50 times faster than true CPU for Qwen3 0.6B and 3.31 times faster for Qwen3 1.7B. Generation improved 16.2% and 15.9%, while package peaks were 24 C and 26 C lower. Those were the two clean full-Vulkan models.
Were the i915 GPU hangs real?
Yes. Qwen3 4B reached a reset timeout, Phi-4 Mini and Qwen3 8B coincided with i915 GPU hangs, and Gemma 3 ended with fence timeouts, an i915 reset, and vk::DeviceLostError. The kernel recovered the GPU. The events are preserved, but this test did not measure a repeatable failure rate.
Did MTP speed up Qwen3.5 or Gemma 4 on the N5095?
No. Ollama MTP draft depths 1 through 4 were slower than MTP off for Qwen3.5 0.8B, Qwen3.5 2B, and Gemma 4 E2B. Even depth 1 reduced generation by 22.8% to 46.7%. Service logs confirmed that the draft path was active.
How fast was Ling-mini-2.0 IQ4_XS on the X1S?
The pinned Bartowski IQ4_XS GGUF reached 4.083 generation tokens per second at four CPU threads in a five-repetition pp128/tg96 test. It peaked at 85 C under a disclosed 90 C abort. The earlier clean three-thread result was 3.091 tokens per second.
Can the X1S run Qwen3.5 9B and BitCPM-CANN 1B?
The official Qwen3.5 9B Q4_K_M Ollama tag completed five prompts at a 1.110 tokens per second average and an 82 C maximum. Ollama 0.32.1 rejected the official BitCPM-CANN 1B TQ2_0 file with a tensor-size overflow, but true-CPU llama.cpp ran it at 8.584 generation tokens per second.
Did you remove the thermal and GPU safety limits?
No. The normal thermal abort stayed at 85 C. I repeated three incomplete CPU configurations at 90 C, a 5.9% increase, and marked those rows. Kernel-error aborts, i915 recovery, and request timeouts stayed enabled.
Scripts, hashes, and evidence
The existing X1S repository now contains all three stages of the project: the original Kali and CPU work, the published Round 2 Vulkan work, and this controlled matched retest. I kept one repository because the hardware, scripts, and evidence trail are continuous. The README separates the rounds so the new results do not overwrite the history.
The repo includes the native build script, matched runtime collector, true-CPU and Vulkan mode runner, MTP depth sweep, exact Ling downloader, compatibility patch, aggregate CSV files, artifact hashes, and sanitized i915 evidence. If you repeat the test, publish the model hash, runtime version, prompt, thread and batch settings, thermal ceiling, and kernel window with the throughput number.
Get notified when I publish new hardware reviews, benchmarks, and security research. No spam, unsubscribe anytime.
I respect your privacy. Powered by Buttondown.