Project: WasmEdge Runtime (Runtime / Container Runtime)
File: vercel.md

In this article, we will show you two serverless functions in Rust and WasmEdge deployed on Vercel. One is the image processing function, the other one is the TensorFlow inference function. For more insights on why WasmEdge on Vercel, please refer to the article . Since our demo WebAssembly functions are written in Rust, you will need a . Make sure that you install the `wasm32-wasi` compiler target as follows, in order to generate WebAssembly bytecode. ```bash rustup target add wasm32-wasi ``` The demo application front end is written in , and deployed on Vercel. We will assume that you already have the basic knowledge of how to work with Vercel. Our first demo application allows users to upload an image and then invoke a serverless function to turn it into black and white. A deployed on Vercel is available. Fork the to get started. To deploy the application on Vercel, just from web page. This repo is a standard Next.js application for the Vercel platform. The backend serverless function is in the folder. The file contains the Rust programs source code. The Rust program reads image data from the `STDIN`, and then outputs the black-white image to the `STDOUT`. ```rust use hex; use std::io::{self, Read}; use image::{ImageOutputFormat, ImageFormat}; fn main() { let mut buf = Vec::new(); io::stdin().readtoend(&mut buf).unwrap(); let imageformatdetected: ImageFormat = image::guess_format(&buf).unwrap(); let img = image::loadfrommemory(&buf).unwrap(); let filtered = img.grayscale(); let mut buf = vec![]; match imageformatdetected { ImageFormat::Gif => { filtered.write_to(&mut buf, ImageOutputFormat::Gif).unwrap(); }, _ => { filtered.write_to(&mut buf, ImageOutputFormat::Png).unwrap(); }, }; io::stdout().write_all(&buf).unwrap(); io::stdout().flush().unwrap(); } ``` You can use Rusts `cargo` tool to build the Rust program into WebAssembly bytecode or native code. ```bash cd api/functions/image-grayscale/ cargo build --release --target wasm32-wasi ``` Copy the build artifacts to the `api` folder. ```bash cp target/wasm32-wasi/release/grayscale.wasm ../../ ``` Vercel runs upon setting up the serverless environment. It installs the WasmEdge runtime, and then compiles each WebAssembly bytecode program into a native `so` library for faster execution. The file conforms Vercel serverless specification. It loads the WasmEdge runtime, starts the compiled WebAssembly program in WasmEdge, and passes the uploaded image data via `STDIN`. Notice runs the compiled `grayscale.so` file generated by for better performance. ```javascript const fs = require('fs'); const { spawn } = require('child_process'); const path = require('path'); module.exports = (req, res) => { const wasmedge = spawn( path.join(dirname, 'wasmedge'), [path.join(dirname, 'grayscale.so')]); let d = []; wasmedge.stdout.on('data', (data) => { d.push(data); }); wasmedge.on('close', (code) => { let buf = Buffer.concat(d); res.setHeader('Content-Type', req.headers['image-type']); res.send(buf); }); wasmedge.stdin.write(req.body); wasmedge.stdin.end(''); } ``` That's it. and you now have a Vercel Jamstack app with a high-performance Rust and WebAssembly based serverless

The application allows users to upload an image and then invoke a serverless function to classify the main subject on the image. It is in as the previous example but in the `tensorflow` branch. Note: when you on the Vercel website, it will create a for each branch. The `tensorflow` branch would have its own deployment URL. The backend serverless function for image classification is in the folder in the `tensorflow` branch. The file contains the Rust programs source code. The Rust program reads image data from the `STDIN`, and then outputs the text output to the `STDOUT`. It utilizes the WasmEdge Tensorflow API to run the AI inference. ```rust pub fn main() { // Step 1: Load the TFLite model let modeldata: &[u8] = includebytes!("models/mobilenetv11.0224/mobilenetv11.0224_quant.tflite"); let labels = includestr!("models/mobilenetv11.0224/labelsmobilenetquantv1224.txt"); // Step 2: Read image from STDIN let mut buf = Vec::new(); io::stdin().readtoend(&mut buf).unwrap(); // Step 3: Resize the input image for the tensorflow model let flatimg = wasmedgetensorflowinterface::loadjpgimageto_rgb8(&buf, 224, 224); // Step 4: AI inference let mut session = wasmedgetensorflowinterface::Session::new(&modeldata, wasmedgetensorflow_interface::ModelType::TensorFlowLite); session.addinput("input", &flatimg, &[1, 224, 224, 3]) .run(); let resvec: Vec<u8> = session.getoutput("MobilenetV1/Predictions/Reshape_1"); // Step 5: Find the food label that responds to the highest probability in res_vec // ... ... let mut label_lines = labels.lines(); for i in 0..maxindex { label_lines.next(); } // Step 6: Generate the output text let classname = labellines.next().unwrap().to_string(); if max_value > 50 { println!("It {} a <a href='https://www.google.com/search?q={}'>{}</a> in the picture", confidence.tostring(), classname, class_name); } else { println!("It does not appears to be any food item in the picture."); } } ``` You can use the `cargo` tool to build the Rust program into WebAssembly bytecode or native code. ```bash cd api/functions/image-classification/ cargo build --release --target wasm32-wasi ``` Copy the build artifacts to the `api` folder. ```bash cp target/wasm32-wasi/release/classify.wasm ../../ ``` Again, the script installs WasmEdge runtime and its Tensorflow dependencies in this application. It also compiles the `classify.wasm` bytecode program to the `classify.so` native shared library at the time of deployment. The file conforms Vercel serverless specification. It loads the WasmEdge runtime, starts the compiled WebAssembly program in WasmEdge, and passes the uploaded image data via `STDIN`. Notice runs the compiled `classify.so` file generated by for better performance. ```javascript const fs = require('fs'); const { spawn } = require('child_process'); const path = require('path'); module.exports = (req, res) => { const wasmedge = spawn( path.join(dirname, 'wasmedge-tensorflow-lite'), [path.join(dirname, 'classify.so')], {env: {'LDLIBRARYPATH': dirname}} ); let d = []; wasmedge.stdout.on('data', (data) => { d.push(data); }); wasmedge.on('close', (code) => { res.setHeader('Content-Type', `text/plain`); res.send(d.join('')); }); wasmedge.stdin.write(req.body); wasmedge.stdin.end(''); } ``` You can now and have a web app for subject classification. Next, it's your turn to use as a template to develop your own Rust serverless functions in Vercel. Looking forward to your great work.