clarifai 11.1.2__tar.gz → 11.1.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. {clarifai-11.1.2/clarifai.egg-info → clarifai-11.1.4}/PKG-INFO +1 -1
  2. clarifai-11.1.4/clarifai/__init__.py +1 -0
  3. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/cli/model.py +20 -8
  4. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/runners/dockerfile_template/Dockerfile.template +3 -34
  5. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/runners/models/model_builder.py +102 -62
  6. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/runners/models/model_run_locally.py +3 -2
  7. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/runners/utils/const.py +6 -0
  8. {clarifai-11.1.2 → clarifai-11.1.4/clarifai.egg-info}/PKG-INFO +1 -1
  9. clarifai-11.1.2/clarifai/__init__.py +0 -1
  10. {clarifai-11.1.2 → clarifai-11.1.4}/LICENSE +0 -0
  11. {clarifai-11.1.2 → clarifai-11.1.4}/MANIFEST.in +0 -0
  12. {clarifai-11.1.2 → clarifai-11.1.4}/README.md +0 -0
  13. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/cli/README.md +0 -0
  14. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/cli/__init__.py +0 -0
  15. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/cli/__main__.py +0 -0
  16. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/cli/base.py +0 -0
  17. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/cli/compute_cluster.py +0 -0
  18. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/cli/deployment.py +0 -0
  19. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/cli/nodepool.py +0 -0
  20. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/cli.py +0 -0
  21. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/client/__init__.py +0 -0
  22. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/client/app.py +0 -0
  23. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/client/auth/__init__.py +0 -0
  24. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/client/auth/helper.py +0 -0
  25. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/client/auth/register.py +0 -0
  26. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/client/auth/stub.py +0 -0
  27. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/client/base.py +0 -0
  28. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/client/compute_cluster.py +0 -0
  29. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/client/dataset.py +0 -0
  30. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/client/deployment.py +0 -0
  31. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/client/input.py +0 -0
  32. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/client/lister.py +0 -0
  33. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/client/model.py +0 -0
  34. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/client/module.py +0 -0
  35. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/client/nodepool.py +0 -0
  36. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/client/search.py +0 -0
  37. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/client/user.py +0 -0
  38. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/client/workflow.py +0 -0
  39. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/constants/base.py +0 -0
  40. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/constants/dataset.py +0 -0
  41. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/constants/input.py +0 -0
  42. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/constants/model.py +0 -0
  43. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/constants/rag.py +0 -0
  44. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/constants/search.py +0 -0
  45. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/constants/workflow.py +0 -0
  46. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/datasets/__init__.py +0 -0
  47. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/datasets/export/__init__.py +0 -0
  48. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/datasets/export/inputs_annotations.py +0 -0
  49. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/datasets/upload/__init__.py +0 -0
  50. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/datasets/upload/base.py +0 -0
  51. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/datasets/upload/features.py +0 -0
  52. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/datasets/upload/image.py +0 -0
  53. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/datasets/upload/loaders/README.md +0 -0
  54. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/datasets/upload/loaders/__init__.py +0 -0
  55. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/datasets/upload/loaders/coco_captions.py +0 -0
  56. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/datasets/upload/loaders/coco_detection.py +0 -0
  57. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/datasets/upload/loaders/imagenet_classification.py +0 -0
  58. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/datasets/upload/loaders/xview_detection.py +0 -0
  59. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/datasets/upload/multimodal.py +0 -0
  60. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/datasets/upload/text.py +0 -0
  61. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/datasets/upload/utils.py +0 -0
  62. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/errors.py +0 -0
  63. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/models/__init__.py +0 -0
  64. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/models/api.py +0 -0
  65. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/modules/README.md +0 -0
  66. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/modules/__init__.py +0 -0
  67. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/modules/css.py +0 -0
  68. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/modules/pages.py +0 -0
  69. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/modules/style.css +0 -0
  70. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/rag/__init__.py +0 -0
  71. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/rag/rag.py +0 -0
  72. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/rag/utils.py +0 -0
  73. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/runners/__init__.py +0 -0
  74. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/runners/models/__init__.py +0 -0
  75. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/runners/models/base_typed_model.py +0 -0
  76. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/runners/models/model_class.py +0 -0
  77. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/runners/models/model_runner.py +0 -0
  78. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/runners/models/model_servicer.py +0 -0
  79. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/runners/server.py +0 -0
  80. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/runners/utils/__init__.py +0 -0
  81. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/runners/utils/data_handler.py +0 -0
  82. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/runners/utils/data_utils.py +0 -0
  83. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/runners/utils/loader.py +0 -0
  84. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/runners/utils/url_fetcher.py +0 -0
  85. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/schema/search.py +0 -0
  86. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/urls/helper.py +0 -0
  87. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/utils/__init__.py +0 -0
  88. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/utils/cli.py +0 -0
  89. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/utils/constants.py +0 -0
  90. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/utils/evaluation/__init__.py +0 -0
  91. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/utils/evaluation/helpers.py +0 -0
  92. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/utils/evaluation/main.py +0 -0
  93. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/utils/evaluation/testset_annotation_parser.py +0 -0
  94. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/utils/logging.py +0 -0
  95. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/utils/misc.py +0 -0
  96. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/utils/model_train.py +0 -0
  97. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/versions.py +0 -0
  98. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/workflows/__init__.py +0 -0
  99. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/workflows/export.py +0 -0
  100. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/workflows/utils.py +0 -0
  101. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai/workflows/validate.py +0 -0
  102. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai.egg-info/SOURCES.txt +0 -0
  103. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai.egg-info/dependency_links.txt +0 -0
  104. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai.egg-info/entry_points.txt +0 -0
  105. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai.egg-info/requires.txt +0 -0
  106. {clarifai-11.1.2 → clarifai-11.1.4}/clarifai.egg-info/top_level.txt +0 -0
  107. {clarifai-11.1.2 → clarifai-11.1.4}/pyproject.toml +0 -0
  108. {clarifai-11.1.2 → clarifai-11.1.4}/requirements.txt +0 -0
  109. {clarifai-11.1.2 → clarifai-11.1.4}/setup.cfg +0 -0
  110. {clarifai-11.1.2 → clarifai-11.1.4}/setup.py +0 -0
  111. {clarifai-11.1.2 → clarifai-11.1.4}/tests/test_app.py +0 -0
  112. {clarifai-11.1.2 → clarifai-11.1.4}/tests/test_auth.py +0 -0
  113. {clarifai-11.1.2 → clarifai-11.1.4}/tests/test_data_upload.py +0 -0
  114. {clarifai-11.1.2 → clarifai-11.1.4}/tests/test_eval.py +0 -0
  115. {clarifai-11.1.2 → clarifai-11.1.4}/tests/test_misc.py +0 -0
  116. {clarifai-11.1.2 → clarifai-11.1.4}/tests/test_model_predict.py +0 -0
  117. {clarifai-11.1.2 → clarifai-11.1.4}/tests/test_model_train.py +0 -0
  118. {clarifai-11.1.2 → clarifai-11.1.4}/tests/test_modules.py +0 -0
  119. {clarifai-11.1.2 → clarifai-11.1.4}/tests/test_rag.py +0 -0
  120. {clarifai-11.1.2 → clarifai-11.1.4}/tests/test_search.py +0 -0
  121. {clarifai-11.1.2 → clarifai-11.1.4}/tests/test_stub.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: clarifai
