Gorgon Halo Arrives in gmkTek.. do you need 192gb of LPDDR5?!?

Gorgon Halo from gmkTek

This is the first Gorgon Halo box that I get to play with! Faster memory, and 50% more of it; what’s not to love? ( aside from the price )

TODO VIDEO HERE

There’s a coupon for Level1Techs Viewers

GMKtec Official Store:

Amazon US - 2TB

Amazon US - 4TB

Discount Code: EVOX5PRO

Official Store: $100 OFF

Amazon US: 5% OFF

Review



Gorgon Halo vs DGX Spark (that’s what we gotta do, right??)

Two unified-memory machines, one 184 GiB (usable) and one 121 GiB (usable), asked to serve the same models. Well it turns out that’s more complicated than it would appear.

One box wins on a dense model, the other on a sparse one; it seems like I can explain some of that split, but some of it? Not so much…

Platform Engine Model Mode Plotted Not measured Excluded or quarantined Qualified
AMD ds4 deepseek-v4.1-flash PP 3 / 7 1024, 4096, 16384, 32768 none 3 single-run
AMD ds4 deepseek-v4.1-flash TG 0 / 6 1024, 2048, 4096, 8192, 16384 none clean
AMD halogen halogen-qwen3.8-27b PP 7 / 7 none none clean
AMD halogen halogen-qwen3.8-27b TG 6 / 6 none none 5 stopped short; 2 single-run
AMD halogen-flash-server halogen-qwen3.8-flash-next PP 7 / 7 none none 1 single-run
AMD halogen-flash-server halogen-qwen3.8-flash-next TG 0 / 6 512, 1024, 2048, 4096, 8192, 16384 none clean
AMD llamacpp glm-5.3-flash-q5k-iq3s PP 7 / 7 none none clean
AMD llamacpp glm-5.3-flash-q5k-iq3s TG 6 / 6 none none 2 single-run
AMD llamacpp qwen3.8-27b-q4km PP 7 / 7 none none 1 single-run
AMD llamacpp qwen3.8-27b-q4km TG 6 / 6 none none 2 single-run
AMD vllm Qwen3.8-27B-AWQ-INT4 PP 7 / 7 none none 1 single-run
AMD vllm Qwen3.8-27B-AWQ-INT4 TG 3 / 6 4096, 8192, 16384 none clean
Spark ds4 deepseek-v4.1-flash PP 4 / 7 1024, 4096, 16384 none 4 single-run
Spark ds4 deepseek-v4.1-flash TG 0 / 6 1024, 2048, 4096, 8192, 16384 none clean
Spark llama.cpp qwen3.8-flash-next-ud-q4kxl PP 7 / 7 none none clean
Spark llama.cpp qwen3.8-flash-next-ud-q4kxl TG 2 / 6 2048, 4096, 8192, 16384 none clean
Spark maya glm-5.3-flash PP 7 / 7 none none 1 checkpoint-assisted
Spark maya glm-5.3-flash TG 3 / 6 none 4096, 8192, 16384 clean
Spark vllm Qwen3.8-27B-AWQ-INT4 PP 7 / 7 none none 1 single-run
Spark vllm Qwen3.8-27B-AWQ-INT4 TG 3 / 6 4096, 8192, 16384 none clean
Spark vllm Qwen3.8-27B-NVFP4 PP 7 / 7 none none clean
Spark vllm Qwen3.8-27B-NVFP4 TG 6 / 6 none none 2 single-run
Spark vllm-c4 Qwen3.8-27B-NVFP4 PP 0 / 7 512, 1024, 2048, 4096, 8192, 16384, 32768 none clean
Spark vllm-c4 Qwen3.8-27B-NVFP4 TG 1 / 6 1024, 2048, 4096, 8192, 16384 none clean
AMD cpukit + codecs CPU: pcore-4 single 12 / 12 none none clean
AMD cpukit + codecs CPU: all-nosmt all 12 / 12 none none clean
AMD cpukit + codecs CPU: all-smt all 12 / 12 none none clean
Spark cpukit + codecs CPU: pcore-19 single 12 / 12 none none clean
Spark cpukit + codecs CPU: ecore-4 single 12 / 12 none none clean
Spark cpukit + codecs CPU: all all 12 / 12 none none clean

Serving engines

