diff --git a/serverless/pytorch/omerferhatt/vit-b/nuclio/function-gpu.yaml b/serverless/pytorch/omerferhatt/vit-b/nuclio/function-gpu.yaml new file mode 100644 index 000000000000..66b2850c521d --- /dev/null +++ b/serverless/pytorch/omerferhatt/vit-b/nuclio/function-gpu.yaml @@ -0,0 +1,88 @@ +metadata: + name: pth-omerferhatt-vitb + namespace: cvat + annotations: + name: ViT-B + type: detector + framework: pytorch + spec: | + [ + { "id": 0, "name": "tench", "type": "tag" }, + { "id": 1, "name": "goldfish", "type": "tag" }, + { "id": 2, "name": "great white shark", "type": "tag" }, + { "id": 3, "name": "tiger shark", "type": "tag" }, + { "id": 4, "name": "hammerhead shark", "type": "tag" }, + { "id": 5, "name": "electric ray", "type": "tag" }, + { "id": 6, "name": "stingray", "type": "tag" }, + { "id": 7, "name": "cock", "type": "tag" }, + { "id": 8, "name": "hen", "type": "tag" }, + { "id": 9, "name": "ostrich", "type": "tag" }, + { "id": 10, "name": "brambling", "type": "tag" }, + { "id": 11, "name": "goldfinch", "type": "tag" }, + { "id": 12, "name": "house finch", "type": "tag" }, + { "id": 13, "name": "junco", "type": "tag" }, + { "id": 14, "name": "indigo bunting", "type": "tag" }, + { "id": 15, "name": "robin", "type": "tag" }, + { "id": 16, "name": "bulbul", "type": "tag" }, + { "id": 17, "name": "jay", "type": "tag" }, + { "id": 18, "name": "magpie", "type": "tag" }, + { "id": 19, "name": "chickadee", "type": "tag" }, + { "id": 20, "name": "water ouzel", "type": "tag" }, + { "id": 21, "name": "kite", "type": "tag" }, + { "id": 22, "name": "bald eagle", "type": "tag" }, + { "id": 23, "name": "vulture", "type": "tag" }, + { "id": 24, "name": "great grey owl", "type": "tag" }, + { "id": 25, "name": "European fire salamander", "type": "tag" }, + { "id": 26, "name": "common newt", "type": "tag" }, + { "id": 27, "name": "eft", "type": "tag" }, + { "id": 28, "name": "spotted salamander", "type": "tag" }, + { "id": 29, "name": "axolotl", "type": "tag" } + ] +spec: + description: ImageNet-1k pretrained ViT-B + runtime: 'python:3.8' + handler: main:handler + eventTimeout: 30s + build: + image: cvat.pth.omerferhatt.vitb:latest-gpu + baseImage: nvidia/cuda:12.1.0-runtime-ubuntu22.04 + + directives: + preCopy: + - kind: RUN + value: |- + apt update \ + && apt install -y --no-install-recommends \ + wget \ + git \ + ca-certificates \ + python-is-python3 \ + python3 \ + python3-pip \ + && rm -rf /var/lib/apt/lists/* + - kind: WORKDIR + value: /opt/nuclio + - kind: RUN + value: pip install pillow pyyaml + - kind: RUN + value: |- + pip install torch torchvision + + triggers: + myHttpTrigger: + maxWorkers: 1 + kind: 'http' + workerAvailabilityTimeoutMilliseconds: 10000 + attributes: + maxRequestBodySize: 33554432 # 32MB + + resources: + limits: + nvidia.com/gpu: 1 + + platform: + attributes: + restartPolicy: + name: always + maximumRetryCount: 3 + mountMode: volume diff --git a/serverless/pytorch/omerferhatt/vit-b/nuclio/function.yaml b/serverless/pytorch/omerferhatt/vit-b/nuclio/function.yaml new file mode 100644 index 000000000000..5ff3df14788f --- /dev/null +++ b/serverless/pytorch/omerferhatt/vit-b/nuclio/function.yaml @@ -0,0 +1,84 @@ +metadata: + name: pth-omerferhatt-vitb + namespace: cvat + annotations: + name: ViT-B + type: detector + framework: pytorch + spec: | + [ + { "id": 0, "name": "tench", "type": "tag" }, + { "id": 1, "name": "goldfish", "type": "tag" }, + { "id": 2, "name": "great white shark", "type": "tag" }, + { "id": 3, "name": "tiger shark", "type": "tag" }, + { "id": 4, "name": "hammerhead shark", "type": "tag" }, + { "id": 5, "name": "electric ray", "type": "tag" }, + { "id": 6, "name": "stingray", "type": "tag" }, + { "id": 7, "name": "cock", "type": "tag" }, + { "id": 8, "name": "hen", "type": "tag" }, + { "id": 9, "name": "ostrich", "type": "tag" }, + { "id": 10, "name": "brambling", "type": "tag" }, + { "id": 11, "name": "goldfinch", "type": "tag" }, + { "id": 12, "name": "house finch", "type": "tag" }, + { "id": 13, "name": "junco", "type": "tag" }, + { "id": 14, "name": "indigo bunting", "type": "tag" }, + { "id": 15, "name": "robin", "type": "tag" }, + { "id": 16, "name": "bulbul", "type": "tag" }, + { "id": 17, "name": "jay", "type": "tag" }, + { "id": 18, "name": "magpie", "type": "tag" }, + { "id": 19, "name": "chickadee", "type": "tag" }, + { "id": 20, "name": "water ouzel", "type": "tag" }, + { "id": 21, "name": "kite", "type": "tag" }, + { "id": 22, "name": "bald eagle", "type": "tag" }, + { "id": 23, "name": "vulture", "type": "tag" }, + { "id": 24, "name": "great grey owl", "type": "tag" }, + { "id": 25, "name": "European fire salamander", "type": "tag" }, + { "id": 26, "name": "common newt", "type": "tag" }, + { "id": 27, "name": "eft", "type": "tag" }, + { "id": 28, "name": "spotted salamander", "type": "tag" }, + { "id": 29, "name": "axolotl", "type": "tag" } + ] +spec: + description: ImageNet-1k pretrained ViT-B + runtime: 'python:3.8' + handler: main:handler + eventTimeout: 30s + build: + image: cvat.pth.omerferhatt.vitb + baseImage: ubuntu:22.04 + + directives: + preCopy: + - kind: RUN + value: |- + apt update \ + && apt install -y --no-install-recommends \ + wget \ + git \ + ca-certificates \ + python-is-python3 \ + python3 \ + python3-pip \ + && rm -rf /var/lib/apt/lists/* + - kind: WORKDIR + value: /opt/nuclio + - kind: RUN + value: pip install pillow pyyaml + - kind: RUN + value: |- + pip install torch torchvision --extra-index-url https://download.pytorch.org/whl/cpu + + triggers: + myHttpTrigger: + maxWorkers: 2 + kind: 'http' + workerAvailabilityTimeoutMilliseconds: 10000 + attributes: + maxRequestBodySize: 33554432 # 32MB + + platform: + attributes: + restartPolicy: + name: always + maximumRetryCount: 3 + mountMode: volume diff --git a/serverless/pytorch/omerferhatt/vit-b/nuclio/main.py b/serverless/pytorch/omerferhatt/vit-b/nuclio/main.py new file mode 100644 index 000000000000..a94349944c40 --- /dev/null +++ b/serverless/pytorch/omerferhatt/vit-b/nuclio/main.py @@ -0,0 +1,43 @@ +import base64 +import io +import json +import yaml + +from model_handler import ModelHandler +from PIL import Image + + +def init_context(context): + context.logger.info("Init context... 0%") + with open("/opt/nuclio/function.yaml", "rb") as function_file: + config_yaml = yaml.load(function_file, Loader=yaml.FullLoader) + + model = ModelHandler() + context.user_data.labels = [ + label["name"] for label in eval(config_yaml["metadata"]["annotations"]["spec"]) + ] + context.user_data.yaml = config_yaml + context.user_data.model = model + context.logger.info("Init context...100%") + +def handler(context, event): + context.logger.info("Run ViT-B model") + data = event.body + image = Image.open(io.BytesIO(base64.b64decode(data["image"]))).convert("RGB") + + class_id, _, score = context.user_data.model.infer(image) + + results = [{ + "confidence": str(score), + "label": context.user_data.labels[class_id], + "type": "tag", + "objectType": "tag", + }] + context.logger.info(f"Results: {results}") + + return context.Response( + body=json.dumps(results), + headers={}, + content_type="application/json", + status_code=200, + ) diff --git a/serverless/pytorch/omerferhatt/vit-b/nuclio/model_handler.py b/serverless/pytorch/omerferhatt/vit-b/nuclio/model_handler.py new file mode 100644 index 000000000000..a9ceccb8b27b --- /dev/null +++ b/serverless/pytorch/omerferhatt/vit-b/nuclio/model_handler.py @@ -0,0 +1,27 @@ +from typing import Tuple + +import torch +import torchvision as tv +from PIL import Image + + +class ModelHandler: + weights = tv.models.ViT_B_16_Weights.DEFAULT + preprocess = weights.transforms() + + def __init__(self) -> None: + self.model = tv.models.vit_b_16(weights=self.weights) + self.model.eval() + self.device = torch.device("cpu") + if torch.cuda.is_available(): + self.device = torch.device("cuda") + self.model = self.model.to(self.device) + + def infer(self, image: Image) -> Tuple[int, str, float]: + with torch.inference_mode(): + batch = self.preprocess(image).unsqueeze(0).to(self.device) + prediction = self.model(batch).squeeze(0).softmax(0) + class_id = prediction.argmax().item() + score = prediction[class_id].item() + category_name = self.weights.meta["categories"][class_id] + return (class_id, category_name, score)