3
- Version: 11.1.2
3
+ Version: 11.1.4
4
4
  Summary: Clarifai Python SDK
5
5
  Home-page: https://github.com/Clarifai/clarifai-python
6
6
  Author: Clarifai
@@ -0,0 +1 @@
1
+ __version__ = "11.1.4"
@@ -15,10 +15,13 @@ def model():
15
15
  required=True,
16
16
  help='Path to the model directory.')
17
17
  @click.option(
18
- '--download_checkpoints',
19
- is_flag=True,
18
+ '--stage',
19
+ required=False,
20
+ type=click.Choice(['runtime', 'build', 'upload'], case_sensitive=True),
21
+ default="upload",
22
+ show_default=True,
20
23
  help=
21
- 'Flag to download checkpoints before uploading and including them in the tar file that is uploaded. Defaults to False, which will attempt to download them at docker build time.',
24
+ 'The stage we are calling download checkpoints from. Typically this would "upload" and will download checkpoints if config.yaml checkpoints section has when set to "upload". Other options include "runtime" to be used in load_model or "upload" to be used during model upload. Set this stage to whatever you have in config.yaml to force downloading now.'
22
25
  )
23
26
  @click.option(
24
27
  '--skip_dockerfile',
@@ -26,10 +29,10 @@ def model():
26
29
  help=
27
30
  'Flag to skip generating a dockerfile so that you can manually edit an already created dockerfile.',
28
31
  )
