Skip to content

Commit

Permalink
Unify the log configuration using kserve logger (kserve#3577)
Browse files Browse the repository at this point in the history
* Configure logging for serving runtimes

Signed-off-by: Sivanantham Chinnaiyan <sivanantham.chinnaiyan@ideas2it.com>

* Add pyyaml dependency

Signed-off-by: Sivanantham Chinnaiyan <sivanantham.chinnaiyan@ideas2it.com>

* black format

Signed-off-by: Sivanantham Chinnaiyan <sivanantham.chinnaiyan@ideas2it.com>

* fix pyproject.toml

Signed-off-by: Sivanantham Chinnaiyan <sivanantham.chinnaiyan@ideas2it.com>

* Rebase master

Signed-off-by: Sivanantham Chinnaiyan <sivanantham.chinnaiyan@ideas2it.com>

* cleanup logger for e2e

Signed-off-by: Sivanantham Chinnaiyan <sivanantham.chinnaiyan@ideas2it.com>

* Modify logger format to include func name

Signed-off-by: Sivanantham Chinnaiyan <sivanantham.chinnaiyan@ideas2it.com>

* Log model download time.

Signed-off-by: Sivanantham Chinnaiyan <sivanantham.chinnaiyan@ideas2it.com>

* Rebase master

Signed-off-by: Sivanantham Chinnaiyan <sivanantham.chinnaiyan@ideas2it.com>

* Allow disabling logger configuration and deprecate logger related arg in model server

Signed-off-by: Sivanantham Chinnaiyan <sivanantham.chinnaiyan@ideas2it.com>

* Rebase master

Signed-off-by: Sivanantham Chinnaiyan <sivanantham.chinnaiyan@ideas2it.com>

* Resolve comments

Signed-off-by: Sivanantham Chinnaiyan <sivanantham.chinnaiyan@ideas2it.com>

* pyyaml=^6.0.0 to fix build failure

Signed-off-by: Sivanantham Chinnaiyan <sivanantham.chinnaiyan@ideas2it.com>

* Remove logger related parameters from model server

Signed-off-by: Sivanantham Chinnaiyan <sivanantham.chinnaiyan@ideas2it.com>

---------

Signed-off-by: Sivanantham Chinnaiyan <sivanantham.chinnaiyan@ideas2it.com>
  • Loading branch information
sivanantha321 authored and cmaddalozzo committed May 24, 2024
1 parent 5901a3b commit 5a14e77
Show file tree
Hide file tree
Showing 65 changed files with 307 additions and 215 deletions.
4 changes: 2 additions & 2 deletions docs/samples/explanation/aif/germancredit/bias.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ spec:
containerConcurrency: 0
containers:
- image: aipipeline/aifserver:predictor
name: kfserving-container
name: kserve-container
resources:
limits:
cpu: "1"
Expand Down Expand Up @@ -61,4 +61,4 @@ spec:
memory: 2Gi
requests:
cpu: "2"
memory: 2Gi
memory: 2Gi
11 changes: 9 additions & 2 deletions docs/samples/explanation/aif/germancredit/server/model.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import argparse

import kserve
from typing import Dict, Union

Expand All @@ -7,7 +9,7 @@
load_preproc_data_german,
)

