clarifai 10.11.0__py3-none-any.whl → 10.11.2rc1__py3-none-any.whl
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/__init__.py +1 -1
- clarifai/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/__pycache__/errors.cpython-310.pyc +0 -0
- clarifai/__pycache__/versions.cpython-310.pyc +0 -0
- clarifai/cli/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/cli/__pycache__/base.cpython-310.pyc +0 -0
- clarifai/cli/__pycache__/compute_cluster.cpython-310.pyc +0 -0
- clarifai/cli/__pycache__/deployment.cpython-310.pyc +0 -0
- clarifai/cli/__pycache__/model.cpython-310.pyc +0 -0
- clarifai/cli/__pycache__/nodepool.cpython-310.pyc +0 -0
- clarifai/cli/model.py +206 -10
- clarifai/client/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/app.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/base.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/dataset.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/input.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/lister.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/model.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/module.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/runner.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/search.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/user.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/workflow.cpython-310.pyc +0 -0
- clarifai/client/auth/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/client/auth/__pycache__/helper.cpython-310.pyc +0 -0
- clarifai/client/auth/__pycache__/register.cpython-310.pyc +0 -0
- clarifai/client/auth/__pycache__/stub.cpython-310.pyc +0 -0
- clarifai/client/dataset.py +4 -4
- clarifai/client/model.py +94 -13
- clarifai/constants/__pycache__/dataset.cpython-310.pyc +0 -0
- clarifai/constants/__pycache__/model.cpython-310.pyc +0 -0
- clarifai/constants/__pycache__/search.cpython-310.pyc +0 -0
- clarifai/datasets/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/datasets/export/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/datasets/export/__pycache__/inputs_annotations.cpython-310.pyc +0 -0
- clarifai/datasets/upload/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/datasets/upload/__pycache__/base.cpython-310.pyc +0 -0
- clarifai/datasets/upload/__pycache__/features.cpython-310.pyc +0 -0
- clarifai/datasets/upload/__pycache__/image.cpython-310.pyc +0 -0
- clarifai/datasets/upload/__pycache__/text.cpython-310.pyc +0 -0
- clarifai/datasets/upload/__pycache__/utils.cpython-310.pyc +0 -0
- clarifai/datasets/upload/features.py +1 -1
- clarifai/datasets/upload/multimodal.py +2 -1
- clarifai/datasets/upload/text.py +3 -2
- clarifai/models/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/models/model_serving/README.md +158 -0
- clarifai/models/model_serving/__init__.py +14 -0
- clarifai/models/model_serving/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/models/model_serving/__pycache__/constants.cpython-310.pyc +0 -0
- clarifai/models/model_serving/cli/__init__.py +12 -0
- clarifai/models/model_serving/cli/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/models/model_serving/cli/__pycache__/_utils.cpython-310.pyc +0 -0
- clarifai/models/model_serving/cli/__pycache__/base.cpython-310.pyc +0 -0
- clarifai/models/model_serving/cli/__pycache__/build.cpython-310.pyc +0 -0
- clarifai/models/model_serving/cli/__pycache__/create.cpython-310.pyc +0 -0
- clarifai/models/model_serving/cli/_utils.py +53 -0
- clarifai/models/model_serving/cli/base.py +14 -0
- clarifai/models/model_serving/cli/build.py +79 -0
- clarifai/models/model_serving/cli/clarifai_clis.py +33 -0
- clarifai/models/model_serving/cli/create.py +171 -0
- clarifai/models/model_serving/cli/example_cli.py +34 -0
- clarifai/models/model_serving/cli/login.py +26 -0
- clarifai/models/model_serving/cli/upload.py +183 -0
- clarifai/models/model_serving/constants.py +21 -0
- clarifai/models/model_serving/docs/cli.md +161 -0
- clarifai/models/model_serving/docs/concepts.md +229 -0
- clarifai/models/model_serving/docs/dependencies.md +11 -0
- clarifai/models/model_serving/docs/inference_parameters.md +139 -0
- clarifai/models/model_serving/docs/model_types.md +19 -0
- clarifai/models/model_serving/model_config/__init__.py +16 -0
- clarifai/models/model_serving/model_config/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/models/model_serving/model_config/__pycache__/base.cpython-310.pyc +0 -0
- clarifai/models/model_serving/model_config/__pycache__/config.cpython-310.pyc +0 -0
- clarifai/models/model_serving/model_config/__pycache__/inference_parameter.cpython-310.pyc +0 -0
- clarifai/models/model_serving/model_config/__pycache__/output.cpython-310.pyc +0 -0
- clarifai/models/model_serving/model_config/base.py +369 -0
- clarifai/models/model_serving/model_config/config.py +312 -0
- clarifai/models/model_serving/model_config/inference_parameter.py +129 -0
- clarifai/models/model_serving/model_config/model_types_config/multimodal-embedder.yaml +25 -0
- clarifai/models/model_serving/model_config/model_types_config/text-classifier.yaml +19 -0
- clarifai/models/model_serving/model_config/model_types_config/text-embedder.yaml +20 -0
- clarifai/models/model_serving/model_config/model_types_config/text-to-image.yaml +19 -0
- clarifai/models/model_serving/model_config/model_types_config/text-to-text.yaml +19 -0
- clarifai/models/model_serving/model_config/model_types_config/visual-classifier.yaml +22 -0
- clarifai/models/model_serving/model_config/model_types_config/visual-detector.yaml +32 -0
- clarifai/models/model_serving/model_config/model_types_config/visual-embedder.yaml +19 -0
- clarifai/models/model_serving/model_config/model_types_config/visual-segmenter.yaml +19 -0
- clarifai/models/model_serving/model_config/output.py +133 -0
- clarifai/models/model_serving/model_config/triton/__init__.py +14 -0
- clarifai/models/model_serving/model_config/triton/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/models/model_serving/model_config/triton/__pycache__/serializer.cpython-310.pyc +0 -0
- clarifai/models/model_serving/model_config/triton/__pycache__/triton_config.cpython-310.pyc +0 -0
- clarifai/models/model_serving/model_config/triton/__pycache__/wrappers.cpython-310.pyc +0 -0
- clarifai/models/model_serving/model_config/triton/serializer.py +136 -0
- clarifai/models/model_serving/model_config/triton/triton_config.py +182 -0
- clarifai/models/model_serving/model_config/triton/wrappers.py +281 -0
- clarifai/models/model_serving/repo_build/__init__.py +14 -0
- clarifai/models/model_serving/repo_build/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/models/model_serving/repo_build/__pycache__/build.cpython-310.pyc +0 -0
- clarifai/models/model_serving/repo_build/build.py +198 -0
- clarifai/models/model_serving/repo_build/static_files/__pycache__/base_test.cpython-310-pytest-7.2.0.pyc +0 -0
- clarifai/models/model_serving/repo_build/static_files/_requirements.txt +2 -0
- clarifai/models/model_serving/repo_build/static_files/base_test.py +169 -0
- clarifai/models/model_serving/repo_build/static_files/inference.py +26 -0
- clarifai/models/model_serving/repo_build/static_files/sample_clarifai_config.yaml +25 -0
- clarifai/models/model_serving/repo_build/static_files/test.py +40 -0
- clarifai/models/model_serving/repo_build/static_files/triton/model.py +75 -0
- clarifai/models/model_serving/utils.py +31 -0
- clarifai/rag/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/rag/__pycache__/rag.cpython-310.pyc +0 -0
- clarifai/rag/__pycache__/utils.cpython-310.pyc +0 -0
- clarifai/rag/rag.py +6 -2
- clarifai/runners/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/runners/__pycache__/server.cpython-310.pyc +0 -0
- clarifai/runners/deepgram_live_transcribe.py +98 -0
- clarifai/runners/deepgram_live_transcribe.py~ +98 -0
- clarifai/runners/deepgram_runner.py +131 -0
- clarifai/runners/deepgram_runner.py~ +130 -0
- clarifai/runners/dockerfile_template/Dockerfile.cpu.template +31 -0
- clarifai/runners/dockerfile_template/Dockerfile.cuda.template +79 -0
- clarifai/runners/dockerfile_template/Dockerfile.template +2 -0
- clarifai/runners/example_llama2.py~ +72 -0
- clarifai/runners/matt_example.py +89 -0
- clarifai/runners/matt_example.py~ +87 -0
- clarifai/runners/matt_llm_example.py +129 -0
- clarifai/runners/matt_llm_example.py~ +128 -0
- clarifai/runners/models/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/runners/models/__pycache__/base_typed_model.cpython-310.pyc +0 -0
- clarifai/runners/models/__pycache__/model_class.cpython-310.pyc +0 -0
- clarifai/runners/models/__pycache__/model_run_locally.cpython-310.pyc +0 -0
- clarifai/runners/models/__pycache__/model_runner.cpython-310.pyc +0 -0
- clarifai/runners/models/__pycache__/model_servicer.cpython-310.pyc +0 -0
- clarifai/runners/models/__pycache__/model_upload.cpython-310.pyc +0 -0
- clarifai/runners/models/model_run_locally.py +358 -33
- clarifai/runners/models/model_upload.py +116 -65
- clarifai/runners/server.py +2 -0
- clarifai/runners/utils/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/const.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/data_handler.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/data_utils.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/loader.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/logging.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/url_fetcher.cpython-310.pyc +0 -0
- clarifai/runners/utils/const.py +42 -0
- clarifai/runners/utils/loader.py +31 -16
- clarifai/runners/utils/logging.py +6 -0
- clarifai/schema/__pycache__/search.cpython-310.pyc +0 -0
- clarifai/urls/__pycache__/helper.cpython-310.pyc +0 -0
- clarifai/utils/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/utils/__pycache__/logging.cpython-310.pyc +0 -0
- clarifai/utils/__pycache__/misc.cpython-310.pyc +0 -0
- clarifai/utils/__pycache__/model_train.cpython-310.pyc +0 -0
- clarifai/utils/logging.py +7 -0
- clarifai/workflows/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/workflows/__pycache__/export.cpython-310.pyc +0 -0
- clarifai/workflows/__pycache__/utils.cpython-310.pyc +0 -0
- clarifai/workflows/__pycache__/validate.cpython-310.pyc +0 -0
- {clarifai-10.11.0.dist-info → clarifai-10.11.2rc1.dist-info}/METADATA +86 -16
- clarifai-10.11.2rc1.dist-info/RECORD +242 -0
- {clarifai-10.11.0.dist-info → clarifai-10.11.2rc1.dist-info}/WHEEL +1 -1
- clarifai-10.11.0.dist-info/RECORD +0 -99
- {clarifai-10.11.0.dist-info → clarifai-10.11.2rc1.dist-info}/LICENSE +0 -0
- {clarifai-10.11.0.dist-info → clarifai-10.11.2rc1.dist-info}/entry_points.txt +0 -0
- {clarifai-10.11.0.dist-info → clarifai-10.11.2rc1.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,6 @@
|
|
1
1
|
import os
|
2
2
|
import re
|
3
|
+
import sys
|
3
4
|
import time
|
4
5
|
from string import Template
|
5
6
|
|
@@ -8,8 +9,12 @@ from clarifai_grpc.grpc.api import resources_pb2, service_pb2
|
|
8
9
|
from clarifai_grpc.grpc.api.status import status_code_pb2
|
9
10
|
from google.protobuf import json_format
|
10
11
|
from rich import print
|
12
|
+
from rich.markup import escape
|
11
13
|
|
12
14
|
from clarifai.client import BaseClient
|
15
|
+
from clarifai.runners.utils.const import (AVAILABLE_PYTHON_IMAGES, AVAILABLE_TORCH_IMAGES,
|
16
|
+
CONCEPTS_REQUIRED_MODEL_TYPE, DEFAULT_PYTHON_VERSION,
|
17
|
+
PYTHON_BASE_IMAGE, TORCH_BASE_IMAGE)
|
13
18
|
from clarifai.runners.utils.loader import HuggingFaceLoader
|
14
19
|
from clarifai.urls.helper import ClarifaiUrlHelper
|
15
20
|
from clarifai.utils.logging import logger
|
@@ -23,53 +28,18 @@ def _clear_line(n: int = 1) -> None:
|
|
23
28
|
|
24
29
|
|
25
30
|
class ModelUploader:
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
cuda_version: ['124']
|
34
|
-
'''
|
35
|
-
AVAILABLE_TORCH_IMAGES = [
|
36
|
-
'2.0.0-py3.8-cuda124',
|
37
|
-
'2.0.0-py3.9-cuda124',
|
38
|
-
'2.0.0-py3.10-cuda124',
|
39
|
-
'2.0.0-py3.11-cuda124',
|
40
|
-
'2.1.0-py3.8-cuda124',
|
41
|
-
'2.1.0-py3.9-cuda124',
|
42
|
-
'2.1.0-py3.10-cuda124',
|
43
|
-
'2.1.0-py3.11-cuda124',
|
44
|
-
'2.2.0-py3.8-cuda124',
|
45
|
-
'2.2.0-py3.9-cuda124',
|
46
|
-
'2.2.0-py3.10-cuda124',
|
47
|
-
'2.2.0-py3.11-cuda124',
|
48
|
-
'2.3.0-py3.8-cuda124',
|
49
|
-
'2.3.0-py3.9-cuda124',
|
50
|
-
'2.3.0-py3.10-cuda124',
|
51
|
-
'2.3.0-py3.11-cuda124',
|
52
|
-
'2.4.0-py3.8-cuda124',
|
53
|
-
'2.4.0-py3.9-cuda124',
|
54
|
-
'2.4.0-py3.10-cuda124',
|
55
|
-
'2.4.0-py3.11-cuda124',
|
56
|
-
'2.4.1-py3.8-cuda124',
|
57
|
-
'2.4.1-py3.9-cuda124',
|
58
|
-
'2.4.1-py3.10-cuda124',
|
59
|
-
'2.4.1-py3.11-cuda124',
|
60
|
-
]
|
61
|
-
AVAILABLE_PYTHON_IMAGES = ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13']
|
62
|
-
PYTHON_BASE_IMAGE = 'public.ecr.aws/clarifai-models/python-base:{python_version}'
|
63
|
-
TORCH_BASE_IMAGE = 'public.ecr.aws/clarifai-models/torch:{torch_version}-py{python_version}-cuda{cuda_version}'
|
64
|
-
|
65
|
-
CONCEPTS_REQUIRED_MODEL_TYPE = [
|
66
|
-
'visual-classifier', 'visual-detector', 'visual-segmenter', 'text-classifier'
|
67
|
-
]
|
68
|
-
|
69
|
-
def __init__(self, folder: str):
|
31
|
+
|
32
|
+
def __init__(self, folder: str, validate_api_ids: bool = True):
|
33
|
+
"""
|
34
|
+
:param folder: The folder containing the model.py, config.yaml, requirements.txt and
|
35
|
+
checkpoints.
|
36
|
+
:param validate_api_ids: Whether to validate the user_id and app_id in the config file.
|
37
|
+
"""
|
70
38
|
self._client = None
|
71
39
|
self.folder = self._validate_folder(folder)
|
72
40
|
self.config = self._load_config(os.path.join(self.folder, 'config.yaml'))
|
41
|
+
self.validate_api_ids = validate_api_ids
|
42
|
+
self._validate_config()
|
73
43
|
self.model_proto = self._get_model_proto()
|
74
44
|
self.model_id = self.model_proto.id
|
75
45
|
self.model_version_id = None
|
@@ -108,13 +78,64 @@ class ModelUploader:
|
|
108
78
|
assert "repo_id" in self.config.get("checkpoints"), "No repo_id specified in the config file"
|
109
79
|
repo_id = self.config.get("checkpoints").get("repo_id")
|
110
80
|
|
111
|
-
#
|
112
|
-
|
113
|
-
hf_token = os.environ['HF_TOKEN']
|
114
|
-
else:
|
115
|
-
hf_token = self.config.get("checkpoints").get("hf_token", None)
|
81
|
+
# get from config.yaml otherwise fall back to HF_TOKEN env var.
|
82
|
+
hf_token = self.config.get("checkpoints").get("hf_token", os.environ.get("HF_TOKEN", None))
|
116
83
|
return repo_id, hf_token
|
117
84
|
|
85
|
+
def _check_app_exists(self):
|
86
|
+
if not self.validate_api_ids:
|
87
|
+
return True
|
88
|
+
resp = self.client.STUB.GetApp(service_pb2.GetAppRequest(user_app_id=self.client.user_app_id))
|
89
|
+
if resp.status.code == status_code_pb2.SUCCESS:
|
90
|
+
return True
|
91
|
+
return False
|
92
|
+
|
93
|
+
def _validate_config_model(self):
|
94
|
+
assert "model" in self.config, "model section not found in the config file"
|
95
|
+
model = self.config.get('model')
|
96
|
+
assert "user_id" in model, "user_id not found in the config file"
|
97
|
+
assert "app_id" in model, "app_id not found in the config file"
|
98
|
+
assert "model_type_id" in model, "model_type_id not found in the config file"
|
99
|
+
assert "id" in model, "model_id not found in the config file"
|
100
|
+
if '.' in model.get('id'):
|
101
|
+
logger.error(
|
102
|
+
"Model ID cannot contain '.', please remove it from the model_id in the config file")
|
103
|
+
sys.exit(1)
|
104
|
+
|
105
|
+
assert model.get('user_id') != "", "user_id cannot be empty in the config file"
|
106
|
+
assert model.get('app_id') != "", "app_id cannot be empty in the config file"
|
107
|
+
assert model.get('model_type_id') != "", "model_type_id cannot be empty in the config file"
|
108
|
+
assert model.get('id') != "", "model_id cannot be empty in the config file"
|
109
|
+
|
110
|
+
if not self._check_app_exists():
|
111
|
+
logger.error(
|
112
|
+
f"App {self.client.user_app_id.app_id} not found for user {self.client.user_app_id.user_id}"
|
113
|
+
)
|
114
|
+
sys.exit(1)
|
115
|
+
|
116
|
+
def _validate_config(self):
|
117
|
+
self._validate_config_model()
|
118
|
+
|
119
|
+
if self.config.get("checkpoints"):
|
120
|
+
self._validate_config_checkpoints()
|
121
|
+
|
122
|
+
assert "inference_compute_info" in self.config, "inference_compute_info not found in the config file"
|
123
|
+
|
124
|
+
if self.config.get("concepts"):
|
125
|
+
model_type_id = self.config.get('model').get('model_type_id')
|
126
|
+
assert model_type_id in CONCEPTS_REQUIRED_MODEL_TYPE, f"Model type {model_type_id} not supported for concepts"
|
127
|
+
|
128
|
+
if self.config.get("checkpoints"):
|
129
|
+
_, hf_token = self._validate_config_checkpoints()
|
130
|
+
|
131
|
+
if hf_token:
|
132
|
+
is_valid_token = HuggingFaceLoader.validate_hftoken(hf_token)
|
133
|
+
if not is_valid_token:
|
134
|
+
logger.error(
|
135
|
+
"Invalid Hugging Face token provided in the config file, this might cause issues with downloading the restricted model checkpoints."
|
136
|
+
)
|
137
|
+
logger.info("Continuing without Hugging Face token")
|
138
|
+
|
118
139
|
@property
|
119
140
|
def client(self):
|
120
141
|
if self._client is None:
|
@@ -233,33 +254,35 @@ class ModelUploader:
|
|
233
254
|
build_info = self.config.get('build_info', {})
|
234
255
|
if 'python_version' in build_info:
|
235
256
|
python_version = build_info['python_version']
|
236
|
-
if python_version not in
|
257
|
+
if python_version not in AVAILABLE_PYTHON_IMAGES:
|
237
258
|
logger.error(
|
238
|
-
f"Python version {python_version} not supported, please use one of the following versions: {
|
259
|
+
f"Python version {python_version} not supported, please use one of the following versions: {AVAILABLE_PYTHON_IMAGES}"
|
239
260
|
)
|
240
261
|
return
|
241
262
|
logger.info(
|
242
263
|
f"Using Python version {python_version} from the config file to build the Dockerfile")
|
243
264
|
else:
|
244
265
|
logger.info(
|
245
|
-
f"Python version not found in the config file, using default Python version: {
|
266
|
+
f"Python version not found in the config file, using default Python version: {DEFAULT_PYTHON_VERSION}"
|
246
267
|
)
|
247
|
-
python_version =
|
268
|
+
python_version = DEFAULT_PYTHON_VERSION
|
248
269
|
|
249
|
-
base_image =
|
270
|
+
base_image = PYTHON_BASE_IMAGE.format(python_version=python_version)
|
250
271
|
|
251
272
|
# Parse the requirements.txt file to determine the base image
|
252
273
|
dependencies = self._parse_requirements()
|
253
274
|
if 'torch' in dependencies and dependencies['torch']:
|
254
275
|
torch_version = dependencies['torch']
|
255
276
|
|
256
|
-
for image in
|
277
|
+
for image in AVAILABLE_TORCH_IMAGES:
|
257
278
|
if torch_version in image and f'py{python_version}' in image:
|
258
|
-
|
279
|
+
cuda_version = image.split('-')[-1].replace('cuda', '')
|
280
|
+
base_image = TORCH_BASE_IMAGE.format(
|
259
281
|
torch_version=torch_version,
|
260
282
|
python_version=python_version,
|
261
|
-
cuda_version=
|
262
|
-
|
283
|
+
cuda_version=cuda_version,
|
284
|
+
)
|
285
|
+
logger.info(f"Using Torch version {torch_version} base image to build the Docker image")
|
263
286
|
break
|
264
287
|
|
265
288
|
# Replace placeholders with actual values
|
@@ -296,6 +319,7 @@ class ModelUploader:
|
|
296
319
|
|
297
320
|
if not success:
|
298
321
|
logger.error(f"Failed to download checkpoints for model {repo_id}")
|
322
|
+
sys.exit(1)
|
299
323
|
else:
|
300
324
|
logger.info(f"Downloaded checkpoints for model {repo_id}")
|
301
325
|
return success
|
@@ -314,7 +338,7 @@ class ModelUploader:
|
|
314
338
|
config = yaml.safe_load(file)
|
315
339
|
model = config.get('model')
|
316
340
|
model_type_id = model.get('model_type_id')
|
317
|
-
assert model_type_id in
|
341
|
+
assert model_type_id in CONCEPTS_REQUIRED_MODEL_TYPE, f"Model type {model_type_id} not supported for concepts"
|
318
342
|
concept_protos = self._concepts_protos_from_concepts(labels)
|
319
343
|
|
320
344
|
config['concepts'] = [{'id': concept.id, 'name': concept.name} for concept in concept_protos]
|
@@ -332,7 +356,7 @@ class ModelUploader:
|
|
332
356
|
)
|
333
357
|
|
334
358
|
model_type_id = self.config.get('model').get('model_type_id')
|
335
|
-
if model_type_id in
|
359
|
+
if model_type_id in CONCEPTS_REQUIRED_MODEL_TYPE:
|
336
360
|
|
337
361
|
if 'concepts' in self.config:
|
338
362
|
labels = self.config.get('concepts')
|
@@ -347,7 +371,10 @@ class ModelUploader:
|
|
347
371
|
labels = sorted(labels.items(), key=lambda x: int(x[0]))
|
348
372
|
|
349
373
|
config_file = os.path.join(self.folder, 'config.yaml')
|
350
|
-
|
374
|
+
try:
|
375
|
+
self.hf_labels_to_config(labels, config_file)
|
376
|
+
except Exception as e:
|
377
|
+
logger.error(f"Failed to update the config.yaml file with the concepts: {e}")
|
351
378
|
|
352
379
|
model_version_proto.output_info.data.concepts.extend(
|
353
380
|
self._concepts_protos_from_concepts(labels))
|
@@ -359,7 +386,7 @@ class ModelUploader:
|
|
359
386
|
|
360
387
|
model_type_id = self.config.get('model').get('model_type_id')
|
361
388
|
|
362
|
-
if (model_type_id in
|
389
|
+
if (model_type_id in CONCEPTS_REQUIRED_MODEL_TYPE) and 'concepts' not in self.config:
|
363
390
|
logger.info(
|
364
391
|
f"Model type {model_type_id} requires concepts to be specified in the config.yaml file.."
|
365
392
|
)
|
@@ -387,10 +414,10 @@ class ModelUploader:
|
|
387
414
|
model_version_proto = self.get_model_version_proto()
|
388
415
|
|
389
416
|
if download_checkpoints:
|
390
|
-
tar_cmd = f"tar --exclude=*~ -czvf {self.tar_file} -C {self.folder} ."
|
417
|
+
tar_cmd = f"tar --exclude=*~ --exclude={self.tar_file} -czvf {self.tar_file} -C {self.folder} ."
|
391
418
|
else: # we don't want to send the checkpoints up even if they are in the folder.
|
392
419
|
logger.info(f"Skipping {self.checkpoint_path} in the tar file that is uploaded.")
|
393
|
-
tar_cmd = f"tar --exclude={self.checkpoint_suffix} --exclude=*~ -czvf {self.tar_file} -C {self.folder} ."
|
420
|
+
tar_cmd = f"tar --exclude={self.checkpoint_suffix} --exclude=*~ --exclude={self.tar_file} -czvf {self.tar_file} -C {self.folder} ."
|
394
421
|
# Tar the folder
|
395
422
|
logger.debug(tar_cmd)
|
396
423
|
os.system(tar_cmd)
|
@@ -400,6 +427,9 @@ class ModelUploader:
|
|
400
427
|
logger.info(f"Size of the tar is: {file_size} bytes")
|
401
428
|
|
402
429
|
self.maybe_create_model()
|
430
|
+
if not self.check_model_exists():
|
431
|
+
logger.error(f"Failed to create model: {self.model_proto.id}")
|
432
|
+
sys.exit(1)
|
403
433
|
|
404
434
|
for response in self.client.STUB.PostModelVersionsUpload(
|
405
435
|
self.model_version_stream_upload_iterator(model_version_proto, file_path),):
|
@@ -464,7 +494,7 @@ class ModelUploader:
|
|
464
494
|
file_size = os.path.getsize(file_path)
|
465
495
|
logger.info(f"Uploading model version of model {self.model_proto.id}")
|
466
496
|
logger.info(f"Using file '{os.path.basename(file_path)}' of size: {file_size} bytes")
|
467
|
-
|
497
|
+
result = service_pb2.PostModelVersionsUploadRequest(
|
468
498
|
upload_config=service_pb2.PostModelVersionsUploadConfig(
|
469
499
|
user_app_id=self.client.user_app_id,
|
470
500
|
model_id=self.model_proto.id,
|
@@ -472,9 +502,23 @@ class ModelUploader:
|
|
472
502
|
total_size=file_size,
|
473
503
|
is_v3=self.is_v3,
|
474
504
|
))
|
505
|
+
return result
|
506
|
+
|
507
|
+
def get_model_build_logs(self):
|
508
|
+
logs_request = service_pb2.ListLogEntriesRequest(
|
509
|
+
log_type="builder",
|
510
|
+
user_app_id=self.client.user_app_id,
|
511
|
+
model_id=self.model_proto.id,
|
512
|
+
model_version_id=self.model_version_id,
|
513
|
+
page=1,
|
514
|
+
per_page=50)
|
515
|
+
response = self.client.STUB.ListLogEntries(logs_request)
|
516
|
+
|
517
|
+
return response
|
475
518
|
|
476
519
|
def monitor_model_build(self):
|
477
520
|
st = time.time()
|
521
|
+
seen_logs = set() # To avoid duplicate log messages
|
478
522
|
while True:
|
479
523
|
resp = self.client.STUB.GetModelVersion(
|
480
524
|
service_pb2.GetModelVersionRequest(
|
@@ -485,6 +529,13 @@ class ModelUploader:
|
|
485
529
|
status_code = resp.model_version.status.code
|
486
530
|
if status_code == status_code_pb2.MODEL_BUILDING:
|
487
531
|
print(f"Model is building... (elapsed {time.time() - st:.1f}s)", end='\r', flush=True)
|
532
|
+
|
533
|
+
# Fetch and display the logs
|
534
|
+
logs = self.get_model_build_logs()
|
535
|
+
for log_entry in logs.log_entries:
|
536
|
+
if log_entry.url not in seen_logs:
|
537
|
+
seen_logs.add(log_entry.url)
|
538
|
+
print(f"Model Building Logs...: {escape(log_entry.message.strip())}")
|
488
539
|
time.sleep(1)
|
489
540
|
elif status_code == status_code_pb2.MODEL_TRAINED:
|
490
541
|
logger.info(f"\nModel build complete! (elapsed {time.time() - st:.1f}s)")
|
clarifai/runners/server.py
CHANGED
@@ -108,6 +108,7 @@ def main():
|
|
108
108
|
runner_id="n/a",
|
109
109
|
nodepool_id="n/a",
|
110
110
|
compute_cluster_id="n/a",
|
111
|
+
user_id="n/a",
|
111
112
|
health_check_port=None, # not needed when running local server
|
112
113
|
)
|
113
114
|
|
@@ -127,6 +128,7 @@ def main():
|
|
127
128
|
service_pb2_grpc.add_V2Servicer_to_server(servicer, server)
|
128
129
|
server.start()
|
129
130
|
logger.info("Started server on port %s", parsed_args.port)
|
131
|
+
logger.info(f"Access the model at http://localhost:{parsed_args.port}")
|
130
132
|
server.wait_for_termination()
|
131
133
|
else: # start the runner with the proper env variables and as a runner protocol.
|
132
134
|
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,42 @@
|
|
1
|
+
import os
|
2
|
+
|
3
|
+
registry = os.environ.get('CLARIFAI_BASE_IMAGE_REGISTRY', 'public.ecr.aws/clarifai-models')
|
4
|
+
|
5
|
+
PYTHON_BASE_IMAGE = registry + '/python-base:{python_version}'
|
6
|
+
TORCH_BASE_IMAGE = registry + '/torch:{torch_version}-py{python_version}-cuda{cuda_version}'
|
7
|
+
|
8
|
+
# List of available python base images
|
9
|
+
AVAILABLE_PYTHON_IMAGES = ['3.11', '3.12', '3.13']
|
10
|
+
|
11
|
+
DEFAULT_PYTHON_VERSION = 3.12
|
12
|
+
|
13
|
+
# List of available torch images
|
14
|
+
AVAILABLE_TORCH_IMAGES = [
|
15
|
+
'2.2.2-py3.11-cuda121',
|
16
|
+
'2.3.1-py3.11-cuda121',
|
17
|
+
'2.4.0-py3.11-cuda121',
|
18
|
+
'2.4.0-py3.11-cuda124',
|
19
|
+
'2.4.1-py3.11-cuda121',
|
20
|
+
'2.4.1-py3.11-cuda124',
|
21
|
+
'2.5.1-py3.11-cuda121',
|
22
|
+
'2.5.1-py3.11-cuda124',
|
23
|
+
'2.2.2-py3.12-cuda121',
|
24
|
+
'2.3.1-py3.12-cuda121',
|
25
|
+
'2.4.0-py3.12-cuda121',
|
26
|
+
'2.4.0-py3.12-cuda124',
|
27
|
+
'2.4.1-py3.12-cuda121',
|
28
|
+
'2.4.1-py3.12-cuda124',
|
29
|
+
'2.5.1-py3.12-cuda121',
|
30
|
+
'2.5.1-py3.12-cuda124',
|
31
|
+
# '2.2.2-py3.13-cuda121',
|
32
|
+
# '2.3.1-py3.13-cuda121',
|
33
|
+
# '2.4.0-py3.13-cuda121',
|
34
|
+
# '2.4.0-py3.13-cuda124',
|
35
|
+
# '2.4.1-py3.13-cuda121',
|
36
|
+
# '2.4.1-py3.13-cuda124',
|
37
|
+
# '2.5.1-py3.13-cuda121',
|
38
|
+
# '2.5.1-py3.13-cuda124',
|
39
|
+
]
|
40
|
+
CONCEPTS_REQUIRED_MODEL_TYPE = [
|
41
|
+
'visual-classifier', 'visual-detector', 'visual-segmenter', 'text-classifier'
|
42
|
+
]
|
clarifai/runners/utils/loader.py
CHANGED
@@ -14,26 +14,32 @@ class HuggingFaceLoader:
|
|
14
14
|
self.repo_id = repo_id
|
15
15
|
self.token = token
|
16
16
|
if token:
|
17
|
-
|
18
|
-
if importlib.util.find_spec("huggingface_hub") is None:
|
19
|
-
raise ImportError(self.HF_DOWNLOAD_TEXT)
|
20
|
-
os.environ['HF_TOKEN'] = token
|
21
|
-
from huggingface_hub import HfApi
|
22
|
-
|
23
|
-
api = HfApi()
|
24
|
-
api.whoami(token=token)
|
25
|
-
|
17
|
+
if self.validate_hftoken(token):
|
26
18
|
subprocess.run(f'huggingface-cli login --token={os.environ["HF_TOKEN"]}', shell=True)
|
27
|
-
|
28
|
-
|
29
|
-
f"Error setting up Hugging Face token, please make sure you have the correct token: {e}"
|
30
|
-
)
|
19
|
+
logger.info("Hugging Face token validated")
|
20
|
+
else:
|
31
21
|
logger.info("Continuing without Hugging Face token")
|
32
22
|
|
23
|
+
@classmethod
|
24
|
+
def validate_hftoken(cls, hf_token: str):
|
25
|
+
try:
|
26
|
+
if importlib.util.find_spec("huggingface_hub") is None:
|
27
|
+
raise ImportError(cls.HF_DOWNLOAD_TEXT)
|
28
|
+
os.environ['HF_TOKEN'] = hf_token
|
29
|
+
from huggingface_hub import HfApi
|
30
|
+
|
31
|
+
api = HfApi()
|
32
|
+
api.whoami(token=hf_token)
|
33
|
+
return True
|
34
|
+
except Exception as e:
|
35
|
+
logger.error(
|
36
|
+
f"Error setting up Hugging Face token, please make sure you have the correct token: {e}")
|
37
|
+
return False
|
38
|
+
|
33
39
|
def download_checkpoints(self, checkpoint_path: str):
|
34
40
|
# throw error if huggingface_hub wasn't installed
|
35
41
|
try:
|
36
|
-
from huggingface_hub import snapshot_download
|
42
|
+
from huggingface_hub import list_repo_files, snapshot_download
|
37
43
|
except ImportError:
|
38
44
|
raise ImportError(self.HF_DOWNLOAD_TEXT)
|
39
45
|
if os.path.exists(checkpoint_path) and self.validate_download(checkpoint_path):
|
@@ -46,10 +52,19 @@ class HuggingFaceLoader:
|
|
46
52
|
if not is_hf_model_exists:
|
47
53
|
logger.error("Model %s not found on Hugging Face" % (self.repo_id))
|
48
54
|
return False
|
55
|
+
|
56
|
+
ignore_patterns = None # Download everything.
|
57
|
+
repo_files = list_repo_files(repo_id=self.repo_id, token=self.token)
|
58
|
+
if any(f.endswith(".safetensors") for f in repo_files):
|
59
|
+
logger.info(f"SafeTensors found in {self.repo_id}, downloading only .safetensors files.")
|
60
|
+
ignore_patterns = ["**/original/*", "**/*.pth", "**/*.bin"]
|
49
61
|
snapshot_download(
|
50
|
-
repo_id=self.repo_id,
|
62
|
+
repo_id=self.repo_id,
|
63
|
+
local_dir=checkpoint_path,
|
64
|
+
local_dir_use_symlinks=False,
|
65
|
+
ignore_patterns=ignore_patterns)
|
51
66
|
except Exception as e:
|
52
|
-
logger.
|
67
|
+
logger.error(f"Error downloading model checkpoints {e}")
|
53
68
|
return False
|
54
69
|
finally:
|
55
70
|
is_downloaded = self.validate_download(checkpoint_path)
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
clarifai/utils/logging.py
CHANGED
@@ -282,6 +282,11 @@ class JsonFormatter(logging.Formatter):
|
|
282
282
|
except Exception:
|
283
283
|
self.source_host = ""
|
284
284
|
|
285
|
+
self.extra_blacklist_fields = []
|
286
|
+
extra_blacklist_fields = os.getenv('EXTRA_JSON_LOGGER_BLACKLIST_FIELDS', None)
|
287
|
+
if extra_blacklist_fields:
|
288
|
+
self.extra_blacklist_fields = extra_blacklist_fields.split(",")
|
289
|
+
|
285
290
|
def _build_fields(self, defaults, fields):
|
286
291
|
"""Return provided fields including any in defaults
|
287
292
|
"""
|
@@ -302,6 +307,8 @@ class JsonFormatter(logging.Formatter):
|
|
302
307
|
msg = record.getMessage()
|
303
308
|
for k in FIELD_BLACKLIST:
|
304
309
|
fields.pop(k, None)
|
310
|
+
for k in self.extra_blacklist_fields:
|
311
|
+
fields.pop(k, None)
|
305
312
|
# Rename 'levelname' to 'level' and make the value lowercase to match Go logs
|
306
313
|
level = fields.pop('levelname', None)
|
307
314
|
if level:
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: clarifai
|
3
|
-
Version: 10.11.
|
3
|
+
Version: 10.11.2rc1
|
4
4
|
Summary: Clarifai Python SDK
|
5
5
|
Home-page: https://github.com/Clarifai/clarifai-python
|
6
6
|
Author: Clarifai
|
@@ -20,22 +20,21 @@ 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>=
|
24
|
-
Requires-Dist: clarifai-protocol>=0.0.
|
25
|
-
Requires-Dist: numpy>=1.22.0
|
26
|
-
Requires-Dist: tqdm>=4.65.0
|
27
|
-
Requires-Dist: tritonclient>=2.34.0
|
28
|
-
Requires-Dist: rich>=13.4.2
|
29
|
-
Requires-Dist: PyYAML>=6.0.1
|
30
|
-
Requires-Dist: schema==0.7.5
|
31
|
-
Requires-Dist: Pillow>=9.5.0
|
32
|
-
Requires-Dist: inquirerpy==0.3.4
|
33
|
-
Requires-Dist: tabulate>=0.9.0
|
34
|
-
Requires-Dist:
|
35
|
-
Requires-Dist:
|
36
|
-
Requires-Dist: click==8.1.7
|
23
|
+
Requires-Dist: clarifai-grpc >=11.0.0
|
24
|
+
Requires-Dist: clarifai-protocol >=0.0.14
|
25
|
+
Requires-Dist: numpy >=1.22.0
|
26
|
+
Requires-Dist: tqdm >=4.65.0
|
27
|
+
Requires-Dist: tritonclient >=2.34.0
|
28
|
+
Requires-Dist: rich >=13.4.2
|
29
|
+
Requires-Dist: PyYAML >=6.0.1
|
30
|
+
Requires-Dist: schema ==0.7.5
|
31
|
+
Requires-Dist: Pillow >=9.5.0
|
32
|
+
Requires-Dist: inquirerpy ==0.3.4
|
33
|
+
Requires-Dist: tabulate >=0.9.0
|
34
|
+
Requires-Dist: fsspec ==2024.6.1
|
35
|
+
Requires-Dist: click ==8.1.7
|
37
36
|
Provides-Extra: all
|
38
|
-
Requires-Dist: pycocotools==2.0.6; extra ==
|
37
|
+
Requires-Dist: pycocotools ==2.0.6 ; extra == 'all'
|
39
38
|
|
40
39
|
<h1 align="center">
|
41
40
|
<a href="https://www.clarifai.com/"><img alt="Clarifai" title="Clarifai" src="https://github.com/user-attachments/assets/623b883b-7fe5-4b95-bbfa-8691f5779af4"></a>
|
@@ -73,6 +72,10 @@ Give the repo a star ⭐
|
|
73
72
|
|
74
73
|
* **[Installation](#rocket-installation)**
|
75
74
|
* **[Getting Started](#memo-getting-started)**
|
75
|
+
* **[Compute Orchestration](#rocket-compute-orchestration)**
|
76
|
+
* [Cluster Operations](#cluster-operations)
|
77
|
+
* [Nodepool Operations](#nodepool-operations)
|
78
|
+
* [Depolyment Operations](#deployment-operations)
|
76
79
|
* **[Interacting with Datasets](#floppy_disk-interacting-with-datasets)**
|
77
80
|
* **[Interacting with Inputs](#floppy_disk-interacting-with-inputs)**
|
78
81
|
* [Input Upload](#input-upload)
|
@@ -157,6 +160,73 @@ client = User(user_id="user_id", pat="your personal access token")
|
|
157
160
|
```
|
158
161
|
|
159
162
|
|
163
|
+
## :rocket: Compute Orchestration
|
164
|
+
|
165
|
+
Clarifai’s Compute Orchestration offers a streamlined solution for managing the infrastructure required for training, deploying, and scaling machine learning models and workflows.
|
166
|
+
|
167
|
+
This flexible system supports any compute instance — across various hardware providers and deployment methods — and provides automatic scaling to match workload demands. [More Details](https://www.clarifai.com/products/compute-orchestration)
|
168
|
+
|
169
|
+
#### Cluster Operations
|
170
|
+
```python
|
171
|
+
from clarifai.client.user import User
|
172
|
+
client = User(user_id="user_id",base_url="https://api.clarifai.com")
|
173
|
+
|
174
|
+
# Create a new compute cluster
|
175
|
+
compute_cluster = client.create_compute_cluster(compute_cluster_id="demo-id",config_filepath="computer_cluster_config.yaml")
|
176
|
+
|
177
|
+
# List Clusters
|
178
|
+
all_compute_clusters = list(client.list_compute_clusters())
|
179
|
+
print(all_compute_clusters)
|
180
|
+
```
|
181
|
+
##### [Example Cluster Config](https://github.com/Clarifai/examples/blob/main/ComputeOrchestration/configs/compute_cluster_config.yaml)
|
182
|
+
|
183
|
+
|
184
|
+
|
185
|
+
#### Nodepool Operations
|
186
|
+
```python
|
187
|
+
from clarifai.client.compute_cluster import ComputeCluster
|
188
|
+
|
189
|
+
# Initialize the ComputeCluster instance
|
190
|
+
compute_cluster = ComputeCluster(user_id="user_id",compute_cluster_id="demo-id")
|
191
|
+
|
192
|
+
# Create a new nodepool
|
193
|
+
nodepool = compute_cluster.create_nodepool(nodepool_id="demo-nodepool-id",config_filepath="nodepool_config.yaml")
|
194
|
+
|
195
|
+
#Get a nodepool
|
196
|
+
nodepool = compute_cluster.nodepool(nodepool_id="demo-nodepool-id")
|
197
|
+
print(nodepool)
|
198
|
+
|
199
|
+
# List nodepools
|
200
|
+
all_nodepools = list(compute_cluster.list_nodepools())
|
201
|
+
print(all_nodepools)
|
202
|
+
```
|
203
|
+
##### [Example Nodepool config](https://github.com/Clarifai/examples/blob/main/ComputeOrchestration/configs/nodepool_config.yaml)
|
204
|
+
|
205
|
+
#### Deployment Operations
|
206
|
+
```python
|
207
|
+
from clarifai.client.nodepool import Nodepool
|
208
|
+
|
209
|
+
# Initialize the Nodepool instance
|
210
|
+
nodepool = Nodepool(user_id="user_id",nodepool_id="demo-nodepool-id")
|
211
|
+
|
212
|
+
# Create a new deployment
|
213
|
+
deployment = nodepool.create_deployment(deployment_id="demo-deployment-id",config_filepath="deployment_config.yaml")
|
214
|
+
|
215
|
+
#Get a deployment
|
216
|
+
deployment = nodepool.deployment(nodepool_id="demo-deployment-id")
|
217
|
+
print(deployment)
|
218
|
+
|
219
|
+
# List deployments
|
220
|
+
all_deployments = list(nodepool.list_deployments())
|
221
|
+
print(all_deployments)
|
222
|
+
|
223
|
+
```
|
224
|
+
##### [Example Deployment config](https://github.com/Clarifai/examples/blob/main/ComputeOrchestration/configs/deployment_config.yaml)
|
225
|
+
|
226
|
+
#### Compute Orchestration CLI Operations
|
227
|
+
Refer Here: https://github.com/Clarifai/clarifai-python/tree/master/clarifai/cli
|
228
|
+
|
229
|
+
|
160
230
|
## :floppy_disk: Interacting with Datasets
|
161
231
|
|
162
232
|
Clarifai datasets help in managing datasets used for model training and evaluation. It provides functionalities like creating datasets,uploading datasets, retrying failed uploads from logs and exporting datasets as .zip files.
|