From 5e367baab990901517cc152d39b5089620394421 Mon Sep 17 00:00:00 2001 From: Prakash Narayana Moorthy Date: Fri, 12 Apr 2024 19:49:24 +0000 Subject: [PATCH] address review comments on PR Signed-off-by: Prakash Narayana Moorthy --- docs/notebooks/index.md | 4 +- inference-contract/README.md | 50 +++++-- .../docs/notebooks/documents/overview.md | 24 +-- .../docs/notebooks/factories/token-issuer.py | 15 +- inference-contract/docs/notebooks/index.md | 8 +- .../docs/notebooks/templates/token-issuer.py | 32 ++-- .../docs/notebooks/templates/token.py | 40 +++-- inference-contract/test/guardian_frontend.sh | 138 ------------------ inference-contract/test/script_test.sh | 2 + 9 files changed, 100 insertions(+), 213 deletions(-) delete mode 100755 inference-contract/test/guardian_frontend.sh diff --git a/docs/notebooks/index.md b/docs/notebooks/index.md index f48d3c4..c85957f 100644 --- a/docs/notebooks/index.md +++ b/docs/notebooks/index.md @@ -53,8 +53,8 @@ The Digital Assets contract family implements a basic digital asset for bitmap i The Inference contract family provides contracts for creating a confidentiality preserving policy-wrapper around the usage of a machine learning (ML) model. -At its core, the implementation uses a token contract to specify and enforce -policies to be followed while using the ML model for inferecing operations. +The policy-wrapper specifies and helps enforce policies to be followed while +using the ML model for inferencing operations, and is implemented as a PDO contract. To experiment with inference contracts, explore the [Inference Contract Family notebook](inference/index.ipynb) diff --git a/inference-contract/README.md b/inference-contract/README.md index d25f451..4d8c43d 100644 --- a/inference-contract/README.md +++ b/inference-contract/README.md @@ -3,13 +3,13 @@ Licensed under Creative Commons Attribution 4.0 International License https://creativecommons.org/licenses/by/4.0/ ---> -# NFT and openvino inference contracts using PDO # +# NFT and openVINO inference contracts using PDO # This directory contains a Private Data Objects contract family for creating a confidentiality preserving policy-wrapper around the usage of a machine learning (ML) model. At its core, the implementation contains a Token Object PDO contract that specifies and checks the -policies to be followed while using the ML model for inferecing +policies to be followed while using the ML model for inferencing operations. In this implementation, the ML Model is assumed to be an [OpenVINO based IR](https://docs.openvino.ai/2023.2/openvino_ir.html) model. The model itself is deployed via an asset guardian service; the @@ -46,7 +46,7 @@ contract and the model usage. We note that while the Token Object smart contract is executed within Intel SGX enclaves (via PDO), the asset guardian service in this -impelementation is not protected by TEEs. A prospective asset-user +implementation is not protected by TEEs. A prospective asset-user (token owner) relies on the asset owner for the trustworthiness of the guardian service. However, it is entirely possible to extend the protocols and implementation here to offer increased protection by @@ -63,7 +63,7 @@ docker pull openvino/model_server:latest ``` Our tests are based on the -[classication demo model](https://github.com/openvinotoolkit/model_server/tree/main/demos/image_classification) +[Classification demo model](https://github.com/openvinotoolkit/model_server/tree/main/demos/image_classification) contained within the OpenVINO repository. Please use the following commands use to download the model and deploy the OpenVINO model server docker container loaded with the classification model. @@ -79,7 +79,7 @@ The model server endpoint is `127.0.0.1:9000`. Please note that we want the model server to be accessible only from the Guardian Service frontend. In our tests, we assume that the Guardian Service and the model server are hosted on the same machine. The token owner (in -practice situated on a remote node) submits inference reqeust first to +practice situated on a remote node) submits inference request first to the token object, and gets back a capability package (see above for definition). As a second step, the token owner submits the capability package to the Guardian Service. The Guardian Service verifies the @@ -112,14 +112,38 @@ cd $PDO_CONTRACTS_SOURCE_ROOT/inference-contract/test/ We provide [Jupyter Notebooks](./docs/notebooks/README.md) that can be executed in an interactive manner to illustrate the functionality of the inference -contract family. The notebooks assume that the pdo services, -pdo ledger as well the asset guardian service are running prior to executing -notebook commands. As noted earlier, the guardian backend is the OpenVINO -model server; the `docker run` command provided above is used to deploy the -backend. The frontend can be deployed (on bare-metal) using the following -command: +contract family. We support Jupyter notebook deployment via both docker containers +as well as bare-metal. + +For docker, please invoke the `make test_jupyter` command +from within the docker folder contained within this repo. This command deploys the +pdo ledger, pdo services, guardian frontend as well as the openVINO containers in +addition to the container that hosts the Jupyter server for interaction. + +If bare-metal deployment of Jupyter server is desired, please ensure that pdo services, pdo ledger +as well the asset guardian service are running prior to starting the Jupyter server +on bare-metal. Note that these services may be deployed either on bare-metal or docker, +even though the Jupyter server is deployed on bare-metal. Please consult the +[PDO repo] `https://github.com/hyperledger-labs/private-data-objects/tree/main` repo for deployment +options for pdo ledger and services. Regarding deployment of the model guardian, +the guardian backend is the OpenVINO model server; the `docker run` command provided above +is used to deploy the backend. Deploying openVINO model server without docker is possible; +please consult `https://docs.openvino.ai/2022.3/ovms_what_is_openvino_model_server.html` +for instructions. For deploying the guardian front end on bare-metal, please use the following +commands to sequentially deploy the guardian storage service first, and then the guardian web service. ```bash -cd $PDO_CONTRACTS_SOURCE_ROOT/inference-contract/test/ -./guardian_frontend.sh +${PDO_HOME}/contracts/inference/scripts/ss_start.sh -c -o ${PDO_HOME}/logs -- \ + --loglevel debug \ + --config guardian_service.toml \ + --config-dir ${PDO_HOME}/etc/contracts \ + --identity guardian_sservice + +${PDO_HOME}/contracts/inference/scripts/gs_start.sh -c -o ${PDO_HOME}/logs -- \ + --loglevel debug \ + --config guardian_service.toml \ + --config-dir ${PDO_HOME}/etc/contracts \ + --identity guardian_service \ + --bind host ${PDO_HOSTNAME} \ + --bind service_host ${PDO_HOSTNAME} ``` diff --git a/inference-contract/docs/notebooks/documents/overview.md b/inference-contract/docs/notebooks/documents/overview.md index bba47fe..37c9a8a 100644 --- a/inference-contract/docs/notebooks/documents/overview.md +++ b/inference-contract/docs/notebooks/documents/overview.md @@ -14,13 +14,13 @@ jupyter: # Inference contracts using PDO # -The Inference contract family is a suite of contracts that extend the -capabilities of the [Exchange Contract Family ](../exchange/documents/overview.ipynb) +The Inference contract family is a suite of contracts that extend the +capabilities of the [Exchange Contract Family ](../exchange/documents/overview.ipynb) in order to create a confidentiality preserving policy-wrapper around the -usage of a machine learning (ML) model. At its core, the implementation -contains a Token Object PDO contract that specifies and checks the -policies to be followed while using the ML model for inferecing -operations. In this implementation, the ML Model is assumed to be an +usage of a machine learning (ML) model. The policy-wrapper specifies and checks the +policies to be followed while using the ML model for inferencing +operations, and is implemented as a PDO contract that we refer to as the Token Object. +In this implementation, the ML Model is assumed to be an [OpenVINO based IR](https://docs.openvino.ai/2023.2/openvino_ir.html) model. The model itself is deployed via an asset guardian service; the overall architecture of how a PDO token object gets used to manage an @@ -32,14 +32,18 @@ for the foundational secure communication protocols between the Token Object and the Asset Guardian Service. The asset guardian service here is implemented as a web service -containing a frontend and backend portions.The backend of the guardian +containing a frontend and backend portions. The backend of the guardian service implements the OpenVINO model server capable of performing inferencing operations using the OpenVINO IR model. The frontend of the guardian service at a high level performs two -functions: 1. Processes the capability package generated by the token +functions: + +1. Processes the capability package generated by the token object and generates/invokes the API for the backend. The capability package may be thought of the asset-usage approval generated by the -token object smart contract. 2. Implements any input preprocessing and +token object smart contract. + +2. Implements any input preprocessing and output postprocessing (collectively referred to as model scoring) as determined necessary by the original asset owner. @@ -53,7 +57,7 @@ contract and the model usage. We note that while the Token Object smart contract is executed within Intel SGX enclaves (via PDO), the asset guardian service in this -impelementation is not protected by TEEs. A prospective asset-user +implementation is not protected by TEEs. A prospective asset-user (token owner) relies on the asset owner for the trustworthiness of the guardian service. However, it is entirely possible to extend the protocols and implementation here to offer increased protection by diff --git a/inference-contract/docs/notebooks/factories/token-issuer.py b/inference-contract/docs/notebooks/factories/token-issuer.py index b1f47ec..73ccd30 100644 --- a/inference-contract/docs/notebooks/factories/token-issuer.py +++ b/inference-contract/docs/notebooks/factories/token-issuer.py @@ -16,8 +16,8 @@ # %% [markdown] # # Token Family Factory # -# This notebook simplifies the creation of an instance of a token issuer. -# Update the token configuration information then evaluate the notebook to +# This notebook simplifies the creation of an instance of a token issuer. +# Update the token configuration information then evaluate the notebook to # create a new token issuer. That token issuer will be able to mint tokens # for the underlying ML model for which policy-based inferencing need to be # enabled. The created token is then exchanged to a prospective model user @@ -35,20 +35,21 @@ # %% [markdown] # ## Configure Token Information # -# This section enables customization of the token that will be minted. +# This section enables customization of the token that will be minted. # Edit the variables in the section below as necessary. # # * identity : the identity of the token creator # * token_class : the name of tokens that will be generated # -# Note that the notebook assumes that there is a key file for the identity of -# the form: `${keys}/${identity}_private.pem`. +# Note that the notebook assumes that there is a key file for the identity of +# the form: `${keys}/${identity}_private.pem`. Please use the /documents/key_manager.ipynb +# notebook to create desired keys. # %% tags=["parameters"] identity = input('Identity of the token issuer: ') token_class = input('Name of the class of tokens to issue: ') -service_host = input('Service host [localhost]: ') +service_host = input('Service host [localhost]: ') or 'localhost' # %% [markdown] @@ -66,4 +67,4 @@ } instance_file = pc_jupyter.instantiate_notebook_from_template(token_class, 'token-issuer', instance_parameters) -ip_display.display(ip_display.Markdown('[Token Issuer]({})'.format(instance_file))) +ip_display.display(ip_display.Markdown('[Newly created token issuer]({})'.format(instance_file))) diff --git a/inference-contract/docs/notebooks/index.md b/inference-contract/docs/notebooks/index.md index 217b949..eb2fadb 100644 --- a/inference-contract/docs/notebooks/index.md +++ b/inference-contract/docs/notebooks/index.md @@ -14,12 +14,12 @@ jupyter: # Inference Contract Family -The Inference contract family is a suite of contracts that extend the -capabilities of the [Exchange Contract Family ](../exchange/documents/overview.ipynb) +The Inference contract family is a suite of contracts that extend the +capabilities of the [Exchange Contract Family ](../exchange/documents/overview.ipynb) in order to create a confidentiality preserving policy-wrapper around the -usage of a machine learning (ML) model. This directory contains sample +usage of a machine learning (ML) model. This directory contains sample Jupyter notebooks that can be used to create and interact with contract -objects in the Inference contract family. The structure of notebooks follows +objects in the Inference contract family. The structure of notebooks follows the pattern followed by the notebooks used to illustrate the exchange contracts family. diff --git a/inference-contract/docs/notebooks/templates/token-issuer.py b/inference-contract/docs/notebooks/templates/token-issuer.py index f6d989f..a942f63 100644 --- a/inference-contract/docs/notebooks/templates/token-issuer.py +++ b/inference-contract/docs/notebooks/templates/token-issuer.py @@ -14,15 +14,15 @@ # %% [markdown] # # Token Issuer Notebook -# This section enables customization of the token that will be minted. Edit the variables in the section below as necessary. +# This section enables customization of the token that will be minted. Edit the variables in the section below as necessary. +# +# * token_owner : the identity of the token creator +# * token_class : the name of tokens that will be generated, this is only used to simplify local access (e.g. context file name) +# * token_description : a description of the asset associated with the minted tokens +# * token_metadata : additional information about the token +# * count : the number of tokens to mint for the asset +# * service_host : the host for the eservice where tokens will be minted, this will use the default service group # -# identity : the identity of the token creator -# service_host : the host for the eservice where tokens will be minted, this will use the default service group -# token_class : the name of tokens that will be generated, this is only used to simplify local access (e.g. context file name) -# token_description : a description of the asset associated with the minted tokens -# token_metadata : additional information about the token -# count : the number of tokens to mint for the asset - # Note that the notebook assumes that there is a key file for the identity of the form: `${keys}/${identity}_private.pem`. @@ -52,8 +52,8 @@ # ### Initialize the PDO Environment # # Initialize the PDO environment. This assumes that a functional PDO configuration -# is in place and that the PDO virtual environment has been activated. In particular, -# ensure that the groups file and eservice database have been configured correctly. +# is in place and that the PDO virtual environment has been activated. In particular, +# ensure that the groups file and eservice database have been configured correctly. # If you do not have a service groups configuration, you can create it for a single # service host by running the following: @@ -83,8 +83,8 @@ # ### Initialize the Contract Context # # The contract context defines the configuration for a collection of contract objects -# that interact with one another. By default, the context file used in this notebook -# is specific to the token. If you prefer to use a common context file, edit the +# that interact with one another. By default, the context file used in this notebook +# is specific to the token. If you prefer to use a common context file, edit the # `context_file` variable below. # # For the most part, no other modifications should be required. @@ -114,10 +114,10 @@ # %% [markdown] # ### Create the Token Issuer Contract # -# The process of creating the token issuer will also create an asset type contract object, -# a vetting organization contract object, and the guardian contract object. -# The asset type and vetting organization contract objects are principally used -# to complete the canonical asset interface that enables transparent value exchanges +# The process of creating the token issuer will also create an asset type contract object, +# a vetting organization contract object, and the guardian contract object. +# The asset type and vetting organization contract objects are principally used +# to complete the canonical asset interface that enables transparent value exchanges # with tokens and other digital assets. # %% diff --git a/inference-contract/docs/notebooks/templates/token.py b/inference-contract/docs/notebooks/templates/token.py index 6cb6b86..adb47d8 100644 --- a/inference-contract/docs/notebooks/templates/token.py +++ b/inference-contract/docs/notebooks/templates/token.py @@ -104,7 +104,12 @@ # %% [markdown] -# ### Invoke Inference Operation +# ## Operations that can be performed on the Token +# Below we illustrate some of the operations that a token owner can perform on the token. +# Note that what is permissible is entirely dependant on the policies +# implemented by the token contract +# +# ### Operation 1. Invoke Inference Operation # # The model is an image classfication model. Use the following cell to # provide input to the classification oepration. Current token object policy @@ -115,9 +120,9 @@ # via the contracts docker container, copy your test image to # `$PDO_CONTRACTS_SRC_ROOT/docker/xfer/client/` folder and # provide the value `/project/pdo/xfer/client` for the input `path`. -# -# Also, please note that `$PDO_CONTRACTS_SRC_ROOT/inference-contract/data` folder -# contains the sample image `zebra_wiki.jpg` that may be used for testing +# A sample test image `zebra_wiki.jpg` can be found at +# `$PDO_CONTRACTS_SRC_ROOT/inference-contract/data`. + # %% tags=["parameters"] image_name = input('Name of the image file') @@ -131,7 +136,7 @@ # %% [markdown] -# ### Transfer Ownership to a New User +# ### Operation 2. Transfer Ownership (and hence the right to perform inference) to a New User # # User1 now transfers ownership of the token object (and hence its capabilities) # to a new user. Note that the notebook assumes that user1 knows the public key @@ -147,35 +152,24 @@ state, token_context, new_owner=new_user_identity) # %% [markdown] -# ### Test Ownership -# -# Let's ensure that user1 can no longer perform operations on the asset. -# The following asset usage command should fail: - -# %% -inference_result = pc_jupyter.pcommand.invoke_contract_cmd( - pc_jupyter.ml_inference_token_object.cmd_do_inference, - state, token_context, image=image_name, search_path=[path]) - -# %% [markdown] -# ### New User Performs Operations on the Asset +# ### Operation 3.New User Performs Operations on the Asset # -# Let's also ensure that user2 can indeed perform operations on the asset. # Note that in the following command, we explicitly pass the identity of the caller +# The old token owner after ownership transfer can longer invoke inference oeprations. # %% inference_result = pc_jupyter.pcommand.invoke_contract_cmd( pc_jupyter.ml_inference_token_object.cmd_do_inference, - state, token_context, image=image_name, search_path=[path], identity='user2') + state, token_context, image=image_name, search_path=[path], identity=new_user_identity) # %% [markdown] -# ### Onwership Transfer Is Still Possible, But now done by user2! +# ### Operation 4. Re-transfer of ownership to a 3rd user Test Ownership # -# User2 is the current owner of the token, and can transfer asset-usage rights to -# a third person, say user3. +# The token policy in this example permits re-transfer of ownership. + # %% -current_owner_identity = new_user_identity #user2 +current_owner_identity = new_user_identity new_user_identity = 'user3' pc_jupyter.pcommand.invoke_contract_cmd( pc_jupyter.ml_inference_token_object.cmd_transfer_assets, diff --git a/inference-contract/test/guardian_frontend.sh b/inference-contract/test/guardian_frontend.sh deleted file mode 100755 index bd9c159..0000000 --- a/inference-contract/test/guardian_frontend.sh +++ /dev/null @@ -1,138 +0,0 @@ -#!/bin/bash - -# Copyright 2023 Intel Corporation -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# ----------------------------------------------------------------- -# ----------------------------------------------------------------- -: "${PDO_LEDGER_URL?Missing environment variable PDO_LEDGER_URL}" -: "${PDO_HOME?Missing environment variable PDO_HOME}" -: "${PDO_SOURCE_ROOT?Missing environment variable PDO_SOURCE_ROOT}" - -# ----------------------------------------------------------------- -# ----------------------------------------------------------------- - -source ${PDO_HOME}/bin/lib/common.sh -check_python_version - -if ! command -v pdo-shell &> /dev/null ; then - yell unable to locate pdo-shell - exit 1 -fi - - -# ----------------------------------------------------------------- -# ----------------------------------------------------------------- -if [ "${PDO_LEDGER_TYPE}" == "ccf" ]; then - if [ ! -f "${PDO_LEDGER_KEY_ROOT}/networkcert.pem" ]; then - die "CCF ledger keys are missing, please copy and try again" - fi -fi - -# ----------------------------------------------------------------- -# Process command line arguments -# ----------------------------------------------------------------- -SCRIPTDIR="$(dirname $(readlink --canonicalize ${BASH_SOURCE}))" -SOURCE_ROOT="$(realpath ${SCRIPTDIR}/..)" - -F_SCRIPT=$(basename ${BASH_SOURCE[-1]} ) -F_SERVICE_HOST=${PDO_HOSTNAME} -F_GUARDIAN_HOST=${PDO_HOSTNAME} -F_LEDGER_URL=${PDO_LEDGER_URL} -F_LOGLEVEL=${PDO_LOG_LEVEL:-info} -F_LOGFILE=${PDO_LOG_FILE:-__screen__} -F_CONTEXT_FILE=${SOURCE_ROOT}/test/test_context.toml -F_CONTEXT_TEMPLATES=${PDO_HOME}/contracts/inference/context -F_EXCHANGE_TEMPLATES=${PDO_HOME}/contracts/exchange/context - -F_USAGE='--host service-host | --ledger url | --loglevel [debug|info|warn] | --logfile file' -SHORT_OPTS='h:l:' -LONG_OPTS='host:,ledger:,loglevel:,logfile:' - -TEMP=$(getopt -o ${SHORT_OPTS} --long ${LONG_OPTS} -n "${F_SCRIPT}" -- "$@") -if [ $? != 0 ] ; then echo "Usage: ${F_SCRIPT} ${F_USAGE}" >&2 ; exit 1 ; fi - -eval set -- "$TEMP" -while true ; do - case "$1" in - -h|--host) F_SERVICE_HOST="$2" ; shift 2 ;; - -1|--ledger) F_LEDGER_URL="$2" ; shift 2 ;; - --loglevel) F_LOGLEVEL="$2" ; shift 2 ;; - --logfile) F_LOGFILE="$2" ; shift 2 ;; - --help) echo "Usage: ${SCRIPT_NAME} ${F_USAGE}"; exit 0 ;; - --) shift ; break ;; - *) echo "Internal error!" ; exit 1 ;; - esac -done - -F_SERVICE_GROUPS_FILE=${SOURCE_ROOT}/test/${F_SERVICE_HOST}_groups.toml -F_SERVICE_DB_FILE=${SOURCE_ROOT}/test/${F_SERVICE_HOST}_db - -_COMMON_=("--logfile ${F_LOGFILE}" "--loglevel ${F_LOGLEVEL}") -_COMMON_+=("--ledger ${F_LEDGER_URL}") -_COMMON_+=("--bind service_host ${F_SERVICE_HOST}") -_COMMON_+=("--service-groups ${F_SERVICE_GROUPS_FILE}") -_COMMON_+=("--service-db ${F_SERVICE_DB_FILE}") -_COMMON_+=("--context-file ${F_CONTEXT_FILE}") -OPTS=${_COMMON_[@]} - -F_KEY_FILES=() -KEYGEN=${PDO_SOURCE_ROOT}/build/__tools__/make-keys - -if [ ! -f ${PDO_HOME}/keys/guardian_service.pem ]; then - yell create keys for the guardian service - ${KEYGEN} --keyfile ${PDO_HOME}/keys/guardian_service --format pem - F_KEY_FILES+=(${PDO_HOME}/keys/guardian_service.pem) - - ${KEYGEN} --keyfile ${PDO_HOME}/keys/guardian_sservice --format pem - F_KEY_FILES+=(${PDO_HOME}/keys/guardian_sservice.pem) -fi - -# ----------------------------------------------------------------- -function cleanup { - rm -f ${F_SERVICE_GROUPS_FILE} - rm -f ${F_SERVICE_DB_FILE} ${F_SERVICE_DB_FILE}-lock - rm -f ${F_CONTEXT_FILE} - for key_file in ${F_KEY_FILES[@]} ; do - rm -f ${key_file} - done - - yell "shutdown guardian and storage service" - ${PDO_HOME}/contracts/inference/scripts/gs_stop.sh - ${PDO_HOME}/contracts/inference/scripts/ss_stop.sh -} - -trap cleanup EXIT - -# ----------------------------------------------------------------- -# Start the guardian service and the storage service -# ----------------------------------------------------------------- -try ${PDO_HOME}/contracts/inference/scripts/ss_start.sh -c -o ${PDO_HOME}/logs -- \ - --loglevel debug \ - --config guardian_service.toml \ - --config-dir ${PDO_HOME}/etc/contracts \ - --identity guardian_sservice - -sleep 3 - -try ${PDO_HOME}/contracts/inference/scripts/gs_start.sh -c -o ${PDO_HOME}/logs -- \ - --loglevel debug \ - --config guardian_service.toml \ - --config-dir ${PDO_HOME}/etc/contracts \ - --identity guardian_service \ - --bind host ${F_GUARDIAN_HOST} \ - --bind service_host ${F_SERVICE_HOST} - -read -p "Guardian Service Frontend Running. Press any key to exit" -exit diff --git a/inference-contract/test/script_test.sh b/inference-contract/test/script_test.sh index 513c43a..6fb40df 100755 --- a/inference-contract/test/script_test.sh +++ b/inference-contract/test/script_test.sh @@ -222,4 +222,6 @@ fi try inference_token do_inference ${OPTS} --identity token_holder1 \ --contract token.test1.token_object.token_1 --image "zebra_wiki.jpg" +#sleep for 10s + exit