clarifai 10.8.2__tar.gz → 10.8.3__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.
Files changed (153) hide show
  1. {clarifai-10.8.2/clarifai.egg-info → clarifai-10.8.3}/PKG-INFO +3 -2
  2. clarifai-10.8.3/clarifai/__init__.py +1 -0
  3. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/client/app.py +3 -4
  4. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/client/model.py +1 -2
  5. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/repo_build/static_files/base_test.py +4 -4
  6. clarifai-10.8.3/clarifai/runners/__init__.py +14 -0
  7. clarifai-10.8.3/clarifai/runners/dockerfile_template/Dockerfile.cpu.template +31 -0
  8. clarifai-10.8.3/clarifai/runners/dockerfile_template/Dockerfile.cuda.template +129 -0
  9. clarifai-10.8.3/clarifai/runners/models/base_typed_model.py +235 -0
  10. clarifai-10.8.3/clarifai/runners/models/model_class.py +41 -0
  11. clarifai-10.8.3/clarifai/runners/models/model_runner.py +175 -0
  12. clarifai-10.8.3/clarifai/runners/models/model_servicer.py +79 -0
  13. clarifai-10.8.3/clarifai/runners/models/model_upload.py +315 -0
  14. clarifai-10.8.3/clarifai/runners/server.py +130 -0
  15. clarifai-10.8.3/clarifai/runners/utils/data_handler.py +244 -0
  16. clarifai-10.8.3/clarifai/runners/utils/data_utils.py +15 -0
  17. clarifai-10.8.3/clarifai/runners/utils/loader.py +70 -0
  18. clarifai-10.8.3/clarifai/runners/utils/logging.py +6 -0
  19. clarifai-10.8.3/clarifai/runners/utils/url_fetcher.py +42 -0
  20. clarifai-10.8.3/clarifai/utils/__init__.py +0 -0
  21. clarifai-10.8.3/clarifai/utils/logging.py +359 -0
  22. clarifai-10.8.3/clarifai/workflows/__init__.py +0 -0
  23. {clarifai-10.8.2 → clarifai-10.8.3/clarifai.egg-info}/PKG-INFO +3 -2
  24. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai.egg-info/SOURCES.txt +16 -0
  25. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai.egg-info/requires.txt +2 -1
  26. {clarifai-10.8.2 → clarifai-10.8.3}/requirements.txt +2 -1
  27. {clarifai-10.8.2 → clarifai-10.8.3}/tests/test_app.py +18 -0
  28. {clarifai-10.8.2 → clarifai-10.8.3}/tests/test_data_upload.py +51 -3
  29. clarifai-10.8.3/tests/test_misc.py +67 -0
  30. {clarifai-10.8.2 → clarifai-10.8.3}/tests/test_model_train.py +1 -0
  31. clarifai-10.8.2/clarifai/__init__.py +0 -1
  32. clarifai-10.8.2/clarifai/utils/logging.py +0 -153
  33. clarifai-10.8.2/tests/test_misc.py +0 -19
  34. {clarifai-10.8.2 → clarifai-10.8.3}/LICENSE +0 -0
  35. {clarifai-10.8.2 → clarifai-10.8.3}/MANIFEST.in +0 -0
  36. {clarifai-10.8.2 → clarifai-10.8.3}/README.md +0 -0
  37. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/cli.py +0 -0
  38. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/client/__init__.py +0 -0
  39. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/client/auth/__init__.py +0 -0
  40. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/client/auth/helper.py +0 -0
  41. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/client/auth/register.py +0 -0
  42. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/client/auth/stub.py +0 -0
  43. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/client/base.py +0 -0
  44. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/client/dataset.py +0 -0
  45. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/client/input.py +0 -0
  46. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/client/lister.py +0 -0
  47. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/client/module.py +0 -0
  48. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/client/search.py +0 -0
  49. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/client/user.py +0 -0
  50. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/client/workflow.py +0 -0
  51. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/constants/dataset.py +0 -0
  52. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/constants/input.py +0 -0
  53. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/constants/model.py +0 -0
  54. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/constants/rag.py +0 -0
  55. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/constants/search.py +0 -0
  56. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/constants/workflow.py +0 -0
  57. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/datasets/__init__.py +0 -0
  58. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/datasets/export/__init__.py +0 -0
  59. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/datasets/export/inputs_annotations.py +0 -0
  60. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/datasets/upload/__init__.py +0 -0
  61. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/datasets/upload/base.py +0 -0
  62. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/datasets/upload/features.py +0 -0
  63. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/datasets/upload/image.py +0 -0
  64. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/datasets/upload/loaders/README.md +0 -0
  65. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/datasets/upload/loaders/__init__.py +0 -0
  66. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/datasets/upload/loaders/coco_captions.py +0 -0
  67. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/datasets/upload/loaders/coco_detection.py +0 -0
  68. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/datasets/upload/loaders/imagenet_classification.py +0 -0
  69. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/datasets/upload/loaders/xview_detection.py +0 -0
  70. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/datasets/upload/text.py +0 -0
  71. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/datasets/upload/utils.py +0 -0
  72. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/errors.py +0 -0
  73. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/__init__.py +0 -0
  74. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/api.py +0 -0
  75. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/README.md +0 -0
  76. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/__init__.py +0 -0
  77. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/cli/__init__.py +0 -0
  78. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/cli/_utils.py +0 -0
  79. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/cli/base.py +0 -0
  80. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/cli/build.py +0 -0
  81. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/cli/clarifai_clis.py +0 -0
  82. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/cli/create.py +0 -0
  83. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/cli/example_cli.py +0 -0
  84. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/cli/login.py +0 -0
  85. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/cli/upload.py +0 -0
  86. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/constants.py +0 -0
  87. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/docs/cli.md +0 -0
  88. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/docs/concepts.md +0 -0
  89. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/docs/dependencies.md +0 -0
  90. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/docs/inference_parameters.md +0 -0
  91. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/docs/model_types.md +0 -0
  92. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/model_config/__init__.py +0 -0
  93. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/model_config/base.py +0 -0
  94. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/model_config/config.py +0 -0
  95. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/model_config/inference_parameter.py +0 -0
  96. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/model_config/model_types_config/multimodal-embedder.yaml +0 -0
  97. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/model_config/model_types_config/text-classifier.yaml +0 -0
  98. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/model_config/model_types_config/text-embedder.yaml +0 -0
  99. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/model_config/model_types_config/text-to-image.yaml +0 -0
  100. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/model_config/model_types_config/text-to-text.yaml +0 -0
  101. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/model_config/model_types_config/visual-classifier.yaml +0 -0
  102. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/model_config/model_types_config/visual-detector.yaml +0 -0
  103. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/model_config/model_types_config/visual-embedder.yaml +0 -0
  104. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/model_config/model_types_config/visual-segmenter.yaml +0 -0
  105. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/model_config/output.py +0 -0
  106. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/model_config/triton/__init__.py +0 -0
  107. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/model_config/triton/serializer.py +0 -0
  108. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/model_config/triton/triton_config.py +0 -0
  109. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/model_config/triton/wrappers.py +0 -0
  110. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/repo_build/__init__.py +0 -0
  111. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/repo_build/build.py +0 -0
  112. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/repo_build/static_files/_requirements.txt +0 -0
  113. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/repo_build/static_files/inference.py +0 -0
  114. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/repo_build/static_files/sample_clarifai_config.yaml +0 -0
  115. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/repo_build/static_files/test.py +0 -0
  116. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/repo_build/static_files/triton/model.py +0 -0
  117. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/models/model_serving/utils.py +0 -0
  118. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/modules/README.md +0 -0
  119. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/modules/__init__.py +0 -0
  120. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/modules/css.py +0 -0
  121. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/modules/pages.py +0 -0
  122. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/modules/style.css +0 -0
  123. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/rag/__init__.py +0 -0
  124. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/rag/rag.py +0 -0
  125. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/rag/utils.py +0 -0
  126. {clarifai-10.8.2/clarifai/utils → clarifai-10.8.3/clarifai/runners/models}/__init__.py +0 -0
  127. {clarifai-10.8.2/clarifai/workflows → clarifai-10.8.3/clarifai/runners/utils}/__init__.py +0 -0
  128. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/schema/search.py +0 -0
  129. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/urls/helper.py +0 -0
  130. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/utils/constants.py +0 -0
  131. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/utils/evaluation/__init__.py +0 -0
  132. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/utils/evaluation/helpers.py +0 -0
  133. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/utils/evaluation/main.py +0 -0
  134. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/utils/evaluation/testset_annotation_parser.py +0 -0
  135. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/utils/misc.py +0 -0
  136. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/utils/model_train.py +0 -0
  137. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/versions.py +0 -0
  138. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/workflows/export.py +0 -0
  139. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/workflows/utils.py +0 -0
  140. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai/workflows/validate.py +0 -0
  141. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai.egg-info/dependency_links.txt +0 -0
  142. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai.egg-info/entry_points.txt +0 -0
  143. {clarifai-10.8.2 → clarifai-10.8.3}/clarifai.egg-info/top_level.txt +0 -0
  144. {clarifai-10.8.2 → clarifai-10.8.3}/pyproject.toml +0 -0
  145. {clarifai-10.8.2 → clarifai-10.8.3}/setup.cfg +0 -0
  146. {clarifai-10.8.2 → clarifai-10.8.3}/setup.py +0 -0
  147. {clarifai-10.8.2 → clarifai-10.8.3}/tests/test_auth.py +0 -0
  148. {clarifai-10.8.2 → clarifai-10.8.3}/tests/test_eval.py +0 -0
  149. {clarifai-10.8.2 → clarifai-10.8.3}/tests/test_model_predict.py +0 -0
  150. {clarifai-10.8.2 → clarifai-10.8.3}/tests/test_modules.py +0 -0
  151. {clarifai-10.8.2 → clarifai-10.8.3}/tests/test_rag.py +0 -0
  152. {clarifai-10.8.2 → clarifai-10.8.3}/tests/test_search.py +0 -0
  153. {clarifai-10.8.2 → clarifai-10.8.3}/tests/test_stub.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: clarifai
3
- Version: 10.8.2
3
+ Version: 10.8.3
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.6
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.3"
@@ -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, module_version_id: str = "", **kwargs) -> Module:
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", module_version_id="module_version_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
- if not self.model_info.model_type_id or not self.model_info.model_version.train_log:
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 ...constants import IMAGE_TENSOR_NAME, TEXT_TENSOR_NAME
9
- from ...model_config import (ClassifierOutput, EmbeddingOutput, ImageOutput, InferParam,
10
- InferParamManager, MasksOutput, ModelTypes, TextOutput,
11
- VisualDetector, load_user_config)
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")