Platform Engine Version Licence Port Image
AMD halogen-server 0.1.4 closed source 8731 ghcr.io/peonist-ai/halogen:0.1.4
AMD halogen-flash-server 0.18.17 closed source 8731 ghcr.io/peonist-ai/halogen-flash-server:latest
AMD vLLM 0.32.0+strix open source 8000 kyuz0/vllm-therock-gfx1151:latest
AMD llama.cpp build 11870, commit 74bca3950 open source 8732 kyuz0/amd-strix-halo-toolboxes:rocm-10.0
Spark vLLM 0.26.1rc1.dev1219+g46638857f open source 8000 vllm/vllm-openai:nightly-46638857fdbb30e0c232c9e8f9cb1ff6d6f545c3
Spark project-maya v1.1.34 open source 8080 source build, github.com/mw00/project-maya

Method and the fairness problem

A clean hardware A/B test generally requires the same software on both boxes with the same artifact. For most of this campaign I just couldn’t do that, and no amount of protocol discipline really keeps things apples-to-apples. The two AMD Halogen engine builds are closed source and run only on AMD hardware. vLLM is the Spark path (but that’s also not the only path on Spark, either). Ds4 exists on both boxes and is the only clean-ish cross-platform control we have. So most of what follows is an engine comparison that happens to run on two different pieces of hardware…

vLLM runs on both boxes, but even that’s a bit fuzzy because the two boxes ran different vLLM builds (0.32.0+strix against 0.26.1rc1), different native 4-bit kernels, and different attention paths.

Oh, and there’s an out-of-tree patch for vLLM I mentioned in the video that shores up Spark’s problems on Qwen 3.8 flash next…

Cold cache is usually useful for measuring the cost of prefill, but I don’t like it for because it’s not what a chat user is going to feel at a small scale because chat users in local AI contexts are generally going to have warm prefixes. I think this might be okay as a measure of what the machine can do, though.

The confounds, and what was done about each

Confound Why it matters Mitigation actually adopted
No common engine An engine win cannot be attributed to the hardware. Only identical-artifact comparisons are treated as platform signals, and even those are qualified: the two ds4 runs use one source tree but different backends (ROCm against CUDA), so that control narrows the software difference rather than eliminating it. Every other segment is labelled as an engine comparison.
Quantization density Fewer bits per weight means fewer bytes moved per token, which changes decode speed independently of the hardware. Qwen3.8-27B was matched at decode density and is the lead comparison. GLM-5.3-Flash could not be matched and is labelled as not like-for-like.
Speculative decoding A drafter inflates decode throughput by design and is not comparable to a non-speculative engine. The AMD Qwen series was pinned to the serial drafter path. The speculative paths are reported separately, as a gain over serial.
Prefix cache A cache hit makes prefill look faster than the machine can compute it. Every request carries a unique nonce prefix. Points that still showed a cache signature were quarantined by the loader.
Context window A larger n_ctx costs memory and can change prefill cost. The ladder runs at one context per series; the context sweep is a separate experiment with its own key space.
Chat versus completion endpoint project-maya has no /v1/completions endpoint, so its numbers come from a different API surface than the others. Disclosed. Not much to be done about this…

Qwen3.8-27B at matched density

The Qwen3.8-27B segment is the closest thing this review has to a controlled comparison. Same base model on both boxes, and – after we parsed the containers rather than trusting the file sizes – a decode-time byte cost of 1.07x. That is close enough to call matched. It still is not a hardware A/B, because the engines differ and there is no way around that. But when the artifacts are this close, and both machines land near their own cited memory-bandwidth ceilings, the numbers describe the two platform stacks more than they describe any one engine’s tuning – while still being a property of silicon and software together, not of silicon alone.

The byte cost at decode is 1.07x, not 1.64x.

Quantity AMD halogen .hgn Spark NVFP4
Repository peonist-ai/halogen-qwen3.8-27b nvidia/Qwen3.8-27B-NVFP4
Quantization w4a4/fp8r/i4l mixed ModelOpt mixed: NVFP4 on MLP and lm_head, FP8 on linear attention, rest BF16
On disk 33.40 GiB (35.87 GB) 20.42 GiB (21.92 GB)
Prefill-only duplicate 12.35 GB of .i4l planes, read at prefill, not at decode none
Decode-resident 21.8971 GiB (23.51 GB) 20.4159 GiB
Decode density 6.3228 bpw over 29.7485B logical parameters no equivalent decode-resident figure recorded
Bits per weight, text model 6.4386 5.9936
On-disk ratio 1.64x 1.00x
Decode byte ratio 1.07x 1.00x

