<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Inference :: Ay Docs</title>
    <link>https://ops.docs.72602.space/kubernetes/serverless/kserve/serving/predictive/index.html</link>
    <description>First Pytorch ISVC First Custom Model First Model In Minio Kafka Sink Transformer</description>
    <generator>Hugo</generator>
    <language>en</language>
    <lastBuildDate>Thu, 07 Mar 2024 15:00:59 +0800</lastBuildDate>
    <atom:link href="https://ops.docs.72602.space/kubernetes/serverless/kserve/serving/predictive/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>First Pytorch ISVC</title>
      <link>https://ops.docs.72602.space/kubernetes/serverless/kserve/serving/predictive/first_pytorch_infer/index.html</link>
      <pubDate>Thu, 07 Mar 2024 15:00:59 +0800</pubDate>
      <guid>https://ops.docs.72602.space/kubernetes/serverless/kserve/serving/predictive/first_pytorch_infer/index.html</guid>
      <description>Mnist Inference More Information about mnist service can be found 🔗link&#xA;create a namespace kubectl create namespace kserve-test deploy a sample iris service kubectl apply -n kserve-test -f - &lt;&lt;EOF apiVersion: &#34;serving.kserve.io/v1beta1&#34; kind: &#34;InferenceService&#34; metadata: name: &#34;first-torchserve&#34; namespace: kserve-test spec: predictor: model: modelFormat: name: pytorch storageUri: gs://kfserving-examples/models/torchserve/image_classifier/v1 resources: limits: memory: 4Gi EOF Check InferenceService status kubectl -n kserve-test get inferenceservices first-torchserve Expectd Output kubectl -n kserve-test get pod #NAME READY STATUS RESTARTS AGE #first-torchserve-predictor-00001-deplo... 2/2 Running 0 25s kubectl -n kserve-test get inferenceservices first-torchserve #NAME URL READY PREV LATEST PREVROLLEDOUTREVISION LATESTREADYREVISION AGE #kserve-test first-torchserve http://first-torchserve.kserve-test.example.com True 100 first-torchserve-predictor-00001 2m59s After all pods are ready, you can access the service by using the following command</description>
    </item>
    <item>
      <title>First Custom Model</title>
      <link>https://ops.docs.72602.space/kubernetes/serverless/kserve/serving/predictive/first_custom_model/index.html</link>
      <pubDate>Thu, 07 Mar 2024 15:00:59 +0800</pubDate>
      <guid>https://ops.docs.72602.space/kubernetes/serverless/kserve/serving/predictive/first_custom_model/index.html</guid>
      <description>AlexNet Inference More Information about AlexNet service can be found 🔗link&#xA;Implement Custom Model using KServe API 1import argparse 2import base64 3import io 4import time 5 6from fastapi.middleware.cors import CORSMiddleware 7from torchvision import models, transforms 8from typing import Dict 9import torch 10from PIL import Image 11 12import kserve 13from kserve import Model, ModelServer, logging 14from kserve.model_server import app 15from kserve.utils.utils import generate_uuid 16 17 18class AlexNetModel(Model): 19 def __init__(self, name: str): 20 super().__init__(name, return_response_headers=True) 21 self.name = name 22 self.load() 23 self.ready = False 24 25 def load(self): 26 self.model = models.alexnet(pretrained=True) 27 self.model.eval() 28 # The ready flag is used by model ready endpoint for readiness probes, 29 # set to True when model is loaded successfully without exceptions. 30 self.ready = True 31 32 async def predict( 33 self, 34 payload: Dict, 35 headers: Dict[str, str] = None, 36 response_headers: Dict[str, str] = None, 37 ) -&gt; Dict: 38 start = time.time() 39 # Input follows the Tensorflow V1 HTTP API for binary values 40 # https://www.tensorflow.org/tfx/serving/api_rest#encoding_binary_values 41 img_data = payload[&#34;instances&#34;][0][&#34;image&#34;][&#34;b64&#34;] 42 raw_img_data = base64.b64decode(img_data) 43 input_image = Image.open(io.BytesIO(raw_img_data)) 44 preprocess = transforms.Compose([ 45 transforms.Resize(256), 46 transforms.CenterCrop(224), 47 transforms.ToTensor(), 48 transforms.Normalize(mean=[0.485, 0.456, 0.406], 49 std=[0.229, 0.224, 0.225]), 50 ]) 51 input_tensor = preprocess(input_image).unsqueeze(0) 52 output = self.model(input_tensor) 53 torch.nn.functional.softmax(output, dim=1) 54 values, top_5 = torch.topk(output, 5) 55 result = values.flatten().tolist() 56 end = time.time() 57 response_id = generate_uuid() 58 59 # Custom response headers can be added to the inference response 60 if response_headers is not None: 61 response_headers.update( 62 {&#34;prediction-time-latency&#34;: f&#34;{round((end - start) * 1000, 9)}&#34;} 63 ) 64 65 return {&#34;predictions&#34;: result} 66 67 68parser = argparse.ArgumentParser(parents=[kserve.model_server.parser]) 69args, _ = parser.parse_known_args() 70 71if __name__ == &#34;__main__&#34;: 72 # Configure kserve and uvicorn logger 73 if args.configure_logging: 74 logging.configure_logging(args.log_config_file) 75 model = AlexNetModel(args.model_name) 76 model.load() 77 # Custom middlewares can be added to the model 78 app.add_middleware( 79 CORSMiddleware, 80 allow_origins=[&#34;*&#34;], 81 allow_credentials=True, 82 allow_methods=[&#34;*&#34;], 83 allow_headers=[&#34;*&#34;], 84 ) 85 ModelServer().start([model]) create requirements.txt kserve torchvision==0.18.0 pillow&gt;=10.3.0,&lt;11.0.0 create Dockerfile FROM m.daocloud.io/docker.io/library/python:3.11-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY model.py . CMD [&#34;python&#34;, &#34;model.py&#34;, &#34;--model_name=custom-model&#34;] build and push custom docker image docker build -t ay-custom-model . docker tag ddfd0186813e docker-registry.lab.zverse.space/ay/ay-custom-model:latest docker push docker-registry.lab.zverse.space/ay/ay-custom-model:latest create a namespace kubectl create namespace kserve-test deploy a sample custom-model service kubectl apply -n kserve-test -f - &lt;&lt;EOF apiVersion: serving.kserve.io/v1beta1 kind: InferenceService metadata: name: ay-custom-model spec: predictor: containers: - name: kserve-container image: docker-registry.lab.zverse.space/ay/ay-custom-model:latest EOF Check InferenceService status kubectl -n kserve-test get inferenceservices ay-custom-model Expectd Output kubectl -n kserve-test get pod #NAME READY STATUS RESTARTS AGE #ay-custom-model-predictor-00003-dcf4rk 2/2 Running 0 167m kubectl -n kserve-test get inferenceservices ay-custom-model #NAME URL READY PREV LATEST PREVROLLEDOUTREVISION LATESTREADYREVISION AGE #ay-custom-model http://ay-custom-model.kserve-test.example.com True 100 ay-custom-model-predictor-00003 177m After all pods are ready, you can access the service by using the following command</description>
    </item>
    <item>
      <title>First Model In Minio</title>
      <link>https://ops.docs.72602.space/kubernetes/serverless/kserve/serving/predictive/first_s3_model/index.html</link>
      <pubDate>Thu, 07 Mar 2024 15:00:59 +0800</pubDate>
      <guid>https://ops.docs.72602.space/kubernetes/serverless/kserve/serving/predictive/first_s3_model/index.html</guid>
      <description>Inference Model In Minio More Information about Deploy InferenceService with a saved model on S3 can be found 🔗link&#xA;Create Service Account === “yaml”&#xA;apiVersion: v1 kind: ServiceAccount metadata: name: sa annotations: eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/s3access # replace with your IAM role ARN serving.kserve.io/s3-endpoint: s3.amazonaws.com # replace with your s3 endpoint e.g minio-service.kubeflow:9000 serving.kserve.io/s3-usehttps: &#34;1&#34; # by default 1, if testing with minio you can set to 0 serving.kserve.io/s3-region: &#34;us-east-2&#34; serving.kserve.io/s3-useanoncredential: &#34;false&#34; # omitting this is the same as false, if true will ignore provided credential and use anonymous credentials === “kubectl”</description>
    </item>
    <item>
      <title>Kafka Sink Transformer</title>
      <link>https://ops.docs.72602.space/kubernetes/serverless/kserve/serving/predictive/first_custom_transformer/index.html</link>
      <pubDate>Thu, 07 Mar 2024 15:00:59 +0800</pubDate>
      <guid>https://ops.docs.72602.space/kubernetes/serverless/kserve/serving/predictive/first_custom_transformer/index.html</guid>
      <description>AlexNet Inference More Information about Custom Transformer service can be found 🔗link&#xA;Implement Custom Transformer ./model.py using Kserve API 1import os 2import argparse 3import json 4 5from typing import Dict, Union 6from kafka import KafkaProducer 7from cloudevents.http import CloudEvent 8from cloudevents.conversion import to_structured 9 10from kserve import ( 11 Model, 12 ModelServer, 13 model_server, 14 logging, 15 InferRequest, 16 InferResponse, 17) 18 19from kserve.logging import logger 20from kserve.utils.utils import generate_uuid 21 22kafka_producer = KafkaProducer( 23 value_serializer=lambda v: json.dumps(v).encode(&#39;utf-8&#39;), 24 bootstrap_servers=os.environ.get(&#39;KAFKA_BOOTSTRAP_SERVERS&#39;, &#39;localhost:9092&#39;) 25) 26 27class ImageTransformer(Model): 28 def __init__(self, name: str): 29 super().__init__(name, return_response_headers=True) 30 self.ready = True 31 32 33 def preprocess( 34 self, payload: Union[Dict, InferRequest], headers: Dict[str, str] = None 35 ) -&gt; Union[Dict, InferRequest]: 36 logger.info(&#34;Received inputs %s&#34;, payload) 37 logger.info(&#34;Received headers %s&#34;, headers) 38 self.request_trace_key = os.environ.get(&#39;REQUEST_TRACE_KEY&#39;, &#39;algo.trace.requestId&#39;) 39 if self.request_trace_key not in payload: 40 logger.error(&#34;Request trace key &#39;%s&#39; not found in payload, you cannot trace the prediction result&#34;, self.request_trace_key) 41 if &#34;instances&#34; not in payload: 42 raise ValueError( 43 f&#34;Request trace key &#39;{self.request_trace_key}&#39; not found in payload and &#39;instances&#39; key is missing.&#34; 44 ) 45 else: 46 headers[self.request_trace_key] = payload.get(self.request_trace_key) 47 48 return {&#34;instances&#34;: payload[&#34;instances&#34;]} 49 50 def postprocess( 51 self, 52 infer_response: Union[Dict, InferResponse], 53 headers: Dict[str, str] = None, 54 response_headers: Dict[str, str] = None, 55 ) -&gt; Union[Dict, InferResponse]: 56 logger.info(&#34;postprocess headers: %s&#34;, headers) 57 logger.info(&#34;postprocess response headers: %s&#34;, response_headers) 58 logger.info(&#34;postprocess response: %s&#34;, infer_response) 59 60 attributes = { 61 &#34;source&#34;: &#34;data-and-computing/kafka-sink-transformer&#34;, 62 &#34;type&#34;: &#34;org.zhejianglab.zverse.data-and-computing.kafka-sink-transformer&#34;, 63 &#34;request-host&#34;: headers.get(&#39;host&#39;, &#39;unknown&#39;), 64 &#34;kserve-isvc-name&#34;: headers.get(&#39;kserve-isvc-name&#39;, &#39;unknown&#39;), 65 &#34;kserve-isvc-namespace&#34;: headers.get(&#39;kserve-isvc-namespace&#39;, &#39;unknown&#39;), 66 self.request_trace_key: headers.get(self.request_trace_key, &#39;unknown&#39;), 67 } 68 69 _, cloudevent = to_structured(CloudEvent(attributes, infer_response)) 70 try: 71 kafka_producer.send(os.environ.get(&#39;KAFKA_TOPIC&#39;, &#39;test-topic&#39;), value=cloudevent.decode(&#39;utf-8&#39;).replace(&#34;&#39;&#34;, &#39;&#34;&#39;)) 72 kafka_producer.flush() 73 except Exception as e: 74 logger.error(&#34;Failed to send message to Kafka: %s&#34;, e) 75 return infer_response 76 77parser = argparse.ArgumentParser(parents=[model_server.parser]) 78args, _ = parser.parse_known_args() 79 80if __name__ == &#34;__main__&#34;: 81 if args.configure_logging: 82 logging.configure_logging(args.log_config_file) 83 logging.logger.info(&#34;available model name: %s&#34;, args.model_name) 84 logging.logger.info(&#34;all args: %s&#34;, args.model_name) 85 model = ImageTransformer(args.model_name) 86 ModelServer().start([model]) modify ./pyproject.toml [tool.poetry] name = &#34;custom_transformer&#34; version = &#34;0.15.2&#34; description = &#34;Custom Transformer Examples. Not intended for use outside KServe Frameworks Images.&#34; authors = [&#34;Dan Sun &lt;dsun20@bloomberg.net&gt;&#34;] license = &#34;Apache-2.0&#34; packages = [ { include = &#34;*.py&#34; } ] [tool.poetry.dependencies] python = &#34;&gt;=3.9,&lt;3.13&#34; kserve = {path = &#34;../kserve&#34;, develop = true} pillow = &#34;^10.3.0&#34; kafka-python = &#34;^2.2.15&#34; cloudevents = &#34;^1.11.1&#34; [[tool.poetry.source]] name = &#34;pytorch&#34; url = &#34;https://download.pytorch.org/whl/cpu&#34; priority = &#34;explicit&#34; [tool.poetry.group.test] optional = true [tool.poetry.group.test.dependencies] pytest = &#34;^7.4.4&#34; mypy = &#34;^0.991&#34; [tool.poetry.group.dev] optional = true [tool.poetry.group.dev.dependencies] black = { version = &#34;~24.3.0&#34;, extras = [&#34;colorama&#34;] } [tool.poetry-version-plugin] source = &#34;file&#34; file_path = &#34;../VERSION&#34; [build-system] requires = [&#34;poetry-core&gt;=1.0.0&#34;] build-backend = &#34;poetry.core.masonry.api&#34; prepare ../custom_transformer.Dockerfile ARG PYTHON_VERSION=3.11 ARG BASE_IMAGE=python:${PYTHON_VERSION}-slim-bookworm ARG VENV_PATH=/prod_venv FROM ${BASE_IMAGE} AS builder # Install Poetry ARG POETRY_HOME=/opt/poetry ARG POETRY_VERSION=1.8.3 RUN python3 -m venv ${POETRY_HOME} &amp;&amp; ${POETRY_HOME}/bin/pip install poetry==${POETRY_VERSION} ENV PATH=&#34;$PATH:${POETRY_HOME}/bin&#34; # Activate virtual env ARG VENV_PATH ENV VIRTUAL_ENV=${VENV_PATH} RUN python3 -m venv $VIRTUAL_ENV ENV PATH=&#34;$VIRTUAL_ENV/bin:$PATH&#34; COPY kserve/pyproject.toml kserve/poetry.lock kserve/ RUN cd kserve &amp;&amp; poetry install --no-root --no-interaction --no-cache COPY kserve kserve RUN cd kserve &amp;&amp; poetry install --no-interaction --no-cache COPY custom_transformer/pyproject.toml custom_transformer/poetry.lock custom_transformer/ RUN cd custom_transformer &amp;&amp; poetry install --no-root --no-interaction --no-cache COPY custom_transformer custom_transformer RUN cd custom_transformer &amp;&amp; poetry install --no-interaction --no-cache FROM ${BASE_IMAGE} AS prod COPY third_party third_party # Activate virtual env ARG VENV_PATH ENV VIRTUAL_ENV=${VENV_PATH} ENV PATH=&#34;$VIRTUAL_ENV/bin:$PATH&#34; RUN useradd kserve -m -u 1000 -d /home/kserve COPY --from=builder --chown=kserve:kserve $VIRTUAL_ENV $VIRTUAL_ENV COPY --from=builder kserve kserve COPY --from=builder custom_transformer custom_transformer USER 1000 ENTRYPOINT [&#34;python&#34;, &#34;-m&#34;, &#34;custom_transformer.model&#34;] regenerate poetry.lock poetry lock --no-update build and push custom docker image cd python podman build -t docker-registry.lab.zverse.space/data-and-computing/ay-dev/msg-transformer:dev9 -f custom_transformer.Dockerfile . podman push docker-registry.lab.zverse.space/data-and-computing/ay-dev/msg-transformer:dev9</description>
    </item>
  </channel>
</rss>