Test FP32 Ethos-U delegation

Prepare the MobileNetV2 model used in Module 2, this time for the Ethos-U backend rather than a CPU backend like XNNPACK.

Run on the Linux host:

    

        
        
python module-4-ethos-npu-accelerated-inference/scripts/aot/prepare_mobilenetv2.py \
  --out module-4-ethos-npu-accelerated-inference/artifacts/mobilenetv2

    

The preparation script downloads the same TorchVision MobileNetV2 IMAGENET1K_V1 weights and public-domain yellow Labrador image used in Module 2, saves a state dict, and writes ImageNet labels:

    

        
        
weights = MobileNet_V2_Weights.IMAGENET1K_V1
model = mobilenet_v2(weights=weights).eval()
torch.save(model.state_dict(), weights_path)

labels_path.write_text(json.dumps(weights.meta["categories"], indent=2) + "\n")

    

The script also writes the model input shape and preprocessing settings and creates model_spec.json:

    

        
        
spec = {
    "name": "mobilenetv2",
    "weights": weights_path.name,
    "labels": labels_path.name,
    "sample_image": sample_path.name if sample_path.exists() else None,
    "input": {
        "shape": [1, 3, 224, 224],
        "preprocessing": {
            "resize": 256,
            "center_crop": 224,
            "mean": [0.485, 0.456, 0.406],
            "std": [0.229, 0.224, 0.225],
        },
    },
}

    

The shape [1, 3, 224, 224] is one RGB image in NCHW order: batch, channels, height, and width. The resize, crop, mean, and standard deviation are the ImageNet preprocessing values expected by the pre-trained MobileNetV2 model.

Attempt to lower the FP32 model for Ethos-U:

    

        
        
python module-4-ethos-npu-accelerated-inference/scripts/aot/lower_fp32_ethosu.py \
  --spec module-4-ethos-npu-accelerated-inference/artifacts/mobilenetv2/model_spec.json \
  --target ethos-u85-256 \
  --system-config Ethos_U85_SYS_DRAM_Mid \
  --memory-mode Shared_Sram

    

You should expect to see output similar to this:

    

        
        
PTE size: 14.24 MB

Delegation
==========
Ethos-U delegate call sites: 0
Fallback call_function ops:  461

Selected non-delegated operators:
  aten._native_batch_norm_legit_no_training.out (52)
  aten.add.out (10)
  aten.addmm.out (1)
  aten.convolution.out (52)
  aten.hardtanh.out (35)
  aten.mean.out (1)

    

Record the results you obtain:

ItemResult, and what it means
Ethos-U delegate call sites
Fallback call_function operations

The script writes a .pte artifact, but the delegation summary shows that no region was handed to Ethos-U. The selected operators show that the MobileNetV2 convolutions, batch normalization, activations, and classifier remain outside the Ethos-U delegate. This result is expected. Ethos-U acceleration is designed around quantized integer workloads. An FP32 .pte artifact can still be generated, but no subgraphs are delegated to the NPU. Its operations remain on the default ExecuTorch path and would require compatible target CPU kernels to run. Generating the artifact does not prove that it can execute on the FVP; this module does not run it.

Understand the script

The script follows the same basic export-and-lower pattern used in Module 2. It reloads the MobileNetV2 weights prepared earlier, creates an example tensor with the shape from model_spec.json, exports the model, lowers with a backend partitioner, writes the .pte artifact, and prints a delegation summary.

    

        
        
spec = json.loads(args.spec.read_text())
artifact_dir = args.spec.parent

model = mobilenet_v2(weights=None).eval()
model.load_state_dict(torch.load(artifact_dir / spec["weights"], map_location="cpu"))

example_inputs = (torch.randn(*spec["input"]["shape"]),)
exported = export_no_guards(model, example_inputs)

    

The main difference from Module 2 is the backend. Module 2 used XnnpackPartitioner for CPU execution. This script uses an Ethos-U compile specification and EthosUPartitioner, so the Arm backend can identify regions that Vela can compile for the selected Ethos-U target.

The lowering stage is:

    

        
        
compile_spec = EthosUCompileSpec(
    target=args.target,
    system_config=args.system_config,
    memory_mode=args.memory_mode,
    extra_flags=args.extra_flag,
)

edge = to_edge_transform_and_lower(
    exported,
    compile_config=EdgeCompileConfig(_check_ir_validity=False),
    partitioner=[EthosUPartitioner(compile_spec)],
)

    
ExecuTorch API Highlight

EthosUCompileSpec records the target NPU, system configuration, memory mode, and Vela options used by the Arm backend. EthosUPartitioner uses this configuration when identifying regions that can be compiled by Vela. The partitioner is supplied to the same to_edge_transform_and_lower() API used with XNNPACK in earlier modules.

The compile specification tells the Arm backend which NPU target, system configuration, and memory mode to use. In this module, the target is ethos-u85-256, the system configuration is Ethos_U85_SYS_DRAM_Mid, and the memory mode is Shared_Sram.

Previous page Complete and continue