Prefill and decode across depth

Figure 2. Decode against generation depth, all five series. Quantization: NVFP4-modelopt-mixed (Spark vLLM); w4a4/fp8r/i4l mixed 33.40 GiB .hgn (AMD halogen); Q4_K_M at 5.10 bpw (AMD llama.cpp); Maya-S-v2-IQ2_XXS (Spark); Q5K-IQ3S 143.54 GiB GGUF (AMD llama.cpp). Cache: cold, unique nonce prefix per request. The AMD halogen points are drawn as markers, not a line, because five of six stopped short of their requested length and sit at the depths they actually reached. A hollow ring marks a single run. The three Qwen3.8-27B series are nearly coincident, which is the decode half of the three-engine finding: engine choice barely moves a bandwidth-bound rate. Coverage is not uniform: four of the five series carry all six decode depths, but Spark project-maya has only three of six (512, 1024, 2048), because its 4096, 8192 and 16384 runs stopped short and were excluded.

pp (tokens) AMD (halogen) Spark (vllm)
512 668.51 ± 0.64 1978.52 ± 13.13
1024 683.53 ± 9.00 2017.32 ± 17.89
2048 670.18 ± 1.29 2383.97 ± 9.64
4096 662.73 ± 1.82 2346.93 ± 10.17
8192 645.90 ± 0.74 2363.43 ± 13.38
16384 610.42 ± 0.41 2294.55 ± 11.85
32768 550.08 ± 0.54 2089.52 ± 5.76
tg (tokens) AMD (halogen) Spark (vllm)
512 10.49 ± 0.00 12.38 ± 0.01
1024 10.63 ± 0.08 12.31 ± 0.15
2048 10.71 ± 0.03 12.61 ± 0.01
4096 10.61 ± 0.13 12.54 ± 0.02
8192 10.46; n=1 12.15; n=1
16384 10.57; n=1 12.23; n=1

Qwen3.8-27B prefill at matched depth, one column per engine. Quantization: w4a4/fp8r/i4l mixed 33.40 GiB .hgn (AMD halogen); Q4_K_M at 5.10 bpw (AMD llama.cpp); NVFP4-modelopt-mixed (Spark vLLM). Cache: cold, unique nonce prefix per request. The two AMD columns are the same box and the same base model through two engines, so the gap between them is software. All three datasets descend from the same donor, so this is an engine comparison not precision.

Qwen3.8-27B decode at matched depth, one column per engine. Quantization: w4a4/fp8r/i4l mixed 33.40 GiB .hgn (AMD halogen); Q4_K_M at 5.10 bpw (AMD llama.cpp); NVFP4-modelopt-mixed (Spark vLLM). Cache: cold, unique nonce prefix per request. Only depth 512 is common to all three columns: five of halogen’s six decode points stopped short and are drawn at the depths they actually reached, which do not coincide with the other two ladders. The three AMD rates sit within 16 percent of each other, and the reason is bandwidth, in section 10.

Benchmark llama.cpp HIP (Q4_K_M, 5.10 bpw) halogen-server 0.1.4 (.hgn, 6.32 bpw) vLLM AWQ-INT4, AMD (4.25 bpw) vLLM, Spark reference (NVFP4, 4-bit)
pp512 382.49 ± 0.58 668.51 ± 0.64 365.40 ± 0.60 1978.52 ± 13.13
pp1024 407.60 ± 0.61 683.53 ± 9.00 310.30 ± 0.20 2017.32 ± 17.89
pp2048 417.11 ± 0.65 670.18 ± 1.29 254.50 ± 2.50 2383.97 ± 9.64
pp4096 412.05 ± 0.44 662.73 ± 1.82 197.90 ± 0.20 2346.93 ± 10.17
pp8192 403.27 ± 0.20 645.90 ± 0.74 145.70 ± 0.40 2363.43 ± 13.38
pp16384 383.53 ± 0.10 610.42 ± 0.41 148.40 ± 0.40 2294.55 ± 11.85
pp32768 346.60; n=1 550.08 ± 0.54 122.14; n=1 2089.52 ± 5.76
tg512 12.20 ± 0.00 10.49 ± 0.00 11.83 ± 0.00 12.38 ± 0.01
tg1024 12.19 ± 0.00 10.63 ± 0.08; short, 376 actual 11.39 ± 0.00 12.31 ± 0.15
tg2048 12.16 ± 0.00 10.71 ± 0.03; short, 578 actual 10.65 ± 0.01 12.61 ± 0.01
tg4096 12.12 ± 0.00 10.61 ± 0.13; short, 852 actual — 12.54 ± 0.02

