From e9e4afe2c7930508c2cb399946ad8afb7d01b6c5 Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Tue, 13 Apr 2021 12:16:15 -0700 Subject: [PATCH] wasi-nn: use the MobileNet model instead of AlexNet The MobileNet model is significantly smaller in size (14MB) than the AlexNet model (233MB); this change should reduce bandwidth used during CI. --- ci/run-wasi-nn-example.sh | 10 +++++----- .../examples/classification-example/src/main.rs | 15 +++++++++------ 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/ci/run-wasi-nn-example.sh b/ci/run-wasi-nn-example.sh index e24ffa75ac..49c472c95e 100755 --- a/ci/run-wasi-nn-example.sh +++ b/ci/run-wasi-nn-example.sh @@ -7,7 +7,7 @@ # executed with the Wasmtime CLI. set -e WASMTIME_DIR=$(dirname "$0" | xargs dirname) -FIXTURE=https://github.com/intel/openvino-rs/raw/main/crates/openvino/tests/fixtures/alexnet +FIXTURE=https://github.com/intel/openvino-rs/raw/main/crates/openvino/tests/fixtures/mobilenet if [ -z "${1+x}" ]; then # If no temporary directory is specified, create one. TMP_DIR=$(mktemp -d -t ci-XXXXXXXXXX) @@ -26,9 +26,9 @@ source /opt/intel/openvino/bin/setupvars.sh OPENVINO_INSTALL_DIR=/opt/intel/openvino cargo build -p wasmtime-cli --features wasi-nn # Download all necessary test fixtures to the temporary directory. -wget --no-clobber --directory-prefix=$TMP_DIR $FIXTURE/alexnet.bin -wget --no-clobber --directory-prefix=$TMP_DIR $FIXTURE/alexnet.xml -wget --no-clobber --directory-prefix=$TMP_DIR $FIXTURE/tensor-1x3x227x227-f32.bgr +wget --no-clobber $FIXTURE/mobilenet.bin --output-document=$TMP_DIR/model.bin +wget --no-clobber $FIXTURE/mobilenet.xml --output-document=$TMP_DIR/model.xml +wget --no-clobber $FIXTURE/tensor-1x224x224x3-f32.bgr --output-document=$TMP_DIR/tensor.bgr # Now build an example that uses the wasi-nn API. pushd $WASMTIME_DIR/crates/wasi-nn/examples/classification-example @@ -42,4 +42,4 @@ OPENVINO_INSTALL_DIR=/opt/intel/openvino cargo run --features wasi-nn -- run --m # Clean up the temporary directory only if it was not specified (users may want to keep the directory around). if [[ $REMOVE_TMP_DIR -eq 1 ]]; then rm -rf $TMP_DIR -fi \ No newline at end of file +fi diff --git a/crates/wasi-nn/examples/classification-example/src/main.rs b/crates/wasi-nn/examples/classification-example/src/main.rs index 5f0a7f4e5a..6b415fb96b 100644 --- a/crates/wasi-nn/examples/classification-example/src/main.rs +++ b/crates/wasi-nn/examples/classification-example/src/main.rs @@ -3,10 +3,10 @@ use std::fs; use wasi_nn; pub fn main() { - let xml = fs::read_to_string("fixture/alexnet.xml").unwrap(); + let xml = fs::read_to_string("fixture/model.xml").unwrap(); println!("Read graph XML, first 50 characters: {}", &xml[..50]); - let weights = fs::read("fixture/alexnet.bin").unwrap(); + let weights = fs::read("fixture/model.bin").unwrap(); println!("Read graph weights, size in bytes: {}", weights.len()); let graph = unsafe { @@ -24,10 +24,10 @@ pub fn main() { // Load a tensor that precisely matches the graph input tensor (see // `fixture/frozen_inference_graph.xml`). - let tensor_data = fs::read("fixture/tensor-1x3x227x227-f32.bgr").unwrap(); + let tensor_data = fs::read("fixture/tensor.bgr").unwrap(); println!("Read input tensor, size in bytes: {}", tensor_data.len()); let tensor = wasi_nn::Tensor { - dimensions: &[1, 3, 227, 227], + dimensions: &[1, 3, 224, 224], r#type: wasi_nn::TENSOR_TYPE_F32, data: &tensor_data, }; @@ -42,7 +42,7 @@ pub fn main() { println!("Executed graph inference"); // Retrieve the output. - let mut output_buffer = vec![0f32; 1000]; + let mut output_buffer = vec![0f32; 1001]; unsafe { wasi_nn::get_output( context, @@ -60,10 +60,13 @@ pub fn main() { // Sort the buffer of probabilities. The graph places the match probability for each class at the // index for that class (e.g. the probability of class 42 is placed at buffer[42]). Here we convert -// to a wrapping InferenceResult and sort the results. +// to a wrapping InferenceResult and sort the results. It is unclear why the MobileNet output +// indices are "off by one" but the `.skip(1)` below seems necessary to get results that make sense +// (e.g. 763 = "revolver" vs 762 = "restaurant") fn sort_results(buffer: &[f32]) -> Vec { let mut results: Vec = buffer .iter() + .skip(1) .enumerate() .map(|(c, p)| InferenceResult(c, *p)) .collect();