AMD Ryzen AI 300 NPU versus Radeon 890M: supporting data¶
These are the numeric tables for the September 2026 AMD Ryzen AI 300 NPU / Radeon 890M comparison:
- 24 aggregate cells: four models × two backends × three input lengths, with twelve requests per row.
- 96 block summaries: the same cells split across four server runs, with three requests per row.
- 288 request observations: one row per captured request, retaining its block and repetition identifiers.
There are four counterbalanced blocks × three repetitions of the same prompt per model/backend/input cell. These are descriptive timing repetitions on one host, not twelve distinct quality tasks or independent machines. The request table follows the captured schedule; no first request or outlier is removed.
| Column | Meaning |
|---|---|
model |
Model identifier used by the experiment |
backend |
flm = FastFlowLM/NPU; vulkan = llama.cpp/Radeon 890M |
nominal_tokens |
Full rendered input length; FLM Qwen reports four fewer native prefill tokens because of deferred controls |
block |
Zero-based block/server-run identifier (0–3), within each model/backend |
iteration |
Zero-based repetition at that input length within the server run (0–2); request table only |
n |
Number of requests summarized: 12 in cells, 3 in blocks; absent from request rows |
wall_s |
Client request time to completed stream, seconds; excludes server/model load |
first_answer_s |
Client latency to first answer text, seconds |
native_decode_tps |
Backend-reported decode rate; the native timing/count definitions differ between backends |
socket_mean_w |
Time-weighted mean firmware SocketPower over the request, watts |
socket_integral_j |
Integrated firmware SocketPower over the request, joules; not wall energy |
Metric columns hold medians in the cell/block tables and individual observations
in the request table. Each cell/block metric also has _min and _max
columns for its observed request range, not a confidence interval. All tables
keep full numeric precision so the rounded article values can be regenerated.
Medians of different fields are calculated separately: multiplying median
power by median time need not
reproduce the median integral.
Socket integrals use linear interpolation at client request boundaries and trapezoidal integration of one-second-filtered samples. Model loading, idle subtraction and phase-isolated energy are excluded. See the article for sampling, boundary sensitivity, memory/thermal limits and the Gemma counter correction. No per-second or per-token hardware-speed ratio can be inferred by treating native backend counters as interchangeable.
Evidence and verification¶
The sanitized NPU/iGPU evidence archive
contains the submitted prompts and requests, streams, server logs, telemetry,
model pairings and artifact fingerprints. The
verification instructions
recompute all three CSVs and the supporting memory, thermal and energy
calculations without inference. Python 3.11+ and
7-Zip with PPMd support
are required; extraction is automatic. These links pin signed commit
d22bc59, not the moving repository branch.
This is not a complete unchanged capture: weights, tokenizers, model-authored templates and process censuses are omitted. Gemma answer re-tokenization remains a historical audit assertion unless the optional check is run with the exact fingerprinted tokenizer; neither mode recovers original sampled token IDs. See the privacy and evidence limits and license boundaries.
Reproduction record¶
The captured runtime reported llama.cpp build 10809 (v0.4.0), compiled
with GNU 16.2.0. The NPU device reported firmware 1.1.2.64. Runtime,
kernel, Mesa and XRT package versions are listed in the article.
The following are the complete captured server argument lists, parameterized
only for the model identifier and local GGUF path. MODEL_ID is one of
qwen3.5:2b, qwen3.5:4b, qwen3.6-moe:35b-a3b, or gemma4-it:e4b;
MODEL_GGUF points to its paired file. Run only one server at a time on the
dedicated loopback port. These examples describe the capture, not permission
to interrupt another service or a complete benchmark-launch procedure.
llama-server -m "$MODEL_GGUF" --alias "$MODEL_ID" \
--host 127.0.0.1 --port 52730 -dev Vulkan0 -ngl 99 \
--parallel 1 --ctx-size 65536 -fa on -ctk f16 -ctv f16 \
-b 2048 -ub 512 -t 12 -tb 12 --spec-type none \
--cache-ram 0 --ctx-checkpoints 0 --reasoning off --jinja \
--fit off --log-verbosity 4
/usr/bin/flm serve "$MODEL_ID" --host 127.0.0.1 --port 52730 \
--ctx-len 65536 --prefill-chunk-len 4096 --pmode performance \
--asr 0 --embed 0 --cors 0 --preemption 0
The launcher removed inherited LLAMA_ARG_* variables, explicitly selected
the FLM model root through FLM_MODEL_PATH and the registry through
FLM_CONFIG_PATH, and used a fresh private working directory. The other
environment variables were inherited but not exported. Consequently, these
arguments are not a capture of the complete process environment. The evidence
archive retains the sanitized request bodies, prompt construction, schedule,
guards and loaded-artifact fingerprints, but cannot reconstruct omitted state.
Selected installed llama.cpp records report USE="vulkan openmp flexiblas"
(relevant enabled subset), with ROCm/CUDA disabled, and:
CHOST=x86_64-pc-linux-gnu
CFLAGS=-O2 -pipe -march=znver5 -mtune=znver5 -mno-rdrnd -mno-rdseed
CXXFLAGS=-O2 -pipe -march=znver5 -mtune=znver5 -mno-rdrnd -mno-rdseed
LDFLAGS=-Wl,-O1 -Wl,--as-needed -Wl,-z,pack-relative-relocs
The runtime's build banner also says debug; this does not establish an
unoptimized build, and the saved flags above explicitly contain -O2.
These are selected package records, not a complete compiler-command replay.
FLM's ebuild also builds the host runtime from source; its installed record
contains the same host C/C++ flags. Those flags do not describe compilation
of the separately supplied NPU kernel binaries.
Retained installed-ebuild SHA-256 identifiers:
llama-cpp-0.4.0.ebuild
e7b3953a95f0db69e6b59963c7ea4fb158c4d753cc1ae1cf53f7ad4cfda32789
fastflowlm-1.0.4.ebuild
47cbe1fdcd44f2154bae15cceccd07f0d492c2e9d394ea2a45616f5c3420ca75
These identify recorded ebuild files, not the executables, all dependencies or model tensors. Captured executable, library and model fingerprints, along with the analysis tooling, are available in the evidence archive and repository linked above. The numeric CSVs alone do not replace that bundle.
Artifact comparability¶
The selected model pairs are the closest practical profiles, not precision-matched artifacts. The Gemma GGUF labelled Q4_1 contains mixed tensor types: approximately 48.7% of stored tensor bytes are Q4_1, 38.3% Q5_K, 7.5% Q4_K and the remainder BF16/F32. These percentages describe storage bytes, not parameter counts or measured quality. They do not establish equivalence with the native FLM conversion.
Architecture dimensions, shared vocabulary token IDs and offline rendered prompt bytes agree across each selected pair. Exact base-checkpoint revisions and cross-format tensor equivalence are not established. llama.cpp used f16 K/V cache; FLM exposes bf16 accessors, but its internal layout and precision were not independently established.
Native token accounting¶
FLM's Qwen path defers four template-control tokens from its prefill count. Its reported prompt counts are therefore 1,020 / 8,188 / 32,764, while the full rendered inputs remain 1,024 / 8,192 / 32,768. This is not cached input or a shorter corpus. Its native decode timer includes deferred-control work and excludes work covered by the client timer. llama.cpp's native decode rate uses 255 timed steps for a reported 256-token response. Native decode rates therefore cannot be treated as interchangeable cross-backend timers.
Gemma/FLM emits a first token outside its native completion counter. Source inspection and a separate six-request diagnostic supported a native cap of 255 for a source-inferred 256 emitted tokens. In the historical audit, all 36 main Gemma/FLM answers re-tokenized to 256. Native counters remain unchanged. Complete-answer re-tokenization corroborates the source explanation but is not a capture of original sampled token IDs.
The public verifier labels this re-tokenization result as a historical
assertion unless its optional check is supplied with the exact fingerprinted
tokenizer. The adjustment applies only to the tested FLM build and Gemma path;
it is not a general recommendation to change max_tokens.
Validation and exclusions¶
The capture audit reconciled all 288 request streams with saved log ranges, checked token counts and cache behavior, and verified artifact stability. Every server exited cleanly. All scheduled performance requests remain in the numeric tables, including first requests and the initial Vulkan Qwen2B power transient.
The 48 preflight requests and six separate Gemma diagnostics are not included in the performance dataset. Public validation uses the sanitized evidence and the verification scope described above; it does not authenticate the private originals or turn historical assertions into independently repeated checks.