Notes: Cold cache, greedy sampling, means in tokens per second with the stdev across repeats where more than one repeat was made. The three AMD arms run at different precisions, so read the ratios as approximate; The halogen decode points from tg1024 up stopped short of their requested completion length and are labelled with the depth they reached.

The same three engines produce 10.5, 12.2, and 11.8 tokens per second – a spread of 16 percent, with llama.cpp narrowly ahead. Decode is bound by how fast bytes move; prefill is bound by how much arithmetic can be issued. Engine quality buys you a great deal on the compute-bound path and almost nothing on the memory-bound one.

Remember what I said in the video about mtp though: llama.cpp’s MTP head is silently dropped. Build 11870 does not wire qwen35.nextn_predict_layers, so it ignores the 15 blk.64.* tensors in the GGUF, 227.9 MiB or 1.37 percent of the file. There is no speculation in these numbers in other words. I think that makes the llama.cpp decode rate a fair comparison to halogen in serial mode, (i.e. not a fair comparison to mtp or dflash2, which is the same restriction the AMD Qwen ladder in section 4 carries.) So don’t think you’re going to get 10t/s “real world” when you have some options for performance improvement like mtp or dflash2. I just want to compare boxes as fairly as possible.

Speculative Decode

Just to give you an idea of the perf you can get with a model that needs lots of compute (like Qwen 27b Dense – which needs more compute per token than qwen 3.8 flash next!!)

..yes.. that’s looking better. Still the same w4a4/fp8r/i4l mixed 33.40 GiB .hgn

So what about Qwen 3.8 flash next??

This is a bigger model, so worse right? Nope.

Flash-Next runs on both boxes, and on that model the AMD machine measured roughly 2x faster at the corresponding requested depths: 2,002 against 1,023 tokens per second at a nominal 8192, and 2,031 against 941 at a nominal 32768. (The Spark’s actual prompt lengths overshot those labels, 8,896 and 35,709 tokens; the AMD ladder ran exact. Rates are per actual token on both sides, so the comparison is fair per token, but it is not a matched-depth experiment.) So the AMD box is not uniformly slower at prefill. It is slower on the one model and faster on the other.

(UPDATE: I learned later that there is a pending patch for Spark for llama.cpp for this exact issue, but that patch doesn’t make it faster than Gorgon Halo – it makes it the same speed. That JUST came to my attention right before I dropped this review so I need to revisit that soon).

The 27B engine is not slow. It is doing far more work per token: comparing throughput across two architectures requires dividing by the work each token represents, which means counting active parameters rather than stored ones. Flash-Next stores 176.9 billion parameters but computes with 6.7 billion of them per token whereas the 27B computes with all 25.6 billion for every token. That’s what dense means. It’s a 3.84x difference in arithmetic per token and that explains most of the gap between these two models on this one box.

Flash-Next on both boxes

Prompt tokens AMD (t/s) Spark (t/s) AMD / Spark
512 1423.11 693.37 +/- 4.0 2.05x
1024 1659.86 826.21 +/- 8.2 2.01x
2048 1810.46 952.78 +/- 5.0 1.90x
4096 1902.09 1014.29 +/- 4.1 1.88x
8192 2002.20 1023.34 +/- 11.5 1.96x
16384 2032.15 1003.00 +/- 5.9 2.03x
32768 2031.18 n=1 941.10 +/- 13.2 2.16x

GLM-5.3-Flash, fitting a 321B model

The GLM segment is not a like-for-like speed comparison and it should not be read as one. The AMD box runs a 3.84 bits-per-weight GGUF with the routed experts resident in GTT. The Spark runs a ~2-bit expert build under a third-party engine. The Spark’s artifact is roughly half the AMD one’s density. Any decode advantage the Spark shows here is substantially a quantization advantage, and any fidelity advantage the AMD box shows is the thing that density bought.

