From e5aa48fbd6e0a33825bd27dfaedf86c9c5fe509c Mon Sep 17 00:00:00 2001 From: dante <45801863+alexander-camuto@users.noreply.github.com> Date: Sat, 5 Oct 2024 10:43:12 -0400 Subject: [PATCH 1/2] chore: support all padding types (#848) --- Cargo.lock | 18 +++++-------- examples/onnx/boolean/gen.py | 4 ++- examples/onnx/boolean/input.json | 2 +- examples/onnx/boolean/network.onnx | 26 ++++++++---------- src/graph/node.rs | 14 ++++++++++ src/graph/utilities.rs | 43 +++++++++++++++--------------- 6 files changed, 57 insertions(+), 50 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1ac569874..0fdf7eb27 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2950,11 +2950,11 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" dependencies = [ - "spin 0.5.2", + "spin", ] [[package]] @@ -3532,9 +3532,9 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -4426,7 +4426,7 @@ dependencies = [ "cfg-if", "getrandom", "libc", - "spin 0.9.8", + "spin", "untrusted", "windows-sys 0.52.0", ] @@ -4980,12 +4980,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - [[package]] name = "spin" version = "0.9.8" diff --git a/examples/onnx/boolean/gen.py b/examples/onnx/boolean/gen.py index 0a434ccf4..c6564fd87 100644 --- a/examples/onnx/boolean/gen.py +++ b/examples/onnx/boolean/gen.py @@ -9,7 +9,9 @@ def __init__(self): super(MyModel, self).__init__() def forward(self, w, x, y, z): - return [((x & y)) == (x & (y | (z ^ w)))] + a = (x & y) + b = (y & (z ^ w)) + return [a & b] circuit = MyModel() diff --git a/examples/onnx/boolean/input.json b/examples/onnx/boolean/input.json index f4c5b9b85..18d044f3c 100644 --- a/examples/onnx/boolean/input.json +++ b/examples/onnx/boolean/input.json @@ -1 +1 @@ -{"input_data": [[false, true, false], [true, false, false], [true, false, false], [false, false, false]]} \ No newline at end of file +{"input_data": [[false, true, true], [false, true, true], [true, false, false], [false, true, true]]} \ No newline at end of file diff --git a/examples/onnx/boolean/network.onnx b/examples/onnx/boolean/network.onnx index b3b9a95e8..c16e16602 100644 --- a/examples/onnx/boolean/network.onnx +++ b/examples/onnx/boolean/network.onnx @@ -1,21 +1,17 @@ -pytorch1.12.1:« -+ +pytorch2.2.2:„ +* input1 -input2 onnx::Equal_4And_0"And -' +input2 /And_output_0/And"And +) input3 -input -onnx::Or_5Xor_1"Xor -+ +input /Xor_output_0/Xor"Xor +5 input2 - -onnx::Or_5 onnx::And_6Or_2"Or -0 -input1 - onnx::And_6 onnx::Equal_7And_3"And -6 - onnx::Equal_4 - onnx::Equal_7outputEqual_4"Equal torch_jitZ! + /Xor_output_0/And_1_output_0/And_1"And +5 + /And_output_0 +/And_1_output_0output/And_2"And +main_graphZ! input    diff --git a/src/graph/node.rs b/src/graph/node.rs index 539f10d79..a46654752 100644 --- a/src/graph/node.rs +++ b/src/graph/node.rs @@ -125,6 +125,7 @@ impl RebaseScale { if (op_out_scale > (global_scale * scale_rebase_multiplier as i32)) && !inner.is_constant() && !inner.is_input() + && !inner.is_identity() { let multiplier = scale_to_multiplier(op_out_scale - global_scale * scale_rebase_multiplier as i32); @@ -326,6 +327,19 @@ impl SupportedOp { SupportedOp::RebaseScale(op) => op, } } + + /// check if is the identity operation + /// # Returns + /// * `true` if the operation is the identity operation + /// * `false` otherwise + pub fn is_identity(&self) -> bool { + match self { + SupportedOp::Linear(op) => matches!(op, PolyOp::Identity { .. }), + SupportedOp::Rescaled(op) => op.inner.is_identity(), + SupportedOp::RebaseScale(op) => op.inner.is_identity(), + _ => false, + } + } } impl From>> for SupportedOp { diff --git a/src/graph/utilities.rs b/src/graph/utilities.rs index 75b8610c5..8bb2eb193 100644 --- a/src/graph/utilities.rs +++ b/src/graph/utilities.rs @@ -41,7 +41,7 @@ use tract_onnx::tract_hir::{ ops::konst::Const, ops::nn::DataFormat, tract_core::ops::cast::Cast, - tract_core::ops::cnn::{conv::KernelFormat, MaxPool, PaddingSpec, SumPool}, + tract_core::ops::cnn::{conv::KernelFormat, MaxPool, SumPool}, }; /// Quantizes an iterable of f32s to a [Tensor] of i32s using a fixed point representation. @@ -94,17 +94,18 @@ pub fn multiplier_to_scale(mult: f64) -> crate::Scale { /// extract padding from a onnx node. pub fn extract_padding( pool_spec: &PoolSpec, - num_dims: usize, + image_size: &[usize], ) -> Result, GraphError> { - let padding = match &pool_spec.padding { - PaddingSpec::Explicit(b, a) | PaddingSpec::ExplicitOnnxPool(b, a, _) => { - b.iter().zip(a.iter()).map(|(b, a)| (*b, *a)).collect() - } - PaddingSpec::Valid => vec![(0, 0); num_dims], - _ => { - return Err(GraphError::MissingParams("padding".to_string())); - } - }; + let num_relevant_dims = pool_spec.kernel_shape.len(); + + // get the last num_relevant_dims of the image size + let image_size = &image_size[image_size.len() - num_relevant_dims..]; + + let dims = pool_spec.computed_padding(image_size); + let mut padding = Vec::new(); + for dim in dims { + padding.push((dim.pad_before, dim.pad_after)); + } Ok(padding) } @@ -1016,8 +1017,13 @@ pub fn new_op_from_onnx( if raw_values.log2().fract() == 0.0 { inputs[const_idx].decrement_use(); deleted_indices.push(const_idx); + // get the non constant index + let non_const_idx = if const_idx == 0 { 1 } else { 0 }; + op = SupportedOp::Linear(PolyOp::Identity { - out_scale: Some(input_scales[0] + raw_values.log2() as i32), + out_scale: Some( + input_scales[non_const_idx] + raw_values.log2() as i32, + ), }); } } @@ -1108,7 +1114,7 @@ pub fn new_op_from_onnx( } let stride = extract_strides(pool_spec)?; - let padding = extract_padding(pool_spec, input_dims[0].len())?; + let padding = extract_padding(pool_spec, &input_dims[0])?; let kernel_shape = &pool_spec.kernel_shape; SupportedOp::Hybrid(HybridOp::MaxPool { @@ -1178,7 +1184,7 @@ pub fn new_op_from_onnx( let pool_spec = &conv_node.pool_spec; let stride = extract_strides(pool_spec)?; - let padding = extract_padding(pool_spec, input_dims[0].len())?; + let padding = extract_padding(pool_spec, &input_dims[0])?; // if bias exists then rescale it to the input + kernel scale if input_scales.len() == 3 { @@ -1236,7 +1242,7 @@ pub fn new_op_from_onnx( let pool_spec = &deconv_node.pool_spec; let stride = extract_strides(pool_spec)?; - let padding = extract_padding(pool_spec, input_dims[0].len())?; + let padding = extract_padding(pool_spec, &input_dims[0])?; // if bias exists then rescale it to the input + kernel scale if input_scales.len() == 3 { let bias_scale = input_scales[2]; @@ -1349,7 +1355,7 @@ pub fn new_op_from_onnx( } let stride = extract_strides(pool_spec)?; - let padding = extract_padding(pool_spec, input_dims[0].len())?; + let padding = extract_padding(pool_spec, &input_dims[0])?; SupportedOp::Hybrid(HybridOp::SumPool { padding, @@ -1358,11 +1364,6 @@ pub fn new_op_from_onnx( normalized: sumpool_node.normalize, }) } - // "GlobalAvgPool" => SupportedOp::Linear(PolyOp::SumPool { - // padding: [(0, 0); 2], - // stride: (1, 1), - // kernel_shape: (inputs[0].out_dims()[0][1], inputs[0].out_dims()[0][2]), - // }), "Pad" => { let pad_node: &Pad = match node.op().downcast_ref::() { Some(b) => b, From a06b09ef1f55fef1c940d248ccb31828ac6171db Mon Sep 17 00:00:00 2001 From: Jseam Date: Tue, 15 Oct 2024 15:36:24 +0800 Subject: [PATCH 2/2] docs: add batch demo (#849) --- examples/notebooks/ezkl_demo_batch.ipynb | 771 +++++++++++++++++++++++ tests/py_integration_tests.rs | 3 +- 2 files changed, 773 insertions(+), 1 deletion(-) create mode 100644 examples/notebooks/ezkl_demo_batch.ipynb diff --git a/examples/notebooks/ezkl_demo_batch.ipynb b/examples/notebooks/ezkl_demo_batch.ipynb new file mode 100644 index 000000000..1eef1d531 --- /dev/null +++ b/examples/notebooks/ezkl_demo_batch.ipynb @@ -0,0 +1,771 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "n8QlFzjPRIGN" + }, + "source": [ + "# EZKL DEMO (BATCHED)\n", + "\n", + "This is mostly similar to the original EZKL demo but includes an example of how batching is handled.\n", + "\n", + "**Learning Objectives**\n", + "1. Learn some basic AI/ML techniques by training a toy model in pytorch to perform classification\n", + "2. Convert the toy model into zk circuit with ezkl to do provable inference\n", + "3. Create a solidity verifier and deploy it on Remix (you can deploy it however you like but we will use Remix as it's quite easy to setup)\n", + "4. Learn how to use batch inputs and outputs\n", + "\n", + "**Important Note**: You might want to avoid calling \"Run All\". There's some file locking issue with Colab which can cause weird bugs. To mitigate this issue you should run cell by cell on Colab." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dx81GOIySIpa" + }, + "source": [ + "# Step 1: Training a toy model\n", + "\n", + "For this demo we will use a toy data set called the Iris dataset to demonstrate how training can be performed. The Iris dataset is a collection of Iris flowers and is one of the earliest dataset used to validate classification methodologies.\n", + "\n", + "[More info in the dataset](https://archive.ics.uci.edu/dataset/53/iris)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JhHE2WMvS9NP" + }, + "source": [ + "First, we will need to import all the various dependencies required to train the model" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "gvQ5HL1bTDWF" + }, + "outputs": [], + "source": [ + "import pandas as pd\n", + "from sklearn.datasets import load_iris\n", + "from sklearn.model_selection import train_test_split\n", + "from sklearn.metrics import accuracy_score, precision_score, recall_score\n", + "import numpy as np\n", + "import torch\n", + "import torch.nn as nn\n", + "import torch.nn.functional as F\n", + "from torch.autograd import Variable\n", + "import tqdm" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Op9SHfZHUkaR" + }, + "source": [ + "Inspect the dataset. Note that for the Iris dataset we have 3 targets.\n", + "\n", + "0 = Iris-setosa\n", + "\n", + "1 = Iris-versicolor\n", + "\n", + "2 = Iris-virginica" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 424 + }, + "id": "C4XXA1hoU30c", + "outputId": "b92f7a06-ace9-4bcc-bd6a-d8e9a5550bd2" + }, + "outputs": [], + "source": [ + "iris = load_iris()\n", + "dataset = pd.DataFrame(\n", + " data= np.c_[iris['data'], iris['target']],\n", + " columns= iris['feature_names'] + ['target'])\n", + "dataset" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "I8RargmGTWN2" + }, + "source": [ + "Next, we can begin defining the neural net model. For this dataset we will use a small fully connected neural net.\n", + "\n", + "
\n", + "\n", + "**Note:**\n", + "For the 1st layer we use 4x20, because there are 4 features we want as inputs. After which we add a ReLU.\n", + "\n", + "For the 2nd layer we use 20x20, then add a ReLU.\n", + "\n", + "And for the last layer we use 20x3, because there are 3 classes we want to classify, then add a ReLU.\n", + "\n", + "The last ReLU function gives us an array of 3 elements where the position of the largest value gives us the target that we want to classify.\n", + "\n", + "For example, if we get [0, 0.001, 0.002] as the output of the last ReLU. As, 0.002 is the largest value, the inferred value is 2.\n", + "\n", + "\n", + "![image.png](data:image/png;base64,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)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "dIdQ9U3yTKtP" + }, + "outputs": [], + "source": [ + "class Model(nn.Module):\n", + " # define nn\n", + " def __init__(self):\n", + " super(Model, self).__init__()\n", + " self.fc1 = nn.Linear(4, 20)\n", + " self.fc2 = nn.Linear(20, 20)\n", + " self.fc3 = nn.Linear(20, 3)\n", + " self.relu = nn.ReLU()\n", + "\n", + " def forward(self, x):\n", + " x = self.fc1(x)\n", + " x = self.relu(x)\n", + " x = self.fc2(x)\n", + " x = self.relu(x)\n", + " x = self.fc3(x)\n", + " x = self.relu(x)\n", + "\n", + " return x\n", + "\n", + "# Initialize Model\n", + "model = Model()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SfC03XLNXDPZ" + }, + "source": [ + "We will now need to split the dataset into a training set and testing set for ML. This is done fairly easily with the `train_test_split` helper function from sklearn." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "agmbEdmfUO1-", + "outputId": "e7de179f-4150-4e03-d04e-2f0ce4f9cea5" + }, + "outputs": [], + "source": [ + "train_X, test_X, train_y, test_y = train_test_split(\n", + " dataset[dataset.columns[0:4]].values, # use columns 0-4 as X\n", + " dataset.target, # use target as y\n", + " test_size=0.2 # use 20% of data for testing\n", + ")\n", + "\n", + "# Uncomment for sanity checks\n", + "# print(\"train_X: \", train_X)\n", + "# print(\"test_X: \", test_X)\n", + "print(\"train_y: \", train_y)\n", + "print(\"test_y: \", test_y)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_FrQXhAGZGS3" + }, + "source": [ + "We can now define the parameters for training, we will use the [Cross Entropy Loss](https://machinelearningmastery.com/cross-entropy-for-machine-learning/) and [Stochastic Gradient Descent Optimizer](https://en.wikipedia.org/wiki/Stochastic_gradient_descent)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "9PjADXnuXbdk", + "outputId": "31588262-5e9e-4db4-82dc-ea3215a638c9" + }, + "outputs": [], + "source": [ + "# our loss function\n", + "loss_fn = nn.CrossEntropyLoss()\n", + "\n", + "# our optimizer\n", + "optimizer = torch.optim.SGD(model.parameters(), lr=0.01)\n", + "\n", + "\n", + "# use 800 EPOCHS\n", + "EPOCHS = 800\n", + "\n", + "# Convert training data to pytorch variables\n", + "train_X = Variable(torch.Tensor(train_X).float())\n", + "test_X = Variable(torch.Tensor(test_X).float())\n", + "train_y = Variable(torch.Tensor(train_y.values).long())\n", + "test_y = Variable(torch.Tensor(test_y.values).long())\n", + "\n", + "\n", + "loss_list = np.zeros((EPOCHS,))\n", + "accuracy_list = np.zeros((EPOCHS,))\n", + "\n", + "\n", + "# we use tqdm for nice loading bars\n", + "for epoch in tqdm.trange(EPOCHS):\n", + "\n", + " # To train, we get a prediction from the current network\n", + " predicted_y = model(train_X)\n", + "\n", + " # Compute the loss to see how bad or good we are doing\n", + " loss = loss_fn(predicted_y, train_y)\n", + "\n", + " # Append the loss to keep track of our performance\n", + " loss_list[epoch] = loss.item()\n", + "\n", + " # Afterwards, we will need to zero the gradients to reset\n", + " optimizer.zero_grad()\n", + " loss.backward()\n", + " optimizer.step()\n", + "\n", + " # Calculate the accuracy, call torch.no_grad() to prevent updating gradients\n", + " # while calculating accuracy\n", + " with torch.no_grad():\n", + " y_pred = model(test_X)\n", + " correct = (torch.argmax(y_pred, dim=1) == test_y).type(torch.FloatTensor)\n", + " accuracy_list[epoch] = correct.mean()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 432 + }, + "id": "2fHJAgvwboCe", + "outputId": "e9b49c61-b3d9-4a61-e439-dcb239e1342f" + }, + "outputs": [], + "source": [ + "# Plot the Accuracy and Loss\n", + "\n", + "# import matplotlib\n", + "import matplotlib.pyplot as plt\n", + "\n", + "plt.style.use('ggplot')\n", + "\n", + "\n", + "fig, (ax1, ax2) = plt.subplots(2, figsize=(12, 6), sharex=True)\n", + "\n", + "ax1.plot(accuracy_list)\n", + "ax1.set_ylabel(\"Accuracy\")\n", + "ax2.plot(loss_list)\n", + "ax2.set_ylabel(\"Loss\")\n", + "ax2.set_xlabel(\"epochs\");" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "djB-UtvgYbF2" + }, + "source": [ + "## Congratulations! You've just trained a neural network\n", + "\n", + "**Exercise:** The model provided is very simplistic, what are other ways the model can be improved upon?" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JgtwrbMZcgla" + }, + "source": [ + "# Step 2: ZK the Neural Network\n", + "\n", + "Now that we have the Neural Network trained, we can use ezkl to easily ZK our model.\n", + "\n", + "To proceed we will now need to install `ezkl`\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "C_YiqknhdDwN" + }, + "outputs": [], + "source": [ + "# check if notebook is in colab\n", + "try:\n", + " import google.colab\n", + " import subprocess\n", + " import sys\n", + " subprocess.check_call([sys.executable, \"-m\", \"pip\", \"install\", \"ezkl\"])\n", + " subprocess.check_call([sys.executable, \"-m\", \"pip\", \"install\", \"onnx\"])\n", + "\n", + "# rely on local installation of ezkl if the notebook is not in colab\n", + "except:\n", + " pass\n", + "\n", + "import os\n", + "import json\n", + "import ezkl" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-b_z_d2FdVTB" + }, + "source": [ + "Next, we will need to export the neural network to a `.onnx` file. ezkl reads this `.onnx` file and converts it into a circuit which then allows you to generate proofs as well as verify proofs" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "YeKWP0tFeCpq" + }, + "outputs": [], + "source": [ + "# Specify all the files we need\n", + "\n", + "model_path = os.path.join('network.onnx')\n", + "data_path = os.path.join('input.json')\n", + "cal_data_path = os.path.join('calibration.json')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "cQeNw_qndQ8g", + "outputId": "c293814a-9d98-4ea6-ff96-f32742bca9a5" + }, + "outputs": [], + "source": [ + "# After training, export to onnx (network.onnx) and create a data file (input.json)\n", + "\n", + "# create a random input\n", + "# note that given that we want to use a batch of 2 we can provide a model input as follows\n", + "x = test_X[:2].reshape(2, 4)\n", + "\n", + "# Flips the neural net into inference mode\n", + "model.eval()\n", + "\n", + "# Export the model\n", + "torch.onnx.export(model, # model being run\n", + " x, # model input (or a tuple for multiple inputs)\n", + " model_path, # where to save the model (can be a file or file-like object)\n", + " export_params=True, # store the trained parameter weights inside the model file\n", + " opset_version=10, # the ONNX version to export the model to\n", + " do_constant_folding=True, # whether to execute constant folding for optimization\n", + " input_names = ['input'], # the model's input names\n", + " output_names = ['output'], # the model's output names\n", + " dynamic_axes={'input' : {0 : 'batch_size'}, # variable length axes\n", + " 'output' : {0 : 'batch_size'}})\n", + "\n", + "data_array = ((x).detach().numpy()).reshape([-1]).tolist()\n", + "\n", + "print(data_array)\n", + "\n", + "data = dict(input_data = [data_array])\n", + "\n", + " # Serialize data into file:\n", + "json.dump(data, open(data_path, 'w'))\n", + "\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9P4x79hIeiLO" + }, + "source": [ + "After which we can proceed to generate the settings file for `ezkl` and run calibrate settings to find the optimal settings for `ezkl`.\n", + "\n", + "Instantiate a PyRunArgs object and set the `batch_size` accordingly." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "cY25BIyreIX8" + }, + "outputs": [], + "source": [ + "!RUST_LOG=trace\n", + "# TODO: Dictionary outputs\n", + "py_run_args = ezkl.PyRunArgs()\n", + "py_run_args.variables = [(\"batch_size\", 2)]\n", + "res = ezkl.gen_settings(model=\"network.onnx\", output=\"settings.json\", py_run_args=py_run_args)\n", + "assert res == True\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "pe0Zoe-ri_l4", + "outputId": "ed0fe6fe-67ca-4da8-ba9e-d6a8ee451ded" + }, + "outputs": [], + "source": [ + "# use the test set to calibrate the circuit\n", + "cal_data = dict(input_data = test_X.flatten().tolist())\n", + "\n", + "# Serialize calibration data into file:\n", + "json.dump(data, open(cal_data_path, 'w'))\n", + "\n", + "# Optimize for resources, we cap logrows at 12 to reduce setup and proving time, at the expense of accuracy\n", + "# You may want to increase the max logrows if accuracy is a concern\n", + "res = await ezkl.calibrate_settings(target = \"resources\", max_logrows = 12, scales = [2])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MFmPMBQ1jYao" + }, + "source": [ + "Next, we will compile the model. The compilation step allow us to generate proofs faster." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "De5XtpGUerkZ" + }, + "outputs": [], + "source": [ + "res = ezkl.compile_circuit()\n", + "assert res == True" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UbkuSVKljmhA" + }, + "source": [ + "Before we can setup the circuit params, we need a SRS (Structured Reference String). The SRS is used to generate the proofs." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "amaTcWG6f2GI" + }, + "outputs": [], + "source": [ + "res = await ezkl.get_srs()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Y92p3GhVj1Jd" + }, + "source": [ + "Now run setup, this will generate a proving key (pk) and verification key (vk). The proving key is used for proving while the verification key is used for verificaton." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "fdsteit9jzfK", + "outputId": "5292ced0-d79b-46fb-df13-fd16355dac90" + }, + "outputs": [], + "source": [ + "res = ezkl.setup()\n", + "\n", + "\n", + "assert res == True" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QYlqpP3jkExm" + }, + "source": [ + "Now, we can generate a proof and verify the proof as a sanity check. We will use the \"evm\" transcript. This will allow us to provide proofs to the EVM." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "yoz5Vks5kaHI" + }, + "outputs": [], + "source": [ + "# Generate the Witness for the proof\n", + "\n", + "# now generate the witness file\n", + "witness_path = os.path.join('witness.json')\n", + "\n", + "res = await ezkl.gen_witness()\n", + "assert os.path.isfile(witness_path)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tmPmQrL1pF9p" + }, + "source": [ + "Note: Instead of having 3 instance variables which corresponds to the outputs of our neural net, we have 6 instance variables since we have 2 inputs in a batch." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "eKkFBZX1kBdE", + "outputId": "59db6c3f-22d5-4258-c70c-6b353a5173b4" + }, + "outputs": [], + "source": [ + "# Generate the proof\n", + "\n", + "proof_path = os.path.join('proof.json')\n", + "\n", + "proof = ezkl.prove(proof_type=\"single\", proof_path=proof_path)\n", + "\n", + "print(proof)\n", + "assert os.path.isfile(proof_path)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "DuuH-qcOkQf1", + "outputId": "a5656e5f-1f81-4236-d9b9-8cf80e020a05" + }, + "outputs": [], + "source": [ + "# verify our proof\n", + "\n", + "res = ezkl.verify()\n", + "\n", + "assert res == True\n", + "print(\"verified\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TOSRigalkwH-" + }, + "source": [ + "## Congratulations! You have just turned your Neural Network into a Halo2 Circuit!\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "flrg3NOGwsJh" + }, + "source": [ + "\n", + "# Part 3: Deploying the Verifier\n", + "Now that we have the circuit setup, we can proceed to deploy the verifier onchain.\n", + "\n", + "We will need to setup `solc=0.8.20` for this." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "CVqMeMYqktvl", + "outputId": "5287ca64-dd25-47b1-8d09-e74d9233f9a6" + }, + "outputs": [], + "source": [ + "# check if notebook is in colab\n", + "try:\n", + " import google.colab\n", + " import subprocess\n", + " import sys\n", + " subprocess.check_call([sys.executable, \"-m\", \"pip\", \"install\", \"solc-select\"])\n", + " !solc-select install 0.8.20\n", + " !solc-select use 0.8.20\n", + " !solc --version\n", + "\n", + "# rely on local installation if the notebook is not in colab\n", + "except:\n", + " pass" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HRHvkMjVlfWU" + }, + "source": [ + "With solc in our environment we can now create the evm verifier." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "gYlw20VZkva7", + "outputId": "4b0a9e46-6c60-45cb-f4d5-5fdfa17335f0" + }, + "outputs": [], + "source": [ + "sol_code_path = os.path.join('Verifier.sol')\n", + "abi_path = os.path.join('Verifier.abi')\n", + "\n", + "res = await ezkl.create_evm_verifier(\n", + " sol_code_path=sol_code_path,\n", + " abi_path=abi_path,\n", + " )\n", + "\n", + "assert res == True\n", + "assert os.path.isfile(sol_code_path)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "jQSAVMvxrBQD", + "outputId": "e2cf297c-85ed-432c-ad11-7b5350220939" + }, + "outputs": [], + "source": [ + "onchain_input_array = []\n", + "\n", + "# using a loop\n", + "# avoiding printing last comma\n", + "formatted_output = \"[\"\n", + "for i, value in enumerate(proof[\"instances\"]):\n", + " for j, field_element in enumerate(value):\n", + " onchain_input_array.append(ezkl.felt_to_big_endian(field_element))\n", + " formatted_output += '\"' + str(onchain_input_array[-1]) + '\"'\n", + " if j != len(value) - 1:\n", + " formatted_output += \", \"\n", + " if i != len(proof[\"instances\"]) - 1:\n", + " formatted_output += \", \"\n", + "formatted_output += \"]\"\n", + "\n", + "# This will be the values you use onchain\n", + "# copy them over to remix and see if they verify\n", + "# What happens when you change a value?\n", + "print(\"pubInputs: \", formatted_output)\n", + "print(\"proof: \", proof[\"proof\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zrzPxPvZmX9b" + }, + "source": [ + "We will exit colab for the next steps. At the left of colab you can see a folder icon. Click on that.\n", + "\n", + "\n", + "You should see a `Verifier.sol`. Right-click and save it locally.\n", + "\n", + "Now go to [https://remix.ethereum.org](https://remix.ethereum.org).\n", + "\n", + "Create a new file within remix and copy the verifier code over.\n", + "\n", + "Finally, compile the code and deploy. For the demo you can deploy to the test environment within remix.\n", + "\n", + "If everything works, you would have deployed your verifer onchain! Copy the values in the cell above to the respective fields to test if the verifier is working.\n", + "\n", + "**Note that right now this setup accepts random values!**\n", + "\n", + "This might not be great for some applications. For that we will want to use a data attested verifier instead. [See this tutorial.](https://github.com/zkonduit/ezkl/blob/main/examples/notebooks/data_attest.ipynb)\n", + "\n", + "## Congratulations for making it this far!\n", + "\n", + "If you have followed the whole tutorial, you would have deployed a neural network inference model onchain! That's no mean feat!" + ] + } + ], + "metadata": { + "colab": { + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.2" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/tests/py_integration_tests.rs b/tests/py_integration_tests.rs index e84646422..bb28f7f1c 100644 --- a/tests/py_integration_tests.rs +++ b/tests/py_integration_tests.rs @@ -123,7 +123,8 @@ mod py_tests { } } - const TESTS: [&str; 33] = [ + const TESTS: [&str; 34] = [ + "ezkl_demo_batch.ipynb", "proof_splitting.ipynb", // 0 "variance.ipynb", "mnist_gan.ipynb",