Linear Regression

In this series of tutorial, we delve into the world of traditional machine learning models for ZKML. Despite the hype surrounding advanced AI techniques, traditional ML models often offer superior performance or sufficiently robust results for specific applications. This is particularly true for ZKML use cases, where computational proof costs can be a critical factor. Our aim is to equip you with guides on how to implement machine learning algorithms suitable for Giza platform applications. This includes practical steps for converting your scikit-learn models to the ONNX format, transpiling them to Orion Cairo, and deploying inference endpoints for prediction in AI Action.

In this tutorial you will learn how to use the Giza tools though a Linear Regression model.

Before Starting

Before we start, ensure you installed the Giza stack, created a user and logged-in.

$ pipx install giza-cli # Install the Giza-CLI
$ pip install giza-actions # Install the AI Actions SDK

$ giza users create # Create a user
$ giza users login # Login to your account
$ giza users create-api-key # Create an API key. We recommend you do this so you don't have to reconnect.

Create and Train a Linear Regression Model

We'll start by creating a simple linear regression model using Scikit-Learn and train it with some dummy data.

import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split

# Generate some dummy data
X = np.random.rand(100, 1) * 10  # 100 samples, 1 feature
y = 2 * X + 1 + np.random.randn(100, 1) * 2  # y = 2x + 1 + noise

# Split the data into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Create a linear regression model
model = LinearRegression()

# Train the model
model.fit(X_train, y_train)

Convert the Model to ONNX Format

Giza only supports ONNX models so you'll need to convert the model to ONNX format. After the model is trained, you can convert it to ONNX format using the skl2onnx library.

from skl2onnx import convert_sklearn
from skl2onnx.common.data_types import FloatTensorType

# Define the initial types for the ONNX model
initial_type = [('float_input', FloatTensorType([None, X_train.shape[1]]))]

# Convert the scikit-learn model to ONNX
onnx_model = convert_sklearn(model, initial_types=initial_type)

# Save the ONNX model to a file
with open("linear_regression.onnx", "wb") as f:
    f.write(onnx_model.SerializeToString())

Transpile your model to Orion Cairo

We will use Giza-CLI to transpile our ONNX model to Orion Cairo.

$ giza transpile linear_regression.onnx --output-path verifiable_lr
>>>>
[giza][2024-03-19 10:43:11.351] No model id provided, checking if model exists βœ…
[giza][2024-03-19 10:43:11.354] Model name is: linear_regression
[giza][2024-03-19 10:43:11.586] Model Created with id -> 447! βœ…
[giza][2024-03-19 10:43:12.093] Version Created with id -> 1! βœ…
[giza][2024-03-19 10:43:12.094] Sending model for transpilation βœ… 
[giza][2024-03-19 10:43:43.185] Transpilation is fully compatible. Version compiled and Sierra is saved at Giza βœ…
β § Transpiling Model...
[giza][2024-03-19 10:43:43.723] Downloading model βœ…
[giza][2024-03-19 10:43:43.731] model saved at: verifiable_lr

Deploy an inference endpoint

Now that our model is transpiled to Cairo we can deploy an endpoint to run verifiable inferences. We will use Giza CLI again to run deploy an endpoint. Ensure to replace model-id and version-id with your ids provided during transpilation.

$ giza endpoints deploy --model-id 447 --version-id 1

β–°β–±β–±β–±β–±β–±β–± Creating endpoint!
[giza][2024-03-19 10:51:48.551] Endpoint is successful βœ…
[giza][2024-03-19 10:51:48.557] Endpoint created with id -> 109 βœ…
[giza][2024-03-19 10:51:48.558] Endpoint created with endpoint URL: https://endpoint-raphael-doukhan-447-1-a09e4e6f-7i3yxzspbq-ew.a.run.app πŸŽ‰

Run a verifiable inference in AI Actions

To streamline verifiable inference, you might consider using the endpoint URL obtained after transpilation. However, this approach requires manual serialization of the input for the Cairo program and handling the deserialization process. To make this process more user-friendly and keep you within a Python environment, we've introduced AI Actionsβ€”a Python SDK designed to facilitate the creation of ML workflows and execution of verifiable predictions. When you initiate a prediction, our system automatically retrieves the endpoint URL you deployed earlier, converts your input into Cairo-compatible format, executes the prediction, and then converts the output back into a numpy object. More info about AI Actions here.

