Skip to content

Commit 4065c18

Browse files
marc0oloclaude
andcommitted
chore: migrate rust/face-recognition to icp-cli
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent bafb2cf commit 4065c18

41 files changed

Lines changed: 264 additions & 5234 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: face-recognition
2+
3+
on:
4+
push:
5+
branches: [master]
6+
pull_request:
7+
paths:
8+
- rust/face-recognition/**
9+
- .github/workflows/face-recognition.yml
10+
11+
concurrency:
12+
group: ${{ github.workflow }}-${{ github.ref }}
13+
cancel-in-progress: true
14+
15+
jobs:
16+
rust-face-recognition:
17+
runs-on: ubuntu-24.04
18+
container: ghcr.io/dfinity/icp-dev-env-rust:1.0.0
19+
env:
20+
ICP_CLI_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
21+
steps:
22+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
23+
- name: Deploy and test
24+
working-directory: rust/face-recognition
25+
run: |
26+
icp network start -d
27+
icp deploy
28+
make test

‎.github/workflows/rust-face-recognition-example.yaml‎

Lines changed: 0 additions & 46 deletions
This file was deleted.

‎rust/face-recognition/.cargo/config.toml‎

Lines changed: 0 additions & 5 deletions
This file was deleted.

‎rust/face-recognition/.gitignore‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
.dfx/
21
build/
32
node_modules/
43
dist/
@@ -8,6 +7,7 @@ _MACOSX
87
target/
98
*.old.did
109
.idea
11-
src/backend/assets/version-RFB-320.onnx
12-
src/backend/assets/facerec.onnx
13-
.env
10+
backend/assets/version-RFB-320.onnx
11+
backend/assets/facerec.onnx
12+
frontend/src/bindings/
13+
.icp/cache/

‎rust/face-recognition/Cargo.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
[workspace]
2-
members = ["src/backend"]
2+
members = ["backend"]
33
resolver = "2"

‎rust/face-recognition/Makefile‎

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
.PHONY: test upload-models
2+
3+
test:
4+
@echo "=== Test 1: clear_face_detection_model_bytes returns unit ==="
5+
@result=$$(icp canister call backend clear_face_detection_model_bytes '()') && \
6+
echo "$$result" && \
7+
echo "PASS" || (echo "FAIL" && exit 1)
8+
9+
@echo "=== Test 2: clear_face_recognition_model_bytes returns unit ==="
10+
@result=$$(icp canister call backend clear_face_recognition_model_bytes '()') && \
11+
echo "$$result" && \
12+
echo "PASS" || (echo "FAIL" && exit 1)
13+
14+
@echo "=== Test 3: append_face_detection_model_bytes accepts bytes ==="
15+
@result=$$(icp canister call backend append_face_detection_model_bytes '(blob "\00\01\02")') && \
16+
echo "$$result" && \
17+
echo "PASS" || (echo "FAIL" && exit 1)
18+
19+
@echo "=== Test 4: run_detection returns Err when model is not set up ==="
20+
@result=$$(icp canister call --query backend run_detection '()') && \
21+
echo "$$result" && \
22+
echo "$$result" | grep -q 'Err' && \
23+
echo "PASS" || (echo "FAIL" && exit 1)
24+
25+
# Upload ONNX model files to the canister incrementally.
26+
# Requires: ic-file-uploader (cargo install ic-file-uploader)
27+
# First download the models: ./download-face-detection-model.sh
28+
# and obtain face-recognition.onnx (see README), then run: make upload-models
29+
upload-models:
30+
icp canister call backend clear_face_detection_model_bytes '()'
31+
icp canister call backend clear_face_recognition_model_bytes '()'
32+
ic-file-uploader backend append_face_detection_model_bytes version-RFB-320.onnx
33+
ic-file-uploader backend append_face_recognition_model_bytes face-recognition.onnx
34+
icp canister call backend setup_models '()'

‎rust/face-recognition/README.md‎

Lines changed: 51 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,96 +1,94 @@
11
# ICP face recognition
22

3-
This is an ICP smart contract runs face detection and face recognition of user's photo that can be uploaded either from a camera or a local file.
3+
This is an ICP smart contract that runs face detection and face recognition on user photos that can be uploaded either from a camera or a local file.
44

55
The smart contract consists of two canisters:
66

7-
- The backend canister embeds the [the Tract ONNX inference engine](https://github.com/sonos/tract) with two ONNX models. One model is used to detect a face in the photo and return its bounding box. Another model is used for computing face embeddings.
8-
- The frontend canister contains the Web assets such as HTML, JS, CSS that are served to the browser.
7+
- The **backend canister** embeds the [Tract ONNX inference engine](https://github.com/sonos/tract) with two ONNX models. One model is used to detect a face in the photo and return its bounding box. Another model is used for computing face embeddings.
8+
- The **frontend canister** contains the Web assets such as HTML, JS, and CSS that are served to the browser.
99

10-
# Models
10+
## Models
1111

1212
The smart contract uses two models: one for detecting the face and another for recognizing the face.
1313

14-
## Face detection
14+
Since the models are large, they cannot be embedded into the Wasm binary of the smart contract. Instead they must be uploaded separately after deployment.
1515

16-
A face detection model finds the bounding box of a face in the image.
17-
You can download [Ultraface](https://github.com/onnx/models/tree/main/validated/vision/body_analysis/ultraface) - ultra-lightweight face detection model - [[here](https://github.com/onnx/models/blob/bec48b6a70e5e9042c0badbaafefe4454e072d08/validated/vision/body_analysis/ultraface/models/version-RFB-320.onnx)].
16+
### Face detection
1817

19-
Alternatively, you can run
18+
A face detection model finds the bounding box of a face in the image.
19+
You can download [Ultraface](https://github.com/onnx/models/tree/main/validated/vision/body_analysis/ultraface) — ultra-lightweight face detection model — by running:
2020

21-
```
21+
```bash
2222
./download-face-detection-model.sh
2323
```
2424

25-
## Face recognition
25+
### Face recognition
2626

2727
A face recognition model computes a vector embedding of an image with a face.
2828
You can obtain a pretrained model from [facenet-pytorch](https://github.com/timesler/facenet-pytorch) as follows.
2929

30-
- #### Step 1: Install `python` and `pip`: https://packaging.python.org/en/latest/tutorials/installing-packages/.
30+
1. Install `python` and `pip`: https://packaging.python.org/en/latest/tutorials/installing-packages/
3131

32-
- #### Step 2: Install `facenet-pytorch` and `torch`:
32+
2. Install `facenet-pytorch`, `torch`, and `onnx`:
3333

34-
```
35-
pip install facenet-pytorch
36-
pip install torch
37-
pip install onnx
38-
```
34+
```bash
35+
pip install facenet-pytorch
36+
pip install torch
37+
pip install onnx
38+
```
3939

40-
- #### Step 3: Export ONNX model. Start a python shell and run the following commands or create a python file and run it:
40+
3. Export the ONNX model. Start a Python shell and run:
4141

42-
```
43-
import torch
44-
import facenet_pytorch
45-
resnet = facenet_pytorch.InceptionResnetV1(pretrained='vggface2').eval()
46-
input = torch.randn(1, 3, 160, 160)
47-
torch.onnx.export(resnet, input, "face-recognition.onnx", verbose=False, opset_version=11)
48-
```
42+
```python
43+
import torch
44+
import facenet_pytorch
45+
resnet = facenet_pytorch.InceptionResnetV1(pretrained='vggface2').eval()
46+
input = torch.randn(1, 3, 160, 160)
47+
torch.onnx.export(resnet, input, "face-recognition.onnx", verbose=False, opset_version=11)
48+
```
4949

50-
- #### Step 4: This should produce `face-recognition.onnx`. Copy the file to the root of this repository.
50+
This produces `face-recognition.onnx`. Copy the file to the root of this repository.
5151

52-
## Prerequisites
52+
## Build and deploy from the command line
5353

54-
- [x] Install the [IC
55-
SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required.
56-
- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples`
57-
- [x] Install `wasi2ic`: Follow the steps in https://github.com/wasm-forge/wasi2ic and make sure that `wasi2ic` binary is in your `$PATH`.
58-
- [x] Install `wasm-opt`: `cargo install wasm-opt`
54+
### Prerequisites
5955

60-
## Build the application
56+
- Node.js
57+
- icp-cli: `npm install -g @icp-sdk/icp-cli @icp-sdk/ic-wasm`
6158

62-
```
63-
dfx start --background
64-
dfx deploy
59+
### Install
60+
61+
```bash
62+
git clone https://github.com/dfinity/examples
63+
cd examples/rust/face-recognition
6564
```
6665

67-
If the deployment is successful, the it will show the `frontend` URL.
68-
Open that URL in browser to interact with the smart contract.
66+
### Deploy and test
6967

70-
## Chunk uploading of models
68+
```bash
69+
icp network start -d
70+
icp deploy
71+
make test
72+
icp network stop
73+
```
7174

72-
Since the models are large, they cannot be embedded into the Wasm binary of the smart contract.
73-
Instead they should be uploaded separately.
75+
Run `npm run dev` from the `frontend/` directory for hot reload during frontend development.
7476

75-
[DecideAI](https://decideai.xyz/) implemented a tool for incremental uploading of models: https://github.com/modclub-app/ic-file-uploader/tree/main.
77+
### Upload the ONNX models
7678

77-
You can install the tool with
79+
After deploying, upload the ONNX models to the canister using [ic-file-uploader](https://github.com/modclub-app/ic-file-uploader/tree/main):
7880

79-
```
81+
```bash
8082
cargo install ic-file-uploader
83+
make upload-models
8184
```
8285

83-
Afterwards, execute the `upload-models-to-canister.sh` script, which runs the following commands:
84-
85-
```
86-
dfx canister call backend clear_face_detection_model_bytes
87-
dfx canister call backend clear_face_recognition_model_bytes
88-
ic-file-uploader backend append_face_detection_model_bytes version-RFB-320.onnx
89-
ic-file-uploader backend append_face_recognition_model_bytes face-recognition.onnx
90-
dfx canister call backend setup_models
91-
```
86+
Once the models are uploaded, open the frontend URL in your browser to interact with the smart contract.
9287

9388
## Credits
9489

9590
Thanks to [DecideAI](https://decideai.xyz/) for discussions and providing [ic-file-uploader](https://github.com/modclub-app/ic-file-uploader/tree/main).
9691

92+
## Security considerations and best practices
93+
94+
See the [ICP security best practices](https://docs.internetcomputer.org/guides/security/overview).

rust/face-recognition/src/backend/Cargo.toml renamed to rust/face-recognition/backend/Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
2-
edition = "2021"
32
name = "backend"
43
version = "1.1.0"
4+
edition = "2021"
55

66
[lib]
77
crate-type = ["cdylib"]
@@ -19,4 +19,3 @@ prost = "0.11.0"
1919
prost-types = "0.11.0"
2020
serde = { version = "1.0", features = ["derive"] }
2121
tract-onnx = { git = "https://github.com/sonos/tract", rev = "2a2914ac29390cc08963301c9f3d437b52dd321a" }
22-
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)