Quantity Value
Parameters 321.3 B
4-bit floor at 321.3 B 160.65 GB
AMD pool, default 92.21 GiB
AMD pool, configured 176.00 GiB
Spark pool 121.69 GiB
AMD artifact on disk 143.54 GiB, 3.84 bits per weight
Spark artifact on disk 89.84 GiB, experts at about 2 bits
Spark deficit vs the 4-bit floor 27.93 GiB minimum, before any KV cache
Spark deficit, NVFP4 experts-only artifact 69.34 GiB

Prefill pp

Requested Actual prompt Overshoot AMD prefill (t/s) Spark prefill (t/s)
512 512 +0.0% 232.78 316.94
1024 1073 +4.8% 206.28 472.43
2048 2190 +6.9% 280.17 612.22
4096 4422 +8.0% 269.64 696.29
8192 8892 +8.5% 237.81 731.03
16384 17828 +8.8% 197.31 745.06
32768 35701 +9.0% 140.86 736.80
checkpoint-assisted

Ah, but decode performance is pretty spot-on:

The model fidelity and tests like our Breakout: Clone tests was much higher on gorgon halo; that was nice to see. A model this large was better served with more ram.

DeepSeek-V4.1-Flash

The AMD box prefills at 651 tokens per second and the Spark at 576. The machine that looks catastrophically slower if you divide tokens by total time is, in steady state, slightly faster. The uncached read was much slower on the AMD box just because it was a different engine setup.

You can get yourself into a paradoxical situation if you aren’t careful testing here: ds4 sizes its expert cache from available RAM, so the AMD box allocates 133.5 gigabytes against the Spark’s smaller allocation, and then has to fill it – on a from-disk read path. More memory buys a larger cache, which costs a longer cold start… and some weights can be left on disk vs come from ram. For a model this size, on this engine, extra RAM is a cold-start liability in that scenario…

Parameter AMD Gorgon Halo (ROCm) DGX Spark (CUDA) Ratio
Marginal rate R 651 t/s 576 t/s 1.13x AMD faster
Points in the fit 3 (pp512, 2048, 8192) 4 (pp512, 2048, 8192, 32768) —
Largest residual 0.87 s 7.45 s —
Mean absolute residual 0.58 s 4.09 s —

The error bars here on prompt processing speed are large enough that “13%” win for AMD here is close to margin of error; the slight advantage to AMD may be down to somewhat better measured apparent memory utilization on the AMD side.

CPU Bonus Round: Arm vs x86!?!?

What about for “Agentic Workloads” ? Let’s look at single core first:

Half the ARM cores really don’t do all that great with branchy code, whereas Gorgon Halo has 16 powerful x86 cores that can run 32 threads.

One worker, pinned to one physical core. Mean of 3 measured reps after one discarded warm-up.

Metric Unit AMD Zen 5 (cpu4) Spark Cortex-X925 (cpu19) Spark Cortex-A725 (cpu4) AMD / X925
cpukit int, ALU chain Mops/s 872.6 ± 0.21 969.0 ± 0.14 930.5 ± 0.22 0.900
cpukit vm, branchy scalar Mops/s 368.9 ± 2.36 715.8 ± 2.56 303.8 ± 0.30 0.515
cpukit lat, pointer chase (lower is better) ns/load 157.8 ± 0.25 116.7 ± 0.20 152.9 ± 0.11 1.352
cpukit mem, int64 triad GB/s 33.21 ± 0.06 47.11 ± 0.08 41.88 ± 0.28 0.705
7-Zip b MIPS 8,608.7 ± 164.3 8,661.7 ± 8.08 4,691.7 ± 8.14 0.994
OpenSSL aes-128-gcm kbytes/s 26.75 M ± 42 k 8.21 M ± 2 k 2.92 M ± 0.73 k 3.259
OpenSSL aes-256-gcm kbytes/s 23.55 M ± 247 k 8.11 M ± 48 k 2.59 M ± 0.62 k 2.902
OpenSSL sha256 kbytes/s 2.55 M ± 2 k 2.45 M ± 3 k 2.09 M ± 0.25 k 1.039
OpenSSL sha512 kbytes/s 1.48 M ± 5 k 1.51 M ± 0.32 k 1.08 M ± 0.03 k 0.976
OpenSSL chacha20-poly1305 kbytes/s 6.41 M ± 2 k 2.15 M ± 0.52 k 825 k ± 0.03 k 2.985
zstd -b1 MB/s 2,061.5 ± 2.69 751.6 ± 0.81 404.7 ± 0.14 2.743
bzip2 -1 MB/s 26.80 ± 0.07 24.56 ± 0.06 15.01 ± 0.01 1.091