29
- def upload(model_path, download_checkpoints, skip_dockerfile):
32
+ def upload(model_path, stage, skip_dockerfile):
30
33
  """Upload a model to Clarifai."""
31
34
  from clarifai.runners.models.model_builder import upload_model
32
- upload_model(model_path, download_checkpoints, skip_dockerfile)
35
+ upload_model(model_path, stage, skip_dockerfile)
33
36
 
34
37
 
35
38
  @model.command()
@@ -44,14 +47,23 @@ def upload(model_path, download_checkpoints, skip_dockerfile):
44
47
  required=False,
45
48
  default=None,
46
49
  help=
47
- '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..'
50
+ 'Option path to write the checkpoints to. This will place them in {out_path}/1/checkpoints If not provided it will default to {model_path}/1/checkpoints where the config.yaml is read.'
51
+ )
52
+ @click.option(
53
+ '--stage',
54
+ required=False,
55
+ type=click.Choice(['runtime', 'build', 'upload'], case_sensitive=True),
56
+ default="build",
57
+ show_default=True,
58
+ help=
59
+ 'The stage we are calling download checkpoints from. Typically this would be in the build stage which is the default. Other options include "runtime" to be used in load_model or "upload" to be used during model upload. Set this stage to whatever you have in config.yaml to force downloading now.'
48
60
  )
49
- def download_checkpoints(model_path, out_path):
61
+ def download_checkpoints(model_path, out_path, stage):
50
62
  """Download checkpoints from external source to local model_path"""
51
63
 
52
64
  from clarifai.runners.models.model_builder import ModelBuilder
53
65
  builder = ModelBuilder(model_path, download_validation_only=True)
54
- builder.download_checkpoints(out_path)
66
+ builder.download_checkpoints(stage=stage, checkpoint_path_override=out_path)
55
67
 
56
68
 
57
69
  @model.command()
@@ -1,30 +1,11 @@
1
1
  # syntax=docker/dockerfile:1.13-labs
2
- #############################
3
- # User specific requirements installed in the pip_packages
4
- #############################
5
- FROM --platform=$TARGETPLATFORM ${FINAL_IMAGE} as pip_packages
2
+ FROM --platform=$TARGETPLATFORM ${FINAL_IMAGE} as final
6
3
 
7
4
  COPY --link requirements.txt /home/nonroot/requirements.txt
8
5
 
9
6
  # Update clarifai package so we always have latest protocol to the API. Everything should land in /venv
10
7
  RUN ["pip", "install", "--no-cache-dir", "-r", "/home/nonroot/requirements.txt"]
11
8
  RUN ["pip", "show", "clarifai"]
12
- #############################
13
-
14
- #############################
15
- # Downloader dependencies image
16
- #############################
17
- FROM --platform=$TARGETPLATFORM ${DOWNLOADER_IMAGE} as downloader
18
-
19
- # make sure we have the latest clarifai package. This version is filled in by SDK.
20
- RUN ["pip", "install", "clarifai==${CLARIFAI_VERSION}"]
21
- #####
22
-
23
-
24
- #############################
25
- # Final runtime image
26
- #############################
27
- FROM --platform=$TARGETPLATFORM ${FINAL_IMAGE} as final
28
9
 