First ensure you have an AI Actions workspace created. This step grants access to a user-friendly UI dashboard, enabling you to monitor and manage workflows with ease.

$ giza workspaces get

# 🚨 If you haven't set up a workspace yet, you can establish one by executing the command below:
# `$ giza workspaces create`

>>>>
[giza][2024-03-19 11:09:38.486] Retrieving workspace information βœ… 
[giza][2024-03-19 11:09:38.610] βœ… Workspace URL: https://actions-server-raphael-doukhan-dblzzhtf5q-ew.a.run.app βœ…
{
  "url": "https://actions-server-raphael-doukhan-dblzzhtf5q-ew.a.run.app",
  "status": "COMPLETED"
}

Now let's run a verifiable inference with AI Actions. To design your workflow in AI Actions, you will need to define your task with @task decorator and then action your tasks with @action decorator. You can track the progress of your workflow via the workspace URL previously provided.

from giza_actions.model import GizaModel
from giza_actions.action import action
from giza_actions.task import task

MODEL_ID = 447  # Update with your model ID
VERSION_ID = 1  # Update with your version ID


@task(name="PredictLRModel")
def prediction(input, model_id, version_id):
    model = GizaModel(id=model_id, version=version_id)

    (result, proof_id) = model.predict(
        input_feed={'input': input}, verifiable=True
    )

    return result, proof_id


@action(name="ExectuteCairoLR", log_prints=True)
def execution():
    # The input data type should match the model's expected input
    input = np.array([[5.5]]).astype(np.float32)

    (result, proof_id) = prediction(input, MODEL_ID, VERSION_ID)

    print(
        f"Predicted value for input {input.flatten()[0]} is {result[0].flatten()[0]}")

    return result, proof_id


execution()
11:34:04.423 | INFO    | Created flow run 'proud-perch' for flow 'ExectuteCairoLR'
11:34:04.424 | INFO    | Action run 'proud-perch' - View at https://actions-server-raphael-doukhan-dblzzhtf5q-ew.a.run.app/flow-runs/flow-run/637bd0e0-d7e8-4d89-8c07-a266e6c280ce
11:34:04.746 | INFO    | Action run 'proud-perch' - Created task run 'PredictLRModel-0' for task 'PredictLRModel'
11:34:04.748 | INFO    | Action run 'proud-perch' - Executing 'PredictLRModel-0' immediately...
πŸš€ Starting deserialization process...
βœ… Deserialization completed! πŸŽ‰
11:34:08.194 | INFO    | Task run 'PredictLRModel-0' - Finished in state Completed()
11:34:08.197 | INFO    | Action run 'proud-perch' - Predicted value for input 5.5 is 12.208511352539062
11:34:08.313 | INFO    | Action run 'proud-perch' - Finished in state Completed()
(array([[12.20851135]]), '"3a15bca06d1f4788b36c1c54fa71ba07"')

Download the proof

Initiating a verifiable inference sets off a proving job on our server, sparing you the complexities of installing and configuring the prover yourself. Upon completion, you can download your proof.

First, let's check the status of the proving job to ensure that it has been completed.

🚨 Remember to substitute endpoint-id and proof-id with the specific IDs assigned to you throughout this tutorial.

$ giza endpoints get-proof --endpoint-id 109 --proof-id 3a15bca06d1f4788b36c1c54fa71ba07

>>>
[giza][2024-03-19 11:51:45.470] Getting proof from endpoint 109 βœ… 
{
  "id": 664,
  "job_id": 831,
  "metrics": {
    "proving_time": 15.083126
  },
  "created_date": "2024-03-19T10:41:11.120310"
}

Once the proof is ready, you can download it.

$ giza endpoints download-proof --endpoint-id 109 --proof-id 3a15bca06d1f4788b36c1c54fa71ba07 --output-path zklr.proof

>>>>
[giza][2024-03-19 11:55:49.713] Getting proof from endpoint 109 βœ… 
[giza][2024-03-19 11:55:50.493] Proof downloaded to zklr.proof βœ… 

Last updated