clarifai 10.8.2__tar.gz → 10.8.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {clarifai-10.8.2/clarifai.egg-info → clarifai-10.8.4}/PKG-INFO +3 -2
- clarifai-10.8.4/clarifai/__init__.py +1 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/client/app.py +3 -4
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/client/model.py +1 -2
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/repo_build/static_files/base_test.py +4 -4
- clarifai-10.8.4/clarifai/runners/__init__.py +14 -0
- clarifai-10.8.4/clarifai/runners/dockerfile_template/Dockerfile.cpu.template +31 -0
- clarifai-10.8.4/clarifai/runners/dockerfile_template/Dockerfile.cuda.template +129 -0
- clarifai-10.8.4/clarifai/runners/models/base_typed_model.py +235 -0
- clarifai-10.8.4/clarifai/runners/models/model_class.py +41 -0
- clarifai-10.8.4/clarifai/runners/models/model_runner.py +175 -0
- clarifai-10.8.4/clarifai/runners/models/model_servicer.py +79 -0
- clarifai-10.8.4/clarifai/runners/models/model_upload.py +315 -0
- clarifai-10.8.4/clarifai/runners/server.py +130 -0
- clarifai-10.8.4/clarifai/runners/utils/data_handler.py +231 -0
- clarifai-10.8.4/clarifai/runners/utils/data_utils.py +15 -0
- clarifai-10.8.4/clarifai/runners/utils/loader.py +71 -0
- clarifai-10.8.4/clarifai/runners/utils/logging.py +6 -0
- clarifai-10.8.4/clarifai/runners/utils/url_fetcher.py +42 -0
- clarifai-10.8.4/clarifai/utils/__init__.py +0 -0
- clarifai-10.8.4/clarifai/utils/logging.py +359 -0
- clarifai-10.8.4/clarifai/workflows/__init__.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4/clarifai.egg-info}/PKG-INFO +3 -2
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai.egg-info/SOURCES.txt +16 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai.egg-info/requires.txt +2 -1
- {clarifai-10.8.2 → clarifai-10.8.4}/requirements.txt +2 -1
- {clarifai-10.8.2 → clarifai-10.8.4}/tests/test_app.py +18 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/tests/test_data_upload.py +51 -3
- clarifai-10.8.4/tests/test_misc.py +67 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/tests/test_model_train.py +1 -0
- clarifai-10.8.2/clarifai/__init__.py +0 -1
- clarifai-10.8.2/clarifai/utils/logging.py +0 -153
- clarifai-10.8.2/tests/test_misc.py +0 -19
- {clarifai-10.8.2 → clarifai-10.8.4}/LICENSE +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/MANIFEST.in +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/README.md +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/cli.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/client/__init__.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/client/auth/__init__.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/client/auth/helper.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/client/auth/register.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/client/auth/stub.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/client/base.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/client/dataset.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/client/input.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/client/lister.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/client/module.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/client/search.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/client/user.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/client/workflow.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/constants/dataset.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/constants/input.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/constants/model.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/constants/rag.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/constants/search.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/constants/workflow.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/datasets/__init__.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/datasets/export/__init__.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/datasets/export/inputs_annotations.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/datasets/upload/__init__.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/datasets/upload/base.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/datasets/upload/features.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/datasets/upload/image.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/datasets/upload/loaders/README.md +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/datasets/upload/loaders/__init__.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/datasets/upload/loaders/coco_captions.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/datasets/upload/loaders/coco_detection.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/datasets/upload/loaders/imagenet_classification.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/datasets/upload/loaders/xview_detection.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/datasets/upload/text.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/datasets/upload/utils.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/errors.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/__init__.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/api.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/README.md +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/__init__.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/cli/__init__.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/cli/_utils.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/cli/base.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/cli/build.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/cli/clarifai_clis.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/cli/create.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/cli/example_cli.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/cli/login.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/cli/upload.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/constants.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/docs/cli.md +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/docs/concepts.md +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/docs/dependencies.md +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/docs/inference_parameters.md +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/docs/model_types.md +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/model_config/__init__.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/model_config/base.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/model_config/config.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/model_config/inference_parameter.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/model_config/model_types_config/multimodal-embedder.yaml +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/model_config/model_types_config/text-classifier.yaml +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/model_config/model_types_config/text-embedder.yaml +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/model_config/model_types_config/text-to-image.yaml +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/model_config/model_types_config/text-to-text.yaml +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/model_config/model_types_config/visual-classifier.yaml +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/model_config/model_types_config/visual-detector.yaml +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/model_config/model_types_config/visual-embedder.yaml +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/model_config/model_types_config/visual-segmenter.yaml +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/model_config/output.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/model_config/triton/__init__.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/model_config/triton/serializer.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/model_config/triton/triton_config.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/model_config/triton/wrappers.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/repo_build/__init__.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/repo_build/build.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/repo_build/static_files/_requirements.txt +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/repo_build/static_files/inference.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/repo_build/static_files/sample_clarifai_config.yaml +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/repo_build/static_files/test.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/repo_build/static_files/triton/model.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/models/model_serving/utils.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/modules/README.md +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/modules/__init__.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/modules/css.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/modules/pages.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/modules/style.css +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/rag/__init__.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/rag/rag.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/rag/utils.py +0 -0
- {clarifai-10.8.2/clarifai/utils → clarifai-10.8.4/clarifai/runners/models}/__init__.py +0 -0
- {clarifai-10.8.2/clarifai/workflows → clarifai-10.8.4/clarifai/runners/utils}/__init__.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/schema/search.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/urls/helper.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/utils/constants.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/utils/evaluation/__init__.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/utils/evaluation/helpers.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/utils/evaluation/main.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/utils/evaluation/testset_annotation_parser.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/utils/misc.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/utils/model_train.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/versions.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/workflows/export.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/workflows/utils.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai/workflows/validate.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai.egg-info/dependency_links.txt +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai.egg-info/entry_points.txt +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/clarifai.egg-info/top_level.txt +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/pyproject.toml +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/setup.cfg +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/setup.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/tests/test_auth.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/tests/test_eval.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/tests/test_model_predict.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/tests/test_modules.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/tests/test_rag.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/tests/test_search.py +0 -0
- {clarifai-10.8.2 → clarifai-10.8.4}/tests/test_stub.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: clarifai
|
3
|
-
Version: 10.8.
|
3
|
+
Version: 10.8.4
|
4
4
|
Summary: Clarifai Python SDK
|
5
5
|
Home-page: https://github.com/Clarifai/clarifai-python
|
6
6
|
Author: Clarifai
|
@@ -20,7 +20,8 @@ Classifier: Operating System :: OS Independent
|
|
20
20
|
Requires-Python: >=3.8
|
21
21
|
Description-Content-Type: text/markdown
|
22
22
|
License-File: LICENSE
|
23
|
-
Requires-Dist: clarifai-grpc>=10.8.
|
23
|
+
Requires-Dist: clarifai-grpc>=10.8.7
|
24
|
+
Requires-Dist: clarifai-protocol>=0.0.4
|
24
25
|
Requires-Dist: numpy>=1.22.0
|
25
26
|
Requires-Dist: tqdm>=4.65.0
|
26
27
|
Requires-Dist: tritonclient>=2.34.0
|
@@ -0,0 +1 @@
|
|
1
|
+
__version__ = "10.8.4"
|
@@ -686,7 +686,7 @@ class App(Lister, BaseClient):
|
|
686
686
|
|
687
687
|
return Workflow.from_auth_helper(auth=self.auth_helper, **kwargs)
|
688
688
|
|
689
|
-
def module(self, module_id: str,
|
689
|
+
def module(self, module_id: str, **kwargs) -> Module:
|
690
690
|
"""Returns a Module object for the existing module ID.
|
691
691
|
|
692
692
|
Args:
|
@@ -699,10 +699,9 @@ class App(Lister, BaseClient):
|
|
699
699
|
Example:
|
700
700
|
>>> from clarifai.client.app import App
|
701
701
|
>>> app = App(app_id="app_id", user_id="user_id")
|
702
|
-
>>> module = app.module(module_id="module_id"
|
702
|
+
>>> module = app.module(module_id="module_id")
|
703
703
|
"""
|
704
|
-
request = service_pb2.GetModuleRequest(
|
705
|
-
user_app_id=self.user_app_id, module_id=module_id, version_id=module_version_id)
|
704
|
+
request = service_pb2.GetModuleRequest(user_app_id=self.user_app_id, module_id=module_id)
|
706
705
|
response = self._grpc_request(self.STUB.GetModule, request)
|
707
706
|
|
708
707
|
if response.status.code != status_code_pb2.SUCCESS:
|
@@ -281,8 +281,7 @@ class Model(Lister, BaseClient):
|
|
281
281
|
"Model version ID is missing. Please provide a `model_version` with a valid `id` as an argument or as a URL in the following format: '{user_id}/{app_id}/models/{your_model_id}/model_version_id/{your_version_model_id}' when initializing."
|
282
282
|
)
|
283
283
|
|
284
|
-
|
285
|
-
self.load_info()
|
284
|
+
self.load_info()
|
286
285
|
if self.model_info.model_type_id not in TRAINABLE_MODEL_TYPES:
|
287
286
|
raise UserError(f"Model type {self.model_info.model_type_id} is not trainable")
|
288
287
|
|
@@ -5,10 +5,10 @@ from typing import Dict, Iterable, List, Union
|
|
5
5
|
import numpy as np
|
6
6
|
import yaml
|
7
7
|
|
8
|
-
from
|
9
|
-
from
|
10
|
-
|
11
|
-
|
8
|
+
from clarifai.models.model_serving.constants import IMAGE_TENSOR_NAME, TEXT_TENSOR_NAME
|
9
|
+
from clarifai.models.model_serving.model_config import (
|
10
|
+
ClassifierOutput, EmbeddingOutput, ImageOutput, InferParam, InferParamManager, MasksOutput,
|
11
|
+
ModelTypes, TextOutput, VisualDetector, load_user_config)
|
12
12
|
|
13
13
|
_default_texts = ["Photo of a cat", "A cat is playing around", "Hello, this is test"]
|
14
14
|
|
@@ -0,0 +1,14 @@
|
|
1
|
+
from .models.base_typed_model import AnyAnyModel, TextInputModel, VisualInputModel
|
2
|
+
from .models.model_runner import ModelRunner
|
3
|
+
from .models.model_upload import ModelUploader
|
4
|
+
from .utils.data_handler import InputDataHandler, OutputDataHandler
|
5
|
+
|
6
|
+
__all__ = [
|
7
|
+
"ModelRunner",
|
8
|
+
"ModelUploader",
|
9
|
+
"InputDataHandler",
|
10
|
+
"OutputDataHandler",
|
11
|
+
"AnyAnyModel",
|
12
|
+
"TextInputModel",
|
13
|
+
"VisualInputModel",
|
14
|
+
]
|
@@ -0,0 +1,31 @@
|
|
1
|
+
ARG PYTHON_VERSION=${PYTHON_VERSION}
|
2
|
+
FROM public.ecr.aws/docker/library/python:${PYTHON_VERSION}-slim as build
|
3
|
+
|
4
|
+
# Set the working directory to /app
|
5
|
+
WORKDIR /app
|
6
|
+
|
7
|
+
COPY requirements.txt .
|
8
|
+
# Install requirements and cleanup before leaving this line.
|
9
|
+
# Note(zeiler): this could be in a future template as {{model_python_deps}}
|
10
|
+
RUN python -m pip install -r requirements.txt && rm -rf /root/.cache
|
11
|
+
|
12
|
+
# Install Clarifai SDK
|
13
|
+
RUN python -m pip install clarifai
|
14
|
+
|
15
|
+
# These will be set by the templaing system.
|
16
|
+
ENV CLARIFAI_PAT=${CLARIFAI_PAT}
|
17
|
+
ENV CLARIFAI_USER_ID=${CLARIFAI_USER_ID}
|
18
|
+
ENV CLARIFAI_RUNNER_ID=${CLARIFAI_RUNNER_ID}
|
19
|
+
ENV CLARIFAI_NODEPOOL_ID=${CLARIFAI_NODEPOOL_ID}
|
20
|
+
ENV CLARIFAI_COMPUTE_CLUSTER_ID=${CLARIFAI_COMPUTE_CLUSTER_ID}
|
21
|
+
ENV CLARIFAI_API_BASE=${CLARIFAI_API_BASE}
|
22
|
+
|
23
|
+
# Copy the current folder into /app/model_dir that the SDK will expect.
|
24
|
+
COPY . /app/model_dir/${name}
|
25
|
+
|
26
|
+
# Add the model directory to the python path.
|
27
|
+
ENV PYTHONPATH "${PYTHONPATH}:/app/model_dir/${name}"
|
28
|
+
|
29
|
+
# Finally run the clarifai entrypoint to start the runner loop and local dev server.
|
30
|
+
# Note(zeiler): we may want to make this a clarifai CLI call.
|
31
|
+
CMD ["python", "-m", "clarifai.runners.server", "--model_path", "/app/model_dir/${name}"]
|
@@ -0,0 +1,129 @@
|
|
1
|
+
# Build a virtualenv containing necessary system libraries and Python packages
|
2
|
+
# for users to install their own packages while also being distroless.
|
3
|
+
# * Install python3-venv
|
4
|
+
# * Install gcc libpython3-dev to compile C Python modules
|
5
|
+
# * In the virtualenv: Update pip setuputils and wheel to support building new packages
|
6
|
+
# * Export environment variables to use the virtualenv by default
|
7
|
+
# * Create a non-root user with minimal privileges and use it
|
8
|
+
ARG TARGET_PLATFORM=linux/amd64
|
9
|
+
ARG CUDA_VERSION=12.4.0
|
10
|
+
FROM --platform=$TARGET_PLATFORM nvidia/cuda:${CUDA_VERSION}-base-ubuntu22.04 AS build
|
11
|
+
|
12
|
+
ARG DRIVER_VERSION=535
|
13
|
+
ARG PYTHON_VERSION=${PYTHON_VERSION}
|
14
|
+
|
15
|
+
ENV DEBIAN_FRONTEND=noninteractive
|
16
|
+
RUN apt-get update && \
|
17
|
+
apt-get install --no-install-suggests --no-install-recommends --yes \
|
18
|
+
software-properties-common \
|
19
|
+
gpg-agent && \
|
20
|
+
add-apt-repository ppa:graphics-drivers/ppa && \
|
21
|
+
add-apt-repository ppa:deadsnakes/ppa && \
|
22
|
+
apt-get update && \
|
23
|
+
apt-get install --no-install-suggests --no-install-recommends --yes \
|
24
|
+
python${PYTHON_VERSION} \
|
25
|
+
python${PYTHON_VERSION}-venv \
|
26
|
+
python${PYTHON_VERSION}-dev \
|
27
|
+
gcc \
|
28
|
+
libpython3-dev \
|
29
|
+
# drivers and nvidia-smi
|
30
|
+
nvidia-utils-${DRIVER_VERSION} \
|
31
|
+
nvidia-driver-${DRIVER_VERSION} \
|
32
|
+
libcap2-bin && \
|
33
|
+
python${PYTHON_VERSION} -m venv /venv && \
|
34
|
+
/venv/bin/pip install --disable-pip-version-check --upgrade pip setuptools wheel && \
|
35
|
+
# Create a non-root user with minimal privileges and set file permissions
|
36
|
+
ln -sf /usr/bin/python${PYTHON_VERSION} /usr/bin/python3 && \
|
37
|
+
apt-get clean && rm -rf /var/lib/apt/lists/*
|
38
|
+
|
39
|
+
|
40
|
+
# Set environment variables to use virtualenv by default
|
41
|
+
ENV VIRTUAL_ENV=/venv
|
42
|
+
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
|
43
|
+
|
44
|
+
#############################
|
45
|
+
# User specific requirements
|
46
|
+
#############################
|
47
|
+
COPY requirements.txt .
|
48
|
+
|
49
|
+
# Install requirements and cleanup before leaving this line.
|
50
|
+
# Note(zeiler): this could be in a future template as {{model_python_deps}}
|
51
|
+
RUN python -m pip install -r requirements.txt && rm -rf /root/.cache
|
52
|
+
|
53
|
+
# Install Clarifai SDK
|
54
|
+
RUN python -m pip install clarifai
|
55
|
+
|
56
|
+
#############################
|
57
|
+
# Finally copy everything we built into a distroless image for runtime.
|
58
|
+
######################>#######
|
59
|
+
ARG TARGET_PLATFORM=linux/amd64
|
60
|
+
# FROM --platform=$TARGET_PLATFORM gcr.io/distroless/python3-debian12:latest
|
61
|
+
FROM --platform=$TARGET_PLATFORM gcr.io/distroless/python3-debian12:debug
|
62
|
+
ARG PYTHON_VERSION=${PYTHON_VERSION}
|
63
|
+
# needed to call pip directly
|
64
|
+
COPY --from=build /bin/sh /bin/sh
|
65
|
+
|
66
|
+
# Copy driver libraries based on architecture
|
67
|
+
# Set FOLDER_NAME based on TARGET_PLATFORM
|
68
|
+
ENV TARGET_PLATFORM=${TARGET_PLATFORM}
|
69
|
+
ENV FOLDER_NAME="x86_64-linux-gnu"
|
70
|
+
# RUN if [ "${TARGET_PLATFORM}" = "linux/arm64" ]; then \
|
71
|
+
# export FOLDER_NAME="aarch64-linux-gnu"; \
|
72
|
+
# fi && \
|
73
|
+
# echo "FOLDER_NAME=${FOLDER_NAME}"
|
74
|
+
|
75
|
+
|
76
|
+
# virtual env
|
77
|
+
COPY --from=build /venv /venv
|
78
|
+
|
79
|
+
# cuda
|
80
|
+
COPY --from=build --chmod=755 /usr/local/cuda /usr/local/cuda
|
81
|
+
|
82
|
+
# We have to overwrite the python3 binary that the distroless image uses
|
83
|
+
COPY --from=build /usr/bin/python${PYTHON_VERSION} /usr/bin/python3
|
84
|
+
# And also copy in all the lib files for it.
|
85
|
+
COPY --from=build /usr/lib/python${PYTHON_VERSION} /usr/lib/python${PYTHON_VERSION}
|
86
|
+
# Note that distroless comes with a fixed python version, so we may need to overwrite that specific
|
87
|
+
# version.
|
88
|
+
|
89
|
+
# for debugging
|
90
|
+
COPY --from=build /usr/bin/nvidia-smi /usr/bin/nvidia-smi
|
91
|
+
# Copy driver libraries based on architecture
|
92
|
+
COPY --from=build /usr/lib/${FOLDER_NAME}/libcuda.so* /usr/lib/${FOLDER_NAME}/
|
93
|
+
COPY --from=build /usr/lib/${FOLDER_NAME}/libnvidia-ml.so* /usr/lib/${FOLDER_NAME}/
|
94
|
+
|
95
|
+
# Set environment variables for CUDA
|
96
|
+
ENV PATH=/usr/local/cuda/bin:${PATH}
|
97
|
+
ENV LD_LIBRARY_PATH=/usr/local/cuda/lib64:/usr/lib/${FOLDER_NAME}:$LD_LIBRARY_PATH
|
98
|
+
ENV CUDA_HOME=/usr/local/cuda
|
99
|
+
|
100
|
+
# Set environment variables to use virtualenv by default
|
101
|
+
ENV VIRTUAL_ENV=/venv
|
102
|
+
# ENV PATH=${VIRTUAL_ENV}/bin:${PATH}
|
103
|
+
ENV PYTHONPATH=${PYTHONPATH}:${VIRTUAL_ENV}/lib/python${PYTHON_VERSION}/site-packages
|
104
|
+
|
105
|
+
# ENTRYPOINT ["${VIRTUAL_ENV}/bin/python"]
|
106
|
+
|
107
|
+
|
108
|
+
# These will be set by the templaing system.
|
109
|
+
ENV CLARIFAI_PAT=${CLARIFAI_PAT}
|
110
|
+
ENV CLARIFAI_USER_ID=${CLARIFAI_USER_ID}
|
111
|
+
ENV CLARIFAI_RUNNER_ID=${CLARIFAI_RUNNER_ID}
|
112
|
+
ENV CLARIFAI_NODEPOOL_ID=${CLARIFAI_NODEPOOL_ID}
|
113
|
+
ENV CLARIFAI_COMPUTE_CLUSTER_ID=${CLARIFAI_COMPUTE_CLUSTER_ID}
|
114
|
+
ENV CLARIFAI_API_BASE=${CLARIFAI_API_BASE}
|
115
|
+
|
116
|
+
# Set the working directory to /app
|
117
|
+
WORKDIR /app
|
118
|
+
|
119
|
+
# Copy the current folder into /app/model_dir that the SDK will expect.
|
120
|
+
# Note(zeiler): would be nice to exclude checkpoints in case they were pre-downloaded.
|
121
|
+
COPY . /app/model_dir/${name}
|
122
|
+
|
123
|
+
# Add the model directory to the python path.
|
124
|
+
ENV PYTHONPATH=${PYTHONPATH}:/app/model_dir/${name}
|
125
|
+
|
126
|
+
|
127
|
+
# Finally run the clarifai entrypoint to start the runner loop and local dev server.
|
128
|
+
# Note(zeiler): we may want to make this a clarifai CLI call.
|
129
|
+
CMD ["-m", "clarifai.runners.server", "--model_path", "/app/model_dir/${name}"]
|
@@ -0,0 +1,235 @@
|
|
1
|
+
import itertools
|
2
|
+
from typing import Any, Dict, Iterator, List, Tuple
|
3
|
+
|
4
|
+
import numpy as np
|
5
|
+
from clarifai_grpc.grpc.api import resources_pb2, service_pb2
|
6
|
+
from clarifai_grpc.grpc.api.service_pb2 import PostModelOutputsRequest
|
7
|
+
from google.protobuf import json_format
|
8
|
+
|
9
|
+
from ..utils.data_handler import InputDataHandler, OutputDataHandler
|
10
|
+
from .model_runner import ModelRunner
|
11
|
+
|
12
|
+
|
13
|
+
class AnyAnyModel(ModelRunner):
|
14
|
+
|
15
|
+
def load_model(self):
|
16
|
+
"""
|
17
|
+
Load inference time artifacts that are called frequently .e.g. models, tokenizers, etc.
|
18
|
+
in this method so they are loaded only once for faster inference.
|
19
|
+
"""
|
20
|
+
raise NotImplementedError
|
21
|
+
|
22
|
+
def parse_input_request(
|
23
|
+
self, input_request: service_pb2.PostModelOutputsRequest) -> Tuple[List[Dict], Dict]:
|
24
|
+
list_input_dict = [
|
25
|
+
InputDataHandler.from_proto(input).to_python() for input in input_request.inputs
|
26
|
+
]
|
27
|
+
inference_params = json_format.MessageToDict(input_request.model.output_info.params)
|
28
|
+
|
29
|
+
return list_input_dict, inference_params
|
30
|
+
|
31
|
+
def convert_output_to_proto(self, outputs: list):
|
32
|
+
assert (isinstance(outputs, Iterator) or isinstance(outputs, list) or
|
33
|
+
isinstance(outputs, tuple)), "outputs must be an Iterator"
|
34
|
+
output_protos = []
|
35
|
+
for output in outputs:
|
36
|
+
if isinstance(output, OutputDataHandler):
|
37
|
+
output = output.proto
|
38
|
+
elif isinstance(output, resources_pb2.Output):
|
39
|
+
pass
|
40
|
+
else:
|
41
|
+
raise NotImplementedError
|
42
|
+
output_protos.append(output)
|
43
|
+
|
44
|
+
return service_pb2.MultiOutputResponse(outputs=output_protos)
|
45
|
+
|
46
|
+
def predict_wrapper(
|
47
|
+
self, request: service_pb2.PostModelOutputsRequest) -> service_pb2.MultiOutputResponse:
|
48
|
+
list_dict_input, inference_params = self.parse_input_request(request)
|
49
|
+
outputs = self.predict(list_dict_input, inference_parameters=inference_params)
|
50
|
+
return self.convert_output_to_proto(outputs)
|
51
|
+
|
52
|
+
def generate_wrapper(
|
53
|
+
self, request: PostModelOutputsRequest) -> Iterator[service_pb2.MultiOutputResponse]:
|
54
|
+
list_dict_input, inference_params = self.parse_input_request(request)
|
55
|
+
outputs = self.generate(list_dict_input, inference_parameters=inference_params)
|
56
|
+
for output in outputs:
|
57
|
+
yield self.convert_output_to_proto(output)
|
58
|
+
|
59
|
+
def _preprocess_stream(
|
60
|
+
self, request: Iterator[PostModelOutputsRequest]) -> Iterator[Tuple[List[Dict], List[Dict]]]:
|
61
|
+
"""Return generator of processed data (from proto to python) and inference parameters like predict and generate"""
|
62
|
+
for i, req in enumerate(request):
|
63
|
+
input_data, _ = self.parse_input_request(req)
|
64
|
+
yield input_data
|
65
|
+
|
66
|
+
def stream_wrapper(self, request: Iterator[PostModelOutputsRequest]
|
67
|
+
) -> Iterator[service_pb2.MultiOutputResponse]:
|
68
|
+
first_request = next(request)
|
69
|
+
_, inference_params = self.parse_input_request(first_request)
|
70
|
+
request_iterator = itertools.chain([first_request], request)
|
71
|
+
outputs = self.stream(self._preprocess_stream(request_iterator), inference_params)
|
72
|
+
for output in outputs:
|
73
|
+
yield self.convert_output_to_proto(output)
|
74
|
+
|
75
|
+
def predict(self, input_data: List[Dict],
|
76
|
+
inference_parameters: Dict[str, Any] = {}) -> List[OutputDataHandler]:
|
77
|
+
"""
|
78
|
+
Prediction method.
|
79
|
+
|
80
|
+
Args:
|
81
|
+
-----
|
82
|
+
- input_data: is list of dict where key is input type name.
|
83
|
+
* image: np.ndarray
|
84
|
+
* text: str
|
85
|
+
* audio: bytes
|
86
|
+
|
87
|
+
- inference_parameters (Dict[str, Union[bool, str, float, int]]): your inference parameters.
|
88
|
+
|
89
|
+
Returns:
|
90
|
+
--------
|
91
|
+
List of OutputDataHandler
|
92
|
+
"""
|
93
|
+
raise NotImplementedError
|
94
|
+
|
95
|
+
def generate(self, input_data: List[Dict],
|
96
|
+
inference_parameters: Dict[str, Any] = {}) -> Iterator[List[OutputDataHandler]]:
|
97
|
+
"""
|
98
|
+
Generate method.
|
99
|
+
|
100
|
+
Args:
|
101
|
+
-----
|
102
|
+
- input_data: is list of dict where key is input type name.
|
103
|
+
* image: np.ndarray
|
104
|
+
* text: str
|
105
|
+
* audio: bytes
|
106
|
+
|
107
|
+
- inference_parameters (Dict[str, Union[bool, str, float, int]]): your inference parameters.
|
108
|
+
|
109
|
+
Yield:
|
110
|
+
--------
|
111
|
+
List of OutputDataHandler
|
112
|
+
"""
|
113
|
+
raise NotImplementedError
|
114
|
+
|
115
|
+
def stream(self, inputs: Iterator[List[Dict[str, Any]]],
|
116
|
+
inference_params: Dict[str, Any]) -> Iterator[List[OutputDataHandler]]:
|
117
|
+
"""
|
118
|
+
Stream method.
|
119
|
+
|
120
|
+
Args:
|
121
|
+
-----
|
122
|
+
input_request: is an Iterator of Tuple which
|
123
|
+
- First element (List[Dict[str, Union[np.ndarray, str, bytes]]]) is list of dict input data type which keys and values are:
|
124
|
+
* image: np.ndarray
|
125
|
+
* text: str
|
126
|
+
* audio: bytes
|
127
|
+
|
128
|
+
- Second element (Dict[str, Union[bool, str, float, int]]): is a dict of inference_parameters
|
129
|
+
|
130
|
+
Yield:
|
131
|
+
--------
|
132
|
+
List of OutputDataHandler
|
133
|
+
"""
|
134
|
+
raise NotImplementedError
|
135
|
+
|
136
|
+
|
137
|
+
class VisualInputModel(AnyAnyModel):
|
138
|
+
|
139
|
+
def parse_input_request(
|
140
|
+
self, input_request: service_pb2.PostModelOutputsRequest) -> Tuple[List[Dict], Dict]:
|
141
|
+
list_input_dict = [
|
142
|
+
InputDataHandler.from_proto(input).image(format="np") for input in input_request.inputs
|
143
|
+
]
|
144
|
+
inference_params = json_format.MessageToDict(input_request.model.output_info.params)
|
145
|
+
|
146
|
+
return list_input_dict, inference_params
|
147
|
+
|
148
|
+
def load_model(self):
|
149
|
+
"""
|
150
|
+
Load inference time artifacts that are called frequently .e.g. models, tokenizers, etc.
|
151
|
+
in this method so they are loaded only once for faster inference.
|
152
|
+
"""
|
153
|
+
raise NotImplementedError
|
154
|
+
|
155
|
+
def predict(self, input_data: List[np.ndarray],
|
156
|
+
inference_parameters: Dict[str, Any] = {}) -> List[OutputDataHandler]:
|
157
|
+
"""
|
158
|
+
Prediction method.
|
159
|
+
|
160
|
+
Args:
|
161
|
+
-----
|
162
|
+
- input_data(List[np.ndarray]): is list of image as np.ndarray type
|
163
|
+
- inference_parameters (Dict[str, Union[bool, str, float, int]]): your inference parameters.
|
164
|
+
|
165
|
+
Returns:
|
166
|
+
--------
|
167
|
+
List of OutputDataHandler
|
168
|
+
"""
|
169
|
+
raise NotImplementedError
|
170
|
+
|
171
|
+
|
172
|
+
class TextInputModel(AnyAnyModel):
|
173
|
+
|
174
|
+
def load_model(self):
|
175
|
+
"""
|
176
|
+
Load inference time artifacts that are called frequently .e.g. models, tokenizers, etc.
|
177
|
+
in this method so they are loaded only once for faster inference.
|
178
|
+
"""
|
179
|
+
raise NotImplementedError
|
180
|
+
|
181
|
+
def parse_input_request(
|
182
|
+
self, input_request: service_pb2.PostModelOutputsRequest) -> Tuple[List[Dict], Dict]:
|
183
|
+
list_input_text = [InputDataHandler.from_proto(input).text for input in input_request.inputs]
|
184
|
+
inference_params = json_format.MessageToDict(input_request.model.output_info.params)
|
185
|
+
|
186
|
+
return list_input_text, inference_params
|
187
|
+
|
188
|
+
def predict(self, input_data: List[str],
|
189
|
+
inference_parameters: Dict[str, Any] = {}) -> List[OutputDataHandler]:
|
190
|
+
"""
|
191
|
+
Prediction method.
|
192
|
+
|
193
|
+
Args:
|
194
|
+
-----
|
195
|
+
- input_data(List[str]): is list of text as str type
|
196
|
+
- inference_parameters (Dict[str, Union[bool, str, float, int]]): your inference parameters.
|
197
|
+
|
198
|
+
Returns:
|
199
|
+
--------
|
200
|
+
List of OutputDataHandler
|
201
|
+
"""
|
202
|
+
raise NotImplementedError
|
203
|
+
|
204
|
+
def generate(self, input_data: List[str],
|
205
|
+
inference_parameters: Dict[str, Any] = {}) -> Iterator[List[OutputDataHandler]]:
|
206
|
+
"""
|
207
|
+
Prediction method.
|
208
|
+
|
209
|
+
Args:
|
210
|
+
-----
|
211
|
+
- input_data(List[str]): is list of text as str type
|
212
|
+
- inference_parameters (Dict[str, Union[bool, str, float, int]]): your inference parameters.
|
213
|
+
|
214
|
+
Yield:
|
215
|
+
--------
|
216
|
+
List of OutputDataHandler
|
217
|
+
"""
|
218
|
+
raise NotImplementedError
|
219
|
+
|
220
|
+
def stream(self, inputs: Iterator[List[str]],
|
221
|
+
inference_params: Dict[str, Any]) -> Iterator[List[OutputDataHandler]]:
|
222
|
+
"""
|
223
|
+
Stream method.
|
224
|
+
|
225
|
+
Args:
|
226
|
+
-----
|
227
|
+
input_request: is an Iterator of Tuple which
|
228
|
+
- First element (List[str]) is list of input text:
|
229
|
+
- Second element (Dict[str, Union[bool, str, float, int]]): is a dict of inference_parameters
|
230
|
+
|
231
|
+
Yield:
|
232
|
+
--------
|
233
|
+
List of OutputDataHandler
|
234
|
+
"""
|
235
|
+
raise NotImplementedError
|
@@ -0,0 +1,41 @@
|
|
1
|
+
from abc import ABC, abstractmethod
|
2
|
+
from typing import Iterator
|
3
|
+
|
4
|
+
from clarifai_grpc.grpc.api import service_pb2
|
5
|
+
|
6
|
+
|
7
|
+
class ModelClass(ABC):
|
8
|
+
|
9
|
+
def predict_wrapper(
|
10
|
+
self, request: service_pb2.PostModelOutputsRequest) -> service_pb2.MultiOutputResponse:
|
11
|
+
"""This method is used for input/output proto data conversion"""
|
12
|
+
return self.predict(request)
|
13
|
+
|
14
|
+
def generate_wrapper(self, request: service_pb2.PostModelOutputsRequest
|
15
|
+
) -> Iterator[service_pb2.MultiOutputResponse]:
|
16
|
+
"""This method is used for input/output proto data conversion and yield outcome"""
|
17
|
+
return self.generate(request)
|
18
|
+
|
19
|
+
def stream_wrapper(self, request: service_pb2.PostModelOutputsRequest
|
20
|
+
) -> Iterator[service_pb2.MultiOutputResponse]:
|
21
|
+
"""This method is used for input/output proto data conversion and yield outcome"""
|
22
|
+
return self.stream(request)
|
23
|
+
|
24
|
+
@abstractmethod
|
25
|
+
def load_model(self):
|
26
|
+
raise NotImplementedError("load_model() not implemented")
|
27
|
+
|
28
|
+
@abstractmethod
|
29
|
+
def predict(self,
|
30
|
+
request: service_pb2.PostModelOutputsRequest) -> service_pb2.MultiOutputResponse:
|
31
|
+
raise NotImplementedError("run_input() not implemented")
|
32
|
+
|
33
|
+
@abstractmethod
|
34
|
+
def generate(self, request: service_pb2.PostModelOutputsRequest
|
35
|
+
) -> Iterator[service_pb2.MultiOutputResponse]:
|
36
|
+
raise NotImplementedError("generate() not implemented")
|
37
|
+
|
38
|
+
@abstractmethod
|
39
|
+
def stream(self, request_iterator: Iterator[service_pb2.PostModelOutputsRequest]
|
40
|
+
) -> Iterator[service_pb2.MultiOutputResponse]:
|
41
|
+
raise NotImplementedError("stream() not implemented")
|