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.
Files changed (160) hide show
  1. clarifai/__init__.py +1 -1
  2. clarifai/cli/__main__.py +4 -0
  3. clarifai/cli/base.py +2 -1
  4. clarifai/cli/model.py +10 -2
  5. clarifai/runners/dockerfile_template/Dockerfile.template +25 -11
  6. clarifai/runners/models/model_run_locally.py +48 -18
  7. clarifai/runners/models/model_upload.py +51 -27
  8. clarifai/runners/utils/const.py +4 -18
  9. clarifai/runners/utils/loader.py +5 -3
  10. clarifai/utils/cli.py +1 -1
  11. clarifai/utils/logging.py +1 -1
  12. {clarifai-11.0.6rc4.dist-info → clarifai-11.0.7.dist-info}/METADATA +25 -16
  13. clarifai-11.0.7.dist-info/RECORD +101 -0
  14. {clarifai-11.0.6rc4.dist-info → clarifai-11.0.7.dist-info}/WHEEL +1 -1
  15. clarifai/__pycache__/__init__.cpython-310.pyc +0 -0
  16. clarifai/__pycache__/errors.cpython-310.pyc +0 -0
  17. clarifai/__pycache__/versions.cpython-310.pyc +0 -0
  18. clarifai/cli/__pycache__/__init__.cpython-310.pyc +0 -0
  19. clarifai/cli/__pycache__/base.cpython-310.pyc +0 -0
  20. clarifai/cli/__pycache__/compute_cluster.cpython-310.pyc +0 -0
  21. clarifai/cli/__pycache__/deployment.cpython-310.pyc +0 -0
  22. clarifai/cli/__pycache__/model.cpython-310.pyc +0 -0
  23. clarifai/cli/__pycache__/nodepool.cpython-310.pyc +0 -0
  24. clarifai/client/__pycache__/__init__.cpython-310.pyc +0 -0
  25. clarifai/client/__pycache__/app.cpython-310.pyc +0 -0
  26. clarifai/client/__pycache__/base.cpython-310.pyc +0 -0
  27. clarifai/client/__pycache__/dataset.cpython-310.pyc +0 -0
  28. clarifai/client/__pycache__/input.cpython-310.pyc +0 -0
  29. clarifai/client/__pycache__/lister.cpython-310.pyc +0 -0
  30. clarifai/client/__pycache__/model.cpython-310.pyc +0 -0
  31. clarifai/client/__pycache__/module.cpython-310.pyc +0 -0
  32. clarifai/client/__pycache__/runner.cpython-310.pyc +0 -0
  33. clarifai/client/__pycache__/search.cpython-310.pyc +0 -0
  34. clarifai/client/__pycache__/user.cpython-310.pyc +0 -0
  35. clarifai/client/__pycache__/workflow.cpython-310.pyc +0 -0
  36. clarifai/client/auth/__pycache__/__init__.cpython-310.pyc +0 -0
  37. clarifai/client/auth/__pycache__/helper.cpython-310.pyc +0 -0
  38. clarifai/client/auth/__pycache__/register.cpython-310.pyc +0 -0
  39. clarifai/client/auth/__pycache__/stub.cpython-310.pyc +0 -0
  40. clarifai/constants/__pycache__/dataset.cpython-310.pyc +0 -0
  41. clarifai/constants/__pycache__/model.cpython-310.pyc +0 -0
  42. clarifai/constants/__pycache__/search.cpython-310.pyc +0 -0
  43. clarifai/datasets/__pycache__/__init__.cpython-310.pyc +0 -0
  44. clarifai/datasets/export/__pycache__/__init__.cpython-310.pyc +0 -0
  45. clarifai/datasets/export/__pycache__/inputs_annotations.cpython-310.pyc +0 -0
  46. clarifai/datasets/upload/__pycache__/__init__.cpython-310.pyc +0 -0
  47. clarifai/datasets/upload/__pycache__/base.cpython-310.pyc +0 -0
  48. clarifai/datasets/upload/__pycache__/features.cpython-310.pyc +0 -0
  49. clarifai/datasets/upload/__pycache__/image.cpython-310.pyc +0 -0
  50. clarifai/datasets/upload/__pycache__/text.cpython-310.pyc +0 -0
  51. clarifai/datasets/upload/__pycache__/utils.cpython-310.pyc +0 -0
  52. clarifai/models/__pycache__/__init__.cpython-310.pyc +0 -0
  53. clarifai/models/model_serving/README.md +0 -158
  54. clarifai/models/model_serving/__init__.py +0 -14
  55. clarifai/models/model_serving/__pycache__/__init__.cpython-310.pyc +0 -0
  56. clarifai/models/model_serving/__pycache__/constants.cpython-310.pyc +0 -0
  57. clarifai/models/model_serving/cli/__init__.py +0 -12
  58. clarifai/models/model_serving/cli/__pycache__/__init__.cpython-310.pyc +0 -0
  59. clarifai/models/model_serving/cli/__pycache__/_utils.cpython-310.pyc +0 -0
  60. clarifai/models/model_serving/cli/__pycache__/base.cpython-310.pyc +0 -0
  61. clarifai/models/model_serving/cli/__pycache__/build.cpython-310.pyc +0 -0
  62. clarifai/models/model_serving/cli/__pycache__/create.cpython-310.pyc +0 -0
  63. clarifai/models/model_serving/cli/_utils.py +0 -53
  64. clarifai/models/model_serving/cli/base.py +0 -14
  65. clarifai/models/model_serving/cli/build.py +0 -79
  66. clarifai/models/model_serving/cli/clarifai_clis.py +0 -33
  67. clarifai/models/model_serving/cli/create.py +0 -171
  68. clarifai/models/model_serving/cli/example_cli.py +0 -34
  69. clarifai/models/model_serving/cli/login.py +0 -26
  70. clarifai/models/model_serving/cli/upload.py +0 -183
  71. clarifai/models/model_serving/constants.py +0 -21
  72. clarifai/models/model_serving/docs/cli.md +0 -161
  73. clarifai/models/model_serving/docs/concepts.md +0 -229
  74. clarifai/models/model_serving/docs/dependencies.md +0 -11
  75. clarifai/models/model_serving/docs/inference_parameters.md +0 -139
  76. clarifai/models/model_serving/docs/model_types.md +0 -19
  77. clarifai/models/model_serving/model_config/__init__.py +0 -16
  78. clarifai/models/model_serving/model_config/__pycache__/__init__.cpython-310.pyc +0 -0
  79. clarifai/models/model_serving/model_config/__pycache__/base.cpython-310.pyc +0 -0
  80. clarifai/models/model_serving/model_config/__pycache__/config.cpython-310.pyc +0 -0
  81. clarifai/models/model_serving/model_config/__pycache__/inference_parameter.cpython-310.pyc +0 -0
  82. clarifai/models/model_serving/model_config/__pycache__/output.cpython-310.pyc +0 -0
  83. clarifai/models/model_serving/model_config/base.py +0 -369
  84. clarifai/models/model_serving/model_config/config.py +0 -312
  85. clarifai/models/model_serving/model_config/inference_parameter.py +0 -129
  86. clarifai/models/model_serving/model_config/model_types_config/multimodal-embedder.yaml +0 -25
  87. clarifai/models/model_serving/model_config/model_types_config/text-classifier.yaml +0 -19
  88. clarifai/models/model_serving/model_config/model_types_config/text-embedder.yaml +0 -20
  89. clarifai/models/model_serving/model_config/model_types_config/text-to-image.yaml +0 -19
  90. clarifai/models/model_serving/model_config/model_types_config/text-to-text.yaml +0 -19
  91. clarifai/models/model_serving/model_config/model_types_config/visual-classifier.yaml +0 -22
  92. clarifai/models/model_serving/model_config/model_types_config/visual-detector.yaml +0 -32
  93. clarifai/models/model_serving/model_config/model_types_config/visual-embedder.yaml +0 -19
  94. clarifai/models/model_serving/model_config/model_types_config/visual-segmenter.yaml +0 -19
  95. clarifai/models/model_serving/model_config/output.py +0 -133
  96. clarifai/models/model_serving/model_config/triton/__init__.py +0 -14
  97. clarifai/models/model_serving/model_config/triton/__pycache__/__init__.cpython-310.pyc +0 -0
  98. clarifai/models/model_serving/model_config/triton/__pycache__/serializer.cpython-310.pyc +0 -0
  99. clarifai/models/model_serving/model_config/triton/__pycache__/triton_config.cpython-310.pyc +0 -0
  100. clarifai/models/model_serving/model_config/triton/__pycache__/wrappers.cpython-310.pyc +0 -0
  101. clarifai/models/model_serving/model_config/triton/serializer.py +0 -136
  102. clarifai/models/model_serving/model_config/triton/triton_config.py +0 -182
  103. clarifai/models/model_serving/model_config/triton/wrappers.py +0 -281
  104. clarifai/models/model_serving/repo_build/__init__.py +0 -14
  105. clarifai/models/model_serving/repo_build/__pycache__/__init__.cpython-310.pyc +0 -0
  106. clarifai/models/model_serving/repo_build/__pycache__/build.cpython-310.pyc +0 -0
  107. clarifai/models/model_serving/repo_build/build.py +0 -198
  108. clarifai/models/model_serving/repo_build/static_files/__pycache__/base_test.cpython-310-pytest-7.2.0.pyc +0 -0
  109. clarifai/models/model_serving/repo_build/static_files/_requirements.txt +0 -2
  110. clarifai/models/model_serving/repo_build/static_files/base_test.py +0 -169
  111. clarifai/models/model_serving/repo_build/static_files/inference.py +0 -26
  112. clarifai/models/model_serving/repo_build/static_files/sample_clarifai_config.yaml +0 -25
  113. clarifai/models/model_serving/repo_build/static_files/test.py +0 -40
  114. clarifai/models/model_serving/repo_build/static_files/triton/model.py +0 -75
  115. clarifai/models/model_serving/utils.py +0 -31
  116. clarifai/rag/__pycache__/__init__.cpython-310.pyc +0 -0
  117. clarifai/rag/__pycache__/rag.cpython-310.pyc +0 -0
  118. clarifai/rag/__pycache__/utils.cpython-310.pyc +0 -0
  119. clarifai/runners/__pycache__/__init__.cpython-310.pyc +0 -0
  120. clarifai/runners/__pycache__/server.cpython-310.pyc +0 -0
  121. clarifai/runners/deepgram_live_transcribe.py +0 -98
  122. clarifai/runners/deepgram_live_transcribe.py~ +0 -98
  123. clarifai/runners/deepgram_runner.py +0 -131
  124. clarifai/runners/deepgram_runner.py~ +0 -130
  125. clarifai/runners/dockerfile_template/Dockerfile.cpu.template +0 -31
  126. clarifai/runners/dockerfile_template/Dockerfile.cuda.template +0 -79
  127. clarifai/runners/example_llama2.py~ +0 -72
  128. clarifai/runners/matt_example.py +0 -89
  129. clarifai/runners/matt_example.py~ +0 -87
  130. clarifai/runners/matt_llm_example.py +0 -129
  131. clarifai/runners/matt_llm_example.py~ +0 -128
  132. clarifai/runners/models/__pycache__/__init__.cpython-310.pyc +0 -0
  133. clarifai/runners/models/__pycache__/base_typed_model.cpython-310.pyc +0 -0
  134. clarifai/runners/models/__pycache__/model_class.cpython-310.pyc +0 -0
  135. clarifai/runners/models/__pycache__/model_run_locally.cpython-310.pyc +0 -0
  136. clarifai/runners/models/__pycache__/model_runner.cpython-310.pyc +0 -0
  137. clarifai/runners/models/__pycache__/model_servicer.cpython-310.pyc +0 -0
  138. clarifai/runners/models/__pycache__/model_upload.cpython-310.pyc +0 -0
  139. clarifai/runners/utils/__pycache__/__init__.cpython-310.pyc +0 -0
  140. clarifai/runners/utils/__pycache__/const.cpython-310.pyc +0 -0
  141. clarifai/runners/utils/__pycache__/data_handler.cpython-310.pyc +0 -0
  142. clarifai/runners/utils/__pycache__/data_utils.cpython-310.pyc +0 -0
  143. clarifai/runners/utils/__pycache__/loader.cpython-310.pyc +0 -0
  144. clarifai/runners/utils/__pycache__/logging.cpython-310.pyc +0 -0
  145. clarifai/runners/utils/__pycache__/url_fetcher.cpython-310.pyc +0 -0
  146. clarifai/runners/utils/logging.py +0 -6
  147. clarifai/schema/__pycache__/search.cpython-310.pyc +0 -0
  148. clarifai/urls/__pycache__/helper.cpython-310.pyc +0 -0
  149. clarifai/utils/__pycache__/__init__.cpython-310.pyc +0 -0
  150. clarifai/utils/__pycache__/logging.cpython-310.pyc +0 -0
  151. clarifai/utils/__pycache__/misc.cpython-310.pyc +0 -0
  152. clarifai/utils/__pycache__/model_train.cpython-310.pyc +0 -0
  153. clarifai/workflows/__pycache__/__init__.cpython-310.pyc +0 -0
  154. clarifai/workflows/__pycache__/export.cpython-310.pyc +0 -0
  155. clarifai/workflows/__pycache__/utils.cpython-310.pyc +0 -0
  156. clarifai/workflows/__pycache__/validate.cpython-310.pyc +0 -0
  157. clarifai-11.0.6rc4.dist-info/RECORD +0 -242
  158. {clarifai-11.0.6rc4.dist-info → clarifai-11.0.7.dist-info}/LICENSE +0 -0
  159. {clarifai-11.0.6rc4.dist-info → clarifai-11.0.7.dist-info}/entry_points.txt +0 -0
  160. {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.6rc4"
1
+ __version__ = "11.0.7"
@@ -0,0 +1,4 @@
1
+ from clarifai.cli.base import main
2
+
3
+ if __name__ == "__main__":
4
+ main()
clarifai/cli/base.py CHANGED
@@ -108,5 +108,6 @@ def login(ctx, config, env, user_id):
108
108
  # Import the CLI commands to register them
109
109
  load_command_modules()
110
110
 
111
- if __name__ == '__main__':
111
+
112
+ def main():
112
113
  cli()
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
- def download_checkpoints(model_path):
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 ${DOWNLOAD_IMAGE} as pip_packages
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
- # Final image
15
+ # Downloader dependencies image
16
16
  #############################
17
- FROM --platform=$TARGETPLATFORM ${BASE_IMAGE} as final
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
- # make sure we have the latest clarifai package.
28
- RUN (pip install --upgrade --upgrade-strategy only-if-needed --no-cache-dir clarifai==11.0.6rc4 clarifai-grpc clarifai-protocol huggingface_hub[hf_transfer] || true)
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
- # Download any checkpoints now into the final image so we don't copy large checkpoints across stages.
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
- # Mount the folder with the download_checkpoints.py, config.yaml that's been parsed then download
37
- # the checkpoints. This invalidates the cache if we have a different repo_id to download, but the
38
- # HF_TOKEN changing does not invalidate. It's validated before running the dockerfile
39
- RUN --mount=type=secret,id=HF_TOKEN,env=HF_TOKEN --mount=type=bind,rw,source=downloader,target=/home/nonroot/main [ -s /home/nonroot/main/config.yaml ] && clarifai model download-checkpoints --model_path /home/nonroot/main
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 = os.path.join(venv_dir, "bin", "python")
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 = os.path.join(self.venv_dir, "bin", "pip")
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
- uploader = ModelUploader(self.model_path)
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
- command = [
217
- self.python_executable,
218
- "-c",
219
- f"import sys; sys.path.append('{os.path.dirname(os.path.abspath(__file__))}'); "
220
- f"from model_run_locally import ModelRunLocally; ModelRunLocally('{self.model_path}')._run_test()",
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
- "docker", "run", "--name", container_name, '--rm', "--gpus", "all", "--network", "host"
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
- "docker", "run", "--name", container_name, '--rm', "--gpus", "all", "--network", "host"
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 = {'CLARIFAI_PAT': os.environ['CLARIFAI_PAT'], 'CLARIFAI_USER_ID': 'n/a'}
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 (AVAILABLE_PYTHON_IMAGES, AVAILABLE_TORCH_IMAGES,
16
- CONCEPTS_REQUIRED_MODEL_TYPE, DEFAULT_PYTHON_VERSION,
17
- PYTHON_BASE_IMAGE, TORCH_BASE_IMAGE)
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 folder.startswith("/"):
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
- download_image = PYTHON_BASE_IMAGE.format(python_version=python_version)
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
- base_image = TORCH_BASE_IMAGE.format(
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
- base_image = download_image
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
- DOWNLOAD_IMAGE=download_image, # for downloading
305
- BASE_IMAGE=base_image, # for runtime
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 os.path.join(self.folder, self.checkpoint_suffix)
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
- success = loader.download_checkpoints(self.checkpoint_path)
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
- if download_checkpoints:
435
- tar_cmd = f"tar --exclude=*~ --exclude={self.tar_file} -czvf {self.tar_file} -C {self.folder} ."
436
- else: # we don't want to send the checkpoints up even if they are in the folder.
437
- logger.info(f"Skipping {self.checkpoint_path} in the tar file that is uploaded.")
438
- tar_cmd = f"tar --exclude={self.checkpoint_suffix} --exclude=*~ --exclude={self.tar_file} -czvf {self.tar_file} -C {self.folder} ."
439
- # Tar the folder
440
- logger.debug(tar_cmd)
441
- os.system(tar_cmd)
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
- print()
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
- success = self.monitor_model_build()
475
- if success: # cleanup the tar_file if it exists
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
- print(f"Model Building Logs...: {escape(log_entry.message.strip())}")
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(
@@ -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
- PYTHON_BASE_IMAGE = registry + '/python-base:{python_version}'
6
- TORCH_BASE_IMAGE = registry + '/torch:{torch_version}-py{python_version}-cuda{cuda_version}'
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', '3.13']
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 = [
@@ -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
- subprocess.run(f'huggingface-cli login --token={os.environ["HF_TOKEN"]}', shell=True)
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 != 'base': # Skip the base.py file itself
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('%(name)s: %(message)s')
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
1
+ Metadata-Version: 2.2
2
2
  Name: clarifai
3
- Version: 11.0.6rc4
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 >=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
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 ==2.0.6 ; extra == 'all'
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>