You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: content/learning-paths/servers-and-cloud-computing/performix-instruction-mix/_index.md
+6-2Lines changed: 6 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,10 @@
1
1
---
2
2
title: Profile GPT-2 instruction mix with Arm Performix
3
3
4
+
draft: true
5
+
cascade:
6
+
draft: true
7
+
4
8
description: Learn how to profile GPT-2 inference on Arm Neoverse with the Arm Performix Instruction Mix recipe, identify scalar versus vector execution patterns, and improve throughput with NEON, SVE, and KleidiAI kernels.
5
9
6
10
minutes_to_complete: 45
@@ -17,7 +21,7 @@ prerequisites:
17
21
- Access to Arm Performix configured with a remote Arm Linux target. For setup, see the [Arm Performix install guide](/install-guides/performix/)
18
22
- Basic understanding of C++ and compiler optimization
19
23
- Basic understanding of matrix multiplication
20
-
- Basic understanding of writing SIMD code with Neon and/or SVE.
24
+
- Basic understanding of writing SIMD code with Neon or SVE
Copy file name to clipboardExpand all lines: content/learning-paths/servers-and-cloud-computing/performix-instruction-mix/how-to-1.md
+7-7Lines changed: 7 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,12 +1,12 @@
1
1
---
2
-
title: Background
2
+
title: Understand instruction mix profiling
3
3
weight: 2
4
4
5
5
### FIXED, DO NOT MODIFY
6
6
layout: learningpathall
7
7
---
8
8
9
-
## What the instruction mix recipe shows
9
+
## Instruction mix overview
10
10
11
11
The Arm Performix Instruction Mix recipe shows the types and proportions of machine instructions your workload executes at runtime and in static analysis, so you can see how efficiently your code uses Arm CPU hardware resources.
12
12
@@ -25,20 +25,20 @@ The instruction mix result gives you two complementary views:
25
25
26
26
Together, these views help you verify whether architecture-specific features are actually active in hot code paths.
27
27
28
-
## Why instruction mix is useful
28
+
## Detecting missed vectorization
29
29
30
30
Instruction mix is useful when you need to confirm that performance-critical code uses Arm CPU features effectively. This is especially helpful when you are, for example, validating the effectiveness of compiler autovectorization.
31
31
32
32
For example, if a hot function is mostly scalar at runtime when you expected NEON or SVE activity, that often indicates missed vectorization opportunities. You can then focus optimization work on compiler flags, data layout, loop structure, and kernel implementation to improve throughput where it matters most.
33
33
34
-
## Why use a GPT-2 workload
34
+
## GPT-2 as a test workload
35
35
36
-
In this Learning Path, you run the [GPT-2 Medium](https://huggingface.co/openai-community/gpt2-medium) model on a minimal C++ inference engine to analyze instruction mix and throughput. This model is available under a [modified MIT License](https://github.com/openai/gpt-2/blob/master/LICENSE). You will confirm that matrix multiplication (`matmul`) is the hot path, then compare how scalar, NEON, and SVE implementations change instruction behavior and token generation speed.
36
+
You can run the [GPT-2 Medium](https://huggingface.co/openai-community/gpt2-medium) model on a minimal C++ inference engine to analyze instruction mix and throughput. This model is available under a [modified MIT License](https://github.com/openai/gpt-2/blob/master/LICENSE). You will confirm that matrix multiplication (`matmul`) is the hot path, then compare how scalar, NEON, and SVE implementations change instruction behavior and token generation speed.
37
37
38
38
This example implements only the forward inference path, with no back propagation or training. You do not need to understand the full transformer architecture to complete this Learning Path. Familiarity with matrix multiplication is enough. For background on GPT-2, see the original 2019 paper, [Language Models are Unsupervised Multitask Learners](https://cdn.openai.com/better-language-models/language_models_are_unsupervised_multitask_learners.pdf)
39
39
40
40
You will also try implementing your own `matmul` kernels that target NEON and SVE, then use instruction mix data to verify that these vector paths are active and improving throughput.
41
41
42
-
## What you've learned and what's next
42
+
## Next steps
43
43
44
-
In this section, you learned what instruction mix represents and why it is useful for LLM inference optimization on Arm. Next, you will set up the GPT-2 example, build the binaries, and run a baseline test.
44
+
You now know what instruction mix represents and why it matters for LLM inference optimization on Arm. Next, you'll set up the GPT-2 example, build the binaries, and run a baseline test.
Copy file name to clipboardExpand all lines: content/learning-paths/servers-and-cloud-computing/performix-instruction-mix/how-to-2.md
+5-3Lines changed: 5 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -24,7 +24,7 @@ git checkout tags/v0.0.2
24
24
25
25
The C++ runtime expects exported model binaries. Create a Python virtual environment, install dependencies, and export GPT-2 Medium weights and vocabulary:
26
26
27
-
This Learning Path uses [openai-community/gpt2-medium on Hugging Face](https://huggingface.co/openai-community/gpt2-medium), which corresponds to the GPT-2 Medium model from the original OpenAI GPT-2 release in 2019. The model has 355 million parameters, and in this workflow it runs with unquantized FP32 (32-bit floating-point) weights.
27
+
The workload uses [openai-community/gpt2-medium on Hugging Face](https://huggingface.co/openai-community/gpt2-medium), which corresponds to the GPT-2 Medium model from the original OpenAI GPT-2 release in 2019. The model has 355 million parameters, and in this workflow it runs with unquantized FP32 (32-bit floating-point) weights.
28
28
29
29
```bash
30
30
python3 -m venv venv
@@ -105,8 +105,10 @@ Run the scalar baseline binary:
105
105
./build/gpt2 --model gpt2-medium "Once upon a time" -n 20
106
106
```
107
107
108
+
The output is:
109
+
108
110

109
111
110
-
## What you've learned and what's next
112
+
## Next steps
111
113
112
-
You now have a working baseline binary and model files. Next, you will use the Instruction Mix recipe in Arm Performix to inspect static disassembly and dynamic runtime behavior.
114
+
You now have a working baseline binary and model files. Next, you'll use the Instruction Mix recipe in Arm Performix to inspect static disassembly and dynamic runtime behavior.
Copy file name to clipboardExpand all lines: content/learning-paths/servers-and-cloud-computing/performix-instruction-mix/how-to-3.md
+13-8Lines changed: 13 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -12,10 +12,12 @@ Before you optimize, identify where the application spends most of its time. Use
12
12
13
13
Open Arm Performix and select the **Code Hotspots** recipe. If this is your first run on the target, complete tool deployment as prompted.
14
14
15
-
Set the launch command to your baseline binary with the number of tokens (`-n`) set to 150 as per the command below. This value keeps startup overhead small compared to inference time, so the profile minimizes the time taken to load the model weights:
15
+
Set the launch command to your baseline binary with the number of tokens (`-n`) set to 150 as per the command below. This value keeps startup overhead small compared to inference time, so the profile minimizes the time taken to load the model weights.
16
16
17
-
```out
18
-
<path to repository>/build/gpt2 --model gpt2-medium "Once upon a time" -n 150
17
+
Copy and paste the command below as the Performix Workload. If your path is different adjust it to point to `gpt2`.
18
+
19
+
```console
20
+
/home/ubuntu/GPT-2-Example/build/gpt2 --model gpt2-medium "Once upon a time" -n 150
19
21
```
20
22
21
23

@@ -38,13 +40,16 @@ The Instruction Mix recipe helps fill this gap.
38
40
39
41
## Configure the Instruction Mix recipe
40
42
41
-
Open Arm Performix and select the **Instruction Mix** recipe. If this is your first run on the target, complete tool deployment as prompted.
43
+
Open Arm Performix and select the **Instruction Mix** recipe.
44
+
42
45
Set the launch command to your baseline binary with the same runtime arguments used for baseline testing:
43
46
44
-
```output
45
-
</path/to/GPT-2-Example>/build/gpt2 --model gpt2-medium "Once upon a time" -n 150`
47
+
```console
48
+
/home/ubuntu/GPT-2-Example/build/gpt2 --model gpt2-medium "Once upon a time" -n 150
46
49
```
47
50
51
+
Note about number of counters.
52
+
48
53
Use the same model and prompt arguments as your baseline terminal run so the measurements are comparable.
49
54
50
55

@@ -63,6 +68,6 @@ Then inspect dynamic analysis bar chart to see where sampled runtime work is con
63
68
64
69
Finally, in dynamic functions, you can break down operation types to individual functions. This is particularly useful when no single function dominates the profile, allowing you to inspect dynamic instruction patterns for specific functions.
65
70
66
-
## What you've learned and what's next
71
+
## Next steps
67
72
68
-
You used Instruction Mix to confirm that baseline runtime is dominated by scalar-heavy `matmul` execution. Next, you will compare updated instruction mix and throughput across scalar, NEON, SVE, and KleidiAI variants.
73
+
You used Instruction Mix to confirm that baseline runtime is dominated by scalar-heavy `matmul` execution. Next, you'll compare updated instruction mix and throughput across scalar, NEON, SVE, and KleidiAI variants.
Copy file name to clipboardExpand all lines: content/learning-paths/servers-and-cloud-computing/performix-instruction-mix/how-to-4.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,5 +1,5 @@
1
1
---
2
-
title: Optimize
2
+
title: Optimize matmul with vector intrinsics
3
3
weight: 5
4
4
5
5
### FIXED, DO NOT MODIFY
@@ -66,6 +66,6 @@ Restart your coding assistant, then prompt it to run Performix Instruction Mix a
66
66
67
67

68
68
69
-
## What you've learned and what's next
69
+
## Next steps
70
70
71
-
In this optional section, you implemented and profiled a custom `matmul_user` kernel using the same workflow you used for baseline analysis. Next, you will compare instruction mix and throughput across scalar, NEON, SVE, and KleidiAI variants.
71
+
In this optional section, you implemented and profiled a custom `matmul_user` kernel using the same workflow you used for baseline analysis. Next, you'll compare instruction mix and throughput across scalar, NEON, SVE, and KleidiAI variants.
Copy file name to clipboardExpand all lines: content/learning-paths/servers-and-cloud-computing/performix-instruction-mix/how-to-5.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,7 +6,7 @@ weight: 7
6
6
layout: learningpathall
7
7
---
8
8
9
-
## Confirm instruction-mix changes after vectorization
9
+
## Verify vectorization with instruction mix
10
10
11
11
In the earlier build step, you created `gpt2_neon` and `gpt2_sve`. These binaries use the reference solutions in `matmul_neon.cpp` and `matmul_sve.cpp`, respectively. Run the `gpt2_neon` binary with the following command to observe the speedup.
12
12
@@ -56,7 +56,7 @@ For a full-page view, open [Godbolt session with all three matmul kernels](https
56
56
57
57
Run the provided comparison script to measure tokens per second across all available binaries:
58
58
59
-
```bash bash { command_line="user@host | 2-30"}
59
+
```bash bash { command_line="ubuntu@ip | 2-30"}
60
60
./compare_gpt2_variants.sh
61
61
Model: gpt2-medium
62
62
Prompt: Once upon a time
@@ -80,4 +80,4 @@ run 1: 3.04859 tok/s
80
80
avg: 3.048590 tok/s
81
81
```
82
82
83
-
These results show that intrinsics increase throughput from about 3 tok/s in the scalar baseline to about 13.9 tok/s with SVE. Next, you will use optimized libraries to push performance further.
83
+
These results show that intrinsics increase throughput from about 3 tok/s in the scalar baseline to about 13.9 tok/s with SVE. Next, you will use optimized libraries to push performance further.
Copy file name to clipboardExpand all lines: content/learning-paths/servers-and-cloud-computing/performix-instruction-mix/how-to-6.md
+9-7Lines changed: 9 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,7 +6,7 @@ weight: 8
6
6
layout: learningpathall
7
7
---
8
8
9
-
## Understand why KleidiAI improves matmul
9
+
## KleidiAI packing and tiling
10
10
11
11
Getting close to peak matmul performance is complex, especially in transformer inference where one kernel runs many times per token. Raw SIMD intrinsics can accelerate execution, but higher-level algorithms can improve matrix multiplication through techniques such as packing and tiling.
12
12
@@ -15,7 +15,7 @@ Getting close to peak matmul performance is complex, especially in transformer i
15
15
-*Tiling* breaks large matrices into smaller blocks that fit better in cache, so data is reused more often and memory bandwidth pressure is lower.
16
16
Arm created [KleidiAI](https://github.com/ARM-software/kleidiai) to provide the fastest Arm CPU microkernels on packing and tiled matrix multiplication so you can use these optimizations without writing and tuning every low-level kernel yourself.
17
17
18
-
## Trace the KleidiAI path in this GPT-2 example
18
+
## KleidiAI integration in the GPT-2 example
19
19
20
20
The file `src/kernels/matmul_kai_sve.cpp` is the runtime bridge between your model code and a KleidiAI float32 SVE microkernel. Since packing is a preprocessing step, this workflow uses a slightly modified inference engine, `gpt2_kai_sve.cpp`. It builds a `kai_matmul_clamp_f32_f32_f32p_ukernel` function table and binds function pointers such as:
21
21
@@ -27,7 +27,7 @@ The `kai_run_matmul_clamp_f32_f32_f32p4vlx1b_6x4vl_sve_mla` is our entry. As per
27
27
28
28
For more details on KleidiAI, please refer to the [official GitLab repository](https://gitlab.arm.com/kleidi/kleidiai).
29
29
30
-
## Read the source code: key steps
30
+
## Key source code
31
31
32
32
All matmul implementations in `src/kernels/` follow the same high-level pattern from `matmul.h`: they compute float32 output from float32 input vectors and weights. The KleidiAI variant keeps this behavior but changes the RHS argument to a packed buffer (`const uint8_t* rhs_packed`) so the compute path can consume prepacked tiles.
33
33
@@ -62,11 +62,11 @@ The execution flow is:
62
62
In `src/gpt2_kai_sve.cpp`, runtime code prepares packed weights once with `kai_run_rhs_pack_kxn_x32p4vlx1b_x32_x32_sve`, stores them in `PackedWeights`, and calls `kernels::matmul_kai_sve(...)` at runtime. This is why the runtime file and `matmul_kai_sve.cpp` must match: the runtime produces packed buffers in the format expected by the same f32 ukernel family.
63
63
64
64
65
-
## Compare SVE intrinsics and KleidiAI
65
+
## SVE intrinsics versus KleidiAI
66
66
67
67
Run the comparison script from the repository root with the following command.
68
68
69
-
```bash { command_line="user@host | 2-30"}
69
+
```bash { command_line="ubuntu@ip | 2-30"}
70
70
./compare_gpt2_variants.sh kai
71
71
Model: gpt2-medium
72
72
Prompt: Once upon a time
@@ -103,7 +103,7 @@ avg: 3.047840 tok/s
103
103
You can increase throughput by running the KleidiAI path with multiple matmul threads. For this 355M model, tune `--matmul-threads` heuristically on your target system to find the optimal value. For our Graviton 3 instance, we observe a max token generation speed of 34.5 token/s with 4 threads.
104
104
105
105
106
-
```bash { command_line="user@host | 3-50"}
106
+
```bash { command_line="ubuntu@ip | 3-50"}
107
107
cd build
108
108
./gpt2_kai_sve --model gpt2-medium "Once upon a time" -n 150 --matmul-threads 4
@@ -139,4 +139,6 @@ They would be kicked out of the village, and they would suffer and die as punish
139
139
140
140
## Summary
141
141
142
-
In this Learning Path, you used Arm Performix Instruction Mix to detect scalar-heavy hot paths, validated vectorization changes with static and dynamic evidence, and compared baseline, Neon, SVE, and KleidiAI-backed matmul implementations. This workflow is transferable to your own codebase: use instruction mix to detect missed vectorization and other unexpected instruction-balance patterns, validate changes with static and runtime evidence, and then tune to meet your performance requirements.
142
+
You used Arm Performix Instruction Mix to detect scalar-heavy hot paths, validated vectorization changes with static and dynamic evidence, and compared baseline, Neon, SVE, and KleidiAI-backed matmul implementations. Starting from roughly 3 tok/s with scalar code, you reached about 15 tok/s with SVE intrinsics and 35 tok/s with KleidiAI packing, tiling, and multithreading.
143
+
144
+
This workflow is transferable to your own codebase: use instruction mix to detect missed vectorization and other unexpected instruction-balance patterns, validate changes with static and runtime evidence, and then tune to meet your performance requirements.
0 commit comments