29
10
  # Set the NUMBA cache dir to /tmp
30
11
  # Set the TORCHINDUCTOR cache dir to /tmp
@@ -34,12 +15,6 @@ ENV NUMBA_CACHE_DIR=/tmp/numba_cache \
34
15
  HOME=/tmp \
35
16
  DEBIAN_FRONTEND=noninteractive
36
17
 
37
- #####
38
- # Copy the python requirements needed to download checkpoints
39
- #####
40
- COPY --link=true --from=downloader /venv /venv
41
- #####
42
-
43
18
  #####
44
19
  # Copy the files needed to download
45
20
  #####
@@ -47,15 +22,9 @@ COPY --link=true --from=downloader /venv /venv
47
22
  COPY --chown=nonroot:nonroot downloader/unused.yaml /home/nonroot/main/1/checkpoints/.cache/unused.yaml
48
23
 
49
24
  #####
50
- # Download checkpoints
25
+ # Download checkpoints if config.yaml has checkpoints.when = "build"
51
26
  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"]
53
- #####
54
-
55
-
56
- #####
57
- # Copy the python packages from the builder stage.
58
- COPY --link=true --from=pip_packages /venv /venv
27
+ RUN ["python", "-m", "clarifai.cli", "model", "download-checkpoints", "--model_path", "/home/nonroot/main", "--out_path", "/home/nonroot/main/1/checkpoints", "--stage", "build"]
59
28
  #####
60
29
 
61
30
  # Copy in the actual files like config.yaml, requirements.txt, and most importantly 1/model.py
@@ -16,9 +16,10 @@ from rich.markup import escape
16
16
 
17
17
  from clarifai.client import BaseClient
18
18
  from clarifai.runners.models.model_class import ModelClass
19
- from clarifai.runners.utils.const import (AVAILABLE_PYTHON_IMAGES, AVAILABLE_TORCH_IMAGES,
20
- CONCEPTS_REQUIRED_MODEL_TYPE, DEFAULT_PYTHON_VERSION,
21
- PYTHON_BASE_IMAGE, TORCH_BASE_IMAGE)
19
+ from clarifai.runners.utils.const import (
20
+ AVAILABLE_PYTHON_IMAGES, AVAILABLE_TORCH_IMAGES, CONCEPTS_REQUIRED_MODEL_TYPE,
21
+ DEFAULT_DOWNLOAD_CHECKPOINT_WHEN, DEFAULT_PYTHON_VERSION, DEFAULT_RUNTIME_DOWNLOAD_PATH,
22
+ PYTHON_BASE_IMAGE, TORCH_BASE_IMAGE)
22
23
  from clarifai.runners.utils.loader import HuggingFaceLoader
23
24
  from clarifai.urls.helper import ClarifaiUrlHelper
24
25
  from clarifai.utils.logging import logger
@@ -30,19 +31,6 @@ dependencies = [
30
31
  'torch',
31
32
  'clarifai',
32
33
  ]
33
- # Escape dependency names for regex
34
- dep_pattern = '|'.join(map(re.escape, dependencies))
35
- # All possible version specifiers
36
- version_specifiers = '==|>=|<=|!=|~=|>|<'
37
- # Compile a regex pattern with verbose mode for readability
38
- pattern = re.compile(r"""
39
- ^\s* # Start of line, optional whitespace
40
- (?P<dependency>""" + dep_pattern + r""") # Dependency name
41
- \s* # Optional whitespace
42
- (?P<specifier>""" + version_specifiers + r""")? # Optional version specifier
43
- \s* # Optional whitespace
44
- (?P<version>[^\s;]+)? # Optional version (up to space or semicolon)
45
- """, re.VERBOSE)
46
34
 
47
35
 