This also reveals some benchmaxxing aspects from Nvidia’s marketing material I hadn’t quite understood until I got to dig in for this review:

Both cores run the chain at very nearly the same absolute rate – 1306.9 against 1296.4 million operations per second, a 0.8 percent spread – despite the Spark running 1.35x slower on the clock. What? Dividing by gigahertz hands the Spark a 50 percent lead, and turns out that really does belong to the instruction set, not to the core. Which is faster: it depends on whether your compiler fuses, and a benchmark that reports only the ratio is misleading. This has, I think, shown up in Nvidia’s marketing material and I knew it was wrong based on my experience but I couldn’t explain why without thinking about it a bit more and it clicking (I forgot about the fused op from the compiler in other words…). Not every scenario fuses, either to get it done in 25% less clocks (3 clock ticks vs 4).

All cores

The all-core figures run the same twelve measurements as the single-core block, with N single-threaded workers instead of one. Single-core and all-core are the same measurement s, just at different worker counts…

Metric Unit AMD 16C/16T AMD 16C/32T Spark 20C/20T AMD SMT gain
cpukit int, ALU chain Mops/s 13,583 ± 37.17 26,880 ± 117.4 18,975 ± 17.48 1.979
cpukit vm, branchy scalar Mops/s 5,538.8 ± 38.70 8,966.8 ± 39.24 11,733 ± 48.15 1.619
cpukit mem, int64 triad GB/s 115.0 ± 0.06 112.3 ± 0.21 181.2 ± 1.10 0.977
7-Zip b MIPS 73,410 ± 86.08 117,544 ± 36.30 105,329 ± 95.38 1.601
OpenSSL aes-128-gcm kbytes/s 355.32 M ± 921 k 369.31 M ± 2.20 M 110.92 M ± 608 k 1.039
OpenSSL aes-256-gcm kbytes/s 314.98 M ± 420 k 345.60 M ± 232 k 105.91 M ± 262 k 1.097
OpenSSL sha256 kbytes/s 39.10 M ± 36 k 57.79 M ± 99 k 45.50 M ± 28 k 1.478
OpenSSL sha512 kbytes/s 21.38 M ± 13 k 24.40 M ± 33 k 26.00 M ± 14 k 1.142
OpenSSL chacha20-poly1305 kbytes/s 93.79 M ± 69 k 141.60 M ± 48 k 29.78 M ± 25 k 1.510
zstd -b1 MB/s 27,389 ± 87.64 30,001 ± 155.2 11,451 ± 19.22 1.095
bzip2 -1 MB/s 382.8 ± 0.36 532.5 ± 3.33 423.5 ± 0.16 1.391

Remember Spark’s arm setup is ten Cortex-X925 performance cores and ten Cortex-A725 efficiency cores, so that’s why I’ve got two Spark CPUs in these comparisons.

Metric Unit Cortex-X925 (cpu19) Cortex-A725 (cpu4) X925 / A725
cpukit int, ALU chain Mops/s 969.0 930.5 1.041
cpukit vm, branchy scalar Mops/s 715.8 303.8 2.356
cpukit lat, pointer chase ns/load 116.7 152.9 0.763
cpukit mem, int64 triad GB/s 47.11 41.88 1.125
7-Zip b MIPS 8,661.7 4,691.7 1.846
OpenSSL aes-128-gcm kbytes/s 8.21 M 2.92 M 2.809
OpenSSL aes-256-gcm kbytes/s 8.11 M 2.59 M 3.127
OpenSSL sha256 kbytes/s 2.45 M 2.09 M 1.176
OpenSSL sha512 kbytes/s 1.51 M 1.08 M 1.400
OpenSSL chacha20-poly1305 kbytes/s 2.15 M 825 k 2.604
zstd -b1 MB/s 751.6 404.7 1.857
bzip2 -1 MB/s 24.56 15.01 1.637

Also, AMD has SMT. Which does help, except when it doesn’t…

