Skip to content

Commit 6ed288e

Browse files
committed
final review done.
1 parent a4896d6 commit 6ed288e

7 files changed

Lines changed: 289 additions & 214 deletions

File tree

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,54 @@
11
---
2-
title: Multimodal On-Device Inference on Arm v9 with MNN for Audio and Vision
2+
title: Run multimodal inference with MNN on Armv9
33
layout: learningpathall
44
weight: 2
55
---
66

77
## Introduction
88

9-
This module explains why **[MNN](https://github.com/alibaba/MNN)** and an **Omni multimodal model** are a practical combination for **CPU-only on-device inference** on Arm v9 Linux. You will use a single runtime and a single model to run **vision**, **audio**, and **text** prompts, then combine image + audio inputs to generate an operational **restock ticket**.
9+
This section introduces the software stack used throughout this Learning Path. You will use **[MNN](https://github.com/alibaba/MNN)** to run a prebuilt **Omni multimodal model** on an Armv9 Linux system using only the CPU.
1010

11-
## Why MNN for on-device deployment
11+
By the end of this section, you will understand why this combination is a practical starting point for reproducible multimodal inference on Armv9.
1212

13-
MNN is a deployment-focused inference runtime that works well for edge and mobile-style workloads:
13+
## Why use MNN on Armv9
1414

15-
- A **portable runtime** widely used across mobile and embedded environments
16-
- A **CPU-first workflow** that maps naturally to Arm v9 Linux systems
17-
- Native builds can take advantage of **Arm-specific optimizations** (for example, KleidiAI when enabled)
18-
- One codebase can target multiple platforms such as Arm Linux, Android, iOS, and x86 hosts
15+
MNN is a lightweight inference engine designed for deployment across mobile, embedded, and edge platforms. It is a good fit for this Learning Path for four reasons:
1916

20-
## Why Omni multimodal
17+
- It provides a **portable runtime** that can be built and used across different device classes.
18+
- It supports a **CPU-first deployment flow**, which maps well to Armv9 development systems.
19+
- Native builds can take advantage of **Arm-specific optimizations** when they are enabled in the build.
20+
- The same runtime approach can be reused across **Arm Linux, Android, iOS, and x86-based development hosts**.
2121

22-
Omni models simplify multimodal applications by keeping image, audio, and text in a single pipeline:
22+
For this Learning Path, MNN gives you a practical way to validate multimodal inference on Armv9 without introducing extra framework complexity.
2323

24-
- One model can handle **image + audio + text** prompts
25-
- Enables cross-modal tasks such as **“audit the shelf image + listen to a voice note → produce a restock ticket”**
26-
- Prompt control using tags like `<img>...</img>` and `<audio>...</audio>`
27-
- Reduces operational complexity versus maintaining separate vision and speech models
24+
## Why use an Omni multimodal model
2825

29-
## Scope
26+
An Omni model combines **text, image, and audio** understanding in a single inference pipeline. This makes it useful for building compact edge applications that need to reason over more than one input type.
3027

31-
To keep this learning path reproducible and easy to complete, we intentionally constrain the scope:
28+
In this Learning Path, you use the model to:
3229

33-
- **CPU-only**
34-
No GPU or NPU acceleration is required.
30+
- process **text-only prompts**
31+
- describe **image inputs**
32+
- interpret **audio inputs**
33+
- combine **image and audio context** to generate a structured **restock ticket**
3534

36-
- **No export or quantization steps**
37-
You will use a **prebuilt MNN Omni model package** as-is.
35+
This single-model approach keeps the workflow easier to follow than maintaining separate models for vision and speech tasks.
3836

39-
- **No CPU–NPU heterogeneous pipeline**
40-
All compute runs on the Arm v9 CPU. The focus is correctness and reproducibility.
37+
## Scope of this Learning Path
4138

42-
## Next
39+
To keep the workflow reproducible, this Learning Path uses a deliberately narrow scope:
4340

44-
In the next module, you will build MNN on Arm v9 and prepare the prebuilt Omni model and local demo assets.
41+
- **CPU-only execution**
42+
All inference runs on the Armv9 CPU.
43+
44+
- **Prebuilt model assets**
45+
You use a prepared MNN Omni model package instead of exporting or converting models.
46+
47+
- **No heterogeneous scheduling**
48+
This example does not use GPU, NPU, or split CPU-accelerator execution.
49+
50+
This scope keeps the focus on setup, validation, and multimodal application flow.
51+
52+
## Next steps
53+
54+
In the next section, you will build MNN on Armv9 and prepare the model files and local assets used in the remaining examples.

content/learning-paths/cross-platform/multimodel_mnn_v9/2_mnn_build.md

Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,28 @@ weight: 3
44
layout: learningpathall
55
---
66

7-
## Overview
7+
## Introduction
88

99
In this module you will build **MNN** natively on your Arm v9 Linux system and verify that the `llm_demo` binary can load a **prebuilt Omni MNN model package**. This sets up everything needed for the text, vision, and audio demos in later modules.
1010

11-
By the end of this module you will have:
11+
This creates the software environment used in the next modules, where you run text, vision, and audio-enabled multimodal inference on Armv9.
1212

13-
- A working `llm_demo` binary
14-
- A verified Omni model directory containing `config.json`
15-
- A runtime environment that loads the correct MNN shared libraries
13+
At the end of this module, you will have:
1614

15+
- a working `llm_demo` binary
16+
- a validated model directory that includes `config.json`
17+
- a runtime environment that resolves the correct MNN shared libraries
1718

18-
## Step 1 - Create a working directory
19+
## Create a workspace
1920

20-
Create a workspace under your home directory:
21+
Create a working directory under your home folder:
2122

2223
```bash
2324
mkdir -p ~/mnn
2425
cd ~/mnn
2526
```
2627

27-
## Step 2 - Clone and build MNN (native build)
28+
## Build MNN natively on Armv9
2829

2930
Clone the MNN repository:
3031

@@ -33,7 +34,7 @@ git clone https://github.com/alibaba/MNN.git
3334
cd MNN
3435
```
3536

36-
Configure and build:
37+
Configure and build MNN with LLM, audio, and Omni support enabled:
3738

3839
```bash
3940

@@ -51,72 +52,74 @@ cmake .. \
5152
make -j$(nproc)
5253
```
5354

54-
**Key CMake options:**
55+
The most important CMake options are:
5556

56-
- `MNN_BUILD_LLM=ON` enables LLM support required by llm_demo
57-
- `MNN_BUILD_AUDIO=ON` enables audio features used by Omni
58-
- `MNN_BUILD_LLM_OMNI=ON` enables Omni multimodal support
59-
- `MNN_LOW_MEMORY=ON` prefers lower-memory configurations where available
60-
- `MNN_KLEIDIAI=ON` enables KleidiAI-related optimizations on supported Arm platforms
57+
- `MNN_BUILD_LLM=ON` to enable LLM support required by `llm_demo`
58+
- `MNN_BUILD_AUDIO=ON` to enable the audio components used by the Omni model
59+
- `MNN_BUILD_LLM_OMNI=ON` to enable multimodal Omni support
60+
- `MNN_LOW_MEMORY=ON` to prefer lower-memory runtime settings where available
61+
- `MNN_KLEIDIAI=ON` to enable KleidiAI optimizations on supported Arm platforms
6162

62-
63-
Verify that `llm_demo` was built:
63+
Verify that the `llm_demo` binary was created:
6464

6565
```bash
6666
ls -l ~/mnn/MNN/build/llm_demo
6767
```
6868

69+
## Verify shared library resolution
6970

70-
## Step 3 - Confirm the correct shared libraries are loaded
71-
72-
If your system has more than one MNN installation, a common pitfall is building llm_demo in one location but loading libMNN.so from another.
71+
If your system already has another MNN installation, `llm_demo` can load a different `libMNN.so` than the one you just built. This is a common source of runtime errors.
7372

74-
From the build directory, inspect runtime dependencies:
73+
From the build directory, inspect the runtime dependencies:
7574

7675
```bash
7776
cd ~/mnn/MNN/build
7877
ldd ./llm_demo | grep -E "libMNN|Express|Audio|OpenCV" || true
7978
```
8079

81-
You should see `libMNN.so` and `libMNN_Express.so` resolving from your ~/mnn/MNN/build tree.
80+
You should see `libMNN.so` and `libMNN_Express.so` resolving from the `~/mnn/MNN/build` tree.
8281

83-
```
82+
An incorrect result looks like this, where `libMNN.so` is loaded from another location:
83+
84+
```text
8485
libMNNAudio.so => /home/radxa/mnn/MNN/build/tools/audio/libMNNAudio.so (0x0000ffffb6d00000)
85-
libMNN_Express.so => /home/radxa/mnn/MNN/build/express/libMNN_Express.so (0x0000ffffb6c00000)
86-
libMNN.so => /usr/share/cix/lib/libMNN.so (0x0000ffffb6600000)
87-
libMNNOpenCV.so => /home/radxa/mnn/MNN/build/tools/cv/libMNNOpenCV.so (0x0000ffffb61a0000)
86+
libMNN_Express.so => /home/radxa/mnn/MNN/build/express/libMNN_Express.so (0x0000ffffb6c00000)
87+
libMNN.so => /usr/share/cix/lib/libMNN.so (0x0000ffffb6600000)
88+
libMNNOpenCV.so => /home/radxa/mnn/MNN/build/tools/cv/libMNNOpenCV.so (0x0000ffffb61a0000)
8889
```
8990

90-
If you see `libMNN.so` coming from a different directory, set `LD_LIBRARY_PATH` to prefer your build output:
91+
If `libMNN.so` resolves from a different directory, update `LD_LIBRARY_PATH` to prefer the libraries from your local build:
9192

9293
```bash
9394
export LD_LIBRARY_PATH=$HOME/mnn/MNN/build:$HOME/mnn/MNN/build/express:$HOME/mnn/MNN/build/tools/audio:$HOME/mnn/MNN/build/tools/cv:${LD_LIBRARY_PATH:-}
9495
```
9596

96-
Re-check:
97+
Run the check again:
9798

9899
```bash
99100
ldd ./llm_demo | grep -E "libMNN|Express|Audio|OpenCV" || true
100101
```
101102

102-
103-
## Step 4 - Download and verify a prebuilt MNN Omni model package
103+
## Download a prebuilt Omni model package
104104

105105
This learning path uses a prebuilt [Omni model package](https://huggingface.co/taobao-mnn/Qwen2.5-Omni-7B-MNN) that is already in MNN deployable format.
106106

107-
Store the model directory into `~/mnn`
107+
Clone the model into your workspace:
108108

109109
```bash
110110
cd ~/mnn
111111
git clone https://www.modelscope.cn/MNN/Qwen2.5-Omni-7B-MNN.git
112112
```
113113

114-
Verify config.json exists:
114+
Verify that the package includes `config.json`:
115+
115116
```bash
116117
cat ~/mnn/Qwen2.5-Omni-7B-MNN/config.json
117118
```
118119

119-
```
120+
A valid configuration looks similar to:
121+
122+
```json
120123
{
121124
"llm_model": "llm.mnn",
122125
"llm_weight": "llm.mnn.weight",
@@ -139,18 +142,18 @@ cat ~/mnn/Qwen2.5-Omni-7B-MNN/config.json
139142
```
140143

141144
{{% notice Note %}}
142-
This is an MNN-ready model package.
143-
You do not need to export from PyTorch or run additional quantization steps.
144-
{{% /notice %}}
145+
This package is already prepared for MNN deployment.
145146

147+
You do not need to export the model from PyTorch or run additional quantization steps before using it in this learning path.
148+
{{% /notice %}}
146149

147-
### Checkpoint
150+
## Check your setup
148151

149-
Start `llm_demo` with your model config:
152+
Start `llm_demo` with the model configuration:
150153

151154
```bash
152155
cd ~/mnn/MNN/build
153156
./llm_demo ~/mnn/Qwen2.5-Omni-7B-MNN/config.json
154157
```
155158

156-
If the binary starts without `undefined symbol` or library errors, you are ready for the next module.
159+
If the binary starts without `undefined symbol` errors or missing library messages, your environment is ready for the next module.

content/learning-paths/cross-platform/multimodel_mnn_v9/3_mnn_text_baseline.md

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,22 @@
11
---
2-
title: Run a text baseline with an Omni model on MNN
2+
title: Validate text-only inference with an Omni model on Armv9
33
weight: 4
44
layout: learningpathall
55
---
66

7-
## Overview
7+
## Introduction
88

9-
Before running vision and audio prompts, validate that your **runtime + model + prompt I/O** are working end-to-end. In this module you will run a **text-only baseline** using the same Omni model you will use later for multimodal prompts.
9+
Before you add image and audio inputs, validate the basic inference path with a text-only prompt. In this module, you use the same **Qwen2.5-Omni-7B-MNN** package from the previous section and confirm that `llm_demo` can run prompts from a file on your Armv9 system.
1010

11-
By the end of this module you will confirm:
11+
At the end of this module, you will have verified:
1212

13-
- `llm_demo` can load your `config.json` without errors
14-
- A prompt file is parsed correctly (one line per prompt)
15-
- The model returns stable, sensible text output
13+
- the model configuration loads correctly
14+
- prompt input from a text file is parsed as expected
15+
- the runtime returns usable text output without crashes or library errors
1616

17+
## Create a text baseline prompt
1718

18-
## Step 1 - Create a baseline prompt file
19-
20-
Create a simple text prompt file. Keep it short so you can quickly verify the pipeline.
19+
Create a short prompt file in your workspace:
2120

2221
```bash
2322
cat > ~/mnn/text_baseline_prompt.txt <<'EOF'
@@ -26,23 +25,23 @@ EOF
2625
```
2726

2827
{{% notice Note %}}
29-
llm_demo commonly treats each line as a separate prompt. Keep prompts one per line.
28+
`llm_demo` commonly treats each line in the file as a separate prompt. Keep each prompt on a single line.
3029
{{% /notice %}}
3130

31+
## Run `llm_demo` with the prompt file
3232

33-
## Step 2 - Run llm_demo in batch mode
34-
35-
Run llm_demo with your Omni model config.json and the prompt file:
33+
Run `llm_demo` from the MNN build directory and pass both the model configuration and prompt file:
3634

3735
```bash
38-
cd ~/mnn_lp/MNN/build
36+
cd ~/mnn/MNN/build
3937
./llm_demo ~/mnn/Qwen2.5-Omni-7B-MNN/config.json ~/mnn/text_baseline_prompt.txt
4038
```
4139

42-
You should see a response describing the benefits of multimodal on-device inference.
40+
A successful run should load the model, report the detected CPU features, and return a text response for the prompt.
4341

42+
Example output:
4443

45-
```
44+
```text
4645
config path is /home/radxa/mnn/Qwen2.5-Omni-7B-MNN/config.json
4746
CPU Group: [ 1 2 3 4 ], 799999 - 1800968
4847
CPU Group: [ 7 8 ], 799897 - 2199795
@@ -68,18 +67,22 @@ This line reports hardware feature support on your CPU: **i8sdot**, **fp16**, **
6867
A value of `1` means the feature is supported in hardware, and `0` means it is not.
6968
{{% /notice %}}
7069

70+
## Check how prompt files are processed
7171

72-
73-
## Step 3 - Add a second prompt to validate multi-line behavior
74-
75-
Append a second prompt line to confirm that llm_demo processes prompts line-by-line.
72+
To verify that the prompt file is read line by line, append a second prompt:
7673

7774
```bash
78-
cat >> ~/mnn_lp/text_baseline_prompt.txt <<'EOF'
79-
What's Arm CPU arch?
75+
cat >> ~/mnn/text_baseline_prompt.txt <<'EOF'
76+
What is the Arm CPU architecture?
8077
EOF
8178
```
8279

80+
Run the same command again:
81+
```bash
82+
cd ~/mnn/MNN/build
83+
./llm_demo ~/mnn/Qwen2.5-Omni-7B-MNN/config.json ~/mnn/text_baseline_prompt.txt
84+
```
85+
You should now see two responses, one for each line in the prompt file.
8386

8487
```
8588
config path is /home/radxa/mnn/Qwen2.5-Omni-7B-MNN/config.json
@@ -99,7 +102,6 @@ prompt file is /home/radxa/mnn/text_baseline_prompt.txt
99102

100103
You should now see two responses (one per line).
101104

102-
## Step 4 - Start an interactive session (Optional)
103105

104106
If you want to quickly sanity-check interactive mode:
105107

@@ -108,13 +110,17 @@ cd ~/mnn/MNN/build
108110
./llm_demo ~/mnn/Qwen2.5-Omni-7B-MNN/config.json
109111
```
110112

111-
Type a short prompt and confirm the model replies.
112-
113+
Enter a short prompt and confirm that the model returns a reply.
113114

114-
## Checkpoint
115+
## Check your results
115116

116117
You have completed this module when:
117-
- `llm_demo` successfully loads the config and model
118-
- The prompt file produces one response per line
119-
- Responses are stable and sensible (not empty or repeated error text)
120-
- No crashes or runtime errors occur
118+
119+
- `llm_demo` loads `config.json` successfully
120+
- the prompt file produces one response per line
121+
- the model returns non-empty text output
122+
- the runtime completes without crashes or missing-library errors
123+
124+
## Next steps
125+
126+
In the next module, you will add an image input and validate the vision path of the Omni model on Armv9.

0 commit comments

Comments
 (0)