from kserve import InferRequest, InferResponse
from kserve import InferRequest, InferResponse, logging
from kserve.protocol.grpc.grpc_predict_v2_pb2 import (
ModelInferRequest,
ModelInferResponse,
Expand Down Expand Up @@ -47,7 +49,12 @@ def predict(
return {"predictions": predictions.tolist()}


parser = argparse.ArgumentParser(parents=[kserve.model_server.parser])
args, _ = parser.parse_known_args()

if __name__ == "__main__":
model = KServeSampleModel("german-credit")
if args.configure_logging:
logging.configure_logging(args.log_config_file)
model = KServeSampleModel(args.model_name)
model.load()
kserve.ModelServer(workers=1).start([model])
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import kserve
import argparse

from kserve import logging
from .model import RFModel

DEFAULT_MODEL_NAME = "rfserver"
Expand All @@ -27,6 +28,8 @@
args, _ = parser.parse_known_args()

if __name__ == "__main__":
if args.configure_logging:
logging.configure_logging(args.log_config_file)
model = RFModel(args.model_name)
model.load()
kserve.ModelServer().start([model])
4 changes: 2 additions & 2 deletions docs/samples/explanation/aix/mnist/rfserver/rfserver/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import logging
from typing import Dict, Union
import pickle

Expand All @@ -23,6 +22,7 @@
ModelInferRequest,
ModelInferResponse,
)
from kserve.logging import logger


class PipeStep(object):
Expand Down Expand Up @@ -64,7 +64,7 @@ def predict(

try:
inputs = np.asarray(instances)
logging.info("Calling predict on image of shape %s", (inputs.shape,))
logger.info("Calling predict on image of shape %s", (inputs.shape,))
except Exception as e:
raise Exception(
"Failed to initialize NumPy array from inputs: %s, %s" % (e, instances)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@
# 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.

import logging
import argparse
import os
import sys

Expand All @@ -22,12 +21,15 @@
from alibiexplainer.parser import parse_args

import kserve
from kserve import logging
from kserve.storage import Storage

logging.basicConfig(level=kserve.constants.KSERVE_LOGLEVEL)
from kserve.logging import logger

EXPLAINER_FILENAME = "explainer.dill"

parser = argparse.ArgumentParser(parents=[kserve.model_server.parser])
args, _ = parser.parse_known_args()


def main():
args, extra = parse_args(sys.argv[1:])
Expand All @@ -39,7 +41,7 @@ def main():
Storage.download(args.storage_uri), EXPLAINER_FILENAME
)
with open(alibi_model, "rb") as f:
logging.info("Loading Alibi model")
logger.info("Loading Alibi model")
alibi_model = dill.load(f)

explainer = AlibiExplainer(
Expand All @@ -54,4 +56,6 @@ def main():


if __name__ == "__main__":
if args.configure_logging:
logging.configure_logging(args.log_config_file)
main()
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,15 @@
# 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.
import kserve
import logging

import numpy as np
import alibi
from alibi.api.interfaces import Explanation
from alibi.utils.wrappers import ArgmaxTransformer
from alibiexplainer.explainer_wrapper import ExplainerWrapper
from typing import Callable, List, Optional, Dict

logging.basicConfig(level=kserve.constants.KSERVE_LOGLEVEL)
from kserve.logging import logger


class AnchorImages(ExplainerWrapper):
Expand All @@ -44,7 +43,7 @@ def explain(self, inputs: List, headers: Dict[str, str] = None) -> Explanation:
self.anchors_image.predictor = self.predict_fn
else:
self.anchors_image.predictor = ArgmaxTransformer(self.predict_fn)
logging.info("Calling explain on image of shape %s", (arr.shape,))
logging.info("anchor image call with %s", self.kwargs)
logger.info("Calling explain on image of shape %s", (arr.shape,))
logger.info("anchor image call with %s", self.kwargs)
anchor_exp = self.anchors_image.explain(arr[0], **self.kwargs)
return anchor_exp
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,15 @@
# 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.
import kserve
import logging

import numpy as np
import alibi
from alibi.api.interfaces import Explanation
from alibi.utils.wrappers import ArgmaxTransformer
from alibiexplainer.explainer_wrapper import ExplainerWrapper
from typing import Callable, List, Optional, Dict

logging.basicConfig(level=kserve.constants.KSERVE_LOGLEVEL)
from kserve.logging import logger


class AnchorTabular(ExplainerWrapper):
Expand All @@ -41,7 +40,7 @@ def explain(self, inputs: List, headers: Dict[str, str] = None) -> Explanation:
arr = np.array(inputs)
# set anchor_tabular predict function so it always returns predicted class
# See anchor_tabular.__init__
logging.info("Arr shape %s ", (arr.shape,))
logger.info("Arr shape %s ", (arr.shape,))

# check if predictor returns predicted class or prediction probabilities for each class
# if needed adjust predictor so it returns the predicted class
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@
# 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.
import kserve
import logging

import numpy as np
import spacy
import alibi
Expand All @@ -22,7 +21,7 @@
from alibiexplainer.explainer_wrapper import ExplainerWrapper
from typing import Callable, List, Optional, Dict

logging.basicConfig(level=kserve.constants.KSERVE_LOGLEVEL)
from kserve.logging import logger


class AnchorText(ExplainerWrapper):
Expand All @@ -35,12 +34,12 @@ def __init__(
):
self.predict_fn = predict_fn
self.kwargs = kwargs
logging.info("Anchor Text args %s", self.kwargs)
logger.info("Anchor Text args %s", self.kwargs)
if explainer is None:
logging.info("Loading Spacy Language model for %s", spacy_language_model)
logger.info("Loading Spacy Language model for %s", spacy_language_model)
spacy_model(model=spacy_language_model)
self.nlp = spacy.load(spacy_language_model)
logging.info("Language model loaded")
logger.info("Language model loaded")
self.anchors_text = explainer

def explain(self, inputs: List, headers: Dict[str, str] = None) -> Explanation:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,25 @@
# 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.

import json
import logging
import asyncio
from enum import Enum
from typing import List, Any, Mapping, Union, Dict

import kserve
import numpy as np
import nest_asyncio

from alibiexplainer.anchor_images import AnchorImages
from alibiexplainer.anchor_tabular import AnchorTabular
from alibiexplainer.anchor_text import AnchorText
from alibiexplainer.explainer_wrapper import ExplainerWrapper

import nest_asyncio
import kserve
from kserve.logging import logger

nest_asyncio.apply()

logging.basicConfig(level=kserve.constants.KSERVE_LOGLEVEL)


class ExplainerMethod(Enum):
anchor_tabular = "AnchorTabular"
Expand All @@ -51,7 +51,7 @@ def __init__( # pylint:disable=too-many-arguments
):
super().__init__(name)
self.predictor_host = predictor_host
logging.info("Predict URL set to %s", self.predictor_host)
logger.info("Predict URL set to %s", self.predictor_host)
self.method = method

if self.method is ExplainerMethod.anchor_tabular:
Expand Down Expand Up @@ -84,7 +84,7 @@ def explain(self, payload: Dict, headers: Dict[str, str] = None) -> Any:
):
explanation = self.wrapper.explain(payload["instances"])
explanationAsJsonStr = explanation.to_json()
logging.info("Explanation: %s", explanationAsJsonStr)
logger.info("Explanation: %s", explanationAsJsonStr)
return json.loads(explanationAsJsonStr)

raise NotImplementedError
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,16 @@

import argparse
import kserve
import logging
import os
from alibiexplainer.explainer import ExplainerMethod # pylint:disable=no-name-in-module
from alibiexplainer.explainer import ExplainerMethod

logging.basicConfig(level=kserve.constants.KSERVE_LOGLEVEL)
from kserve.logging import logger

DEFAULT_EXPLAINER_NAME = "explainer"
ENV_STORAGE_URI = "STORAGE_URI"


class GroupedAction(argparse.Action): # pylint:disable=too-few-public-methods
class GroupedAction(argparse.Action):
def __call__(self, theparser, namespace, values, option_string=None):
group, dest = self.dest.split(".", 2)
groupspace = getattr(namespace, group, argparse.Namespace())
Expand Down Expand Up @@ -213,5 +212,5 @@ def parse_args(sys_args):
extra = vars(args.explainer)
else:
extra = {}
logging.info("Extra args: %s", extra)
logger.info("Extra args: %s", extra)
return args, extra
5 changes: 2 additions & 3 deletions docs/samples/explanation/alibi/alibiexplainer/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions docs/samples/kafka/image_transformer/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

import kserve
import argparse

from kserve import logging
from .image_transformer import ImageTransformer

DEFAULT_MODEL_NAME = "model"
Expand All @@ -30,6 +32,8 @@
args, _ = parser.parse_known_args()

if __name__ == "__main__":
if args.configure_logging:
logging.configure_logging(args.log_config_file)
transformer = ImageTransformer(args.model_name, predictor_host=args.predictor_host)
server = kserve.ModelServer()
server.start(models=[transformer])
12 changes: 5 additions & 7 deletions docs/samples/kafka/image_transformer/image_transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import logging
from typing import Dict, Union

import boto3
Expand All @@ -20,8 +19,7 @@
import kserve
from kserve import InferRequest, InferResponse
from kserve.protocol.grpc.grpc_predict_v2_pb2 import ModelInferResponse

logging.basicConfig(level=kserve.constants.KSERVE_LOGLEVEL)
from kserve.logging import logger

session = boto3.Session()
client = session.client(
Expand Down Expand Up @@ -49,7 +47,7 @@ def __init__(self, name: str, predictor_host: str):
async def preprocess(
self, inputs: Union[Dict, InferRequest], headers: Dict[str, str] = None
) -> Union[Dict, InferRequest]:
logging.info("Received inputs %s", inputs)
logger.info("Received inputs %s", inputs)
if inputs["EventName"] == "s3:ObjectCreated:Put":
bucket = inputs["Records"][0]["s3"]["bucket"]["name"]
key = inputs["Records"][0]["s3"]["object"]["key"]
Expand All @@ -64,10 +62,10 @@ async def postprocess(
response: Union[Dict, InferResponse, ModelInferResponse],
headers: Dict[str, str] = None,
) -> Union[Dict, ModelInferResponse]:
logging.info("response: %s", response)
logger.info("response: %s", response)
index = response["predictions"][0]["classes"]
logging.info("digit:" + str(index))
logger.info("digit:" + str(index))
upload_path = f"digit-{index}/{self._key}"
client.upload_file("/tmp/" + self._key, digits_bucket, upload_path)
logging.info(f"Image {self._key} successfully uploaded to {upload_path}")
logger.info(f"Image {self._key} successfully uploaded to {upload_path}")
return response

0 comments on commit 5a14e77

Please sign in to comment.