Metric Unit 16C/16T 16C/32T Gain
cpukit int, ALU chain Mops/s 13,583 26,880 1.979
cpukit vm, branchy scalar Mops/s 5,538.8 8,966.8 1.619
cpukit mem, int64 triad GB/s 115.0 112.3 0.977
7-Zip b MIPS 73,410 117,544 1.601
OpenSSL aes-128-gcm kbytes/s 355.32 M 369.31 M 1.039
OpenSSL aes-256-gcm kbytes/s 314.98 M 345.60 M 1.097
OpenSSL sha256 kbytes/s 39.10 M 57.79 M 1.478
OpenSSL sha512 kbytes/s 21.38 M 24.40 M 1.142
OpenSSL chacha20-poly1305 kbytes/s 93.79 M 141.60 M 1.510
zstd -b1 MB/s 27,389 30,001 1.095
bzip2 -1 MB/s 382.8 532.5 1.391

A second thread per core buys 1.98x on the integer chain, because that chain is latency-bound and a second thread fills the stalls. It negatively impacts triad (0.977x or ~3% loss) because the memory controller is already saturated at 16 threads and the extra threads only add queueing. SMT helps exactly where there is idle execution to fill, and not when the bottleneck is off-core.

With this context, the all core table is really something between the two platforms. It depends what you’re doing with your agents! Spark would be a clear winner if all 20 cores could be expected to perform the same, but that isn’t the case.

I came here hoping to find the decode t/s for 3.8 flash next, if perhaps that was also tested?

yes, above, and inline with the published halogen performance numbers. almost 2k t/s prompt processing at times! A solid 1200+ t/s prompt processing anyway.

condition t/s accept
synthetic ceiling (counting) 125.8 0.996
enumeration / tabular 107.4 0.936
JSON 79.6 0.787
code 68.3 0.708
reasoning 64.0 0.651
prose 60.9 0.586
no speculation (serial) 40.5 —

Realistic range 60.9–107.4 t/s (1.76x), floor 40.5, ceiling 125.8 — 3.1x end to end. Best c4 aggregate is 121.7 synthetic / 91.6 on a realistic mix, where each of four users gets ~25 t/s.

1 Like

Ahh my bad. Cheers - just bought one of the AMD branded ones and downloading the model now.

Great effort, Interestingly enough, I switched from Halogen to Gufo a bit ago, and saw a common performance (this was a few weeks ago though), predominately due to the closed source license,. I also have an older 48GB Nvidia Turing card via USB-4 on a framework desktop. It’s amazing how far this performance can go. My thesis is that a next generation QWEN with n-gram and insane NVMe sized embeddings is coming soon, and will provoke a panic.

Thanks also for the pointer on project-maya, will have to look at that as well.

AMD Ryzen AI Halo dev kit (RAH-002) — Qwen3.8 flash-next: config & numbers

Finished building my Ryzen AI Halo dev box. Config and measured numbers below. This was generated using the model mentioned.

System

  • AMD Ryzen AI Halo dev kit (RAH-002) — Ryzen AI Max+ PRO 495, Radeon 8065S, 192 GB LPDDR5X-8533

  • AMD dev image (Debian 13, kernel 7.2.7+rex, ROCm 7.15 therock)

  • Model: Qwen3.8 flash-next MXFP4 (118.1 GiB GGUF / halogen native artifacts)

Key config

  • sudo amd-ttm --set 160 — default 92 GiB pool won’t fit the model; 160 GiB persists across reboots

  • amd_iommu=off on kernel cmdline (rex image uses systemd-boot, not GRUB)

  • memlock unlimited, halogen-flash-server 0.18.22 in root podman

  • ik_llama.cpp HIP build: -DGGML_HIPBLAS=ON -DAMDGPU_TARGETS=gfx1151

Prefill (cold, halogen)

Prompt t/s
436 tok 1,211
1.5K 1,768
6.2K 2,043
12.4K 2,106
32.3K 2,091

Climbs to ~2,100 by 6K and flatlines — matches the published GMKtec numbers (1,423 @512 / 2,032 @32K) almost exactly.

Decode (256-token generations, halogen MTP)

Content My board Published ladder
Enumeration 112.3 107.4
JSON 88.3 79.6
Code 74.6–78.9 68.3
Prose 52.8–57.8 60.9

Open-stack comparison (ik_llama.cpp MTP n=4, same box & prompts)

Code Prose Serial
ik_llama.cpp 30.3 (acc 0.81) 19.6 (acc 0.586) 20.8
halogen ~76 ~55 —

Acceptance rates match halogen’s exactly — the ~2.5× gap is engine quality, not speculation. amd_iommu=off gave prose +5–9%, code flat; NPU gone, costs nothing here. Cold engine warm ≈ 4 min.

Happy to answer setup questions.