This example demonstrates running face detection and face recognition inside an ICP canister using the Tract ONNX inference engine. Users can upload photos from a camera or local file, detect faces, and identify people by name.
The example consists of two canisters:
-
backend — embeds the Tract ONNX inference engine. Exposes endpoints for uploading ONNX model files in chunks, loading them into memory, detecting faces, computing face embeddings, and recognizing people. Also includes
run_detection(query) andrun_recognition(update) endpoints that run the models against a built-in test image — useful during development for capacity planning. Since query calls don't persist logs on ICP, only the update call produces a visible instruction count:icp canister call backend run_recognition '()' icp canister logs backend -
frontend — serves the web UI (HTML/JS/CSS).
The backend uses two ONNX models that are too large to embed in the Wasm binary and must be uploaded after deployment. icp deploy handles this automatically via its sync phase:
- Face detection (Ultraface) — downloaded automatically.
- Face recognition (facenet-pytorch InceptionResnetV1) — generated automatically if Python 3.9–3.12 is available (
facenet-pytorch,torch, andonnxare installed via pip). If no compatible Python is found, placeface-recognition.onnxin the project root manually and runicp deployagain.
Models are stored in stable memory and survive canister upgrades — they reload automatically without re-uploading. Note: the persons database (added via the frontend) is stored in heap memory and is cleared on upgrade.
Required:
- Node.js v18+
- icp-cli:
npm install -g @icp-sdk/icp-cli @icp-sdk/ic-wasm - Rust v1.85+ with
wasm32-wasip1target:rustup target add wasm32-wasip1 - wasi2ic:
cargo install wasi2ic
wasm-opt is installed automatically on first deploy if not already present.
Optional (for automatic face recognition model generation):
- Python 3.9–3.12 with pip — the sync phase auto-installs
facenet-pytorch,torch, andonnxand generatesface-recognition.onnx. Python 3.13+ is not yet supported by torch.
git clone https://github.com/dfinity/examples
cd examples/rust/face-recognitionicp network start -d
icp deploy
icp network stopicp deploy runs three phases:
- Build — compiles the Rust backend to WASM (via wasm32-wasip1 + wasi2ic).
- Deploy — installs the backend and frontend canisters.
- Sync — downloads the face detection model, generates the face recognition model (if Python 3.9–3.12 is available), and uploads both to the canister. Skipped on redeployment if models are already loaded.
After deployment the CLI prints the frontend URL. Open it in a browser to interact with the canister.
bash test.shtest.sh exercises the model management API without requiring models to be loaded. The frontend shows a setup instruction if models are not yet uploaded.
For frontend development with hot reload:
npm run dev --prefix frontendOnly needed if you change the backend endpoints. Requires candid-extractor (cargo install candid-extractor):
icp build backend && candid-extractor ./target/wasm32-wasip1/release/backend.wasm > backend/backend.didThanks to DecideAI for discussions and providing ic-file-uploader.
See the ICP security best practices.