48
36
  def _clear_line(n: int = 1) -> None:
@@ -158,11 +146,24 @@ class ModelBuilder:
158
146
  :return: repo_id location of checkpoint.
159
147
  :return: hf_token token to access checkpoint.
160
148
  """
149
+ if "checkpoints" not in self.config:
150
+ return None, None, None, DEFAULT_DOWNLOAD_CHECKPOINT_WHEN
161
151
  assert "type" in self.config.get("checkpoints"), "No loader type specified in the config file"
162
152
  loader_type = self.config.get("checkpoints").get("type")
163
153
  if not loader_type:
164
154
  logger.info("No loader type specified in the config file for checkpoints")
165
155
  return None, None, None
156
+ checkpoints = self.config.get("checkpoints")
157
+ if 'when' not in checkpoints:
158
+ logger.warn(
159
+ f"No 'when' specified in the config file for checkpoints, defaulting to download at {DEFAULT_DOWNLOAD_CHECKPOINT_WHEN}"
160
+ )
161
+ when = checkpoints.get("when", DEFAULT_DOWNLOAD_CHECKPOINT_WHEN)
162
+ assert when in [
163
+ "upload",
164
+ "build",
165
+ "runtime",
166
+ ], "Invalid value for when in the checkpoint loader when, needs to be one of ['upload', 'build', 'runtime']"
166
167
  assert loader_type == "huggingface", "Only huggingface loader supported for now"
167
168
  if loader_type == "huggingface":
168
169
  assert "repo_id" in self.config.get("checkpoints"), "No repo_id specified in the config file"
@@ -170,7 +171,7 @@ class ModelBuilder:
170
171
 
171
172
  # get from config.yaml otherwise fall back to HF_TOKEN env var.
172
173
  hf_token = self.config.get("checkpoints").get("hf_token", os.environ.get("HF_TOKEN", None))
173
- return loader_type, repo_id, hf_token
174
+ return loader_type, repo_id, hf_token, when
174
175
 
175
176
  def _check_app_exists(self):
176
177
  resp = self.client.STUB.GetApp(service_pb2.GetAppRequest(user_app_id=self.client.user_app_id))
@@ -215,7 +216,7 @@ class ModelBuilder:
215
216
  assert model_type_id in CONCEPTS_REQUIRED_MODEL_TYPE, f"Model type {model_type_id} not supported for concepts"
216
217
 
217
218
  if self.config.get("checkpoints"):
218
- loader_type, _, hf_token = self._validate_config_checkpoints()
219
+ loader_type, _, hf_token, _ = self._validate_config_checkpoints()
219
220
 
220
221
  if loader_type == "huggingface" and hf_token:
221
222
  is_valid_token = HuggingFaceLoader.validate_hftoken(hf_token)
@@ -310,25 +311,41 @@ class ModelBuilder:
310
311
  )
311
312
  return self.client.STUB.PostModels(request)
312
313
 
314
+ def _match_req_line(self, line):
315
+ line = line.strip()
316
+ if not line or line.startswith('#'):
317
+ return None, None
318
+ # split on whitespace followed by #
319
+ line = re.split(r'\s+#', line)[0]
320
+ if "==" in line:
321
+ pkg, version = line.split("==")
322
+ elif ">=" in line:
323
+ pkg, version = line.split(">=")
324
+ elif ">" in line:
325
+ pkg, version = line.split(">")
326
+ elif "<=" in line:
327
+ pkg, version = line.split("<=")
328
+ elif "<" in line:
329
+ pkg, version = line.split("<")
330
+ else:
331
+ pkg, version = line, None # No version specified
332
+ for dep in dependencies:
333
+ if dep == pkg:
334
+ if dep == 'torch' and line.find(
335
+ 'whl/cpu') > 0: # Ignore torch-cpu whl files, use base mage.
336
+ return None, None
337
+ return dep.strip(), version.strip() if version else None
338
+ return None, None
339
+
313
340
  def _parse_requirements(self):
314
341
  dependencies_version = {}
315
342
  with open(os.path.join(self.folder, 'requirements.txt'), 'r') as file:
316
343
  for line in file:
317
344
  # Skip empty lines and comments
318
- line = line.strip()
319
- if not line or line.startswith('#'):
345
+ dependency, version = self._match_req_line(line)
346
+ if dependency is None:
320
347
  continue
321
- # split on whitespace followed by #
322
- line = re.split(r'\s+#', line)[0]
323
- match = pattern.match(line)
324
- if match:
325
- dependency = match.group('dependency')
326
- version = match.group('version')
327
- if dependency == "torch" and line.find(
328
- 'whl/cpu') > 0: # Ignore torch-cpu whl files, use base mage.
329
- continue
330
-
331
- dependencies_version[dependency] = version if version else None
348
+ dependencies_version[dependency] = version if version else None
332
349
  return dependencies_version
333
350
 
334
351
  def create_dockerfile(self):
@@ -395,10 +412,8 @@ class ModelBuilder:
395
412
  with open(os.path.join(self.folder, 'requirements.txt'), 'r') as file:
396
413
  for line in file:
397
414
  # if the line without whitespace is "clarifai"
398
- # split on whitespace followed by #
399
- matchline = re.split(r'\s+#', line)[0]
400
- match = pattern.match(matchline)
401
- if match and match.group('dependency') == "clarifai":
415
+ dependency, version = self._match_req_line(line)
416
+ if dependency and dependency == "clarifai":
402
417
  lines.append(line.replace("clarifai", f"clarifai=={CLIENT_VERSION}"))
403
418
  else:
404
419
  lines.append(line)
@@ -427,31 +442,51 @@ class ModelBuilder:
427
442
 
428
443
  @property
429
444
  def checkpoint_suffix(self):
430
- return '1/checkpoints'
445
+ return os.path.join('1', 'checkpoints')
431
446
 
432
447
  @property
433
448
  def tar_file(self):
434
449
  return f"{self.folder}.tar.gz"
435
450
 
436
- def download_checkpoints(self, checkpoint_path_override: str = None):
451
+ def default_runtime_checkpoint_path(self):
452
+ return DEFAULT_RUNTIME_DOWNLOAD_PATH
453
+
454
+ def download_checkpoints(self,
455
+ stage: str = DEFAULT_DOWNLOAD_CHECKPOINT_WHEN,
456
+ checkpoint_path_override: str = None):
437
457
  """
