Skip to content

Commit 0991159

Browse files
authored
Merge pull request #3420 from anupras-mohapatra-arm/embedded-and-microcontrollers
Deploy ML app with Topo LP review
2 parents c14fca3 + 1d52219 commit 0991159

5 files changed

Lines changed: 99 additions & 93 deletions

File tree

content/learning-paths/embedded-and-microcontrollers/deploy-ml-model-to-npu-with-topo/_index.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
---
2-
title: Deploy an ML application to the Ethos-U65 NPU on NXP FRDM i.MX 93 with Topo
2+
title: Deploy a machine learning application to the Arm Ethos-U65 NPU on NXP FRDM i.MX 93 with Topo
33

44
draft: true
55
cascade:
66
draft: true
77

8-
description: Use Topo to deploy a Cortex-A web application that sends MobileNetV2 image classification requests to Cortex-M33 firmware accelerated by the Ethos-U65 NPU.
8+
description: Use Topo to build and deploy a Cortex-A web application that sends MobileNetV2 image classification requests to Cortex-M33 firmware accelerated by the Ethos-U65 NPU.
99

1010
minutes_to_complete: 60
1111

@@ -21,12 +21,12 @@ prerequisites:
2121
- A host machine (x86 or Arm) with Linux, macOS, or Windows
2222
- An NXP FRDM i.MX 93 target board with Linux setup, accessible over SSH with root access. To do this, see [Use Linux on the NXP FRDM i.MX 93 board](https://learn.arm.com/learning-paths/embedded-and-microcontrollers/linux-nxp-board/).
2323
- Docker installed on the host and target. For installation steps, see [Install Docker](https://learn.arm.com/install-guides/docker/).
24-
- At least 25 GB of free disk space on the host if you are building without cache images.
24+
- At least 25 GB of free disk space on the host if you're building without cache images.
2525
- The Device Tree Compiler (`dtc`) installed on the host.
2626
- lscpu installed on the target (pre-installed on most Linux distributions)
2727
- Topo installed on the host. For installation steps, see [Deploy containerized workloads to Arm-based Linux targets with Topo](https://learn.arm.com/learning-paths/cross-platform/deploy-containerized-workloads-with-topo/).
2828
- Basic familiarity with containers, SSH, and CLI tools
29-
- (Optional) Access to an Agent, such as Codex, or Claude Code
29+
- (Optional) Access to an agent, such as Codex or Claude Code
3030

3131
author: Tomas Agustin Gonzalez Orlando
3232

content/learning-paths/embedded-and-microcontrollers/deploy-ml-model-to-npu-with-topo/build-the-template.md

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
---
22
title: Build the Topo Template from scratch
3+
description: Create a Topo Template from the web application and Cortex-M33 firmware sources by adding Compose services, build artifacts, remoteproc-runtime metadata, and Topo arguments.
34
weight: 4
45

56
### FIXED, DO NOT MODIFY
@@ -8,16 +9,18 @@ layout: learningpathall
89

910
## What you will build
1011

11-
In this section, you will build the `topo-imx93-npu-deployment` Template starting from two non-Topo, non-Compose projects:
12+
In this section, you'll build the `topo-imx93-npu-deployment` Topo Template starting from two non-Topo, non-Compose projects:
1213

1314
- a Cortex-A web application that prepares images, writes model and tensor data into shared memory, and sends inference commands over `RPMsg`
1415
- a Cortex-M33 ExecuTorch runner firmware project for the FRDM i.MX 93
1516

16-
You will combine those sources into one repository, then make the repository a normal Compose project, and only then add the Topo metadata and Remoteproc Runtime services.
17+
You'll combine those sources into one repository, then make the repository a normal Compose project. Then, you'll add the Topo metadata and Remoteproc Runtime services.
1718

1819
## Create the repository from the base projects
1920

20-
We will copy the original base projects from the Topo Template. Clone the Topo Template Format repository for the validation schema, clone the original Topo Template for the source files, and start a new empty repository:
21+
Start by copying the original base projects from the Topo Template.
22+
23+
Clone the Topo Template Format repository for the validation schema, clone the original Topo Template for the source files, and start a new empty repository:
2124

2225
```bash
2326
git clone https://github.com/arm/topo-template-format.git
@@ -32,7 +35,7 @@ Create the project layout:
3235
mkdir -p webapp executorch-runner licenses
3336
```
3437

35-
Copy over the relevant `webapp` files:
38+
Copy the relevant `webapp` files:
3639

3740
```bash
3841
cp -R ../topo-imx93-npu-deployment/webapp/src webapp
@@ -55,18 +58,24 @@ cp -R ../topo-imx93-npu-deployment/licenses .
5558
cp ../topo-imx93-npu-deployment/.gitignore .
5659
```
5760

58-
We have now obtained a typical starting point. We have two sets of source code, combined into one repository. It is not a Compose project and it is not a Topo Template. We will now create a Compose project and Topo Template around the source code.
61+
You have two sets of source code combined into one repository. It's not a Compose project and it's not a Topo Template.
62+
63+
You'll now create a Compose project and Topo Template around the source code.
5964

6065
The Compose project provides the container build and runtime structure. A Dockerfile describes how to build one image. A Compose file describes the services that use those images, their build contexts, ports, volumes, dependencies, and runtime settings. In this Template:
6166

6267
- `webapp/Dockerfile` builds the Flask image.
6368
- `webapp/compose.yaml` keeps the web app's build context and Linux runtime settings close to the web app source.
6469
- `executorch-runner/Dockerfile` builds the ExecuTorch `.pte` model and Cortex-M33 runner ELF through multi-stage Docker builds.
65-
- the root `compose.yaml` is the Template entry point. It combines the web app, artifact build services, the Remoteproc Runtime service, and the root-level `x-topo` metadata.
70+
- the root `compose.yaml` is the Topo Template entry point. It combines the web app, artifact build services, the Remoteproc Runtime service, and the root-level `x-topo` metadata.
6671

6772
For a general introduction to Compose projects, services, and the `compose.yaml` file, see Docker's [How Compose works](https://docs.docker.com/compose/intro/compose-application-model/) documentation.
6873

69-
When a step below says to create a file, paste the complete file contents shown. When a step says to add or update part of an existing Compose file, merge the YAML into the existing top-level key shown by the snippet. For example, if a snippet starts with `services:`, add the named service under the existing top-level `services:` map. Do not create a second `services:` block in the same file.
74+
{{% notice Note %}}
75+
When you creating a file for any of the following steps, paste the complete file contents as shown.
76+
77+
When you update part of an existing Compose file for a step, merge the YAML into the existing top-level key shown by the snippet. For example, if a snippet starts with `services:`, add the named service under the existing top-level `services:` map. Don't create a second `services:` block in the same file.
78+
{{% /notice %}}
7079

7180
## Turn the sources into a Compose project
7281

@@ -128,7 +137,7 @@ Check that Compose can read the project:
128137
docker compose config
129138
```
130139

131-
You should see output that includes the resolved `webapp` service:
140+
The output includes the resolved `webapp` service, and is similar to:
132141

133142
```output
134143
services:
@@ -142,7 +151,7 @@ services:
142151
published: "3001"
143152
```
144153

145-
At this point, Compose can build and run the Cortex-A web application as a normal Linux container. The image runs `webapp/src/app.py`, packages the Jinja templates from `webapp/src/templates/`, the static assets from `webapp/src/static/`, and the ImageNet labels from `webapp/src/data/imagenet_classes.txt`. The container listens on port `3000`, and Compose publishes it on host port `3001` unless you set `WEBAPP_PORT` to another value.
154+
At this point, Compose can build and run the Cortex-A web application as a normal Linux container. The image runs `webapp/src/app.py`. It packages the Jinja templates from `webapp/src/templates/`, the static assets from `webapp/src/static/`, and the ImageNet labels from `webapp/src/data/imagenet_classes.txt`. The container listens on port `3000`, and Compose publishes it on host port `3001` unless you set `WEBAPP_PORT` to another value.
146155

147156
## Add the ExecuTorch artifact pipeline
148157

@@ -206,9 +215,9 @@ services:
206215
- ${IMX93_RUNNER_BUILD_CACHE_IMAGE:-ghcr.io/arm-examples/topo-imx93-npu-deployment/imx93-runner-build:mcux-v25.09.00-armgcc14.2-ubuntu24.04}
207216
```
208217

209-
Do not replace the existing root `webapp` service with the snippet above. The root file should now have three service names under the same top-level `services:` map: `webapp`, `pte-artifacts`, and `runner-artifacts`.
218+
Don't replace the existing root `webapp` service with this snippet. The root file should now have three service names under the same top-level `services:` map: `webapp`, `pte-artifacts`, and `runner-artifacts`.
210219

211-
These services are used only to build artifacts. They do not run as part of the deployed application. `scale: 0` tells Compose not to start containers for them, while still allowing other services to copy files from their build outputs.
220+
These services are used only to build artifacts. They don't run as part of the deployed application. `scale: 0` tells Compose not to start containers for them, while still allowing other services to copy files from their build outputs.
212221

213222
Replace `webapp/compose.yaml` with the following version so the Flask image imports the `.pte` artifact:
214223

@@ -257,9 +266,9 @@ services:
257266
remoteproc.name: imx-rproc
258267
```
259268

260-
Keep the existing `webapp`, `pte-artifacts`, and `runner-artifacts` services in the same file. This step adds one more service; it does not replace any of the previous services.
269+
Keep the existing `webapp`, `pte-artifacts`, and `runner-artifacts` services in the same file. This step adds one more service and doesn't replace any of the previous services.
261270

262-
This is the heterogeneous deployment hook. Docker still builds an image, but the service is not started as a Linux userspace process. The runtime `io.containerd.remoteproc.v1` selects Remoteproc Runtime, and the `remoteproc.name` annotation tells the shim to use the i.MX remote processor driver.
271+
This is the heterogeneous deployment hook. Docker still builds an image, but the service doesn't start as a Linux userspace process. The runtime `io.containerd.remoteproc.v1` selects Remoteproc Runtime, and the `remoteproc.name` annotation tells the shim to use the i.MX remote processor driver.
263272

264273
Update the existing root `webapp` service so it depends on the CM33 runner and passes the cache image values into the build. Keep the existing `extends` block, then add `depends_on` and `build.args` as shown:
265274

@@ -280,14 +289,14 @@ services:
280289

281290
The web app is privileged and mounts `/sys` and `/dev` because it checks the device tree, reads remoteproc state through `/sys/class/remoteproc`, talks to `/dev/ttyRPMSG*`, writes shared memory through `/dev/mem`, and checks for `/dev/ethosu0`.
282291

283-
Keep the web app build context in `webapp/compose.yaml`. The root `webapp.build.args` block above only supplies Topo-collected build arguments; it should not replace the extended build context and Dockerfile from `webapp/compose.yaml`.
292+
Keep the web app build context in `webapp/compose.yaml`. The root `webapp.build.args` block supplies only Topo-collected build arguments. It shouldn't replace the extended build context and Dockerfile from `webapp/compose.yaml`.
284293

285294
## Add Topo metadata and arguments
286295

287296
After the Compose services are complete, add the root-level `x-topo` block.
288297
Keep it at the root of `compose.yaml`, as a sibling of `services`, not under `services`.
289298

290-
If you want to use an agent skill to perform this step, skip to the optional step below.
299+
If you want to use an agent skill to perform this step, skip to the optional step.
291300

292301
```yaml
293302
x-topo:
@@ -306,9 +315,9 @@ x-topo:
306315
default: ghcr.io/arm-examples/topo-imx93-npu-deployment/imx93-runner-build:mcux-v25.09.00-armgcc14.2-ubuntu24.04
307316
```
308317

309-
The `features` value tells Topo that this Template requires `remoteproc-runtime` support on the target. This is useful when checking for project compatibility with the `topo templates --target <target>` command.
318+
The `features` value tells Topo that this template requires `remoteproc-runtime` support on the target. This is useful when checking for project compatibility with the `topo templates --target <target>` command.
310319

311-
The `args` entries describe configurable build inputs. Compose consumes those values through the `cache_from` interpolation you added earlier:
320+
The `args` entries describe configurable build inputs. Compose consumes those values through the `cache_from` interpolation that you added earlier:
312321

313322
```output
314323
cache_from:
@@ -317,13 +326,13 @@ cache_from:
317326

318327
The root `webapp.build.args` block also makes the Topo-provided values visible in the Compose build model while preserving the `webapp/` build context inherited through `extends`.
319328

320-
Keep runtime settings such as `WEBAPP_PORT` as normal Compose interpolation unless you intentionally want Topo to collect them as Template setup arguments.
329+
Keep runtime settings such as `WEBAPP_PORT` as normal Compose interpolation unless you intentionally want Topo to collect them as Topo Template setup arguments.
321330

322331
## (Optional) Use an Agent Skill to add the Topo metadata
323332

324333
The [Topo Template Format](https://github.com/arm/topo-template-format) repository includes public authoring skills for agents that support skill installation:
325334

326-
- `topo-template-context`: provides Topo and Topo Template reference context for `x-topo` metadata, schema, docs, and CLI Template behavior.
335+
- `topo-template-context`: provides Topo and Topo Template reference context for `x-topo` metadata, schema, docs, and CLI template behavior.
327336
- `topo-template-bootstrap`: converts a Compose repository into a Topo Template by adding or improving `compose.yaml` and `x-topo` metadata.
328337
- `topo-template-lint`: reviews a Topo Template for schema correctness, metadata consistency, deployment success messages, and build argument wiring.
329338

@@ -333,7 +342,7 @@ Install the skills with `npx skills`:
333342
npx skills add arm/topo-template-format
334343
```
335344

336-
If your agent does not use `npx skills`, manually copy or symlink the directories under `../topo-template-format/skills/` into your agent's skills directory.
345+
If your agent doesn't use `npx skills`, manually copy or symlink the directories under `../topo-template-format/skills/` into your agent's skills directory.
337346

338347
Restart your agent after installing or updating the skills.
339348

@@ -354,7 +363,7 @@ Validate compose.yaml against the Topo Template Format schema.
354363
Check README alignment, Remoteproc Runtime metadata, and x-topo.args wiring.
355364
```
356365

357-
## Validate the final Template
366+
## Validate the final Topo Template
358367

359368
Check the Compose model and check that the Topo metadata is present:
360369

@@ -368,7 +377,7 @@ In the `docker compose config` output, check that the resolved `webapp` service
368377
- `build.dockerfile` set to `Dockerfile`
369378
- `build.additional_contexts.pte_artifacts` set to `service:pte-artifacts`
370379

371-
Install `check-jsonschema` if it is not already available:
380+
Install `check-jsonschema` if it's not already available:
372381

373382
{{< tabpane code=true >}}
374383
{{< tab header="macOS" language="shell" >}}
@@ -407,4 +416,4 @@ Review these points:
407416

408417
You started with two non-Topo, non-Compose projects, made them a standard Compose project, and then converted that Compose project into a Topo Template. You created the web app image, added artifact builds for the ExecuTorch `.pte` model and Cortex-M33 ELF, packaged the firmware as a Remoteproc Runtime service, and exposed the build cache inputs as Topo arguments.
409418

410-
Next, you will prepare the FRDM i.MX 93 target, deploy the Template with Topo, and run the image classification application.
419+
Next, you'll prepare the FRDM i.MX 93 target, deploy the template with Topo, and run the image classification application.

0 commit comments

Comments
 (0)