From 6588dda39fc04aa4c4d048227d943ce8045158f5 Mon Sep 17 00:00:00 2001 From: Jason Morton Date: Sun, 30 Jul 2023 23:10:07 -0400 Subject: [PATCH] fix: compile model and other updates (#61) * fix cli page * some corrections * more fixes for compile and others --- About_EZKL/Commands.md | 59 +++++++++++++-------- About_EZKL/Parameters.md | 104 -------------------------------------- About_EZKL/RunArgs.md | 67 ++++++++++++------------ About_ONNX.md | 23 --------- Benchmarks.md | 25 --------- Command_Line_Interface.md | 38 ++++++++++++-- Examples.md | 43 ---------------- FAQ.md | 3 +- Getting_Started.md | 5 +- Verifying_On-Chain.md | 38 +++++++++----- default.md | 27 +++++----- 11 files changed, 151 insertions(+), 281 deletions(-) delete mode 100644 About_EZKL/Parameters.md delete mode 100644 About_ONNX.md delete mode 100644 Benchmarks.md delete mode 100644 Examples.md diff --git a/About_EZKL/Commands.md b/About_EZKL/Commands.md index 8295719..dd021b4 100644 --- a/About_EZKL/Commands.md +++ b/About_EZKL/Commands.md @@ -3,11 +3,10 @@ order: 92 --- ## `ezkl` Commands -![](../assets/ezkl_flow.png) Here is some more detail on `ezkl` commands. -### GenSRS +### Getting an SRS `ezkl` uses KZG commitments, which in turn require a structured reference string (SRS). You can download a [KZG](https://cypherpunks.ca/~iang/pubs/PolyCommit-AsiaCrypt.pdf) structured reference string with (for example) 17 rows as follows. @@ -67,6 +66,14 @@ For example, after running the same command with `--target` set to **accuracy**, ``` > Note: You can still use the generic RunArgs for `mock` and `gen-witness` (e.g. `ezkl mock --logrows=22 --bits=21` rather than `ezkl mock --settings-path circuit.json`). However, `--settings-path` takes priority. + +### Compile model +This converts and freezes the onnx file to what ezkl will actually prove against, incorporating the settings, quantizing, etc. + +```bash +ezkl compile-model -M network.onnx -S settings.json --compiled-model network.ezkl +``` + ### Setup Along with our SRS and circuit parameters, we need two other elements to generate a proof: a proving key and a verifying key. You will get both by running `ezkl`'s `setup` command. We need our proving key to generate proofs; we need our verifying key to verify proofs from the corresponding proving key, or to generate an EVM verifier. @@ -74,7 +81,7 @@ Along with our SRS and circuit parameters, we need two other elements to generat Run this command to set up your proving and verifying keys: ```bash -ezkl setup -M examples/onnx/4l_relu_conv_fc/network.onnx --srs-path=17.srs --settings-path=settings.json +ezkl setup -M network.ezkl --srs-path=17.srs --settings-path=settings.json ``` You should now have files called `vk.key` and `pk.key` in the root of your project. You can also specify different paths for these outputs with `--vk-path=altvk.key --pk-path=altpk.key` @@ -83,7 +90,7 @@ You should now have files called `vk.key` and `pk.key` in the root of your proje Now we take the input data, quantize it, and run it through the quantized model, performing any hashing or encryption, to obtain the input and output that we will be proving. ```bash -ezkl gen-witness -M examples/onnx/4l_relu_conv_fc/network.onnx -D examples/onnx/4l_relu_conv_fc/input.json --settings-path settings.json +ezkl gen-witness -M network.ezkl -D examples/onnx/4l_relu_conv_fc/input.json --settings-path settings.json ``` The default output file is `witness.json`. @@ -96,7 +103,7 @@ In a typical zk application, the proof will be generated by or on behalf of the Here is the command for generating a proof from the cli: ```bash -ezkl prove -M examples/onnx/4l_relu_conv_fc/network.onnx --witness witness.json --pk-path=pk.key --proof-path=model.proof --srs-path=15.srs --settings-path=settings.json +ezkl prove -M network.ezkl --witness witness.json --pk-path=pk.key --proof-path=model.proof --srs-path=15.srs --settings-path=settings.json ``` This will create a proof file called `model.proof` that anyone can later use to verify your model was run correctly on the input. @@ -123,7 +130,7 @@ Note that these are not the only operations that can be performed by `ezkl`. You When you're testing a model, you may not want to run `setup` and `prove` with each iteration. `ezkl` provides a simple alternative with `mock`, where you can convert your model to constraints and run the inputs tosee if a proof can be generated. This saves time when testing new iterations of models with potential issues. Here is the command for `mock`: ```bash -ezkl mock -M examples/onnx/1l_sigmoid/network.onnx -D examples/onnx/1l_sigmoid/input.json +ezkl mock -M network.ezkl --witness witness.json --settings-path=settings.json ``` Mock is basically checking that constraints that your model has been translated into are satisfied, without doing any of the subsequent cryptographic heavy lifting to produce a proof. @@ -135,7 +142,7 @@ The `gen-witness` function generates a witness for a given model and input data The function has additional configurable settings, including an ONNX model file path, an input data file path, an output file path, an optional scale, and an optional batch size. More details on the optional scale and optional batch size can be found in [RunArgs](./RunArgs.md). ```bash -ezkl gen-witness -M examples/onnx/1l_sigmoid/network.onnx -D examples/onnx/1l_sigmoid/input.json -O examples/onnx/1l_sigmoid/witness.json +ezkl gen-witness -M network.ezkl -D examples/onnx/1l_sigmoid/input.json ``` ### Table @@ -178,14 +185,13 @@ This will render our circuit as a file named `render.png` in our `examples/onnx/ ![image-20230608155046296](../assets/sigmoidrender.png) -In this photo, +In this image, -- Pink columns represent advice, or private, values -- White columns represent instance, or public, values -- Purple/blue columns represent fixed, or constant, values (lookups as well) +- Pink columns represent advice values +- White columns represent instance values +- Purple/blue columns represent fixed values - Green areas represent regions in our circuit -These renders are great for finding ways to optimize your circuit (perhaps lowering the number of bits per cell or using more rows). ### Aggregate @@ -199,41 +205,52 @@ ezkl gen-srs --logrows 23 --srs-path=23.srs Now, let's say we want to aggregate a `conv` circuit and a `relu` circuit. We can set up the parameters for these different circuits with `gen-circuit-params`. For the sake of the example, let's set one to optimize for accuracy and another to optimize for resources: ```bash -ezkl gen-circuit-params --calibration-target accuracy --model examples/onnx/1l_conv/network.onnx --settings-path circuitconv.json +ezkl gen-settings --model examples/onnx/1l_conv/network.onnx --settings-path circuitconv.json +ezkl calibrate-settings -M examples/onnx/1l_conv/network.onnx -D examples/onnx/1l_conv/input.json --target accuracy -O circuitconv.json ``` and for RELU: ```bash -ezkl gen-circuit-params --calibration-target resources --model examples/onnx/1l_relu/network.onnx --settings-path circuitrelu.json +ezkl gen-settings --model examples/onnx/1l_relu/network.onnx --settings-path circuitrelu.json +ezkl calibrate-settings -M examples/onnx/1l_relu/network.onnx -D examples/onnx/1l_relu/input.json --target resources -O circuitrelu.json ``` Now, we can create our proof keys with `setup` (Note: be sure to use the same KZG parameters for all the circuits you plan to aggregate): ```bash # Conv -ezkl setup -M examples/onnx/1l_conv/network.onnx --srs-path=23.srs --vk-path=vkconv.key --pk-path=pkconv.key --settings-path=circuitconv.json +ezkl compile-model -M examples/onnx/1l_conv/network.onnx --settings-path=circuitconv.json --compiled-model conv.ezkl +ezkl setup -M conv.ezkl --srs-path=23.srs --vk-path=vkconv.key --pk-path=pkconv.key --settings-path=circuitconv.json ``` ```bash # Relu -ezkl setup -M examples/onnx/1l_relu/network.onnx --srs-path=23.srs --vk-path=vkrelu.key --pk-path=pkrelu.key --settings-path=circuitrelu.json +ezkl compile-model -M examples/onnx/1l_relu/network.onnx --settings-path=circuitconv.json --compiled-model relu.ezkl +ezkl setup -M relu.ezkl --srs-path=23.srs --vk-path=vkrelu.key --pk-path=pkrelu.key --settings-path=circuitrelu.json ``` -We then prove them (we'll run with `RUST_LOG=debug` to fetch our allocated constraints: +We then prove them. ```bash # Conv -RUST_LOG=debug ezkl prove --transcript=poseidon --strategy=accum --witness ./examples/onnx/1l_conv/input.json -M examples/onnx/1l_conv/network.onnx --proof-path model.proof --srs-path=23.srs --pk-path=pkconv.key --settings-path=circuitconv.json +ezkl gen-witness -D ./examples/onnx/1l_conv/input.json -M conv.ezkl -O convwit.json --settings-path=circuitconv.json +ezkl prove --transcript=poseidon --strategy=accum --witness convwit.json -M conv.ezkl --proof-path conv.proof --srs-path=23.srs --pk-path=pkconv.key --settings-path=circuitconv.json ``` ```bash # Relu -RUST_LOG=debug ezkl prove --transcript=poseidon --strategy=accum --witness ./examples/onnx/1l_relu/input.json -M examples/onnx/1l_relu/network.onnx --proof-path model1.proof --srs-path=23.srs --pk-path=pkrelu.key --settings-path=circuitrelu.json +ezkl gen-witness -D ./examples/onnx/1l_relu/input.json -M relu.ezkl -O reluwit.json --settings-path=circuitrelu.json +ezkl prove --transcript=poseidon --strategy=accum --witness reluwit.json -M relu.ezkl --proof-path relu.proof --srs-path=23.srs --pk-path=pkrelu.key --settings-path=circuitrelu.json +``` + +Setup the aggregation: +```bash +ezkl setup-aggregate --sample-snarks conv.proof --sample-snarks relu.proof --srs-path 23.srs --logrows 23 ``` Now, we can aggregate the proofs: ```bash -ezkl aggregate --logrows=23 --aggregation-snarks=model.proof --aggregation-snarks=model1.proof --aggregation-vk-paths vkconv.key --aggregation-vk-paths vkrelu.key --vk-path aggr.vk --proof-path aggr.proof --srs-path=23.srs --settings-paths=circuitconv.json --settings-paths=circuitrelu.json +ezkl aggregate --logrows=23 --aggregation-snarks=conv.proof --aggregation-snarks=relu.proof --proof-path aggr.proof --srs-path=23.srs --pk-path pk_aggr.key ``` This creates one proof that simultaneously proves both our `conv` and `relu` circuits as long as we pass both proofs and verifying keys in. The bad news is that computing an aggregation takes a lot of memory and time right now; this proof will probably take about four or five minutes. @@ -243,7 +260,7 @@ This creates one proof that simultaneously proves both our `conv` and `relu` cir Now, we can verify our aggregated proof with: ```bash -ezkl verify-aggr --logrows=23 --proof-path aggr.proof --srs-path=23.srs --vk-path aggr.vk +ezkl verify-aggr --logrows=23 --proof-path aggr.proof --srs-path=23.srs --vk-path vk_aggr.key ``` This should return `verified: true`. You can learn more about aggregation [here](https://vitalik.ca/general/2021/11/05/halo.html). diff --git a/About_EZKL/Parameters.md b/About_EZKL/Parameters.md deleted file mode 100644 index 059558d..0000000 --- a/About_EZKL/Parameters.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -order: 1 ---- - -## `ezkl` Parameters - -Each command in the `ezkl` CLI requires certain parameters to execute. - -### x.srs - -As discussed in the `Commands` section, we use `gen-srs` to create a polynomial commitment scheme parameters file `x.srs` (where `x` is logrows). These parameters are required in: - -- `setup` -- `prove` -- `verify` -- `aggregate` -- `create-evm-verifier` - -### input.json - -The `input.json` file represents the model inputs and outputs. Previously, the model's input shape (e.g. [1, 28, 28]) was required, but now `ezkl` can infer the shape just from the inputs. This JSON object is what you will use to pass arbitrary inputs to your model. If you have a photo, you need to transform it to the appropriate shape for your model. If your model's input is [1, 28, 28] and you have an RGB photo with 1080x1080 pixels, you need to grayscale (channels go from 3 to 1) and resize the pixels (downscale 1080 to 28) so that your model can ingest the data properly. - -`ezkl` takes a longer time to prove models with larger inputs. This means that using high quality images may take a while or run out of memory when generating a circuit. Here are the commands that require `input.json`: - -- `prove` -- `mock` -- `forward` -- `gen-witness` - -The data `.json` file is structured as follows: - -```javascript -{ - "input_data": [[1.0, 22.2, 0.12 ...]], // 2D arrays of floats which represents the (private) inputs we run the proof on - "output_data": [[1.0, 5.0, 6.3 ...]], // 2D arrays of floats which represents the model outputs we want to constrain against (if any) -} -``` - -### settings.json - -Generated with `gen-settings` and used to assist in the construction of a Model Circuit. They include the `RunArgs`, the `Visibility` parameters, the potential number of the constraints in the circuit, and more. The commands that require `settings.json` are: - -- `setup` (just provide the path to write the circuit parameters to) -- `prove` -- `verify` -- `aggregate` (all the params of the circuits you want to aggregate) -- `create-evm-verifier` -- `gen-witness` (can also use generic RunArgs) -- `mock` (can also use generic RunArgs) - -### network.onnx - -[ONNX](https://onnx.ai/) (Open Neural Network Exchange) is an open-source standard for representing deep learning models. It was developed to facilitate interoperability between various deep learning frameworks, such as TensorFlow and PyTorch. ONNX provides a common file format that allows models trained in one framework to be used in another framework for inference, without the need for model conversion. - -ONNX is used for several reasons: - -> ***\*Easy Integration\****: ONNX files are used in ezkl to generate zk-SNARKS from individual operations (e.g. ReLU, Sigmoid, Softmax). The ONNX format makes it straight-forward to parse and separate layers for generating individual circuits. -> -> ***\*Interoperability\****: ONNX enables developers to train models in one deep learning framework and use them in another for inference, without the need for conversion. This eases the process of deploying models and allows developers to use the best tools for each part of the development process. -> -> ***\*Portability\****: ONNX provides a standardized format for deep learning models, making it easier to share models across different platforms and devices. -> -> ***\*Optimization\****: ONNX-compatible tools and libraries, such as ONNX runtimes, can provide optimizations for specific hardware, leading to improved performance. -> -> ***\*Ecosystem support\****: Many popular deep learning frameworks and tools, like TensorFlow, PyTorch, and Microsoft's ONNX Runtime, support ONNX, providing a broad range of options for developers. - -Check out our Python [documentation](https://docs.ezkl.xyz/python_bindings/) and [pyezkl](https://github.com/zkonduit/pyezkl) repository to find detailed steps on generating an ONNX file. Here are the commands that require `network.onnx`: - -- `setup` -- `prove` -- `mock` -- `gen-witness` -- `forward` -- `table` -- `render` - - -### pk.key - -The Proving key for a circuit might be saved as `pk.key`. It is used to generate proofs and derive the verifying key. The commands that require `pk.key` are: - -- `setup` (path to write it to) -- `prove` -- `aggregate` - -### vk.key - -The Verifying key for a circuit might be saved as `vk.key`. It is used to verify proofs created with the corresponding Proving Key. The commands that require `vk.key` are: - -- `setup` (path to write it to) -- `verify` -- `aggregate` -- `verify-aggr` -- `create-evm-verifier` - -### model.pf - -The proof that is generated for a circuit might be called `model.pf` or `network.pf`. It is the actual proof that your verifier will use to verify proofs of your circuit. Typically this proof is generated by the client and verified by a blockchain, server, or another client. `ezkl` provides you with an assortment of tools for verifying the proofs you generate. Please submit an issue if you have any ideas for more platforms we should be looking to build verifiers on! Here are the commands that require a proof (or path to it): - -- `prove` (path to write it to) -- `aggregate` -- `verify` -- `verify-evm` - diff --git a/About_EZKL/RunArgs.md b/About_EZKL/RunArgs.md index f2763c4..b0d6fdd 100644 --- a/About_EZKL/RunArgs.md +++ b/About_EZKL/RunArgs.md @@ -2,7 +2,7 @@ order: 2 --- -`RunArgs` are the fine-tuning parameters that give you more control over various aspects of `ezkl`. The majority of them have default values, so you typically don't see them in our basic instructions. This section will show you the various `RunArgs` you have at your disposal and how you can use them. To begin, here is a list of all the `RunArgs` we support and their flags (you can also take a look at these with `ezkl setup --help`): +`RunArgs` are the fine-tuning parameters that give you more control over various aspects of `ezkl`. The majority of them have default values, so you typically don't see them in our basic instructions. They include: > - Tolerance: `-T` | `--tolerance` > - Scale: `-S` | `--scale` @@ -14,51 +14,53 @@ order: 2 > - Param Visibility: `--param-visibility` > - Allocated Constraints: `--allocated-constraints` -Let's go over each in detail with examples. +they can be edited in the settings file, or passed as arguments to `ezkl gen-settings`. -> Note: `ezkl` can be used with any computational graph with supported operations, including neural networks. You can think of "computational graph" as your model in .onnx format. +``` +Usage: ezkl gen-settings [OPTIONS] --model + +Options: + -M, --model + The path to the .onnx model file + -O, --settings-path + Path to circuit_settings file to output [default: settings.json] + -T, --tolerance + The tolerance for error on model outputs [default: 0] + -S, --scale + The denominator in the fixed point representation used when quantizing [default: 7] + -B, --bits + The number of bits used in lookup tables [default: 16] + -K, --logrows + The log_2 number of rows [default: 17] + --batch-size + The number of batches to split the input data into [default: 1] + --input-visibility + Flags whether inputs are public, private, hashed [default: private] + --output-visibility + Flags whether outputs are public, private, hashed [default: public] + --param-visibility + Flags whether params are public, private, hashed [default: private] + --allocated-constraints + the number of constraints the circuit might use. If not specified, this will be calculated using a 'dummy layout' pass +``` ### Tolerance -Sometimes, quantization can throw off the output of our computational graph. We need to quantize to represent the model using the finite field of our proof system, but you might want to explictly tolerate a small range of values in your output when verifying. For example, let's say we are using a sigmoid layer with 2 values. The output should be `[0.5,0.5]` (would be whole numbers depending on `scale`, using decimals for simplicity), but due to quantization, the SNARK's output is `[0.4, 0.6]`. You know that this result is just from quantization, so you want to allow more values than *strictly* 0.5 and 0.5 to appear in the output. This is where percent tolerance comes in. You can set the tolerance for error on model outputs so that the proof verifies on outputs that aren't **exactly** what you're expecting. You can use it like this: - -```bash -ezkl setup -T 1.0 -M examples/onnx/1l_sigmoid/network.onnx --srs-path 17.srs --vk-path vk.key --pk-path pk.key --settings-path circuit.json -``` - -This will give you a 1% tolerance on your outputs for this setup. +We need to quantize to represent the model using the finite field of our proof system, and this can introduce numerical error. You might want to explictly tolerate a small range of values in your output when verifying. A value of 1.0 is 1% tolerance. ### Scale `ezkl` quantizes a floting point value to a fixed point value by multiplying by $2^{scale}$ and rounding. Then the numerator is stored. The default scale is 7. When two numerators of scale 7 are mutiplied, you get a number of scale 14. Scale can be adjusted with `-S` or `--scale`: -```bash -ezkl setup -S 6 -M examples/onnx/1l_sigmoid/network.onnx --srs-path 17.srs --vk-path vk.key --pk-path pk.key --settings-path circuit.json -``` - ### Bits -Bits is the number of bits used in `ezkl`'s lookup tables for nonlinearities. The default is 16. We can adjust it with the `-B` or `--bits` flag here: +Bits is the number of bits used in `ezkl`'s lookup tables for nonlinearities. The default is 16. We can adjust it with the `-B` or `--bits` flag. -```bash -ezkl setup -B 14 -M examples/onnx/1l_sigmoid/network.onnx --srs-path 17.srs --vk-path vk.key --pk-path pk.key --settings-path circuit.json -``` - -Scale and bits are related. Typically we want bits to be twice scale, plus a margin of error (of perhaps 2 or 3), since two scale 7 numbers multiplied become scale 14, and then adding several of them we get to an even larger scale. That's why the default bits is twice the default scale plus 2. `ezkl` will give some warnings and suggestions if your scale and bits are off. +Scale and bits are related. Typically we want bits to be twice scale, plus a margin of error (of perhaps 2 or 3), since two scale 7 numbers multiplied become scale 14, and then adding several of them we get to an even larger scale. That's why the default bits is twice the default scale plus 2. `ezkl` will give some warnings and suggestions if your scale and bits are off. Or just use `calibrate-settings`. ### Logrows -The `logrows` argument is the base 2 logarithm of the number of rows that are in our halo2 circuit. The default is 17. It cannot exceed the value of `k` in our structure reference string. You can read more about SRS in the first part of the Commands section. Bits must be at most one less than logrows (e.g. 16 when logrows is 17). Let's say that when using `gen-srs` we created a SRS of size 23: - -```bash -ezkl gen-srs --logrows=23 --srs-path=23.srs -``` - - This means we can setup circuits of any size less than or equal to that. Let's set up a circuit with 2^22 rows: - -```bash -ezkl setup --logrows=22 -M examples/onnx/1l_sigmoid/network.onnx --srs-path 23.srs --vk-path vk.key --pk-path pk.key --settings-path circuit.json -``` +The `logrows` argument is the base 2 logarithm of the number of rows that are in our halo2 circuit. The default is 17. It cannot exceed the value of `k` in our structured reference string. You can read more about SRS in the first part of the Commands section. Bits must be at most one less than logrows (e.g. 16 when logrows is 17). ### Batch Size @@ -74,8 +76,7 @@ Set this flag to `private` with `--public-outputs=private` (default `public`) if ### Param Visibility -Set this flag to `public` (default `private`) with `--public-params=public` if you want your circuit parameters to be public. You can also hash these by using `hashed`. These will give you the opportunity to prove you're using certain parameters to certain individuals, but not the public. - +Set this flag to `public` (default `private`) with `--public-params=public` if you want your circuit parameters to be public. You can also hash these by using `hashed`. ### Strategy diff --git a/About_ONNX.md b/About_ONNX.md deleted file mode 100644 index a19ccd9..0000000 --- a/About_ONNX.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -icon: tools -order: 1 ---- - -### What is ONNX? -ONNX (Open Neural Network Exchange) is an open-source standard for representing deep learning models. It was developed to facilitate interoperability between various deep learning frameworks, such as TensorFlow, PyTorch, and Caffe2. ONNX provides a common file format that allows models trained in one framework to be used in another framework for inference, without the need for model conversion. - -### Why do we use ONNX? -ONNX is used for several reasons: - -**Easy Integration**: ONNX files are used in ezkl to generate zk-SNARKS from individual operations (e.g. ReLU, Sigmoid, Softmax). The ONNX format makes it straight-forward to parse and separate layers for generating individual circuits. - -**Interoperability**: ONNX enables developers to train models in one deep learning framework and use them in another for inference, without the need for conversion. This eases the process of deploying models and allows developers to use the best tools for each part of the development process. - -**Portability**: ONNX provides a standardized format for deep learning models, making it easier to share models across different platforms and devices. - -**Optimization**: ONNX-compatible tools and libraries, such as ONNX runtimes, can provide optimizations for specific hardware, leading to improved performance. - -**Ecosystem support**: Many popular deep learning frameworks and tools, like TensorFlow, PyTorch, and Microsoft's ONNX Runtime, support ONNX, providing a broad range of options for developers. - -### How to create an ONNX file -Check out our [pyezkl](https://github.com/zkonduit/pyezkl) repository to find detailed steps on generating an ONNX file. \ No newline at end of file diff --git a/Benchmarks.md b/Benchmarks.md deleted file mode 100644 index 3df4e16..0000000 --- a/Benchmarks.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -icon: thumbsup -order: 3 ---- -We include proof generation time benchmarks for some of the implemented layers including the affine, convolutional, and ReLu operations (more to come). - -To run these benchmarks: - -```bash -cargo bench -``` - -This may take a **long** time. - -To run a specific benchmark append one of `affine, cnvrl, relu` to the command. You can then find benchmarks results and plots in `target/criterion`. Note that depending on the capabilities of your machine you may need to increase the target time on the Criterion config. For instance: - -```rust -criterion_group! { - name = benches; - config = Criterion::default().measurement_time(Duration::from_secs(10)); - targets = runrelu -} -``` ----------------------- -![](../assets/sengine.png) diff --git a/Command_Line_Interface.md b/Command_Line_Interface.md index e7dfb0e..bfe8251 100644 --- a/Command_Line_Interface.md +++ b/Command_Line_Interface.md @@ -7,9 +7,10 @@ The `ezkl` cli provides a simple interface to load `.onnx` files, which represen ## CLI tutorial 👾 -You can easily create an `.onnx` file using `pytorch`. For samples of Onnx files see [here](https://github.com/onnx/models). For a tutorial on how to quickly generate Onnx files using python, check out [pyezkl](https://github.com/zkonduit/pyezkl). You'll also need an `input.json` file with sample inputs and outputs of your model (Note: input shape is no longer needed since this is now inferred by the library). +You can easily create an `.onnx` file using `pytorch`. For samples of Onnx files see [here](https://github.com/onnx/models). To see how to generate Onnx files using python, check out the notebooks.. You'll also need an `input.json` file with sample inputs and outputs of your model. + +Sample onnx files are also available in the repo . -Sample onnx files are also available in `./examples/onnx`. #### Initializing the project To generate a proof on one of the examples, first install `ezkl` [!ref](/getting_started) @@ -41,21 +42,36 @@ ezkl calibrate-settings -M network.onnx -D input.json --target resources ``` In this example, we set the `--target` to **"resources"** so that we can optimize for CPU and memory usage. The other option is **"accuracy"**, which optimizes for accuracy given the fixed point representation of the input model. Our circuit parameters are generated, then saved to `settings.json`. You can pass a `--settings-path` to read from an existing settings file, and only modify the parts changed by calibration (e.g. leaving visibility or tolerance unchanged). You can customize this file and even change the way it is generated. Learn more about `gen-settings` and `calibrate-settings` in the [Commands](https://docs.ezkl.xyz/about_ezkl/commands/) section. + +#### Compiling the model +From the onnx file, we will create a `.ezkl` file that uses the settings to convert the onnx model to a format ready for proving. + +```bash +ezkl compile-model -M network.onnx -S settings.json --compiled-model network.ezkl +``` + + #### Creating the circuit Now, we use `setup` to create a proving and verifying key for our circuit, using the SRS, our circuit settings, and the .onnx file. ```bash -ezkl setup -M network.onnx --srs-path=15.srs --vk-path=vk.key --pk-path=pk.key --settings-path=settings.json +ezkl setup -M network.ezkl --srs-path=15.srs --vk-path=vk.key --pk-path=pk.key --settings-path=settings.json ``` This creates the verification key, proving key, and circuit settings in the locations you specify. > Note: You can view the options associated to a subcommand such as `setup` by typing `ezkl setup` with no parameters. If you provide some but not all required parameters, `ezkl` will tell you what else it needs. #### Making a proof +First we generate a witness file. + +```bash +ezkl gen-witness -D input.json -M network.ezkl -S settings.json +``` + Next we will generate a proof that the model was correctly run on private inputs (this is the default setting). It then outputs the resulting proof at the path specfifed by `--proof-path`. ```bash -ezkl prove -M network.onnx --witness input.json --pk-path=pk.key --proof-path=model.proof --srs-path=15.srs --settings-path=settings.json +ezkl prove -M network.ezkl --witness witness.json --pk-path=pk.key --proof-path=model.proof --srs-path=15.srs --settings-path=settings.json ``` #### Verification @@ -64,5 +80,19 @@ We can then verify our generated proof with the `verify` command: ezkl verify --proof-path=model.proof --settings-path=settings.json --vk-path=vk.key --srs-path=15.srs ``` +#### All together +```bash +cp ~/ezkl/examples/onnx/4l_relu_conv_fc/network.onnx ./ +cp ~/ezkl/examples/onnx/4l_relu_conv_fc/input.json ./ +ezkl gen-settings -M network.onnx +ezkl calibrate-settings -M network.onnx -D input.json --target resources +ezkl get-srs -S settings.json +ezkl compile-model -M network.onnx -S settings.json --compiled-model network.ezkl +ezkl setup -M network.ezkl --srs-path=kzg.srs --vk-path=vk.key --pk-path=pk.key --settings-path=settings.json +ezkl gen-witness -D input.json -M network.ezkl -S settings.json +ezkl prove -M network.ezkl --witness witness.json --pk-path=pk.key --proof-path=model.proof --srs-path=kzg.srs --settings-path=settings.json +ezkl verify --proof-path=model.proof --settings-path=settings.json --vk-path=vk.key --srs-path=kzg.srs +``` + diff --git a/Examples.md b/Examples.md deleted file mode 100644 index 9751688..0000000 --- a/Examples.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -icon: book -order: 6 ---- - -This repository includes onnx example files as a submodule for testing out the cli. - -If you want to add a model to `examples/onnx`, open a PR creating a new folder within `examples/onnx` with a descriptive model name. This folder should contain: -- an `input.json` input file, with the fields expected by the [ezkl](https://github.com/zkonduit/ezkl) cli. -- a `network.onnx` file representing the trained model -- a `gen.py` file for generating the `.json` and `.onnx` files following the general structure of `examples/tutorial/tutorial.py`. - - -TODO: add associated python files in the onnx model directories. - ----------------------- - - -## library examples 🔍 - -Beyond the `.onnx` examples detailed above, we also include examples which directly use some of our rust API; allowing users to code up computational graphs and circuits from scratch in rust without having to go via python. - -The MNIST inference example using `ezkl` as a library is contained in `examples/conv2d_mnist`. To run it: - -```bash -# download MNIST data -chmod +x data.sh -./data.sh -# test the model (takes 600-700 seconds) -cargo run --release --example conv2d_mnist -``` - -We also provide an example which runs an MLP on input data with four dimensions. To run it: - -```bash -cargo run --release --example mlp_4d -``` - ----------------------- - - - - diff --git a/FAQ.md b/FAQ.md index a27e997..125d6f7 100644 --- a/FAQ.md +++ b/FAQ.md @@ -64,8 +64,7 @@ This error is typically thrown when no public variables are passed to the circui This error is thrown when attempting to rescale inputs for an operation ### Error: ModelLoad This error is thrown when a model fails to load; please check your onnx file for missing connections / unsupported layers. We suggest using [Netron](https://netron.app/) to view onnx files. -### Error: PackingExponent -PackingExponent is thrown when the scale for packing tensor values is too large. Keep the exponent under the logarithm (with your chosen base) of `i128::MAX` (about 38 for base 10, about 88 for base `e`). + diff --git a/Getting_Started.md b/Getting_Started.md index ecc8a55..d4406db 100644 --- a/Getting_Started.md +++ b/Getting_Started.md @@ -4,10 +4,13 @@ order: 95 --- ### Installing EZKL -You may want to download a release binary from the GitHub, or use `ezkl` from Python with `pip install ezkl`. If you want the latest build, you can also install from source. +To use `ezkl` in Python, just `!pip install ezkl`. You will generally also need `onnx` installed if you are exporting models, and Pytorch, Tensorflow, or similar if you are creating models. `ezkl` uses your system `solc` Solidity compiler, so you may need to tweak it using svm-rs or solc-select, particularly if you are targeting a specific hardfork. +To use the cli, download a [release binary](https://github.com/zkonduit/ezkl/releases) from GitHub. If you want the latest build, you can also install from source. + + ### Building from source 🔨 Ezkl is built in rust. First [install rust](https://www.rust-lang.org/tools/install), e.g. by ```bash diff --git a/Verifying_On-Chain.md b/Verifying_On-Chain.md index f6834b3..a7b61b7 100644 --- a/Verifying_On-Chain.md +++ b/Verifying_On-Chain.md @@ -2,9 +2,9 @@ icon: workflow order: 7 --- -#### verifying with the EVM ◊ +#### Verifying with the EVM ◊ -Verification can also be run with an EVM verifier. This can be done by generating a verifier smart contract after performing setup. +To verify on-chain, generate a verifier smart contract after performing setup. You can use the example from Commands, or create it by copying over a network and input file (assuming the ezkl repo is in your home directory): ```bash @@ -13,22 +13,23 @@ cp ~/ezkl/examples/onnx/4l_relu_conv_fc/input.json ./ ``` then create the setup ```bash -ezkl gen-srs --logrows 16 --srs-path=16.srs ezkl gen-settings -M network.onnx ezkl calibrate-settings -M network.onnx -D input.json --target resources -ezkl setup -M network.onnx --srs-path=16.srs --settings-path=settings.json +ezkl get-srs -S settings.json +ezkl compile-model -M network.onnx -S settings.json --compiled-model network.ezkl +ezkl setup -M network.ezkl --srs-path=kzg.srs --settings-path=settings.json ``` -Now we use the setup to create an EVM verifier, which would be deployed on-chain. +Now we use this setup to create an EVM verifier, which would be deployed on-chain. ```bash # gen evm verifier -ezkl create-evm-verifier --srs-path=16.srs --vk-path vk.key --sol-code-path verif.sol --settings-path=settings.json +ezkl create-evm-verifier --srs-path=kzg.srs --vk-path vk.key --sol-code-path verif.sol --settings-path=settings.json ``` ```bash -ezkl gen-witness -D input.json -M network.onnx --settings-path=settings.json -ezkl prove --transcript=evm --witness witness.json -M network.onnx --proof-path model.pf --pk-path pk.key --srs-path=16.srs --settings-path=settings.json +ezkl gen-witness -D input.json -M network.ezkl --settings-path=settings.json +ezkl prove --transcript=evm --witness witness.json -M network.ezkl --proof-path model.pf --pk-path pk.key --srs-path=kzg.srs --settings-path=settings.json ``` ```bash @@ -51,7 +52,11 @@ ezkl deploy-evm-verifier --addr-path=addr.txt --rpc-url=http://127.0.0.1:3030 -- ezkl verify-evm --proof-path model.pf --addr=*paste address in addr.txt here* --rpc-url=http://127.0.0.1:3030 ``` -Note that the `.sol` file above can be deployed and composed with other Solidity contracts, via a `verify()` function. Please read [this document](https://hackmd.io/QOHOPeryRsOraO7FUnG-tg) for more information about the interface of the contract, how to obtain the data needed for its function parameters, and its limitations. +Note that the `.sol` file above can be deployed and composed with other Solidity contracts, via a `verify()` function. + +#### Aggregation + +> Note: this is an advanced technique, very resource-intensive, and chances are you don't want to use this; if you are having trouble with proof size, first try asking about your problem in Telegram or Discord. The above pipeline can also be run using proof aggregation to reduce the final proof size and the size and execution cost of the on-chain verifier. A sample pipeline for doing so would be as follows. @@ -72,20 +77,27 @@ ezkl gen-settings -M network.onnx ezkl calibrate-settings -M network.onnx -D input.json --target resources ``` +Set up the first proof. ```bash # Set up a new circuit -ezkl setup -M network.onnx --srs-path=20.srs --vk-path=vk.key --pk-path=pk.key --settings-path=settings.json +ezkl compile-model -M network.onnx -S settings.json --compiled-model network.ezkl +ezkl setup -M network.ezkl --srs-path=20.srs --vk-path=vk.key --pk-path=pk.key --settings-path=settings.json ``` ```bash # Single proof -> single proof we are going to feed into aggregation circuit. (Mock)-verifies + verifies natively as sanity check -ezkl gen-witness -D input.json -M network.onnx --settings-path=settings.json -ezkl prove --transcript=poseidon --strategy=accum -W witness.json -M network.onnx --proof-path first.pf --srs-path=20.srs --pk-path=pk.key --settings-path=settings.json +ezkl gen-witness -D input.json -M network.ezkl --settings-path=settings.json +ezkl prove --transcript=poseidon --strategy=accum -W witness.json -M network.ezkl --proof-path first.pf --srs-path=20.srs --pk-path=pk.key --settings-path=settings.json +``` + +Setup the aggregate proof. +```bash +ezkl setup-aggregate --sample-snarks first.pf --srs-path 20.srs --logrows 20 ``` ```bash # Aggregate -> generates aggregate proof -ezkl aggregate --logrows=20 --aggregation-snarks=first.pf --srs-path=20.srs +ezkl aggregate --logrows=20 --aggregation-snarks=first.pf --srs-path=20.srs --pk-path pk_aggr.key ``` ```bash diff --git a/default.md b/default.md index 19e87a0..f993a80 100644 --- a/default.md +++ b/default.md @@ -14,12 +14,14 @@ order: 100 > "I correctly ran this publicly available neural network on some public data and it produced this output" -These proofs can be trusted by anyone with a copy of the verifier, and even verified on Ethereum. `ezkl` can be used as a command-line tool, or directly from Python; [see this colab notebook](https://colab.research.google.com/drive/1XuXNKqH7axOelZXyU3gpoTOCvFetIsKu?usp=sharing) and the python bindings docs. [!ref](/python_bindings) +These proofs can be trusted by anyone with a copy of the verifier, and verified directly on Ethereum and compatible chains. `ezkl` can be used directly from Python; [see this colab notebook](https://colab.research.google.com/drive/1XuXNKqH7axOelZXyU3gpoTOCvFetIsKu?usp=sharing) and the python bindings docs. It can also be used from the command line. `ezkl` can prove an MNIST-sized inference in less than a second and under 180mb of memory and verify it on the Ethereum Virtual Machine (or on the command line, or in the browser using wasm). You can install the Python version with `pip install ezkl`. +`ezkl` can be used to move large and complex computations off-chain in a way that is easy to program (you can write your own functions in Python) and manage. You are not limited to a pre-defined set of functions, there is no limit on input size (using hashing), and there is no centralized sequencer. + For more details on how to use `ezkl`, we invite you to explore the docs and check out the repo, especially the notebooks. ---------------------- @@ -50,18 +52,19 @@ The outputs of setup are: - the verification key, and - the circuit settings: serialized flags, settings, and options, and a few numbers that describe the shape of the resulting circuit. -Before setup can run, the settings need to be generated with `gen-settings` and optionally `calibrate-settings`. +Before setup can run, the settings need to be generated with `gen-settings` and optionally `calibrate-settings`, and the model must be compiled. ```python ezkl.gen_settings(onnx_filename, settings_filename) ezkl.calibrate_settings( input_filename, onnx_filename, settings_filename, "resources") +res = ezkl.compile_model(model_path, compiled_model_path, settings_path) res = ezkl.setup( - onnx_filename, + compiled_model_path, vk_path, pk_path, - params_path, - settings_filename, + srs_path, + settings_path, ) ``` @@ -70,7 +73,7 @@ Prove, invoked with `ezkl prove` at the cli or `ezkl.prove()` in Python, is call The inputs to prove are: - the witness data for the claim: an (input, output) pair $(x,y)$ such that model(input) = output (this pair can be produced from $x$ using the `gen-witness` command) -- the model (as an onnx file) +- the model (as a compiled model file, made from an onnx file) - the proving key - the structured reference string, and - the circuit settings. @@ -79,17 +82,17 @@ The outputs of prove are: - the proof file. ```python -res = ezkl.gen_witness(input_filename, onnx_filename, witness_path, settings_path = settings_filename) +res = ezkl.gen_witness(data_path, compiled_model_path, witness_path, settings_path = settings_path) -proof = ezkl.prove( +res = ezkl.prove( witness_path, - onnx_filename, + compiled_model_path, pk_path, proof_path, - params_path, + srs_path, "evm", "single", - settings_filename, + settings_path, ) ``` @@ -133,7 +136,7 @@ The inputs to (non-EVM) verify are: ## Contributing 🌎 -If you're interested in contributing and are unsure where to start, reach out to one of the maintainers on our [Telegram group](https://t.me/+QRzaRvTPIthlYWMx). +If you're interested in contributing and are unsure where to start, reach out to one of the maintainers on our [Telegram group](https://t.me/+QRzaRvTPIthlYWMx) or our [Discord](https://discord.gg/mqgdwdSgzA). More broadly: