← All courses ← Course home

Lesson 05 of 07

Convert so the runtime gets a graph it can run

The export and conversion steps are required, not optional extras. They make a graph that Core AI and its Metal path can actually run.

Agent brief (llms.md)

Environment setup

Use Python 3.11 or newer on macOS. uv manages the project and virtual environment. The device check picks Apple Silicon MPS when it is available, and CPU if it is not.

curl -LsSf https://astral.sh/uv/install.sh | sh
mkdir -p clothing-coreai && cd clothing-coreai
uv init --python 3.11
uv venv
uv add torch torchvision coreai-torch
uv run python -c "import torch, torchvision; print(torch.__version__, torchvision.__version__); print('MPS:', torch.backends.mps.is_available())"
uv run python convert.py

Save the lesson code as train.py or the named script for this lesson. uv run uses the project environment, so you do not need a global pip install.

Work backward from AIModel and main. The app needs a portable clothing.aimodel with named tensors and operations that Core AI can turn into hardware work. That is why the original course uses torch.export and coreai-torch. Conversion is a runtime need that you can see as a build step.

Build the graph the runtime can run

PyTorchClothingCNN
IRtorch.export
Loweringget_decomp_table()
Assetclothing.aimodel

torch.export makes the graph and its assumptions clear. get_decomp_table() gives the Core AI breakdown choices so bigger operations become forms the converter can handle. TorchConverter packages the resulting program as a Core AI file with input name image, output name logits, and function main.

# The forward course has the full script. The order is the point.
example = torch.zeros(1, 1, 28, 28, dtype=torch.float32)
ep = torch.export.export(model.eval(), args=(example,))
ep = ep.run_decompositions(get_decomp_table())

# Register any release-supported custom Metal kernels first.
# register_custom_kernels(...)
coreai_program = TorchConverter().add_exported_program(
    ep, input_names=["image"], output_names=["logits"]
)
asset = coreai_program.to_coreai().save_asset("clothing.aimodel")

The custom-kernel line is a reminder of where it goes, not a fake API recipe. When you use the Apple and coreai-torch custom Metal tools, register the kernels before add_exported_program and follow the names in the installed release. Without custom kernels, ordinary graph lowering still handles the operations that are supported.

Names are part of the runtime contract

Input nameimage
Shape[1,1,28,28] float32
Functionmain
Output namelogits [1,10]

Inspect the saved file in Xcode's model viewer. Confirm the function name, tensor names, shapes, and element types before you debug Swift. A successful Python conversion does not prove that the app is passing the right array. The runtime and the app both depend on the same description.

What conversion must give Metal

Conversion also depends on the step before it. The graph can only be exported because training produced a model with sensible fixed shapes, class order, and portable weights. Continue to Training must give conversion a model it can use, then compare the original training lesson.

Key concepts

  • Conversion exists so the runtime gets a graph it can run.
  • The path is ClothingCNN to torch.export to get_decomp_table() to TorchConverter to clothing.aimodel.
  • Export with a float32 [1, 1, 28, 28] example. Names image, logits, and main are part of the contract.
  • Inspect the saved asset in the Xcode model viewer before you debug Swift.

Takeaways

  • Successful Python conversion does not prove the app passes the right array.
  • Fixed example shapes in export must match what the app will pass.
  • Only supported lowerings or clearly registered custom kernels should reach the file.