438
458
  Downloads the checkpoints specified in the config file.
439
459
 
440
- :param checkpoint_path_override: The path to download the checkpoints to. If not provided, the
441
- default path is used based on the folder ModelUploader was initialized with. The
442
- checkpoint_suffix will be appended to the path.
460
+ :param stage: The stage of the build process. This is used to determine when to download the
461
+ checkpoints. The stage can be one of ['build', 'upload', 'runtime']. If you want to force
462
+ downloading now then set stage to match e when field of the checkpoints section of you config.yaml.
463
+ :param checkpoint_path_override: The path to download the checkpoints to (with 1/checkpoints added as suffix). If not provided, the
464
+ default path is used based on the folder ModelUploader was initialized with. The checkpoint_suffix will be appended to the path.
465
+ If stage is 'runtime' and checkpoint_path_override is None, the default runtime path will be used.
466
+
467
+ :return: The path to the downloaded checkpoints. Even if it doesn't download anything, it will return the default path.
443
468
  """
469
+ path = self.checkpoint_path # default checkpoint path.
444
470
  if not self.config.get("checkpoints"):
445
471
  logger.info("No checkpoints specified in the config file")
446
- return True
472
+ return path
447
473
 
448
- loader_type, repo_id, hf_token = self._validate_config_checkpoints()
474
+ loader_type, repo_id, hf_token, when = self._validate_config_checkpoints()
475
+ if stage not in ["build", "upload", "runtime"]:
476
+ raise Exception("Invalid stage provided, must be one of ['build', 'upload', 'runtime']")
477
+ if when != stage:
478
+ logger.info(
479
+ f"Skipping downloading checkpoints for stage {stage} since config.yaml says to download them at stage {when}"
480
+ )
481
+ return path
449
482
 
450
483
  success = True
451
484
  if loader_type == "huggingface":
452
485
  loader = HuggingFaceLoader(repo_id=repo_id, token=hf_token)
453
- path = self._checkpoint_path(
454
- checkpoint_path_override) if checkpoint_path_override else self.checkpoint_path
486
+ # for runtime default to /tmp path
487
+ if stage == "runtime" and checkpoint_path_override is None:
488
+ checkpoint_path_override = self.default_runtime_checkpoint_path()
489
+ path = checkpoint_path_override if checkpoint_path_override else self.checkpoint_path
455
490
  success = loader.download_checkpoints(path)
456
491
 
457
492
  if loader_type:
@@ -460,7 +495,7 @@ class ModelBuilder:
460
495
  sys.exit(1)
461
496
  else:
462
497
  logger.info(f"Downloaded checkpoints for model {repo_id}")
463
- return success
498
+ return path
464
499
 
465
500
  def _concepts_protos_from_concepts(self, concepts):
466
501
  concept_protos = []
@@ -519,11 +554,12 @@ class ModelBuilder:
519
554
  self._concepts_protos_from_concepts(labels))
520
555
  return model_version_proto
521
556
 
522
- def upload_model_version(self, download_checkpoints):
557
+ def upload_model_version(self):
523
558
  file_path = f"{self.folder}.tar.gz"
524
559
  logger.debug(f"Will tar it into file: {file_path}")
525
560
 
526
561
  model_type_id = self.config.get('model').get('model_type_id')
562
+ loader_type, repo_id, hf_token, when = self._validate_config_checkpoints()
527
563
 
528
564
  if (model_type_id in CONCEPTS_REQUIRED_MODEL_TYPE) and 'concepts' not in self.config:
529
565
  logger.info(
@@ -533,15 +569,13 @@ class ModelBuilder:
533
569
  logger.info(
534
570
  "Checkpoints specified in the config.yaml file, will download the HF model's config.json file to infer the concepts."
535
571
  )
536
-
537
- if not download_checkpoints and not HuggingFaceLoader.validate_config(
538
- self.checkpoint_path):
539
-
540
- input(
541
- "Press Enter to download the HuggingFace model's config.json file to infer the concepts and continue..."
542
- )
543
- loader_type, repo_id, hf_token = self._validate_config_checkpoints()
544
- if loader_type == "huggingface":
572
+ # If we don't already have the concepts, download the config.json file from HuggingFace
573
+ if loader_type == "huggingface":
574
+ # If the config.yaml says we'll download in the future (build time or runtime) then we need to get this config now.
575
+ if when != "upload" and not HuggingFaceLoader.validate_config(self.checkpoint_path):
576
+ input(
577
+ "Press Enter to download the HuggingFace model's config.json file to infer the concepts and continue..."
578
+ )
545
579
  loader = HuggingFaceLoader(repo_id=repo_id, token=hf_token)
546
580
  loader.download_config(self.checkpoint_path)
547
581
 
@@ -556,7 +590,7 @@ class ModelBuilder:
556
590
  def filter_func(tarinfo):
557
591
  name = tarinfo.name
558
592
  exclude = [self.tar_file, "*~"]
559
- if not download_checkpoints:
593
+ if when != "upload":
560
594
  exclude.append(self.checkpoint_suffix)
561
595
  return None if any(name.endswith(ex) for ex in exclude) else tarinfo
562
596
 
@@ -568,12 +602,12 @@ class ModelBuilder:
568
602
  logger.debug(f"Size of the tar is: {file_size} bytes")
569
603
 
570
604
  self.storage_request_size = self._get_tar_file_content_size(file_path)
571
- if not download_checkpoints and self.config.get("checkpoints"):
605
+ if when != "upload" and self.config.get("checkpoints"):
572
606
  # Get the checkpoint size to add to the storage request.
573
607
  # First check for the env variable, then try querying huggingface. If all else fails, use the default.
574
608
  checkpoint_size = os.environ.get('CHECKPOINT_SIZE_BYTES', 0)
575
609
  if not checkpoint_size:
576
- _, repo_id, _ = self._validate_config_checkpoints()
610
+ _, repo_id, _, _ = self._validate_config_checkpoints()
577
611
  checkpoint_size = HuggingFaceLoader.get_huggingface_checkpoint_total_size(repo_id)
578
612
  if not checkpoint_size:
579
613
  checkpoint_size = self.DEFAULT_CHECKPOINT_SIZE
@@ -701,10 +735,16 @@ class ModelBuilder:
701
735
  return False
702
736
 
703
737
 
704
- def upload_model(folder, download_checkpoints, skip_dockerfile):
738
+ def upload_model(folder, stage, skip_dockerfile):
739
+ """
740
+ Uploads a model to Clarifai.
741
+
742
+ :param folder: The folder containing the model files.
743
+ :param stage: The stage we are calling download checkpoints from. Typically this would "upload" and will download checkpoints if config.yaml checkpoints section has when set to "upload". Other options include "runtime" to be used in load_model or "upload" to be used during model upload. Set this stage to whatever you have in config.yaml to force downloading now.
744
+ :param skip_dockerfile: If True, will not create a Dockerfile.
745
+ """
705
746
  builder = ModelBuilder(folder)
706
- if download_checkpoints:
707
- builder.download_checkpoints()
747
+ builder.download_checkpoints(stage=stage)
708
748
  if not skip_dockerfile:
709
749
  builder.create_dockerfile()
710
750
  exists = builder.check_model_exists()
@@ -716,4 +756,4 @@ def upload_model(folder, download_checkpoints, skip_dockerfile):
716
756
  logger.info(f"New model will be created at {builder.model_url} with it's first version.")
717
757
 
718
758
  input("Press Enter to continue...")
719
- builder.upload_model_version(download_checkpoints)
759
+ builder.upload_model_version()
@@ -475,13 +475,14 @@ def main(model_path,
475
475
  keep_env=False,
476
476
  keep_image=False):
477
477
 
478
- if not os.environ['CLARIFAI_PAT']:
478
+ if not os.environ.get("CLARIFAI_PAT", None):
479
479
  logger.error(
480
480
  "CLARIFAI_PAT environment variable is not set! Please set your PAT in the 'CLARIFAI_PAT' environment variable."
481
481
  )
482
482
  sys.exit(1)
483
483
  manager = ModelRunLocally(model_path)
484
- manager.builder.download_checkpoints()
484
+ # stage="any" forces downloaded now regardless of config.yaml
485
+ manager.builder.download_checkpoints(stage="any")
485
486
  if inside_container:
486
487
  if not manager.is_docker_installed():
487
488
  sys.exit(1)
@@ -12,6 +12,12 @@ AVAILABLE_PYTHON_IMAGES = ['3.11', '3.12']
12
12
 
13
13
  DEFAULT_PYTHON_VERSION = 3.12
14
14
 
15
+ # By default we download at runtime.
16
+ DEFAULT_DOWNLOAD_CHECKPOINT_WHEN = "runtime"
17
+
18
+ # Folder for downloading checkpoints at runtime.
19
+ DEFAULT_RUNTIME_DOWNLOAD_PATH = "/tmp/.cache"
20
+
15
21
  # List of available torch images
16
22
  # Keep sorted by most recent cuda version.
17
23
  AVAILABLE_TORCH_IMAGES = [
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: clarifai
3
- Version: 11.1.2
3
+ Version: 11.1.4
4
4
  Summary: Clarifai Python SDK
5
5
  Home-page: https://github.com/Clarifai/clarifai-python
6
6
  Author: Clarifai
@@ -1 +0,0 @@
1
- __version__ = "11.1.2"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes