clarifai 11.4.1__py3-none-any.whl → 11.4.3rc1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- clarifai/__init__.py +1 -1
- clarifai/__pycache__/__init__.cpython-312.pyc +0 -0
- clarifai/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/__pycache__/errors.cpython-312.pyc +0 -0
- clarifai/__pycache__/errors.cpython-39.pyc +0 -0
- clarifai/__pycache__/versions.cpython-312.pyc +0 -0
- clarifai/__pycache__/versions.cpython-39.pyc +0 -0
- clarifai/cli/__pycache__/__init__.cpython-312.pyc +0 -0
- clarifai/cli/__pycache__/base.cpython-312.pyc +0 -0
- clarifai/cli/__pycache__/compute_cluster.cpython-312.pyc +0 -0
- clarifai/cli/__pycache__/deployment.cpython-312.pyc +0 -0
- clarifai/cli/__pycache__/model.cpython-312.pyc +0 -0
- clarifai/cli/__pycache__/nodepool.cpython-312.pyc +0 -0
- clarifai/cli/base.py +8 -0
- clarifai/cli/model.py +6 -6
- clarifai/client/__pycache__/__init__.cpython-312.pyc +0 -0
- clarifai/client/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/client/__pycache__/app.cpython-312.pyc +0 -0
- clarifai/client/__pycache__/app.cpython-39.pyc +0 -0
- clarifai/client/__pycache__/base.cpython-312.pyc +0 -0
- clarifai/client/__pycache__/base.cpython-39.pyc +0 -0
- clarifai/client/__pycache__/compute_cluster.cpython-312.pyc +0 -0
- clarifai/client/__pycache__/dataset.cpython-312.pyc +0 -0
- clarifai/client/__pycache__/deployment.cpython-312.pyc +0 -0
- clarifai/client/__pycache__/input.cpython-312.pyc +0 -0
- clarifai/client/__pycache__/lister.cpython-312.pyc +0 -0
- clarifai/client/__pycache__/model.cpython-312.pyc +0 -0
- clarifai/client/__pycache__/model_client.cpython-312.pyc +0 -0
- clarifai/client/__pycache__/module.cpython-312.pyc +0 -0
- clarifai/client/__pycache__/nodepool.cpython-312.pyc +0 -0
- clarifai/client/__pycache__/runner.cpython-312.pyc +0 -0
- clarifai/client/__pycache__/search.cpython-312.pyc +0 -0
- clarifai/client/__pycache__/user.cpython-312.pyc +0 -0
- clarifai/client/__pycache__/workflow.cpython-312.pyc +0 -0
- clarifai/client/auth/__pycache__/__init__.cpython-312.pyc +0 -0
- clarifai/client/auth/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/client/auth/__pycache__/helper.cpython-312.pyc +0 -0
- clarifai/client/auth/__pycache__/helper.cpython-39.pyc +0 -0
- clarifai/client/auth/__pycache__/register.cpython-312.pyc +0 -0
- clarifai/client/auth/__pycache__/register.cpython-39.pyc +0 -0
- clarifai/client/auth/__pycache__/stub.cpython-312.pyc +0 -0
- clarifai/client/auth/__pycache__/stub.cpython-39.pyc +0 -0
- clarifai/client/dataset.py +6 -0
- clarifai/constants/__pycache__/base.cpython-312.pyc +0 -0
- clarifai/constants/__pycache__/base.cpython-39.pyc +0 -0
- clarifai/constants/__pycache__/dataset.cpython-312.pyc +0 -0
- clarifai/constants/__pycache__/input.cpython-312.pyc +0 -0
- clarifai/constants/__pycache__/model.cpython-312.pyc +0 -0
- clarifai/constants/__pycache__/rag.cpython-312.pyc +0 -0
- clarifai/constants/__pycache__/search.cpython-312.pyc +0 -0
- clarifai/constants/__pycache__/workflow.cpython-312.pyc +0 -0
- clarifai/datasets/__pycache__/__init__.cpython-312.pyc +0 -0
- clarifai/datasets/export/__pycache__/__init__.cpython-312.pyc +0 -0
- clarifai/datasets/export/__pycache__/inputs_annotations.cpython-312.pyc +0 -0
- clarifai/datasets/upload/__pycache__/__init__.cpython-312.pyc +0 -0
- clarifai/datasets/upload/__pycache__/base.cpython-312.pyc +0 -0
- clarifai/datasets/upload/__pycache__/features.cpython-312.pyc +0 -0
- clarifai/datasets/upload/__pycache__/image.cpython-312.pyc +0 -0
- clarifai/datasets/upload/__pycache__/multimodal.cpython-312.pyc +0 -0
- clarifai/datasets/upload/__pycache__/text.cpython-312.pyc +0 -0
- clarifai/datasets/upload/__pycache__/utils.cpython-312.pyc +0 -0
- clarifai/datasets/upload/loaders/__pycache__/__init__.cpython-312.pyc +0 -0
- clarifai/datasets/upload/loaders/__pycache__/coco_detection.cpython-312.pyc +0 -0
- clarifai/datasets/upload/loaders/__pycache__/imagenet_classification.cpython-312.pyc +0 -0
- clarifai/modules/__pycache__/__init__.cpython-312.pyc +0 -0
- clarifai/modules/__pycache__/css.cpython-312.pyc +0 -0
- clarifai/rag/__pycache__/__init__.cpython-312.pyc +0 -0
- clarifai/rag/__pycache__/rag.cpython-312.pyc +0 -0
- clarifai/rag/__pycache__/utils.cpython-312.pyc +0 -0
- clarifai/runners/__pycache__/__init__.cpython-312.pyc +0 -0
- clarifai/runners/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/runners/__pycache__/server.cpython-312.pyc +0 -0
- clarifai/runners/models/__pycache__/__init__.cpython-312.pyc +0 -0
- clarifai/runners/models/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/runners/models/__pycache__/base_typed_model.cpython-312.pyc +0 -0
- clarifai/runners/models/__pycache__/mcp_class.cpython-312.pyc +0 -0
- clarifai/runners/models/__pycache__/model_builder.cpython-312.pyc +0 -0
- clarifai/runners/models/__pycache__/model_builder.cpython-39.pyc +0 -0
- clarifai/runners/models/__pycache__/model_class.cpython-312.pyc +0 -0
- clarifai/runners/models/__pycache__/model_run_locally.cpython-312.pyc +0 -0
- clarifai/runners/models/__pycache__/model_runner.cpython-312.pyc +0 -0
- clarifai/runners/models/__pycache__/model_servicer.cpython-312.pyc +0 -0
- clarifai/runners/models/__pycache__/test_model_builder.cpython-312-pytest-8.3.5.pyc +0 -0
- clarifai/runners/models/base_typed_model.py +238 -0
- clarifai/runners/models/example_mcp_server.py +44 -0
- clarifai/runners/models/mcp_class.py +143 -0
- clarifai/runners/models/mcp_class.py~ +149 -0
- clarifai/runners/models/model_builder.py +167 -38
- clarifai/runners/models/model_class.py +5 -22
- clarifai/runners/models/model_run_locally.py +0 -4
- clarifai/runners/models/test_model_builder.py +89 -0
- clarifai/runners/models/visual_classifier_class.py +75 -0
- clarifai/runners/models/visual_detector_class.py +79 -0
- clarifai/runners/utils/__pycache__/__init__.cpython-312.pyc +0 -0
- clarifai/runners/utils/__pycache__/code_script.cpython-312.pyc +0 -0
- clarifai/runners/utils/__pycache__/const.cpython-312.pyc +0 -0
- clarifai/runners/utils/__pycache__/data_handler.cpython-312.pyc +0 -0
- clarifai/runners/utils/__pycache__/data_types.cpython-312.pyc +0 -0
- clarifai/runners/utils/__pycache__/data_utils.cpython-312.pyc +0 -0
- clarifai/runners/utils/__pycache__/loader.cpython-312.pyc +0 -0
- clarifai/runners/utils/__pycache__/method_signatures.cpython-312.pyc +0 -0
- clarifai/runners/utils/__pycache__/serializers.cpython-312.pyc +0 -0
- clarifai/runners/utils/__pycache__/url_fetcher.cpython-312.pyc +0 -0
- clarifai/runners/utils/code_script.py +41 -44
- clarifai/runners/utils/const.py +15 -0
- clarifai/runners/utils/data_handler.py +231 -0
- clarifai/runners/utils/data_types/__pycache__/__init__.cpython-312.pyc +0 -0
- clarifai/runners/utils/data_types/__pycache__/data_types.cpython-312.pyc +0 -0
- clarifai/runners/utils/data_utils.py +33 -5
- clarifai/runners/utils/loader.py +23 -2
- clarifai/runners/utils/method_signatures.py +4 -4
- clarifai/schema/__pycache__/search.cpython-312.pyc +0 -0
- clarifai/urls/__pycache__/helper.cpython-312.pyc +0 -0
- clarifai/utils/__pycache__/__init__.cpython-312.pyc +0 -0
- clarifai/utils/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/utils/__pycache__/cli.cpython-312.pyc +0 -0
- clarifai/utils/__pycache__/config.cpython-312.pyc +0 -0
- clarifai/utils/__pycache__/constants.cpython-312.pyc +0 -0
- clarifai/utils/__pycache__/constants.cpython-39.pyc +0 -0
- clarifai/utils/__pycache__/logging.cpython-312.pyc +0 -0
- clarifai/utils/__pycache__/logging.cpython-39.pyc +0 -0
- clarifai/utils/__pycache__/misc.cpython-312.pyc +0 -0
- clarifai/utils/__pycache__/misc.cpython-39.pyc +0 -0
- clarifai/utils/__pycache__/model_train.cpython-312.pyc +0 -0
- clarifai/utils/__pycache__/protobuf.cpython-312.pyc +0 -0
- clarifai/utils/config.py +19 -0
- clarifai/utils/config.py~ +145 -0
- clarifai/utils/evaluation/__pycache__/__init__.cpython-312.pyc +0 -0
- clarifai/utils/evaluation/__pycache__/helpers.cpython-312.pyc +0 -0
- clarifai/utils/evaluation/__pycache__/main.cpython-312.pyc +0 -0
- clarifai/utils/logging.py +22 -5
- clarifai/workflows/__pycache__/__init__.cpython-312.pyc +0 -0
- clarifai/workflows/__pycache__/export.cpython-312.pyc +0 -0
- clarifai/workflows/__pycache__/utils.cpython-312.pyc +0 -0
- clarifai/workflows/__pycache__/validate.cpython-312.pyc +0 -0
- {clarifai-11.4.1.dist-info → clarifai-11.4.3rc1.dist-info}/METADATA +2 -14
- clarifai-11.4.3rc1.dist-info/RECORD +230 -0
- {clarifai-11.4.1.dist-info → clarifai-11.4.3rc1.dist-info}/WHEEL +1 -1
- clarifai-11.4.1.dist-info/RECORD +0 -109
- {clarifai-11.4.1.dist-info/licenses → clarifai-11.4.3rc1.dist-info}/LICENSE +0 -0
- {clarifai-11.4.1.dist-info → clarifai-11.4.3rc1.dist-info}/entry_points.txt +0 -0
- {clarifai-11.4.1.dist-info → clarifai-11.4.3rc1.dist-info}/top_level.txt +0 -0
@@ -442,10 +442,6 @@ def main(
|
|
442
442
|
manager = ModelRunLocally(model_path)
|
443
443
|
# get whatever stage is in config.yaml to force download now
|
444
444
|
# also always write to where upload/build wants to, not the /tmp folder that runtime stage uses
|
445
|
-
_, _, _, when, _, _ = manager.builder._validate_config_checkpoints()
|
446
|
-
manager.builder.download_checkpoints(
|
447
|
-
stage=when, checkpoint_path_override=manager.builder.checkpoint_path
|
448
|
-
)
|
449
445
|
if inside_container:
|
450
446
|
if not manager.is_docker_installed():
|
451
447
|
sys.exit(1)
|
@@ -0,0 +1,89 @@
|
|
1
|
+
import unittest
|
2
|
+
from unittest.mock import patch, mock_open
|
3
|
+
from clarifai.runners.models.model_builder import (
|
4
|
+
ModelBuilder,
|
5
|
+
DEFAULT_DOWNLOAD_CHECKPOINT_WHEN,
|
6
|
+
)
|
7
|
+
|
8
|
+
mock_data = """
|
9
|
+
checkpoints:
|
10
|
+
type: huggingface
|
11
|
+
repo_id: test_repo
|
12
|
+
model:
|
13
|
+
user_id: test_user
|
14
|
+
app_id: test_app
|
15
|
+
id: test_model
|
16
|
+
model_type_id: test_type
|
17
|
+
inference_compute_info:
|
18
|
+
cpu_limit: "2"
|
19
|
+
cpu_memory: "4Gi"
|
20
|
+
num_accelerators: 0
|
21
|
+
"""
|
22
|
+
|
23
|
+
|
24
|
+
class TestModelBuilder(unittest.TestCase):
|
25
|
+
@patch("builtins.open", new_callable=mock_open, read_data=mock_data)
|
26
|
+
@patch("os.path.exists")
|
27
|
+
@patch("os.listdir")
|
28
|
+
def test_validate_folder(self, mock_listdir, mock_exists, mock_open_file):
|
29
|
+
mock_exists.return_value = True
|
30
|
+
mock_listdir.return_value = ["config.yaml", "1", "requirements.txt"]
|
31
|
+
|
32
|
+
builder = ModelBuilder(folder="test_folder", validate_api_ids=False)
|
33
|
+
validated_folder = builder._validate_folder("test_folder")
|
34
|
+
self.assertIn("test_folder", validated_folder)
|
35
|
+
|
36
|
+
def test_default_download_checkpoint_when(self):
|
37
|
+
self.assertEqual(DEFAULT_DOWNLOAD_CHECKPOINT_WHEN, "runtime")
|
38
|
+
|
39
|
+
@patch(
|
40
|
+
"builtins.open",
|
41
|
+
new_callable=mock_open,
|
42
|
+
read_data="checkpoints:\n type: huggingface\n repo_id: test_repo\n",
|
43
|
+
)
|
44
|
+
@patch("os.path.exists")
|
45
|
+
@patch("yaml.safe_load")
|
46
|
+
def test_load_config(self, mock_yaml_load, mock_exists, mock_open_file):
|
47
|
+
mock_exists.return_value = True
|
48
|
+
mock_yaml_load.return_value = {
|
49
|
+
"checkpoints": {"type": "huggingface", "repo_id": "test_repo"}
|
50
|
+
}
|
51
|
+
config = ModelBuilder._load_config("config.yaml")
|
52
|
+
self.assertIn("checkpoints", config)
|
53
|
+
self.assertEqual(config["checkpoints"]["type"], "huggingface")
|
54
|
+
|
55
|
+
@patch("shutil.copy")
|
56
|
+
@patch("os.path.exists")
|
57
|
+
def test_backup_config(self, mock_exists, mock_copy):
|
58
|
+
mock_exists.side_effect = [True, False] # config exists, backup does not
|
59
|
+
ModelBuilder._backup_config("config.yaml")
|
60
|
+
mock_copy.assert_called_once_with("config.yaml", "config.yaml.bak")
|
61
|
+
|
62
|
+
@patch("builtins.open", new_callable=mock_open)
|
63
|
+
@patch("yaml.safe_dump")
|
64
|
+
def test_save_config(self, mock_yaml_dump, mock_open_file):
|
65
|
+
config = {"key": "value"}
|
66
|
+
ModelBuilder._save_config("config.yaml", config)
|
67
|
+
mock_yaml_dump.assert_called_once_with(config, mock_open_file())
|
68
|
+
|
69
|
+
def test_validate_config_model(self):
|
70
|
+
builder = ModelBuilder(folder="test_folder", validate_api_ids=False)
|
71
|
+
builder.config = {"model": {}}
|
72
|
+
try:
|
73
|
+
builder._validate_config_model()
|
74
|
+
except AssertionError:
|
75
|
+
self.fail("_validate_config_model raised AssertionError unexpectedly!")
|
76
|
+
|
77
|
+
@patch("os.path.exists")
|
78
|
+
@patch("os.listdir")
|
79
|
+
def test_validate_folder_missing_config(self, mock_listdir, mock_exists):
|
80
|
+
mock_exists.return_value = True
|
81
|
+
mock_listdir.return_value = ["1", "requirements.txt"]
|
82
|
+
|
83
|
+
builder = ModelBuilder(folder="test_folder", validate_api_ids=False)
|
84
|
+
with self.assertRaises(AssertionError):
|
85
|
+
builder._validate_folder("test_folder")
|
86
|
+
|
87
|
+
|
88
|
+
if __name__ == "__main__":
|
89
|
+
unittest.main()
|
@@ -0,0 +1,75 @@
|
|
1
|
+
import os
|
2
|
+
import tempfile
|
3
|
+
from io import BytesIO
|
4
|
+
from typing import Dict, Iterator, List
|
5
|
+
|
6
|
+
import cv2
|
7
|
+
import torch
|
8
|
+
from PIL import Image as PILImage
|
9
|
+
|
10
|
+
from clarifai.runners.models.model_class import ModelClass
|
11
|
+
from clarifai.runners.utils.data_types import Concept, Frame, Image
|
12
|
+
from clarifai.utils.logging import logger
|
13
|
+
|
14
|
+
|
15
|
+
class VisualClassifierClass(ModelClass):
|
16
|
+
"""Base class for visual classification models supporting image and video processing."""
|
17
|
+
|
18
|
+
@staticmethod
|
19
|
+
def preprocess_image(image_bytes: bytes) -> PILImage:
|
20
|
+
"""Convert image bytes to PIL Image."""
|
21
|
+
return PILImage.open(BytesIO(image_bytes)).convert("RGB")
|
22
|
+
|
23
|
+
@staticmethod
|
24
|
+
def video_to_frames(video_bytes: bytes) -> Iterator[Frame]:
|
25
|
+
"""Convert video bytes to frames.
|
26
|
+
|
27
|
+
Args:
|
28
|
+
video_bytes: Raw video data in bytes
|
29
|
+
|
30
|
+
Yields:
|
31
|
+
Frame with JPEG encoded frame data as bytes and timestamp in milliseconds
|
32
|
+
"""
|
33
|
+
with tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") as temp_video_file:
|
34
|
+
temp_video_file.write(video_bytes)
|
35
|
+
temp_video_path = temp_video_file.name
|
36
|
+
logger.debug(f"temp_video_path: {temp_video_path}")
|
37
|
+
|
38
|
+
video = cv2.VideoCapture(temp_video_path)
|
39
|
+
logger.debug(f"video opened: {video.isOpened()}")
|
40
|
+
|
41
|
+
while video.isOpened():
|
42
|
+
ret, frame = video.read()
|
43
|
+
if not ret:
|
44
|
+
break
|
45
|
+
# Get frame timestamp in milliseconds
|
46
|
+
timestamp_ms = video.get(cv2.CAP_PROP_POS_MSEC)
|
47
|
+
frame_bytes = cv2.imencode('.jpg', frame)[1].tobytes()
|
48
|
+
yield Frame(image=Image(bytes=frame_bytes), time=timestamp_ms)
|
49
|
+
|
50
|
+
video.release()
|
51
|
+
os.unlink(temp_video_path)
|
52
|
+
|
53
|
+
@staticmethod
|
54
|
+
def process_concepts(
|
55
|
+
logits: torch.Tensor, threshold: float, model_labels: Dict[int, str]
|
56
|
+
) -> List[List[Concept]]:
|
57
|
+
"""Convert model logits into a structured format of concepts.
|
58
|
+
|
59
|
+
Args:
|
60
|
+
logits: Model output logits as a tensor (batch_size x num_classes)
|
61
|
+
model_labels: Dictionary mapping label indices to label names
|
62
|
+
|
63
|
+
Returns:
|
64
|
+
List of lists containing Concept objects for each input in the batch
|
65
|
+
"""
|
66
|
+
outputs = []
|
67
|
+
for logit in logits:
|
68
|
+
probs = torch.softmax(logit, dim=-1)
|
69
|
+
sorted_indices = torch.argsort(probs, dim=-1, descending=True)
|
70
|
+
output_concepts = []
|
71
|
+
for idx in sorted_indices:
|
72
|
+
concept = Concept(name=model_labels[idx.item()], value=probs[idx].item())
|
73
|
+
output_concepts.append(concept)
|
74
|
+
outputs.append(output_concepts)
|
75
|
+
return outputs
|
@@ -0,0 +1,79 @@
|
|
1
|
+
import os
|
2
|
+
import tempfile
|
3
|
+
from io import BytesIO
|
4
|
+
from typing import Dict, Iterator, List
|
5
|
+
|
6
|
+
import cv2
|
7
|
+
import torch
|
8
|
+
from PIL import Image as PILImage
|
9
|
+
|
10
|
+
from clarifai.runners.models.model_class import ModelClass
|
11
|
+
from clarifai.runners.utils.data_types import Concept, Frame, Image, Region
|
12
|
+
from clarifai.utils.logging import logger
|
13
|
+
|
14
|
+
|
15
|
+
class VisualDetectorClass(ModelClass):
|
16
|
+
"""Base class for visual detection models supporting image and video processing."""
|
17
|
+
|
18
|
+
@staticmethod
|
19
|
+
def preprocess_image(image_bytes: bytes) -> PILImage:
|
20
|
+
"""Convert image bytes to PIL Image."""
|
21
|
+
return PILImage.open(BytesIO(image_bytes)).convert("RGB")
|
22
|
+
|
23
|
+
@staticmethod
|
24
|
+
def video_to_frames(video_bytes: bytes) -> Iterator[Frame]:
|
25
|
+
"""Convert video bytes to frames.
|
26
|
+
|
27
|
+
Args:
|
28
|
+
video_bytes: Raw video data in bytes
|
29
|
+
|
30
|
+
Yields:
|
31
|
+
Frame with JPEG encoded frame data as bytes and timestamp in milliseconds
|
32
|
+
"""
|
33
|
+
with tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") as temp_video_file:
|
34
|
+
temp_video_file.write(video_bytes)
|
35
|
+
temp_video_path = temp_video_file.name
|
36
|
+
logger.debug(f"temp_video_path: {temp_video_path}")
|
37
|
+
|
38
|
+
video = cv2.VideoCapture(temp_video_path)
|
39
|
+
logger.debug(f"video opened: {video.isOpened()}")
|
40
|
+
|
41
|
+
while video.isOpened():
|
42
|
+
ret, frame = video.read()
|
43
|
+
if not ret:
|
44
|
+
break
|
45
|
+
# Get frame timestamp in milliseconds
|
46
|
+
timestamp_ms = video.get(cv2.CAP_PROP_POS_MSEC)
|
47
|
+
frame_bytes = cv2.imencode('.jpg', frame)[1].tobytes()
|
48
|
+
yield Frame(image=Image(bytes=frame_bytes), time=timestamp_ms)
|
49
|
+
|
50
|
+
video.release()
|
51
|
+
os.unlink(temp_video_path)
|
52
|
+
|
53
|
+
@staticmethod
|
54
|
+
def process_detections(
|
55
|
+
results: List[Dict[str, torch.Tensor]], threshold: float, model_labels: Dict[int, str]
|
56
|
+
) -> List[List[Region]]:
|
57
|
+
"""Convert model outputs into a structured format of detections.
|
58
|
+
|
59
|
+
Args:
|
60
|
+
results: Raw detection results from model
|
61
|
+
threshold: Confidence threshold for detections
|
62
|
+
model_labels: Dictionary mapping label indices to names
|
63
|
+
|
64
|
+
Returns:
|
65
|
+
List of lists containing Region objects for each detection
|
66
|
+
"""
|
67
|
+
outputs = []
|
68
|
+
for result in results:
|
69
|
+
detections = []
|
70
|
+
for score, label_idx, box in zip(result["scores"], result["labels"], result["boxes"]):
|
71
|
+
if score > threshold:
|
72
|
+
label = model_labels[label_idx.item()]
|
73
|
+
detections.append(
|
74
|
+
Region(
|
75
|
+
box=box.tolist(), concepts=[Concept(name=label, value=score.item())]
|
76
|
+
)
|
77
|
+
)
|
78
|
+
outputs.append(detections)
|
79
|
+
return outputs
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -3,7 +3,7 @@ from typing import List
|
|
3
3
|
|
4
4
|
from clarifai_grpc.grpc.api import resources_pb2
|
5
5
|
|
6
|
-
from clarifai.runners.utils import
|
6
|
+
from clarifai.runners.utils import data_utils
|
7
7
|
|
8
8
|
|
9
9
|
def generate_client_script(
|
@@ -35,19 +35,12 @@ from clarifai.runners.utils import data_types
|
|
35
35
|
model_section = """
|
36
36
|
model = Model.from_current_context()"""
|
37
37
|
else:
|
38
|
-
model_section = """
|
39
|
-
|
38
|
+
model_section = f"""
|
39
|
+
model = Model("https://clarifai.com/{user_id}/{app_id}/models/{model_id}",
|
40
40
|
deployment_id = {deployment_id}, # Only needed for dedicated deployed models
|
41
41
|
{base_url_str}
|
42
42
|
)
|
43
43
|
"""
|
44
|
-
model_section = _CLIENT_TEMPLATE.format(
|
45
|
-
user_id=user_id,
|
46
|
-
app_id=app_id,
|
47
|
-
model_id=model_id,
|
48
|
-
deployment_id=deployment_id,
|
49
|
-
base_url_str=base_url_str,
|
50
|
-
)
|
51
44
|
|
52
45
|
# Generate client template
|
53
46
|
client_template = _CLIENT_TEMPLATE.format(
|
@@ -58,28 +51,24 @@ model = Model.from_current_context()"""
|
|
58
51
|
method_signatures_str = []
|
59
52
|
for method_signature in method_signatures:
|
60
53
|
method_name = method_signature.name
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
client_script_str
|
77
|
-
|
78
|
-
|
79
|
-
elif method_signature.method_type == resources_pb2.RunnerMethodType.UNARY_STREAMING:
|
80
|
-
client_script_str += "\nfor res in response:\n print(res)"
|
81
|
-
client_script_str += "\n"
|
82
|
-
method_signatures_str.append(client_script_str)
|
54
|
+
client_script_str = f'response = model.{method_name}('
|
55
|
+
annotations = _get_annotations_source(method_signature)
|
56
|
+
for param_name, (param_type, default_value) in annotations.items():
|
57
|
+
print(
|
58
|
+
f"param_name: {param_name}, param_type: {param_type}, default_value: {default_value}"
|
59
|
+
)
|
60
|
+
if param_name == "return":
|
61
|
+
continue
|
62
|
+
if default_value is None:
|
63
|
+
default_value = _set_default_value(param_type)
|
64
|
+
client_script_str += f"{param_name}={default_value}, "
|
65
|
+
client_script_str = client_script_str.rstrip(", ") + ")"
|
66
|
+
if method_signature.method_type == resources_pb2.RunnerMethodType.UNARY_UNARY:
|
67
|
+
client_script_str += "\nprint(response)"
|
68
|
+
elif method_signature.method_type == resources_pb2.RunnerMethodType.UNARY_STREAMING:
|
69
|
+
client_script_str += "\nfor res in response:\n print(res)"
|
70
|
+
client_script_str += "\n"
|
71
|
+
method_signatures_str.append(client_script_str)
|
83
72
|
|
84
73
|
method_signatures_str = "\n".join(method_signatures_str)
|
85
74
|
# Combine all parts
|
@@ -107,9 +96,8 @@ def _get_annotations_source(method_signature: resources_pb2.MethodSignature) ->
|
|
107
96
|
if input_field.iterator:
|
108
97
|
param_type = f"Iterator[{param_type}]"
|
109
98
|
default_value = None
|
110
|
-
if input_field
|
99
|
+
if data_utils.Param.get_default(input_field):
|
111
100
|
default_value = _parse_default_value(input_field)
|
112
|
-
|
113
101
|
annotations[param_name] = (param_type, default_value)
|
114
102
|
if not method_signature.output_fields:
|
115
103
|
raise ValueError("MethodSignature must have at least one output field")
|
@@ -177,23 +165,21 @@ def _map_default_value(field_type):
|
|
177
165
|
elif field_type == "bool":
|
178
166
|
default_value = False
|
179
167
|
elif field_type == "data_types.Image":
|
180
|
-
default_value = data_types.Image.from_url("https://samples.clarifai.com/metro-north.jpg")
|
168
|
+
default_value = 'data_types.Image.from_url("https://samples.clarifai.com/metro-north.jpg")'
|
181
169
|
elif field_type == "data_types.Text":
|
182
|
-
default_value = data_types.Text("What
|
170
|
+
default_value = 'data_types.Text("What is the future of AI?")'
|
183
171
|
elif field_type == "data_types.Audio":
|
184
|
-
default_value = data_types.Audio.from_url("https://samples.clarifai.com/audio.mp3")
|
172
|
+
default_value = 'data_types.Audio.from_url("https://samples.clarifai.com/audio.mp3")'
|
185
173
|
elif field_type == "data_types.Video":
|
186
|
-
default_value = data_types.Video.from_url("https://samples.clarifai.com/video.mp4")
|
174
|
+
default_value = 'data_types.Video.from_url("https://samples.clarifai.com/video.mp4")'
|
187
175
|
elif field_type == "data_types.Concept":
|
188
|
-
default_value = data_types.Concept(id="concept_id", name="dog", value=0.95)
|
176
|
+
default_value = 'data_types.Concept(id="concept_id", name="dog", value=0.95)'
|
189
177
|
elif field_type == "data_types.Region":
|
190
|
-
default_value = data_types.Region(
|
191
|
-
box=[0.1, 0.1, 0.5, 0.5],
|
192
|
-
)
|
178
|
+
default_value = 'data_types.Region(box=[0.1, 0.1, 0.5, 0.5],)'
|
193
179
|
elif field_type == "data_types.Frame":
|
194
|
-
default_value = data_types.Frame.from_url("https://samples.clarifai.com/video.mp4", 0)
|
180
|
+
default_value = 'data_types.Frame.from_url("https://samples.clarifai.com/video.mp4", 0)'
|
195
181
|
elif field_type == "data_types.NDArray":
|
196
|
-
default_value = data_types.NDArray([1, 2, 3])
|
182
|
+
default_value = 'data_types.NDArray([1, 2, 3])'
|
197
183
|
else:
|
198
184
|
default_value = None
|
199
185
|
return default_value
|
@@ -203,6 +189,12 @@ def _set_default_value(field_type):
|
|
203
189
|
"""
|
204
190
|
Set the default value of a field if it is not set.
|
205
191
|
"""
|
192
|
+
is_iterator = False
|
193
|
+
print(f"before field_type: {field_type}")
|
194
|
+
if field_type.startswith("Iterator["):
|
195
|
+
is_iterator = True
|
196
|
+
field_type = field_type[9:-1]
|
197
|
+
print(f"after field_type: {field_type}")
|
206
198
|
default_value = None
|
207
199
|
default_value = _map_default_value(field_type)
|
208
200
|
if field_type.startswith("List["):
|
@@ -219,6 +211,11 @@ def _set_default_value(field_type):
|
|
219
211
|
element_type_defaults = [_map_default_value(et) for et in element_types]
|
220
212
|
default_value = f"{{{', '.join([str(et) for et in element_type_defaults])}}}"
|
221
213
|
|
214
|
+
if field_type == 'str':
|
215
|
+
default_value = repr(default_value)
|
216
|
+
if is_iterator:
|
217
|
+
default_value = f'iter([{default_value}])'
|
218
|
+
print(f"after default_value: {default_value}")
|
222
219
|
return default_value
|
223
220
|
|
224
221
|
|
clarifai/runners/utils/const.py
CHANGED
@@ -4,14 +4,28 @@ registry = os.environ.get('CLARIFAI_BASE_IMAGE_REGISTRY', 'public.ecr.aws/clarif
|
|
4
4
|
|
5
5
|
GIT_SHA = "b8ae56bf3b7c95e686ca002b07ca83d259c716eb"
|
6
6
|
|
7
|
+
AMD_GIT_SHA = "81e942130173f54927e7c9a65aabc7e32780616d"
|
8
|
+
|
7
9
|
PYTHON_BASE_IMAGE = registry + '/python-base:{python_version}-' + GIT_SHA
|
8
10
|
TORCH_BASE_IMAGE = registry + '/torch:{torch_version}-py{python_version}-{gpu_version}-' + GIT_SHA
|
9
11
|
|
12
|
+
AMD_PYTHON_BASE_IMAGE = registry + '/amd-python-base:{python_version}-' + AMD_GIT_SHA
|
13
|
+
AMD_TORCH_BASE_IMAGE = (
|
14
|
+
registry + '/amd-torch:{torch_version}-py{python_version}-{gpu_version}-' + AMD_GIT_SHA
|
15
|
+
)
|
16
|
+
AMD_VLLM_BASE_IMAGE = (
|
17
|
+
registry + '/amd-vllm:{torch_version}-py{python_version}-{gpu_version}-' + AMD_GIT_SHA
|
18
|
+
)
|
19
|
+
|
10
20
|
# List of available python base images
|
11
21
|
AVAILABLE_PYTHON_IMAGES = ['3.11', '3.12']
|
12
22
|
|
13
23
|
DEFAULT_PYTHON_VERSION = 3.12
|
14
24
|
|
25
|
+
DEFAULT_AMD_TORCH_VERSION = '2.8.0.dev20250511+rocm6.4'
|
26
|
+
|
27
|
+
DEFAULT_AMD_GPU_VERSION = 'rocm6.4'
|
28
|
+
|
15
29
|
# By default we download at runtime.
|
16
30
|
DEFAULT_DOWNLOAD_CHECKPOINT_WHEN = "runtime"
|
17
31
|
|
@@ -29,6 +43,7 @@ AVAILABLE_TORCH_IMAGES = [
|
|
29
43
|
'2.7.0-py3.12-cu128',
|
30
44
|
'2.7.0-py3.12-rocm6.3',
|
31
45
|
]
|
46
|
+
|
32
47
|
CONCEPTS_REQUIRED_MODEL_TYPE = [
|
33
48
|
'visual-classifier',
|
34
49
|
'visual-detector',
|