clarifai 11.0.6rc4__py3-none-any.whl → 11.0.7__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/cli/__main__.py +4 -0
- clarifai/cli/base.py +2 -1
- clarifai/cli/model.py +10 -2
- clarifai/runners/dockerfile_template/Dockerfile.template +25 -11
- clarifai/runners/models/model_run_locally.py +48 -18
- clarifai/runners/models/model_upload.py +51 -27
- clarifai/runners/utils/const.py +4 -18
- clarifai/runners/utils/loader.py +5 -3
- clarifai/utils/cli.py +1 -1
- clarifai/utils/logging.py +1 -1
- {clarifai-11.0.6rc4.dist-info → clarifai-11.0.7.dist-info}/METADATA +25 -16
- clarifai-11.0.7.dist-info/RECORD +101 -0
- {clarifai-11.0.6rc4.dist-info → clarifai-11.0.7.dist-info}/WHEEL +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/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/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/models/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/models/model_serving/README.md +0 -158
- clarifai/models/model_serving/__init__.py +0 -14
- 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 +0 -12
- 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 +0 -53
- clarifai/models/model_serving/cli/base.py +0 -14
- clarifai/models/model_serving/cli/build.py +0 -79
- clarifai/models/model_serving/cli/clarifai_clis.py +0 -33
- clarifai/models/model_serving/cli/create.py +0 -171
- clarifai/models/model_serving/cli/example_cli.py +0 -34
- clarifai/models/model_serving/cli/login.py +0 -26
- clarifai/models/model_serving/cli/upload.py +0 -183
- clarifai/models/model_serving/constants.py +0 -21
- clarifai/models/model_serving/docs/cli.md +0 -161
- clarifai/models/model_serving/docs/concepts.md +0 -229
- clarifai/models/model_serving/docs/dependencies.md +0 -11
- clarifai/models/model_serving/docs/inference_parameters.md +0 -139
- clarifai/models/model_serving/docs/model_types.md +0 -19
- clarifai/models/model_serving/model_config/__init__.py +0 -16
- 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 +0 -369
- clarifai/models/model_serving/model_config/config.py +0 -312
- clarifai/models/model_serving/model_config/inference_parameter.py +0 -129
- clarifai/models/model_serving/model_config/model_types_config/multimodal-embedder.yaml +0 -25
- clarifai/models/model_serving/model_config/model_types_config/text-classifier.yaml +0 -19
- clarifai/models/model_serving/model_config/model_types_config/text-embedder.yaml +0 -20
- clarifai/models/model_serving/model_config/model_types_config/text-to-image.yaml +0 -19
- clarifai/models/model_serving/model_config/model_types_config/text-to-text.yaml +0 -19
- clarifai/models/model_serving/model_config/model_types_config/visual-classifier.yaml +0 -22
- clarifai/models/model_serving/model_config/model_types_config/visual-detector.yaml +0 -32
- clarifai/models/model_serving/model_config/model_types_config/visual-embedder.yaml +0 -19
- clarifai/models/model_serving/model_config/model_types_config/visual-segmenter.yaml +0 -19
- clarifai/models/model_serving/model_config/output.py +0 -133
- clarifai/models/model_serving/model_config/triton/__init__.py +0 -14
- 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 +0 -136
- clarifai/models/model_serving/model_config/triton/triton_config.py +0 -182
- clarifai/models/model_serving/model_config/triton/wrappers.py +0 -281
- clarifai/models/model_serving/repo_build/__init__.py +0 -14
- 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 +0 -198
- 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 +0 -2
- clarifai/models/model_serving/repo_build/static_files/base_test.py +0 -169
- clarifai/models/model_serving/repo_build/static_files/inference.py +0 -26
- clarifai/models/model_serving/repo_build/static_files/sample_clarifai_config.yaml +0 -25
- clarifai/models/model_serving/repo_build/static_files/test.py +0 -40
- clarifai/models/model_serving/repo_build/static_files/triton/model.py +0 -75
- clarifai/models/model_serving/utils.py +0 -31
- 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/runners/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/runners/__pycache__/server.cpython-310.pyc +0 -0
- clarifai/runners/deepgram_live_transcribe.py +0 -98
- clarifai/runners/deepgram_live_transcribe.py~ +0 -98
- clarifai/runners/deepgram_runner.py +0 -131
- clarifai/runners/deepgram_runner.py~ +0 -130
- clarifai/runners/dockerfile_template/Dockerfile.cpu.template +0 -31
- clarifai/runners/dockerfile_template/Dockerfile.cuda.template +0 -79
- clarifai/runners/example_llama2.py~ +0 -72
- clarifai/runners/matt_example.py +0 -89
- clarifai/runners/matt_example.py~ +0 -87
- clarifai/runners/matt_llm_example.py +0 -129
- clarifai/runners/matt_llm_example.py~ +0 -128
- 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/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/logging.py +0 -6
- 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/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-11.0.6rc4.dist-info/RECORD +0 -242
- {clarifai-11.0.6rc4.dist-info → clarifai-11.0.7.dist-info}/LICENSE +0 -0
- {clarifai-11.0.6rc4.dist-info → clarifai-11.0.7.dist-info}/entry_points.txt +0 -0
- {clarifai-11.0.6rc4.dist-info → clarifai-11.0.7.dist-info}/top_level.txt +0 -0
clarifai/__init__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "11.0.
|
1
|
+
__version__ = "11.0.7"
|
clarifai/cli/__main__.py
ADDED
clarifai/cli/base.py
CHANGED
clarifai/cli/model.py
CHANGED
@@ -39,12 +39,20 @@ def upload(model_path, download_checkpoints, skip_dockerfile):
|
|
39
39
|
type=click.Path(exists=True),
|
40
40
|
required=True,
|
41
41
|
help='Path to the model directory.')
|
42
|
-
|
42
|
+
@click.option(
|
43
|
+
'--out_path',
|
44
|
+
type=click.Path(exists=False),
|
45
|
+
required=False,
|
46
|
+
default=None,
|
47
|
+
help=
|
48
|
+
'Option path to write the checkpoints to. This will place them in {out_path}/ If not provided it will default to {model_path}/1/checkpoints where the config.yaml is read..'
|
49
|
+
)
|
50
|
+
def download_checkpoints(model_path, out_path):
|
43
51
|
"""Download checkpoints from external source to local model_path"""
|
44
52
|
|
45
53
|
from clarifai.runners.models.model_upload import ModelUploader
|
46
54
|
uploader = ModelUploader(model_path, download_validation_only=True)
|
47
|
-
uploader.download_checkpoints()
|
55
|
+
uploader.download_checkpoints(out_path)
|
48
56
|
|
49
57
|
|
50
58
|
@model.command()
|
@@ -2,7 +2,7 @@
|
|
2
2
|
#############################
|
3
3
|
# User specific requirements installed in the pip_packages
|
4
4
|
#############################
|
5
|
-
FROM --platform=$TARGETPLATFORM ${
|
5
|
+
FROM --platform=$TARGETPLATFORM ${BUILDER_IMAGE} as pip_packages
|
6
6
|
|
7
7
|
COPY --link requirements.txt /home/nonroot/requirements.txt
|
8
8
|
|
@@ -12,9 +12,19 @@ RUN pip install --no-cache-dir -r /home/nonroot/requirements.txt && \
|
|
12
12
|
#############################
|
13
13
|
|
14
14
|
#############################
|
15
|
-
#
|
15
|
+
# Downloader dependencies image
|
16
16
|
#############################
|
17
|
-
FROM --platform=$TARGETPLATFORM ${
|
17
|
+
FROM --platform=$TARGETPLATFORM ${DOWNLOADER_IMAGE} as downloader
|
18
|
+
|
19
|
+
# make sure we have the latest clarifai package.
|
20
|
+
RUN (pip install --upgrade --upgrade-strategy only-if-needed --no-cache-dir clarifai clarifai-grpc clarifai-protocol || true)
|
21
|
+
#####
|
22
|
+
|
23
|
+
|
24
|
+
#############################
|
25
|
+
# Final runtime image
|
26
|
+
#############################
|
27
|
+
FROM --platform=$TARGETPLATFORM ${RUNTIME_IMAGE} as final
|
18
28
|
|
19
29
|
# Set the NUMBA cache dir to /tmp
|
20
30
|
# Set the TORCHINDUCTOR cache dir to /tmp
|
@@ -24,26 +34,30 @@ ENV NUMBA_CACHE_DIR=/tmp/numba_cache \
|
|
24
34
|
HOME=/tmp \
|
25
35
|
DEBIAN_FRONTEND=noninteractive
|
26
36
|
|
27
|
-
|
28
|
-
|
37
|
+
#####
|
38
|
+
# Copy the python requirements needed to download checkpoints
|
39
|
+
#####
|
40
|
+
COPY --link=true --from=downloader /venv /venv
|
41
|
+
#####
|
29
42
|
|
30
43
|
#####
|
31
|
-
#
|
44
|
+
# Copy the files needed to download
|
32
45
|
#####
|
33
46
|
# This creates the directory that HF downloader will populate and with nonroot:nonroot permissions up.
|
34
47
|
COPY --chown=nonroot:nonroot downloader/unused.yaml /home/nonroot/main/1/checkpoints/.cache/unused.yaml
|
35
48
|
|
36
|
-
|
37
|
-
#
|
38
|
-
|
39
|
-
RUN
|
49
|
+
#####
|
50
|
+
# Download checkpoints
|
51
|
+
COPY --link=true config.yaml /home/nonroot/main/
|
52
|
+
RUN ["python", "-m", "clarifai.cli", "model", "download-checkpoints", "--model_path", "/home/nonroot/main", "--out_path", "/home/nonroot/main"]
|
40
53
|
#####
|
41
54
|
|
55
|
+
|
42
56
|
#####
|
43
57
|
# Copy the python packages from the previous stage.
|
44
|
-
#####
|
45
58
|
COPY --link=true --from=pip_packages /venv /venv
|
46
59
|
#####
|
60
|
+
|
47
61
|
# Copy in the actual files like config.yaml, requirements.txt, and most importantly 1/model.py
|
48
62
|
# for the actual model.
|
49
63
|
# If checkpoints aren't downloaded since a checkpoints: block is not provided, then they will
|
@@ -2,6 +2,7 @@ import hashlib
|
|
2
2
|
import importlib.util
|
3
3
|
import inspect
|
4
4
|
import os
|
5
|
+
import platform
|
5
6
|
import shutil
|
6
7
|
import signal
|
7
8
|
import subprocess
|
@@ -27,7 +28,7 @@ class ModelRunLocally:
|
|
27
28
|
self.requirements_file = os.path.join(self.model_path, "requirements.txt")
|
28
29
|
|
29
30
|
# ModelUploader contains multiple useful methods to interact with the model
|
30
|
-
self.uploader = ModelUploader(self.model_path)
|
31
|
+
self.uploader = ModelUploader(self.model_path, download_validation_only=True)
|
31
32
|
self.config = self.uploader.config
|
32
33
|
|
33
34
|
def _requirements_hash(self):
|
@@ -35,6 +36,23 @@ class ModelRunLocally:
|
|
35
36
|
with open(self.requirements_file, "r") as f:
|
36
37
|
return hashlib.md5(f.read().encode('utf-8')).hexdigest()
|
37
38
|
|
39
|
+
def _get_env_executable(self):
|
40
|
+
"""Get the python executable from the virtual environment."""
|
41
|
+
# Depending on the platform, venv scripts are placed in either "Scripts" (Windows) or "bin" (Linux/Mac)
|
42
|
+
if platform.system().lower().startswith("win"):
|
43
|
+
scripts_folder = "Scripts"
|
44
|
+
python_exe = "python.exe"
|
45
|
+
pip_exe = "pip.exe"
|
46
|
+
else:
|
47
|
+
scripts_folder = "bin"
|
48
|
+
python_exe = "python"
|
49
|
+
pip_exe = "pip"
|
50
|
+
|
51
|
+
self.python_executable = os.path.join(self.venv_dir, scripts_folder, python_exe)
|
52
|
+
self.pip_executable = os.path.join(self.venv_dir, scripts_folder, pip_exe)
|
53
|
+
|
54
|
+
return self.python_executable, self.pip_executable
|
55
|
+
|
38
56
|
def create_temp_venv(self):
|
39
57
|
"""Create a temporary virtual environment."""
|
40
58
|
requirements_hash = self._requirements_hash()
|
@@ -53,13 +71,13 @@ class ModelRunLocally:
|
|
53
71
|
|
54
72
|
self.venv_dir = venv_dir
|
55
73
|
self.temp_dir = temp_dir
|
56
|
-
self.python_executable =
|
74
|
+
self.python_executable, self.pip_executable = self._get_env_executable()
|
57
75
|
|
58
76
|
return use_existing_venv
|
59
77
|
|
60
78
|
def install_requirements(self):
|
61
79
|
"""Install the dependencies from requirements.txt and Clarifai."""
|
62
|
-
pip_executable =
|
80
|
+
_, pip_executable = self._get_env_executable()
|
63
81
|
try:
|
64
82
|
logger.info(
|
65
83
|
f"Installing requirements from {self.requirements_file}... in the virtual environment {self.venv_dir}"
|
@@ -104,8 +122,7 @@ class ModelRunLocally:
|
|
104
122
|
def _build_request(self):
|
105
123
|
"""Create a mock inference request for testing the model."""
|
106
124
|
|
107
|
-
|
108
|
-
model_version_proto = uploader.get_model_version_proto()
|
125
|
+
model_version_proto = self.uploader.get_model_version_proto()
|
109
126
|
model_version_proto.id = "model_version"
|
110
127
|
|
111
128
|
return service_pb2.PostModelOutputsRequest(
|
@@ -213,12 +230,16 @@ class ModelRunLocally:
|
|
213
230
|
|
214
231
|
def test_model(self):
|
215
232
|
"""Test the model by running it locally in the virtual environment."""
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
233
|
+
|
234
|
+
import_path = repr(os.path.dirname(os.path.abspath(__file__)))
|
235
|
+
model_path = repr(self.model_path)
|
236
|
+
|
237
|
+
command_string = (f"import sys; "
|
238
|
+
f"sys.path.append({import_path}); "
|
239
|
+
f"from model_run_locally import ModelRunLocally; "
|
240
|
+
f"ModelRunLocally({model_path})._run_test()")
|
241
|
+
|
242
|
+
command = [self.python_executable, "-c", command_string]
|
222
243
|
process = None
|
223
244
|
try:
|
224
245
|
logger.info("Testing the model locally...")
|
@@ -335,6 +356,12 @@ class ModelRunLocally:
|
|
335
356
|
logger.info(f"Docker image '{image_name}' does not exist!")
|
336
357
|
return False
|
337
358
|
|
359
|
+
def _gpu_is_available(self):
|
360
|
+
"""
|
361
|
+
Checks if nvidia-smi is available, indicating a GPU is likely accessible.
|
362
|
+
"""
|
363
|
+
return shutil.which("nvidia-smi") is not None
|
364
|
+
|
338
365
|
def run_docker_container(self,
|
339
366
|
image_name,
|
340
367
|
container_name="clarifai-model-container",
|
@@ -344,9 +371,9 @@ class ModelRunLocally:
|
|
344
371
|
try:
|
345
372
|
logger.info(f"Running Docker container '{container_name}' from image '{image_name}'...")
|
346
373
|
# Base docker run command
|
347
|
-
cmd = [
|
348
|
-
|
349
|
-
|
374
|
+
cmd = ["docker", "run", "--name", container_name, '--rm', "--network", "host"]
|
375
|
+
if self._gpu_is_available():
|
376
|
+
cmd.extend(["--gpus", "all"])
|
350
377
|
# Add volume mappings
|
351
378
|
cmd.extend(["-v", f"{self.model_path}:/app/model_dir/main"])
|
352
379
|
# Add environment variables
|
@@ -393,9 +420,9 @@ class ModelRunLocally:
|
|
393
420
|
try:
|
394
421
|
logger.info("Testing the model inside the Docker container...")
|
395
422
|
# Base docker run command
|
396
|
-
cmd = [
|
397
|
-
|
398
|
-
|
423
|
+
cmd = ["docker", "run", "--name", container_name, '--rm', "--network", "host"]
|
424
|
+
if self._gpu_is_available():
|
425
|
+
cmd.extend(["--gpus", "all"])
|
399
426
|
# update the entrypoint for testing the model
|
400
427
|
cmd.extend(["--entrypoint", "python"])
|
401
428
|
# Add volume mappings
|
@@ -502,7 +529,10 @@ def main(model_path,
|
|
502
529
|
if not manager.docker_image_exists(image_name):
|
503
530
|
manager.build_docker_image(image_name=image_name)
|
504
531
|
try:
|
505
|
-
envs = {
|
532
|
+
envs = {
|
533
|
+
'CLARIFAI_PAT': os.environ['CLARIFAI_PAT'],
|
534
|
+
'CLARIFAI_API_BASE': os.environ.get('CLARIFAI_API_BASE', 'https://api.clarifai.com')
|
535
|
+
}
|
506
536
|
if run_model_server:
|
507
537
|
manager.run_docker_container(
|
508
538
|
image_name=image_name, container_name=container_name, port=port, env_vars=envs)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import os
|
2
2
|
import re
|
3
3
|
import sys
|
4
|
+
import tarfile
|
4
5
|
import time
|
5
6
|
from string import Template
|
6
7
|
|
@@ -12,9 +13,9 @@ from rich import print
|
|
12
13
|
from rich.markup import escape
|
13
14
|
|
14
15
|
from clarifai.client import BaseClient
|
15
|
-
from clarifai.runners.utils.const import (
|
16
|
-
|
17
|
-
|
16
|
+
from clarifai.runners.utils.const import (
|
17
|
+
AVAILABLE_PYTHON_IMAGES, AVAILABLE_TORCH_IMAGES, CONCEPTS_REQUIRED_MODEL_TYPE,
|
18
|
+
DEFAULT_PYTHON_VERSION, PYTHON_BUILDER_IMAGE, PYTHON_RUNTIME_IMAGE, TORCH_BASE_IMAGE)
|
18
19
|
from clarifai.runners.utils.loader import HuggingFaceLoader
|
19
20
|
from clarifai.urls.helper import ClarifaiUrlHelper
|
20
21
|
from clarifai.utils.logging import logger
|
@@ -54,7 +55,7 @@ class ModelUploader:
|
|
54
55
|
def _validate_folder(self, folder):
|
55
56
|
if folder == ".":
|
56
57
|
folder = "" # will getcwd() next which ends with /
|
57
|
-
if not
|
58
|
+
if not os.path.isabs(folder):
|
58
59
|
folder = os.path.join(os.getcwd(), folder)
|
59
60
|
logger.info(f"Validating folder: {folder}")
|
60
61
|
if not os.path.exists(folder):
|
@@ -246,6 +247,10 @@ class ModelUploader:
|
|
246
247
|
if match:
|
247
248
|
dependency = match.group('dependency')
|
248
249
|
version = match.group('version')
|
250
|
+
if dependency == "torch" and line.find(
|
251
|
+
'whl/cpu') > 0: # Ignore torch-cpu whl files, use base mage.
|
252
|
+
continue
|
253
|
+
|
249
254
|
deendencies_version[dependency] = version if version else None
|
250
255
|
return deendencies_version
|
251
256
|
|
@@ -278,7 +283,10 @@ class ModelUploader:
|
|
278
283
|
)
|
279
284
|
python_version = DEFAULT_PYTHON_VERSION
|
280
285
|
|
281
|
-
|
286
|
+
# This is always the final image used for runtime.
|
287
|
+
runtime_image = PYTHON_RUNTIME_IMAGE.format(python_version=python_version)
|
288
|
+
builder_image = PYTHON_BUILDER_IMAGE.format(python_version=python_version)
|
289
|
+
downloader_image = PYTHON_BUILDER_IMAGE.format(python_version=python_version)
|
282
290
|
|
283
291
|
# Parse the requirements.txt file to determine the base image
|
284
292
|
dependencies = self._parse_requirements()
|
@@ -289,20 +297,23 @@ class ModelUploader:
|
|
289
297
|
for image in sorted(AVAILABLE_TORCH_IMAGES, reverse=True):
|
290
298
|
if torch_version in image and f'py{python_version}' in image:
|
291
299
|
cuda_version = image.split('-')[-1].replace('cuda', '')
|
292
|
-
|
300
|
+
builder_image = TORCH_BASE_IMAGE.format(
|
293
301
|
torch_version=torch_version,
|
294
302
|
python_version=python_version,
|
295
303
|
cuda_version=cuda_version,
|
296
304
|
)
|
305
|
+
# download_image = base_image
|
297
306
|
logger.info(f"Using Torch version {torch_version} base image to build the Docker image")
|
298
307
|
break
|
299
|
-
else: # if not torch then use the download image for the base image too
|
300
|
-
|
308
|
+
# else: # if not torch then use the download image for the base image too
|
309
|
+
# # base_image = download_image
|
310
|
+
# requirements_image = base_image
|
301
311
|
# Replace placeholders with actual values
|
302
312
|
dockerfile_content = dockerfile_template.safe_substitute(
|
303
313
|
name='main',
|
304
|
-
|
305
|
-
|
314
|
+
BUILDER_IMAGE=builder_image, # for pip requirements
|
315
|
+
RUNTIME_IMAGE=runtime_image, # for runtime
|
316
|
+
DOWNLOADER_IMAGE=downloader_image, # for downloading checkpoints
|
306
317
|
)
|
307
318
|
|
308
319
|
# Write Dockerfile
|
@@ -311,7 +322,10 @@ class ModelUploader:
|
|
311
322
|
|
312
323
|
@property
|
313
324
|
def checkpoint_path(self):
|
314
|
-
return
|
325
|
+
return self._checkpoint_path(self.folder)
|
326
|
+
|
327
|
+
def _checkpoint_path(self, folder):
|
328
|
+
return os.path.join(folder, self.checkpoint_suffix)
|
315
329
|
|
316
330
|
@property
|
317
331
|
def checkpoint_suffix(self):
|
@@ -321,7 +335,14 @@ class ModelUploader:
|
|
321
335
|
def tar_file(self):
|
322
336
|
return f"{self.folder}.tar.gz"
|
323
337
|
|
324
|
-
def download_checkpoints(self):
|
338
|
+
def download_checkpoints(self, checkpoint_path_override: str = None):
|
339
|
+
"""
|
340
|
+
Downloads the checkpoints specified in the config file.
|
341
|
+
|
342
|
+
:param checkpoint_path_override: The path to download the checkpoints to. If not provided, the
|
343
|
+
default path is used based on the folder ModelUploader was initialized with. The
|
344
|
+
checkpoint_suffix will be appended to the path.
|
345
|
+
"""
|
325
346
|
if not self.config.get("checkpoints"):
|
326
347
|
logger.info("No checkpoints specified in the config file")
|
327
348
|
return True
|
@@ -331,7 +352,9 @@ class ModelUploader:
|
|
331
352
|
success = True
|
332
353
|
if loader_type == "huggingface":
|
333
354
|
loader = HuggingFaceLoader(repo_id=repo_id, token=hf_token)
|
334
|
-
|
355
|
+
path = self._checkpoint_path(
|
356
|
+
checkpoint_path_override) if checkpoint_path_override else self.checkpoint_path
|
357
|
+
success = loader.download_checkpoints(path)
|
335
358
|
|
336
359
|
if loader_type:
|
337
360
|
if not success:
|
@@ -431,14 +454,15 @@ class ModelUploader:
|
|
431
454
|
|
432
455
|
model_version_proto = self.get_model_version_proto()
|
433
456
|
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
457
|
+
def filter_func(tarinfo):
|
458
|
+
name = tarinfo.name
|
459
|
+
exclude = [self.tar_file, "*~"]
|
460
|
+
if not download_checkpoints:
|
461
|
+
exclude.append(self.checkpoint_suffix)
|
462
|
+
return None if any(name.endswith(ex) for ex in exclude) else tarinfo
|
463
|
+
|
464
|
+
with tarfile.open(self.tar_file, "w:gz") as tar:
|
465
|
+
tar.add(self.folder, arcname=".", filter=filter_func)
|
442
466
|
logger.info("Tarring complete, about to start upload.")
|
443
467
|
|
444
468
|
file_size = os.path.getsize(self.tar_file)
|
@@ -463,16 +487,16 @@ class ModelUploader:
|
|
463
487
|
f"request_id: {response.status.req_id}",
|
464
488
|
end='\r',
|
465
489
|
flush=True)
|
466
|
-
|
490
|
+
logger.info("")
|
467
491
|
if response.status.code != status_code_pb2.MODEL_BUILDING:
|
468
492
|
logger.error(f"Failed to upload model version: {response}")
|
469
493
|
return
|
470
494
|
self.model_version_id = response.model_version_id
|
471
495
|
logger.info(f"Created Model Version ID: {self.model_version_id}")
|
472
496
|
logger.info(f"Full url to that version is: {self.model_url}")
|
473
|
-
|
474
|
-
|
475
|
-
|
497
|
+
try:
|
498
|
+
self.monitor_model_build()
|
499
|
+
finally:
|
476
500
|
if os.path.exists(self.tar_file):
|
477
501
|
logger.info(f"Cleaning up upload file: {self.tar_file}")
|
478
502
|
os.remove(self.tar_file)
|
@@ -553,11 +577,11 @@ class ModelUploader:
|
|
553
577
|
for log_entry in logs.log_entries:
|
554
578
|
if log_entry.url not in seen_logs:
|
555
579
|
seen_logs.add(log_entry.url)
|
556
|
-
|
580
|
+
logger.info(f"{escape(log_entry.message.strip())}")
|
557
581
|
time.sleep(1)
|
558
582
|
elif status_code == status_code_pb2.MODEL_TRAINED:
|
559
583
|
logger.info(f"\nModel build complete! (elapsed {time.time() - st:.1f}s)")
|
560
|
-
logger.info(f"Check out the model at {self.model_url}")
|
584
|
+
logger.info(f"Check out the model at {self.model_url} version: {self.model_version_id}")
|
561
585
|
return True
|
562
586
|
else:
|
563
587
|
logger.info(
|
clarifai/runners/utils/const.py
CHANGED
@@ -2,40 +2,26 @@ import os
|
|
2
2
|
|
3
3
|
registry = os.environ.get('CLARIFAI_BASE_IMAGE_REGISTRY', 'public.ecr.aws/clarifai-models')
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
PYTHON_BUILDER_IMAGE = registry + '/python-base:builder-{python_version}'
|
6
|
+
PYTHON_RUNTIME_IMAGE = registry + '/python-base:runtime-{python_version}'
|
7
|
+
TORCH_BASE_IMAGE = registry + '/torch:builder-{torch_version}-py{python_version}-cuda{cuda_version}'
|
7
8
|
|
8
9
|
# List of available python base images
|
9
|
-
AVAILABLE_PYTHON_IMAGES = ['3.11', '3.12'
|
10
|
+
AVAILABLE_PYTHON_IMAGES = ['3.11', '3.12']
|
10
11
|
|
11
12
|
DEFAULT_PYTHON_VERSION = 3.12
|
12
13
|
|
13
14
|
# List of available torch images
|
14
15
|
# Keep sorted by most recent cuda version.
|
15
16
|
AVAILABLE_TORCH_IMAGES = [
|
16
|
-
'2.2.2-py3.11-cuda121',
|
17
|
-
'2.3.1-py3.11-cuda121',
|
18
17
|
'2.4.0-py3.11-cuda124',
|
19
|
-
'2.4.0-py3.11-cuda121',
|
20
18
|
'2.4.1-py3.11-cuda124',
|
21
|
-
'2.4.1-py3.11-cuda121',
|
22
19
|
'2.5.1-py3.11-cuda124',
|
23
|
-
'2.5.1-py3.11-cuda121',
|
24
|
-
'2.2.2-py3.12-cuda121',
|
25
|
-
'2.3.1-py3.12-cuda121',
|
26
20
|
'2.4.0-py3.12-cuda124',
|
27
|
-
'2.4.0-py3.12-cuda121',
|
28
21
|
'2.4.1-py3.12-cuda124',
|
29
|
-
'2.4.1-py3.12-cuda121',
|
30
22
|
'2.5.1-py3.12-cuda124',
|
31
|
-
'2.5.1-py3.12-cuda121',
|
32
|
-
# '2.2.2-py3.13-cuda121',
|
33
|
-
# '2.3.1-py3.13-cuda121',
|
34
|
-
# '2.4.0-py3.13-cuda121',
|
35
23
|
# '2.4.0-py3.13-cuda124',
|
36
|
-
# '2.4.1-py3.13-cuda121',
|
37
24
|
# '2.4.1-py3.13-cuda124',
|
38
|
-
# '2.5.1-py3.13-cuda121',
|
39
25
|
# '2.5.1-py3.13-cuda124',
|
40
26
|
]
|
41
27
|
CONCEPTS_REQUIRED_MODEL_TYPE = [
|
clarifai/runners/utils/loader.py
CHANGED
@@ -3,7 +3,6 @@ import importlib.util
|
|
3
3
|
import json
|
4
4
|
import os
|
5
5
|
import shutil
|
6
|
-
import subprocess
|
7
6
|
|
8
7
|
from clarifai.utils.logging import logger
|
9
8
|
|
@@ -17,7 +16,11 @@ class HuggingFaceLoader:
|
|
17
16
|
self.token = token
|
18
17
|
if token:
|
19
18
|
if self.validate_hftoken(token):
|
20
|
-
|
19
|
+
try:
|
20
|
+
from huggingface_hub import login
|
21
|
+
except ImportError:
|
22
|
+
raise ImportError(self.HF_DOWNLOAD_TEXT)
|
23
|
+
login(token=token)
|
21
24
|
logger.info("Hugging Face token validated")
|
22
25
|
else:
|
23
26
|
logger.info("Continuing without Hugging Face token")
|
@@ -44,7 +47,6 @@ class HuggingFaceLoader:
|
|
44
47
|
from huggingface_hub import snapshot_download
|
45
48
|
except ImportError:
|
46
49
|
raise ImportError(self.HF_DOWNLOAD_TEXT)
|
47
|
-
os.environ['HF_HUB_ENABLE_HF_TRANSFER'] = '1'
|
48
50
|
if os.path.exists(checkpoint_path) and self.validate_download(checkpoint_path):
|
49
51
|
logger.info("Checkpoints already exist")
|
50
52
|
return True
|
clarifai/utils/cli.py
CHANGED
@@ -46,7 +46,7 @@ def load_command_modules():
|
|
46
46
|
package_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'cli')
|
47
47
|
|
48
48
|
for _, module_name, _ in pkgutil.iter_modules([package_dir]):
|
49
|
-
if module_name
|
49
|
+
if module_name not in ['base', '__main__']: # Skip the base.py and __main__ file itself
|
50
50
|
importlib.import_module(f'clarifai.cli.{module_name}')
|
51
51
|
|
52
52
|
|
clarifai/utils/logging.py
CHANGED
@@ -144,7 +144,7 @@ def _configure_logger(name: str, logger_level: Union[int, str] = logging.NOTSET)
|
|
144
144
|
# Add the new rich handler and formatter
|
145
145
|
handler = RichHandler(
|
146
146
|
rich_tracebacks=True, log_time_format="%Y-%m-%d %H:%M:%S.%f", console=Console(width=255))
|
147
|
-
formatter = logging.Formatter('%(
|
147
|
+
formatter = logging.Formatter('%(message)s')
|
148
148
|
handler.setFormatter(formatter)
|
149
149
|
logger.addHandler(handler)
|
150
150
|
|
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.2
|
2
2
|
Name: clarifai
|
3
|
-
Version: 11.0.
|
3
|
+
Version: 11.0.7
|
4
4
|
Summary: Clarifai Python SDK
|
5
5
|
Home-page: https://github.com/Clarifai/clarifai-python
|
6
6
|
Author: Clarifai
|
@@ -20,21 +20,30 @@ 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
|
25
|
-
Requires-Dist: numpy
|
26
|
-
Requires-Dist: tqdm
|
27
|
-
Requires-Dist:
|
28
|
-
Requires-Dist:
|
29
|
-
Requires-Dist:
|
30
|
-
Requires-Dist:
|
31
|
-
Requires-Dist:
|
32
|
-
Requires-Dist:
|
33
|
-
Requires-Dist:
|
34
|
-
Requires-Dist: fsspec ==2024.6.1
|
35
|
-
Requires-Dist: click ==8.1.7
|
23
|
+
Requires-Dist: clarifai-grpc>=11.0.4
|
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: rich>=13.4.2
|
28
|
+
Requires-Dist: PyYAML>=6.0.1
|
29
|
+
Requires-Dist: schema==0.7.5
|
30
|
+
Requires-Dist: Pillow>=9.5.0
|
31
|
+
Requires-Dist: tabulate>=0.9.0
|
32
|
+
Requires-Dist: fsspec==2024.6.1
|
33
|
+
Requires-Dist: click==8.1.7
|
36
34
|
Provides-Extra: all
|
37
|
-
Requires-Dist: pycocotools
|
35
|
+
Requires-Dist: pycocotools==2.0.6; extra == "all"
|
36
|
+
Dynamic: author
|
37
|
+
Dynamic: author-email
|
38
|
+
Dynamic: classifier
|
39
|
+
Dynamic: description
|
40
|
+
Dynamic: description-content-type
|
41
|
+
Dynamic: home-page
|
42
|
+
Dynamic: license
|
43
|
+
Dynamic: provides-extra
|
44
|
+
Dynamic: requires-dist
|
45
|
+
Dynamic: requires-python
|
46
|
+
Dynamic: summary
|
38
47
|
|
39
48
|
<h1 align="center">
|
40
49
|
<a href="https://www.clarifai.com/"><img alt="Clarifai" title="Clarifai" src="https://github.com/user-attachments/assets/623b883b-7fe5-4b95-bbfa-8691f5779af4"></a>
|