From 03c248046e7994e9ef49cfa577d7cde5888a65d5 Mon Sep 17 00:00:00 2001 From: Dillon Laird Date: Mon, 22 Apr 2024 14:25:41 -0700 Subject: [PATCH 01/16] added custom tools --- tests/tools/test_tools.py | 70 ++++++++++++++++++++++++++++++++++ vision_agent/tools/__init__.py | 1 + vision_agent/tools/tools.py | 26 ++++++++++++- 3 files changed, 96 insertions(+), 1 deletion(-) diff --git a/tests/tools/test_tools.py b/tests/tools/test_tools.py index 12c21347..6de8d6c8 100644 --- a/tests/tools/test_tools.py +++ b/tests/tools/test_tools.py @@ -2,8 +2,10 @@ import tempfile import numpy as np +import pytest from PIL import Image +from vision_agent.tools import TOOLS, Tool, register_tool from vision_agent.tools.tools import BboxIoU, BoxDistance, SegArea, SegIoU @@ -65,3 +67,71 @@ def test_box_distance(): box1 = [0, 0, 2, 2] box2 = [1, 1, 3, 3] assert box_dist(box1, box2) == 0.0 + + +def test_register_tool(): + assert TOOLS[len(TOOLS) - 1]["name"] != "test_tool_" + + @register_tool + class TestTool(Tool): + name = "test_tool_" + description = "Test Tool" + usage = { + "required_parameters": [{"name": "prompt", "type": "str"}], + "examples": [ + { + "scenario": "Test", + "parameters": {"prompt": "Test Prompt"}, + } + ], + } + + def __call__(self, prompt: str) -> str: + return prompt + + assert TOOLS[len(TOOLS) - 1]["name"] == "test_tool_" + + +def test_register_tool_incorrect(): + with pytest.raises(ValueError): + + @register_tool + class NoAttributes(Tool): + pass + + with pytest.raises(ValueError): + + @register_tool + class NoName(Tool): + description = "Test Tool" + usage = { + "required_parameters": [{"name": "prompt", "type": "str"}], + "examples": [ + { + "scenario": "Test", + "parameters": {"prompt": "Test Prompt"}, + } + ], + } + + with pytest.raises(ValueError): + + @register_tool + class NoDescription(Tool): + name = "test_tool_" + usage = { + "required_parameters": [{"name": "prompt", "type": "str"}], + "examples": [ + { + "scenario": "Test", + "parameters": {"prompt": "Test Prompt"}, + } + ], + } + + with pytest.raises(ValueError): + + @register_tool + class NoUsage(Tool): + name = "test_tool_" + description = "Test Tool" diff --git a/vision_agent/tools/__init__.py b/vision_agent/tools/__init__.py index 1c1c6e73..bf6bf70d 100644 --- a/vision_agent/tools/__init__.py +++ b/vision_agent/tools/__init__.py @@ -14,4 +14,5 @@ SegArea, SegIoU, Tool, + register_tool, ) diff --git a/vision_agent/tools/tools.py b/vision_agent/tools/tools.py index 6d2a7b47..711fc894 100644 --- a/vision_agent/tools/tools.py +++ b/vision_agent/tools/tools.py @@ -2,7 +2,7 @@ import tempfile from abc import ABC from pathlib import Path -from typing import Any, Dict, List, Tuple, Union, cast +from typing import Any, Dict, List, Tuple, Type, Union, cast import numpy as np import requests @@ -765,6 +765,30 @@ def __call__(self, equation: str) -> float: } +def register_tool(tool: Type[Tool]) -> None: + r"""Add a tool to the list of available tools. + + Parameters: + tool: The tool to add. + """ + + if ( + not hasattr(tool, "name") + or not hasattr(tool, "description") + or not hasattr(tool, "usage") + ): + raise ValueError( + "The tool must have 'name', 'description' and 'usage' attributes." + ) + + TOOLS[len(TOOLS)] = { + "name": tool.name, + "description": tool.description, + "usage": tool.usage, + "class": tool, + } + + def _send_inference_request( payload: Dict[str, Any], endpoint_name: str ) -> Dict[str, Any]: From 9effc1f4e054ad357e67a62dcde0cd38445fb4c0 Mon Sep 17 00:00:00 2001 From: Dillon Laird Date: Mon, 22 Apr 2024 14:38:41 -0700 Subject: [PATCH 02/16] updated readme --- README.md | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 741b8ff2..3daa36ef 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ pip install vision-agent ``` Ensure you have an OpenAI API key and set it as an environment variable (if you are -using Azure OpenAI please see the additional setup section): +using Azure OpenAI please see the Azure setup section): ```bash export OPENAI_API_KEY="your-api-key" @@ -96,6 +96,31 @@ you. For example: }] ``` +#### Custom Tools +You can also add your own custom tools for your vision agent to use: + +```python +>>> from vision_agent.tools import Tool, register_tool +>>> @register_tool +>>> class NumItems(Tool): +>>> name = "num_items_" +>>> description = "Returns the number of items in a list." +>>> usage = { +>>> "required_parameters": [{"name": "prompt", "type": "list"}], +>>> "examples": [ +>>> { +>>> "scenario": "How many items are in this list? ['a', 'b', 'c']", +>>> "parameters": {"prompt": "['a', 'b', 'c']"}, +>>> } +>>> ], +>>> } +>>> def __call__(self, prompt: str) -> int: +>>> return len(prompt) +``` +This will register it with the list of tools Vision Agent has access to. It will be able +to pick it based on the tool description and use it based on the usage provided. + +#### Tool List | Tool | Description | | --- | --- | | CLIP | CLIP is a tool that can classify or tag any image given a set of input classes or tags. | @@ -112,7 +137,7 @@ you. For example: It also has a basic set of calculate tools such as add, subtract, multiply and divide. -### Additional Setup +### Azure Setup If you want to use Azure OpenAI models, you can set the environment variable: ```bash From eb793f3a6d147f6d83584663ca30821d3b2ddcf8 Mon Sep 17 00:00:00 2001 From: Dillon Laird Date: Mon, 22 Apr 2024 19:12:11 -0700 Subject: [PATCH 03/16] register tool returns tool' --- vision_agent/tools/tools.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/vision_agent/tools/tools.py b/vision_agent/tools/tools.py index 711fc894..67dc2292 100644 --- a/vision_agent/tools/tools.py +++ b/vision_agent/tools/tools.py @@ -52,6 +52,9 @@ class Tool(ABC): description: str usage: Dict + def __call__(self, *args: Any, **kwargs: Any) -> Any: + raise NotImplementedError + class NoOp(Tool): name = "noop_" @@ -765,7 +768,7 @@ def __call__(self, equation: str) -> float: } -def register_tool(tool: Type[Tool]) -> None: +def register_tool(tool: Type[Tool]) -> Type[Tool]: r"""Add a tool to the list of available tools. Parameters: @@ -787,6 +790,7 @@ def register_tool(tool: Type[Tool]) -> None: "usage": tool.usage, "class": tool, } + return tool def _send_inference_request( From 84b5d9ded09d720be49f20300fc1360fd4ef1494 Mon Sep 17 00:00:00 2001 From: Asia <92344512+AsiaCao@users.noreply.github.com> Date: Mon, 22 Apr 2024 13:52:23 -0700 Subject: [PATCH 04/16] Add a new tool: determine if a bbox is contained within another bbox (#59) * Add a new bounding box contains tool * Fix format --- vision_agent/agent/vision_agent.py | 5 ++- vision_agent/tools/tools.py | 69 +++++++++++++++++++++++++----- 2 files changed, 62 insertions(+), 12 deletions(-) diff --git a/vision_agent/agent/vision_agent.py b/vision_agent/agent/vision_agent.py index bbd2c1a5..3287a174 100644 --- a/vision_agent/agent/vision_agent.py +++ b/vision_agent/agent/vision_agent.py @@ -33,6 +33,7 @@ logging.basicConfig(stream=sys.stdout) _LOGGER = logging.getLogger(__name__) +_MAX_TABULATE_COL_WIDTH = 80 def parse_json(s: str) -> Any: @@ -614,7 +615,7 @@ def retrieval( self.log_progress( f"""Going to run the following tool(s) in sequence: -{tabulate([tool_results], headers="keys", tablefmt="mixed_grid")}""" +{tabulate(tabular_data=[tool_results], headers="keys", tablefmt="mixed_grid", maxcolwidths=_MAX_TABULATE_COL_WIDTH)}""" ) def parse_tool_results(result: Dict[str, Union[Dict, List]]) -> Any: @@ -660,6 +661,6 @@ def create_tasks( task_list = [] self.log_progress( f"""Planned tasks: -{tabulate(task_list, headers="keys", tablefmt="mixed_grid")}""" +{tabulate(task_list, headers="keys", tablefmt="mixed_grid", maxcolwidths=_MAX_TABULATE_COL_WIDTH)}""" ) return task_list diff --git a/vision_agent/tools/tools.py b/vision_agent/tools/tools.py index 67dc2292..36b8454c 100644 --- a/vision_agent/tools/tools.py +++ b/vision_agent/tools/tools.py @@ -253,7 +253,7 @@ def __call__( iou_threshold: the threshold for intersection over union used in nms algorithm. It will suppress the boxes which have iou greater than this threshold. Returns: - A list of dictionaries containing the labels, scores, and bboxes. Each dictionary contains the detection result for an image. + A dictionary containing the labels, scores, and bboxes, which is the detection result for the input image. """ image_size = get_image_size(image) image_b64 = convert_to_b64(image) @@ -349,7 +349,7 @@ def __call__( iou_threshold: the threshold for intersection over union used in nms algorithm. It will suppress the boxes which have iou greater than this threshold. Returns: - A list of dictionaries containing the labels, scores, bboxes and masks. Each dictionary contains the segmentation result for an image. + A dictionary containing the labels, scores, bboxes and masks for the input image. """ image_size = get_image_size(image) image_b64 = convert_to_b64(image) @@ -360,19 +360,15 @@ def __call__( "kwargs": {"box_threshold": box_threshold, "iou_threshold": iou_threshold}, } data: Dict[str, Any] = _send_inference_request(request_data, "tools") - ret_pred: Dict[str, List] = {"labels": [], "bboxes": [], "masks": []} if "bboxes" in data: - ret_pred["bboxes"] = [ - normalize_bbox(box, image_size) for box in data["bboxes"] - ] + data["bboxes"] = [normalize_bbox(box, image_size) for box in data["bboxes"]] if "masks" in data: - ret_pred["masks"] = [ + data["masks"] = [ rle_decode(mask_rle=mask, shape=data["mask_shape"]) for mask in data["masks"] ] - ret_pred["labels"] = data["labels"] - ret_pred["scores"] = data["scores"] - return ret_pred + data.pop("mask_shape", None) + return data class DINOv(Tool): @@ -646,6 +642,58 @@ def __call__(self, mask1: Union[str, Path], mask2: Union[str, Path]) -> float: return cast(float, round(iou, 2)) +class BboxContains(Tool): + name = "bbox_contains_" + description = "Given two bounding boxes, a target bounding box and a region bounding box, 'bbox_contains_' returns the intersection of the two bounding boxes over the target bounding box, reflects the percentage area of the target bounding box overlaps with the region bounding box. This is a good tool for determining if the region object contains the target object." + usage = { + "required_parameters": [ + {"name": "target", "type": "List[int]"}, + {"name": "target_class", "type": "str"}, + {"name": "region", "type": "List[int]"}, + {"name": "region_class", "type": "str"}, + ], + "examples": [ + { + "scenario": "Determine if the dog on the couch, bounding box of the dog: [0.2, 0.21, 0.34, 0.42], bounding box of the couch: [0.3, 0.31, 0.44, 0.52]", + "parameters": { + "target": [0.2, 0.21, 0.34, 0.42], + "target_class": "dog", + "region": [0.3, 0.31, 0.44, 0.52], + "region_class": "couch", + }, + }, + { + "scenario": "Check if the kid is in the pool? bounding box of the kid: [0.2, 0.21, 0.34, 0.42], bounding box of the pool: [0.3, 0.31, 0.44, 0.52]", + "parameters": { + "target": [0.2, 0.21, 0.34, 0.42], + "target_class": "kid", + "region": [0.3, 0.31, 0.44, 0.52], + "region_class": "pool", + }, + }, + ], + } + + def __call__( + self, target: List[int], target_class: str, region: List[int], region_class: str + ) -> Dict[str, Union[str, float]]: + x1, y1, x2, y2 = target + x3, y3, x4, y4 = region + xA = max(x1, x3) + yA = max(y1, y3) + xB = min(x2, x4) + yB = min(y2, y4) + inter_area = max(0, xB - xA) * max(0, yB - yA) + boxa_area = (x2 - x1) * (y2 - y1) + iou = inter_area / float(boxa_area) + area = round(iou, 2) + return { + "target_class": target_class, + "region_class": region_class, + "intersection": area, + } + + class BoxDistance(Tool): name = "box_distance_" description = ( @@ -760,6 +808,7 @@ def __call__(self, equation: str) -> float: SegArea, BboxIoU, SegIoU, + BboxContains, BoxDistance, Calculator, ] From cd7c973faaeb4102f723982717a69024226c0a4e Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot Date: Mon, 22 Apr 2024 20:56:25 +0000 Subject: [PATCH 05/16] [skip ci] chore(release): vision-agent 0.1.5 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 14b1519c..0670265f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "vision-agent" -version = "0.1.4" +version = "0.1.5" description = "Toolset for Vision Agent" authors = ["Landing AI "] readme = "README.md" From f3e7d879e63a53087d32eb812caf9f388055e41a Mon Sep 17 00:00:00 2001 From: Shankar <90070882+shankar-landing-ai@users.noreply.github.com> Date: Mon, 22 Apr 2024 14:09:48 -0700 Subject: [PATCH 06/16] Add Count tools (#56) * Adding counting tools to vision agent * fixed heatmap overlay and addressesessed PR comments * adding the counting tool to take both absolute coordinate and normalized coordinates, refactoring code, adding llm generate counter tool * fix linting --- README.md | 5 +- vision_agent/agent/vision_agent.py | 43 +++++--- vision_agent/image_utils.py | 101 +++++++++++++++++- vision_agent/llm/llm.py | 4 + vision_agent/lmm/lmm.py | 4 + vision_agent/tools/__init__.py | 2 + vision_agent/tools/tools.py | 163 +++++++++++++++++++++++------ 7 files changed, 273 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index 3daa36ef..7383af76 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Vision Agent is a library that helps you utilize agent frameworks for your vision tasks. Many current vision problems can easily take hours or days to solve, you need to find the -right model, figure out how to use it, possibly write programming logic around it to +right model, figure out how to use it, possibly write programming logic around it to accomplish the task you want or even more expensive, train your own model. Vision Agent aims to provide an in-seconds experience by allowing users to describe their problem in text and utilizing agent frameworks to solve the task for them. Check out our discord @@ -133,6 +133,9 @@ to pick it based on the tool description and use it based on the usage provided. | BboxIoU | BboxIoU returns the intersection over union of two bounding boxes normalized to 2 decimal places. | | SegIoU | SegIoU returns the intersection over union of two segmentation masks normalized to 2 decimal places. | | ExtractFrames | ExtractFrames extracts frames with motion from a video. | +| ExtractFrames | ExtractFrames extracts frames with motion from a video. | +| ZeroShotCounting | ZeroShotCounting returns the total number of objects belonging to a single class in a given image | +| VisualPromptCounting | VisualPromptCounting returns the total number of objects belonging to a single class given an image and visual prompt | It also has a basic set of calculate tools such as add, subtract, multiply and divide. diff --git a/vision_agent/agent/vision_agent.py b/vision_agent/agent/vision_agent.py index 3287a174..b02cdf72 100644 --- a/vision_agent/agent/vision_agent.py +++ b/vision_agent/agent/vision_agent.py @@ -8,7 +8,7 @@ from PIL import Image from tabulate import tabulate -from vision_agent.image_utils import overlay_bboxes, overlay_masks +from vision_agent.image_utils import overlay_bboxes, overlay_masks, overlay_heat_map from vision_agent.llm import LLM, OpenAILLM from vision_agent.lmm import LMM, OpenAILMM from vision_agent.tools import TOOLS @@ -336,7 +336,9 @@ def _handle_viz_tools( for param, call_result in zip(parameters, tool_result["call_results"]): # calls can fail, so we need to check if the call was successful - if not isinstance(call_result, dict) or "bboxes" not in call_result: + if not isinstance(call_result, dict) or ( + "bboxes" not in call_result and "masks" not in call_result + ): return image_to_data # if the call was successful, then we can add the image data @@ -349,11 +351,12 @@ def _handle_viz_tools( "scores": [], } - image_to_data[image]["bboxes"].extend(call_result["bboxes"]) - image_to_data[image]["labels"].extend(call_result["labels"]) - image_to_data[image]["scores"].extend(call_result["scores"]) - if "masks" in call_result: - image_to_data[image]["masks"].extend(call_result["masks"]) + image_to_data[image]["bboxes"].extend(call_result.get("bboxes", [])) + image_to_data[image]["labels"].extend(call_result.get("labels", [])) + image_to_data[image]["scores"].extend(call_result.get("scores", [])) + image_to_data[image]["masks"].extend(call_result.get("masks", [])) + if "mask_shape" in call_result: + image_to_data[image]["mask_shape"] = call_result["mask_shape"] return image_to_data @@ -367,6 +370,8 @@ def visualize_result(all_tool_results: List[Dict]) -> Sequence[Union[str, Path]] "grounding_dino_", "extract_frames_", "dinov_", + "zero_shot_counting_", + "visual_prompt_counting_", ]: continue @@ -379,8 +384,11 @@ def visualize_result(all_tool_results: List[Dict]) -> Sequence[Union[str, Path]] for image_str in image_to_data: image_path = Path(image_str) image_data = image_to_data[image_str] - image = overlay_masks(image_path, image_data) - image = overlay_bboxes(image, image_data) + if "_counting_" in tool_result["tool_name"]: + image = overlay_heat_map(image_path, image_data) + else: + image = overlay_masks(image_path, image_data) + image = overlay_bboxes(image, image_data) with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as f: image.save(f.name) visualized_images.append(f.name) @@ -484,11 +492,21 @@ def chat_with_workflow( if image: question += f" Image name: {image}" if reference_data: - if not ("image" in reference_data and "mask" in reference_data): + if not ( + "image" in reference_data + and ("mask" in reference_data or "bbox" in reference_data) + ): raise ValueError( - f"Reference data must contain 'image' and 'mask'. but got {reference_data}" + f"Reference data must contain 'image' and a visual prompt which can be 'mask' or 'bbox'. but got {reference_data}" ) - question += f" Reference image: {reference_data['image']}, Reference mask: {reference_data['mask']}" + visual_prompt_data = ( + f"Reference mask: {reference_data['mask']}" + if "mask" in reference_data + else f"Reference bbox: {reference_data['bbox']}" + ) + question += ( + f" Reference image: {reference_data['image']}, {visual_prompt_data}" + ) reflections = "" final_answer = "" @@ -531,7 +549,6 @@ def chat_with_workflow( final_answer = answer_summarize( self.answer_model, question, answers, reflections ) - visualized_output = visualize_result(all_tool_results) all_tool_results.append({"visualized_output": visualized_output}) if len(visualized_output) > 0: diff --git a/vision_agent/image_utils.py b/vision_agent/image_utils.py index f36a2033..43da645f 100644 --- a/vision_agent/image_utils.py +++ b/vision_agent/image_utils.py @@ -4,7 +4,7 @@ from importlib import resources from io import BytesIO from pathlib import Path -from typing import Dict, Tuple, Union +from typing import Dict, Tuple, Union, List import numpy as np from PIL import Image, ImageDraw, ImageFont @@ -34,6 +34,35 @@ ] +def normalize_bbox( + bbox: List[Union[int, float]], image_size: Tuple[int, ...] +) -> List[float]: + r"""Normalize the bounding box coordinates to be between 0 and 1.""" + x1, y1, x2, y2 = bbox + x1 = round(x1 / image_size[1], 2) + y1 = round(y1 / image_size[0], 2) + x2 = round(x2 / image_size[1], 2) + y2 = round(y2 / image_size[0], 2) + return [x1, y1, x2, y2] + + +def rle_decode(mask_rle: str, shape: Tuple[int, int]) -> np.ndarray: + r"""Decode a run-length encoded mask. Returns numpy array, 1 - mask, 0 - background. + + Parameters: + mask_rle: Run-length as string formated (start length) + shape: The (height, width) of array to return + """ + s = mask_rle.split() + starts, lengths = [np.asarray(x, dtype=int) for x in (s[0:][::2], s[1:][::2])] + starts -= 1 + ends = starts + lengths + img = np.zeros(shape[0] * shape[1], dtype=np.uint8) + for lo, hi in zip(starts, ends): + img[lo:hi] = 1 + return img.reshape(shape) + + def b64_to_pil(b64_str: str) -> ImageType: r"""Convert a base64 string to a PIL Image. @@ -86,6 +115,26 @@ def convert_to_b64(data: Union[str, Path, np.ndarray, ImageType]) -> str: return base64.b64encode(arr_bytes).decode("utf-8") +def denormalize_bbox( + bbox: List[Union[int, float]], image_size: Tuple[int, ...] +) -> List[float]: + r"""DeNormalize the bounding box coordinates so that they are in absolute values.""" + + if len(bbox) != 4: + raise ValueError("Bounding box must be of length 4.") + + arr = np.array(bbox) + if np.all((arr >= 0) & (arr <= 1)): + x1, y1, x2, y2 = bbox + x1 = round(x1 * image_size[1]) + y1 = round(y1 * image_size[0]) + x2 = round(x2 * image_size[1]) + y2 = round(y2 * image_size[0]) + return [x1, y1, x2, y2] + else: + return bbox + + def overlay_bboxes( image: Union[str, Path, np.ndarray, ImageType], bboxes: Dict ) -> ImageType: @@ -103,6 +152,9 @@ def overlay_bboxes( elif isinstance(image, np.ndarray): image = Image.fromarray(image) + if "bboxes" not in bboxes: + return image.convert("RGB") + color = { label: COLORS[i % len(COLORS)] for i, label in enumerate(set(bboxes["labels"])) } @@ -114,8 +166,6 @@ def overlay_bboxes( str(resources.files("vision_agent.fonts").joinpath("default_font_ch_en.ttf")), fontsize, ) - if "bboxes" not in bboxes: - return image.convert("RGB") for label, box, scores in zip(bboxes["labels"], bboxes["bboxes"], bboxes["scores"]): box = [ @@ -150,11 +200,15 @@ def overlay_masks( elif isinstance(image, np.ndarray): image = Image.fromarray(image) + if "masks" not in masks: + return image.convert("RGB") + + if "labels" not in masks: + masks["labels"] = [""] * len(masks["masks"]) + color = { label: COLORS[i % len(COLORS)] for i, label in enumerate(set(masks["labels"])) } - if "masks" not in masks: - return image.convert("RGB") for label, mask in zip(masks["labels"], masks["masks"]): if isinstance(mask, str): @@ -164,3 +218,40 @@ def overlay_masks( mask_img = Image.fromarray(np_mask.astype(np.uint8)) image = Image.alpha_composite(image.convert("RGBA"), mask_img) return image.convert("RGB") + + +def overlay_heat_map( + image: Union[str, Path, np.ndarray, ImageType], masks: Dict, alpha: float = 0.8 +) -> ImageType: + r"""Plots heat map on to an image. + + Parameters: + image: the input image + masks: the heatmap to overlay + alpha: the transparency of the overlay + + Returns: + The image with the heatmap overlayed + """ + if isinstance(image, (str, Path)): + image = Image.open(image) + elif isinstance(image, np.ndarray): + image = Image.fromarray(image) + + if "masks" not in masks: + return image.convert("RGB") + + # Only one heat map per image, so no need to loop through masks + image = image.convert("L") + + if isinstance(masks["masks"][0], str): + mask = b64_to_pil(masks["masks"][0]) + + overlay = Image.new("RGBA", mask.size) + odraw = ImageDraw.Draw(overlay) + odraw.bitmap( + (0, 0), mask, fill=(255, 0, 0, round(alpha * 255)) + ) # fill=(R, G, B, Alpha) + combined = Image.alpha_composite(image.convert("RGBA"), overlay.resize(image.size)) + + return combined.convert("RGB") diff --git a/vision_agent/llm/llm.py b/vision_agent/llm/llm.py index 9352f58b..3f83c269 100644 --- a/vision_agent/llm/llm.py +++ b/vision_agent/llm/llm.py @@ -11,6 +11,7 @@ SYSTEM_PROMPT, GroundingDINO, GroundingSAM, + ZeroShotCounting, ) @@ -127,6 +128,9 @@ def generate_segmentor(self, question: str) -> Callable: return lambda x: GroundingSAM()(**{"prompt": params["prompt"], "image": x}) + def generate_zero_shot_counter(self, question: str) -> Callable: + return lambda x: ZeroShotCounting()(**{"image": x}) + class AzureOpenAILLM(OpenAILLM): def __init__( diff --git a/vision_agent/lmm/lmm.py b/vision_agent/lmm/lmm.py index 615804ed..06ce94a2 100644 --- a/vision_agent/lmm/lmm.py +++ b/vision_agent/lmm/lmm.py @@ -15,6 +15,7 @@ SYSTEM_PROMPT, GroundingDINO, GroundingSAM, + ZeroShotCounting, ) _LOGGER = logging.getLogger(__name__) @@ -272,6 +273,9 @@ def generate_segmentor(self, question: str) -> Callable: return lambda x: GroundingSAM()(**{"prompt": params["prompt"], "image": x}) + def generate_zero_shot_counter(self, question: str) -> Callable: + return lambda x: ZeroShotCounting()(**{"image": x}) + class AzureOpenAILMM(OpenAILMM): def __init__( diff --git a/vision_agent/tools/__init__.py b/vision_agent/tools/__init__.py index bf6bf70d..13629122 100644 --- a/vision_agent/tools/__init__.py +++ b/vision_agent/tools/__init__.py @@ -11,6 +11,8 @@ GroundingDINO, GroundingSAM, ImageCaption, + ZeroShotCounting, + VisualPromptCounting, SegArea, SegIoU, Tool, diff --git a/vision_agent/tools/tools.py b/vision_agent/tools/tools.py index 36b8454c..9e323715 100644 --- a/vision_agent/tools/tools.py +++ b/vision_agent/tools/tools.py @@ -9,7 +9,13 @@ from PIL import Image from PIL.Image import Image as ImageType -from vision_agent.image_utils import convert_to_b64, get_image_size +from vision_agent.image_utils import ( + convert_to_b64, + get_image_size, + rle_decode, + normalize_bbox, + denormalize_bbox, +) from vision_agent.tools.video import extract_frames_from_video from vision_agent.type_defs import LandingaiAPIKey @@ -18,35 +24,6 @@ _LND_API_URL = "https://api.dev.landing.ai/v1/agent" -def normalize_bbox( - bbox: List[Union[int, float]], image_size: Tuple[int, ...] -) -> List[float]: - r"""Normalize the bounding box coordinates to be between 0 and 1.""" - x1, y1, x2, y2 = bbox - x1 = round(x1 / image_size[1], 2) - y1 = round(y1 / image_size[0], 2) - x2 = round(x2 / image_size[1], 2) - y2 = round(y2 / image_size[0], 2) - return [x1, y1, x2, y2] - - -def rle_decode(mask_rle: str, shape: Tuple[int, int]) -> np.ndarray: - r"""Decode a run-length encoded mask. Returns numpy array, 1 - mask, 0 - background. - - Parameters: - mask_rle: Run-length as string formated (start length) - shape: The (height, width) of array to return - """ - s = mask_rle.split() - starts, lengths = [np.asarray(x, dtype=int) for x in (s[0:][::2], s[1:][::2])] - starts -= 1 - ends = starts + lengths - img = np.zeros(shape[0] * shape[1], dtype=np.uint8) - for lo, hi in zip(starts, ends): - img[lo:hi] = 1 - return img.reshape(shape) - - class Tool(ABC): name: str description: str @@ -492,6 +469,130 @@ def __call__( return rets +class ZeroShotCounting(Tool): + r"""ZeroShotCounting is a tool that can count total number of instances of an object + present in an image belonging to same class without a text or visual prompt. + + Example + ------- + >>> import vision_agent as va + >>> zshot_count = va.tools.ZeroShotCounting() + >>> zshot_count("image1.jpg") + {'count': 45} + """ + + name = "zero_shot_counting_" + description = "'zero_shot_counting_' is a tool that counts and returns the total number of instances of an object present in an image belonging to the same class without a text or visual prompt." + + usage = { + "required_parameters": [ + {"name": "image", "type": "str"}, + ], + "examples": [ + { + "scenario": "Can you count the lids in the image ? Image name: lids.jpg", + "parameters": {"image": "lids.jpg"}, + }, + { + "scenario": "Can you count the total number of objects in this image ? Image name: tray.jpg", + "parameters": {"image": "tray.jpg"}, + }, + { + "scenario": "Can you build me an object counting tool ? Image name: shirts.jpg", + "parameters": { + "image": "shirts.jpg", + }, + }, + ], + } + + # TODO: Add support for input multiple images, which aligns with the output type. + def __call__(self, image: Union[str, ImageType]) -> Dict: + """Invoke the Image captioning model. + + Parameters: + image: the input image. + + Returns: + A dictionary containing the key 'count' and the count as value. E.g. {count: 12} + """ + image_b64 = convert_to_b64(image) + data = { + "image": image_b64, + "tool": "zero_shot_counting", + } + return _send_inference_request(data, "tools") + + +class VisualPromptCounting(Tool): + r"""VisualPromptCounting is a tool that can count total number of instances of an object + present in an image belonging to same class with help of an visual prompt which is a bounding box. + + Example + ------- + >>> import vision_agent as va + >>> prompt_count = va.tools.VisualPromptCounting() + >>> prompt_count(image="image1.jpg", prompt="0.1, 0.1, 0.4, 0.42") + {'count': 23} + """ + + name = "visual_prompt_counting_" + description = "'visual_prompt_counting_' is a tool that can count and return total number of instances of an object present in an image belonging to the same class given an example bounding box." + + usage = { + "required_parameters": [ + {"name": "image", "type": "str"}, + {"name": "prompt", "type": "str"}, + ], + "examples": [ + { + "scenario": "Here is an example of a lid '0.1, 0.1, 0.14, 0.2', Can you count the lids in the image ? Image name: lids.jpg", + "parameters": {"image": "lids.jpg", "prompt": "0.1, 0.1, 0.14, 0.2"}, + }, + { + "scenario": "Can you count the total number of objects in this image ? Image name: tray.jpg", + "parameters": {"image": "tray.jpg", "prompt": "0.1, 0.1, 0.2, 0.25"}, + }, + { + "scenario": "Can you build me a few shot object counting tool ? Image name: shirts.jpg", + "parameters": { + "image": "shirts.jpg", + "prompt": "0.1, 0.15, 0.2, 0.2", + }, + }, + { + "scenario": "Can you build me a counting tool based on an example prompt ? Image name: shoes.jpg", + "parameters": { + "image": "shoes.jpg", + "prompt": "0.1, 0.1, 0.6, 0.65", + }, + }, + ], + } + + # TODO: Add support for input multiple images, which aligns with the output type. + def __call__(self, image: Union[str, ImageType], prompt: str) -> Dict: + """Invoke the Image captioning model. + + Parameters: + image: the input image. + + Returns: + A dictionary containing the key 'count' and the count as value. E.g. {count: 12} + """ + image_size = get_image_size(image) + bbox = [float(x) for x in prompt.split(",")] + prompt = ", ".join(map(str, denormalize_bbox(bbox, image_size))) + image_b64 = convert_to_b64(image) + + data = { + "image": image_b64, + "prompt": prompt, + "tool": "few_shot_counting", + } + return _send_inference_request(data, "tools") + + class Crop(Tool): r"""Crop crops an image given a bounding box and returns a file name of the cropped image.""" @@ -801,6 +902,8 @@ def __call__(self, equation: str) -> float: ImageCaption, GroundingDINO, AgentGroundingSAM, + ZeroShotCounting, + VisualPromptCounting, AgentDINOv, ExtractFrames, Crop, From 56d2270ff9c61acdadb28fb942c4ffd4adad8fda Mon Sep 17 00:00:00 2001 From: Asia <92344512+AsiaCao@users.noreply.github.com> Date: Mon, 22 Apr 2024 14:14:35 -0700 Subject: [PATCH 07/16] Remove torch and cuda dependencies (#60) Resolve merge conflicts --- docs/api/data.md | 3 - docs/api/emb.md | 3 - mkdocs.yml | 2 - poetry.lock | 793 +--------------------------------- pyproject.toml | 8 +- tests/test_data.py | 93 ---- vision_agent/__init__.py | 2 - vision_agent/data/__init__.py | 1 - vision_agent/data/data.py | 142 ------ vision_agent/emb/__init__.py | 1 - vision_agent/emb/emb.py | 47 -- 11 files changed, 7 insertions(+), 1088 deletions(-) delete mode 100644 docs/api/data.md delete mode 100644 docs/api/emb.md delete mode 100644 tests/test_data.py delete mode 100644 vision_agent/data/__init__.py delete mode 100644 vision_agent/data/data.py delete mode 100644 vision_agent/emb/__init__.py delete mode 100644 vision_agent/emb/emb.py diff --git a/docs/api/data.md b/docs/api/data.md deleted file mode 100644 index 2e157f7c..00000000 --- a/docs/api/data.md +++ /dev/null @@ -1,3 +0,0 @@ -::: vision_agent.data - -::: vision_agent.data.data \ No newline at end of file diff --git a/docs/api/emb.md b/docs/api/emb.md deleted file mode 100644 index 1421ef8d..00000000 --- a/docs/api/emb.md +++ /dev/null @@ -1,3 +0,0 @@ -::: vision_agent.emb - -::: vision_agent.emb.emb \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 9dd45949..7409b561 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -37,7 +37,5 @@ nav: - vision_agent.tools: api/tools.md - vision_agent.llm: api/llm.md - vision_agent.lmm: api/lmm.md - - vision_agent.data: api/data.md - - vision_agent.emb: api/emb.md - vision_agent.image_utils: api/image_utils.md - Old documentation: old.md diff --git a/poetry.lock b/poetry.lock index a0c62cab..04733555 100644 --- a/poetry.lock +++ b/poetry.lock @@ -293,60 +293,6 @@ files = [ [package.extras] test = ["pytest (>=6)"] -[[package]] -name = "faiss-cpu" -version = "1.8.0" -description = "A library for efficient similarity search and clustering of dense vectors." -optional = false -python-versions = ">=3.8" -files = [ - {file = "faiss-cpu-1.8.0.tar.gz", hash = "sha256:3ee1549491728f37b65267c192a94661a907154a8ae0546ad50a564b8be0d82e"}, - {file = "faiss_cpu-1.8.0-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:134a064c7411acf7d1d863173a9d2605c5a59bd573639ab39a5ded5ca983b1b2"}, - {file = "faiss_cpu-1.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ba8e6202d561ac57394c9d691ff17f8fa6eb9a077913a993fce0a154ec0176f1"}, - {file = "faiss_cpu-1.8.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a66e9fa7b70556a39681f06e0652f4124c8ddb0a1924afe4f0e40b6924dc845b"}, - {file = "faiss_cpu-1.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51aaef5a1255d0ea88ea7e52a2415f98c5dd2dd9cec10348d55136541eeec99f"}, - {file = "faiss_cpu-1.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:38152761242870ec7019e0397cbd0ed0b0716562029ce41a71bb38448bd6d5bc"}, - {file = "faiss_cpu-1.8.0-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:c9e6ad94b86626be1a0faff3e53c4ca169eba88aa156d7e90c5a2e9ba30558fb"}, - {file = "faiss_cpu-1.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4601dbd81733bf1bc3bff690aac981289fb386dc8e60d0c4eec8a37ba6856d20"}, - {file = "faiss_cpu-1.8.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fa943d3b5e8c5c77cdd629d9c3c6f78d7da616e586fdd1b94aecbf2e5fa9ba06"}, - {file = "faiss_cpu-1.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b644b366c3b239b34fa3e08bf65bfc78a24eda1e1ea5b2b6d9be3e8fc73d8179"}, - {file = "faiss_cpu-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:f85ecf3514850f93985be238351f5a70736133cfae784b372640aa17c6343a1b"}, - {file = "faiss_cpu-1.8.0-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:61abc0129a357ac00f17f5167f14dff41480de2cc852f306c3d4cd36b893ccbd"}, - {file = "faiss_cpu-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b788186d6eb94e6333e1aa8bb6c84b66e967458ecdd1cee22e16f04c43ee674c"}, - {file = "faiss_cpu-1.8.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5658d90a202c62e4a69c5b065785e9ddcaf6986cb395c16afed8dbe4c58c31a2"}, - {file = "faiss_cpu-1.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d460a372efce547e53d3c47d2c2a8a90b186ad245969048c10c1d7a1e5cf21b"}, - {file = "faiss_cpu-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:9e6520324f0a6764dd267b3c32c76958bf2b1ec36752950f6fab31a7295980a0"}, - {file = "faiss_cpu-1.8.0-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:fc44be179d5b7f690484ef0d0caf817fea2698a5275a0c7fb6cbf406e5b2e4d1"}, - {file = "faiss_cpu-1.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bbd6f0bc2e1424a12dc7e19d2cc95b53124867966b21110d26f909227e7ed1f1"}, - {file = "faiss_cpu-1.8.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06e7add0c8a06ce8fb0443c38fcaf49c45fb74527ea633b819e56452608e64f5"}, - {file = "faiss_cpu-1.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b864e23c1817fa6cfe9bbec096fd7140d596002934f71aa89b196ffb1b9cd846"}, - {file = "faiss_cpu-1.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:655433755845adbb6f0961e2f8980703640cb9faa96f1cd1ea190252149e0d0a"}, - {file = "faiss_cpu-1.8.0-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:e81fc376a3bcda213ffb395dda1018c953ce927c587731ad582f4e6c2b225363"}, - {file = "faiss_cpu-1.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8c6fa6b7eaf558307b4ab118a236e8d1da79a8685222928e4dd52e277dba144a"}, - {file = "faiss_cpu-1.8.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:652f6812ef2e8b0f9b18209828c590bc618aca82e7f1c1b1888f52928258e406"}, - {file = "faiss_cpu-1.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:304da4e0d19044374b63a5b6467028572eac4bd3f32bc9e8783d800a03fb1f02"}, - {file = "faiss_cpu-1.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:cb475d3f25f08c97ac64dfe026f113e2aeb9829b206b3b046256c3b40dd7eb62"}, -] - -[package.dependencies] -numpy = "*" - -[[package]] -name = "filelock" -version = "3.13.1" -description = "A platform independent file lock." -optional = false -python-versions = ">=3.8" -files = [ - {file = "filelock-3.13.1-py3-none-any.whl", hash = "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c"}, - {file = "filelock-3.13.1.tar.gz", hash = "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e"}, -] - -[package.extras] -docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.24)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] -typing = ["typing-extensions (>=4.8)"] - [[package]] name = "flake8" version = "5.0.4" @@ -363,41 +309,6 @@ mccabe = ">=0.7.0,<0.8.0" pycodestyle = ">=2.9.0,<2.10.0" pyflakes = ">=2.5.0,<2.6.0" -[[package]] -name = "fsspec" -version = "2024.3.1" -description = "File-system specification" -optional = false -python-versions = ">=3.8" -files = [ - {file = "fsspec-2024.3.1-py3-none-any.whl", hash = "sha256:918d18d41bf73f0e2b261824baeb1b124bcf771767e3a26425cd7dec3332f512"}, - {file = "fsspec-2024.3.1.tar.gz", hash = "sha256:f39780e282d7d117ffb42bb96992f8a90795e4d0fb0f661a70ca39fe9c43ded9"}, -] - -[package.extras] -abfs = ["adlfs"] -adl = ["adlfs"] -arrow = ["pyarrow (>=1)"] -dask = ["dask", "distributed"] -devel = ["pytest", "pytest-cov"] -dropbox = ["dropbox", "dropboxdrivefs", "requests"] -full = ["adlfs", "aiohttp (!=4.0.0a0,!=4.0.0a1)", "dask", "distributed", "dropbox", "dropboxdrivefs", "fusepy", "gcsfs", "libarchive-c", "ocifs", "panel", "paramiko", "pyarrow (>=1)", "pygit2", "requests", "s3fs", "smbprotocol", "tqdm"] -fuse = ["fusepy"] -gcs = ["gcsfs"] -git = ["pygit2"] -github = ["requests"] -gs = ["gcsfs"] -gui = ["panel"] -hdfs = ["pyarrow (>=1)"] -http = ["aiohttp (!=4.0.0a0,!=4.0.0a1)"] -libarchive = ["libarchive-c"] -oci = ["ocifs"] -s3 = ["s3fs"] -sftp = ["paramiko"] -smb = ["smbprotocol"] -ssh = ["paramiko"] -tqdm = ["tqdm"] - [[package]] name = "ghp-import" version = "2.1.0" @@ -485,39 +396,6 @@ cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] http2 = ["h2 (>=3,<5)"] socks = ["socksio (==1.*)"] -[[package]] -name = "huggingface-hub" -version = "0.21.4" -description = "Client library to download and publish models, datasets and other repos on the huggingface.co hub" -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "huggingface_hub-0.21.4-py3-none-any.whl", hash = "sha256:df37c2c37fc6c82163cdd8a67ede261687d80d1e262526d6c0ce73b6b3630a7b"}, - {file = "huggingface_hub-0.21.4.tar.gz", hash = "sha256:e1f4968c93726565a80edf6dc309763c7b546d0cfe79aa221206034d50155531"}, -] - -[package.dependencies] -filelock = "*" -fsspec = ">=2023.5.0" -packaging = ">=20.9" -pyyaml = ">=5.1" -requests = "*" -tqdm = ">=4.42.1" -typing-extensions = ">=3.7.4.3" - -[package.extras] -all = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "gradio", "jedi", "mypy (==1.5.1)", "numpy", "pydantic (>1.1,<2.0)", "pydantic (>1.1,<3.0)", "pytest", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "ruff (>=0.1.3)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"] -cli = ["InquirerPy (==0.3.4)"] -dev = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "gradio", "jedi", "mypy (==1.5.1)", "numpy", "pydantic (>1.1,<2.0)", "pydantic (>1.1,<3.0)", "pytest", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "ruff (>=0.1.3)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"] -fastai = ["fastai (>=2.4)", "fastcore (>=1.3.27)", "toml"] -hf-transfer = ["hf-transfer (>=0.1.4)"] -inference = ["aiohttp", "pydantic (>1.1,<2.0)", "pydantic (>1.1,<3.0)"] -quality = ["mypy (==1.5.1)", "ruff (>=0.1.3)"] -tensorflow = ["graphviz", "pydot", "tensorflow"] -testing = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "gradio", "jedi", "numpy", "pydantic (>1.1,<2.0)", "pydantic (>1.1,<3.0)", "pytest", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "soundfile", "urllib3 (<2.0)"] -torch = ["safetensors", "torch"] -typing = ["types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)"] - [[package]] name = "idna" version = "3.6" @@ -640,17 +518,6 @@ MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] -[[package]] -name = "joblib" -version = "1.3.2" -description = "Lightweight pipelining with Python functions" -optional = false -python-versions = ">=3.7" -files = [ - {file = "joblib-1.3.2-py3-none-any.whl", hash = "sha256:ef4331c65f239985f3f2220ecc87db222f08fd22097a3dd5698f693875f8cbb9"}, - {file = "joblib-1.3.2.tar.gz", hash = "sha256:92f865e621e17784e7955080b6d042489e3b8e294949cc44c6eac304f59772b1"}, -] - [[package]] name = "lazy-loader" version = "0.4" @@ -932,23 +799,6 @@ doc = ["Sphinx (>=1.5.2,<2.0)", "numpydoc (>=0.6.0,<1.0)", "pygame (>=1.9.3,<2.0 optional = ["matplotlib (>=2.0.0,<3.0)", "opencv-python (>=3.0,<4.0)", "scikit-image (>=0.13.0,<1.0)", "scikit-learn", "scipy (>=0.19.0,<1.5)", "youtube_dl"] test = ["coverage (<5.0)", "coveralls (>=1.1,<2.0)", "pytest (>=3.0.0,<4.0)", "pytest-cov (>=2.5.1,<3.0)", "requests (>=2.8.1,<3.0)"] -[[package]] -name = "mpmath" -version = "1.3.0" -description = "Python library for arbitrary-precision floating-point arithmetic" -optional = false -python-versions = "*" -files = [ - {file = "mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c"}, - {file = "mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f"}, -] - -[package.extras] -develop = ["codecov", "pycodestyle", "pytest (>=4.6)", "pytest-cov", "wheel"] -docs = ["sphinx"] -gmpy = ["gmpy2 (>=2.1.0a4)"] -tests = ["pytest (>=4.6)"] - [[package]] name = "mypy" version = "1.7.1" @@ -1070,148 +920,6 @@ files = [ {file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"}, ] -[[package]] -name = "nvidia-cublas-cu12" -version = "12.1.3.1" -description = "CUBLAS native runtime libraries" -optional = false -python-versions = ">=3" -files = [ - {file = "nvidia_cublas_cu12-12.1.3.1-py3-none-manylinux1_x86_64.whl", hash = "sha256:ee53ccca76a6fc08fb9701aa95b6ceb242cdaab118c3bb152af4e579af792728"}, - {file = "nvidia_cublas_cu12-12.1.3.1-py3-none-win_amd64.whl", hash = "sha256:2b964d60e8cf11b5e1073d179d85fa340c120e99b3067558f3cf98dd69d02906"}, -] - -[[package]] -name = "nvidia-cuda-cupti-cu12" -version = "12.1.105" -description = "CUDA profiling tools runtime libs." -optional = false -python-versions = ">=3" -files = [ - {file = "nvidia_cuda_cupti_cu12-12.1.105-py3-none-manylinux1_x86_64.whl", hash = "sha256:e54fde3983165c624cb79254ae9818a456eb6e87a7fd4d56a2352c24ee542d7e"}, - {file = "nvidia_cuda_cupti_cu12-12.1.105-py3-none-win_amd64.whl", hash = "sha256:bea8236d13a0ac7190bd2919c3e8e6ce1e402104276e6f9694479e48bb0eb2a4"}, -] - -[[package]] -name = "nvidia-cuda-nvrtc-cu12" -version = "12.1.105" -description = "NVRTC native runtime libraries" -optional = false -python-versions = ">=3" -files = [ - {file = "nvidia_cuda_nvrtc_cu12-12.1.105-py3-none-manylinux1_x86_64.whl", hash = "sha256:339b385f50c309763ca65456ec75e17bbefcbbf2893f462cb8b90584cd27a1c2"}, - {file = "nvidia_cuda_nvrtc_cu12-12.1.105-py3-none-win_amd64.whl", hash = "sha256:0a98a522d9ff138b96c010a65e145dc1b4850e9ecb75a0172371793752fd46ed"}, -] - -[[package]] -name = "nvidia-cuda-runtime-cu12" -version = "12.1.105" -description = "CUDA Runtime native Libraries" -optional = false -python-versions = ">=3" -files = [ - {file = "nvidia_cuda_runtime_cu12-12.1.105-py3-none-manylinux1_x86_64.whl", hash = "sha256:6e258468ddf5796e25f1dc591a31029fa317d97a0a94ed93468fc86301d61e40"}, - {file = "nvidia_cuda_runtime_cu12-12.1.105-py3-none-win_amd64.whl", hash = "sha256:dfb46ef84d73fababab44cf03e3b83f80700d27ca300e537f85f636fac474344"}, -] - -[[package]] -name = "nvidia-cudnn-cu12" -version = "8.9.2.26" -description = "cuDNN runtime libraries" -optional = false -python-versions = ">=3" -files = [ - {file = "nvidia_cudnn_cu12-8.9.2.26-py3-none-manylinux1_x86_64.whl", hash = "sha256:5ccb288774fdfb07a7e7025ffec286971c06d8d7b4fb162525334616d7629ff9"}, -] - -[package.dependencies] -nvidia-cublas-cu12 = "*" - -[[package]] -name = "nvidia-cufft-cu12" -version = "11.0.2.54" -description = "CUFFT native runtime libraries" -optional = false -python-versions = ">=3" -files = [ - {file = "nvidia_cufft_cu12-11.0.2.54-py3-none-manylinux1_x86_64.whl", hash = "sha256:794e3948a1aa71fd817c3775866943936774d1c14e7628c74f6f7417224cdf56"}, - {file = "nvidia_cufft_cu12-11.0.2.54-py3-none-win_amd64.whl", hash = "sha256:d9ac353f78ff89951da4af698f80870b1534ed69993f10a4cf1d96f21357e253"}, -] - -[[package]] -name = "nvidia-curand-cu12" -version = "10.3.2.106" -description = "CURAND native runtime libraries" -optional = false -python-versions = ">=3" -files = [ - {file = "nvidia_curand_cu12-10.3.2.106-py3-none-manylinux1_x86_64.whl", hash = "sha256:9d264c5036dde4e64f1de8c50ae753237c12e0b1348738169cd0f8a536c0e1e0"}, - {file = "nvidia_curand_cu12-10.3.2.106-py3-none-win_amd64.whl", hash = "sha256:75b6b0c574c0037839121317e17fd01f8a69fd2ef8e25853d826fec30bdba74a"}, -] - -[[package]] -name = "nvidia-cusolver-cu12" -version = "11.4.5.107" -description = "CUDA solver native runtime libraries" -optional = false -python-versions = ">=3" -files = [ - {file = "nvidia_cusolver_cu12-11.4.5.107-py3-none-manylinux1_x86_64.whl", hash = "sha256:8a7ec542f0412294b15072fa7dab71d31334014a69f953004ea7a118206fe0dd"}, - {file = "nvidia_cusolver_cu12-11.4.5.107-py3-none-win_amd64.whl", hash = "sha256:74e0c3a24c78612192a74fcd90dd117f1cf21dea4822e66d89e8ea80e3cd2da5"}, -] - -[package.dependencies] -nvidia-cublas-cu12 = "*" -nvidia-cusparse-cu12 = "*" -nvidia-nvjitlink-cu12 = "*" - -[[package]] -name = "nvidia-cusparse-cu12" -version = "12.1.0.106" -description = "CUSPARSE native runtime libraries" -optional = false -python-versions = ">=3" -files = [ - {file = "nvidia_cusparse_cu12-12.1.0.106-py3-none-manylinux1_x86_64.whl", hash = "sha256:f3b50f42cf363f86ab21f720998517a659a48131e8d538dc02f8768237bd884c"}, - {file = "nvidia_cusparse_cu12-12.1.0.106-py3-none-win_amd64.whl", hash = "sha256:b798237e81b9719373e8fae8d4f091b70a0cf09d9d85c95a557e11df2d8e9a5a"}, -] - -[package.dependencies] -nvidia-nvjitlink-cu12 = "*" - -[[package]] -name = "nvidia-nccl-cu12" -version = "2.18.1" -description = "NVIDIA Collective Communication Library (NCCL) Runtime" -optional = false -python-versions = ">=3" -files = [ - {file = "nvidia_nccl_cu12-2.18.1-py3-none-manylinux1_x86_64.whl", hash = "sha256:1a6c4acefcbebfa6de320f412bf7866de856e786e0462326ba1bac40de0b5e71"}, -] - -[[package]] -name = "nvidia-nvjitlink-cu12" -version = "12.4.99" -description = "Nvidia JIT LTO Library" -optional = false -python-versions = ">=3" -files = [ - {file = "nvidia_nvjitlink_cu12-12.4.99-py3-none-manylinux2014_aarch64.whl", hash = "sha256:75d6498c96d9adb9435f2bbdbddb479805ddfb97b5c1b32395c694185c20ca57"}, - {file = "nvidia_nvjitlink_cu12-12.4.99-py3-none-manylinux2014_x86_64.whl", hash = "sha256:c6428836d20fe7e327191c175791d38570e10762edc588fb46749217cd444c74"}, - {file = "nvidia_nvjitlink_cu12-12.4.99-py3-none-win_amd64.whl", hash = "sha256:991905ffa2144cb603d8ca7962d75c35334ae82bf92820b6ba78157277da1ad2"}, -] - -[[package]] -name = "nvidia-nvtx-cu12" -version = "12.1.105" -description = "NVIDIA Tools Extension" -optional = false -python-versions = ">=3" -files = [ - {file = "nvidia_nvtx_cu12-12.1.105-py3-none-manylinux1_x86_64.whl", hash = "sha256:dc21cf308ca5691e7c04d962e213f8a4aa9bbfa23d95412f452254c2caeb09e5"}, - {file = "nvidia_nvtx_cu12-12.1.105-py3-none-win_amd64.whl", hash = "sha256:65f4d98982b31b60026e0e6de73fbdfc09d08a96f4656dd3665ca616a11e1e82"}, -] - [[package]] name = "openai" version = "1.14.2" @@ -1254,7 +962,8 @@ files = [ [package.dependencies] numpy = [ {version = ">=1.21.0", markers = "python_version == \"3.9\" and platform_system == \"Darwin\" and platform_machine == \"arm64\""}, - {version = ">=1.23.5", markers = "python_version >= \"3.11\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, + {version = ">=1.23.5", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, {version = ">=1.21.4", markers = "python_version >= \"3.10\" and platform_system == \"Darwin\" and python_version < \"3.11\""}, {version = ">=1.21.2", markers = "platform_system != \"Darwin\" and python_version >= \"3.10\" and python_version < \"3.11\""}, {version = ">=1.19.3", markers = "platform_system == \"Linux\" and platform_machine == \"aarch64\" and python_version >= \"3.8\" and python_version < \"3.10\" or python_version > \"3.9\" and python_version < \"3.10\" or python_version >= \"3.9\" and platform_system != \"Darwin\" and python_version < \"3.10\" or python_version >= \"3.9\" and platform_machine != \"arm64\" and python_version < \"3.10\""}, @@ -1322,6 +1031,7 @@ files = [ [package.dependencies] numpy = [ {version = ">=1.22.4,<2", markers = "python_version < \"3.11\""}, + {version = ">=1.26.0,<2", markers = "python_version >= \"3.12\""}, {version = ">=1.23.2,<2", markers = "python_version == \"3.11\""}, ] python-dateutil = ">=2.8.2" @@ -1955,138 +1665,6 @@ urllib3 = ">=1.25.10,<3.0" [package.extras] tests = ["coverage (>=6.0.0)", "flake8", "mypy", "pytest (>=7.0.0)", "pytest-asyncio", "pytest-cov", "pytest-httpserver", "tomli", "tomli-w", "types-requests"] -[[package]] -name = "safetensors" -version = "0.4.2" -description = "" -optional = false -python-versions = ">=3.7" -files = [ - {file = "safetensors-0.4.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:69d8bb8384dc2cb5b72c36c4d6980771b293d1a1377b378763f5e37b6bb8d133"}, - {file = "safetensors-0.4.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3d420e19fcef96d0067f4de4699682b4bbd85fc8fea0bd45fcd961fdf3e8c82c"}, - {file = "safetensors-0.4.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9ca54742122fa3c4821754adb67318e1cd25c3a22bbf0c5520d5176e77a099ac"}, - {file = "safetensors-0.4.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8b47aa643afdfd66cf7ce4c184092ae734e15d10aba2c2948f24270211801c3c"}, - {file = "safetensors-0.4.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d88a16bbc330f27e7f2d4caaf6fb061ad0b8a756ecc4033260b0378e128ce8a2"}, - {file = "safetensors-0.4.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9223b8ac21085db614a510eb3445e7083cae915a9202357555fa939695d4f57"}, - {file = "safetensors-0.4.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce6cb86133dc8930a7ab5e7438545a7f205f7a1cdd5aaf108c1d0da6bdcfbc2b"}, - {file = "safetensors-0.4.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b8a628e0ae2bbc334b62952c384aa5f41621d01850f8d67b04a96b9c39dd7326"}, - {file = "safetensors-0.4.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:88d6beb7f811a081e0e5f1d9669fdac816c45340c04b1eaf7ebfda0ce93ea403"}, - {file = "safetensors-0.4.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b57fc5b1b54cb12d8690a58a4cf4b7144730d4bde9d98aa0e1dab6295a1cd579"}, - {file = "safetensors-0.4.2-cp310-none-win32.whl", hash = "sha256:9d87a1c98803c16cf113b9ba03f07b2dce5e8eabfd1811a7f7323fcaa2a1bf47"}, - {file = "safetensors-0.4.2-cp310-none-win_amd64.whl", hash = "sha256:18930ec1d1ecb526d3d9835abc2489b8f1530877518f0c541e77ef0b7abcbd99"}, - {file = "safetensors-0.4.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:c5dd2ed788730ed56b415d1a11c62026b8cc8c573f55a2092afb3ab383e94fff"}, - {file = "safetensors-0.4.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cc41791b33efb9c83a59b731619f3d15f543dfe71f3a793cb8fbf9bd5d0d5d71"}, - {file = "safetensors-0.4.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c888bf71d5ca12a720f1ed87d407c4918afa022fb247a6546d8fac15b1f112b"}, - {file = "safetensors-0.4.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e6b2feb4b47226a16a792e6fac3f49442714884a3d4c1008569d5068a3941be9"}, - {file = "safetensors-0.4.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f41cc0ee4b838ae8f4d8364a1b162067693d11a3893f0863be8c228d40e4d0ee"}, - {file = "safetensors-0.4.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:51b7228e46c0a483c40ba4b9470dea00fb1ff8685026bb4766799000f6328ac2"}, - {file = "safetensors-0.4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02697f8f2be8ca3c37a4958702dbdb1864447ef765e18b5328a1617022dcf164"}, - {file = "safetensors-0.4.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:27fd8f65cf7c80e4280cae1ee6bcd85c483882f6580821abe71ee1a0d3dcfca7"}, - {file = "safetensors-0.4.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c487b5f113b0924c9534a07dc034830fb4ef05ce9bb6d78cfe016a7dedfe281f"}, - {file = "safetensors-0.4.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:da7f6483f3fe67ff39b3a55552552c67930ea10a36e9f2539d36fc205273d767"}, - {file = "safetensors-0.4.2-cp311-none-win32.whl", hash = "sha256:52a7012f6cb9cb4a132760b6308daede18a9f5f8952ce08adc7c67a7d865c2d8"}, - {file = "safetensors-0.4.2-cp311-none-win_amd64.whl", hash = "sha256:4d1361a097ac430b310ce9eed8ed4746edee33ddafdfbb965debc8966fc34dc2"}, - {file = "safetensors-0.4.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:77af8aa0edcc2863760fd6febbfdb82e88fd75d0e60c1ce4ba57208ba5e4a89b"}, - {file = "safetensors-0.4.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846666c1c5a8c8888d2dfda8d3921cb9cb8e2c5f78365be756c11021e75a0a2a"}, - {file = "safetensors-0.4.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f4bfc7ea19b446bfad41510d4b4c76101698c00caaa8a332c8edd8090a412ef"}, - {file = "safetensors-0.4.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:233436fd30f27ffeb3c3780d0b84f496518868445c7a8db003639a649cc98453"}, - {file = "safetensors-0.4.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7a09237a795d11cd11f9dae505d170a29b5616151db1e10c14f892b11caadc7d"}, - {file = "safetensors-0.4.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de01c9a3a3b7b69627d624ff69d9f11d28ce9908eea2fb6245adafa4b1d43df6"}, - {file = "safetensors-0.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c1f25c5069ee42a5bcffdc66c300a407941edd73f3239e9fdefd26216407391"}, - {file = "safetensors-0.4.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7a73b3649456d09ca8506140d44484b63154a7378434cc1e8719f8056550b224"}, - {file = "safetensors-0.4.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e1625a8d07d046e968bd5c4961810aba1225984e4fb9243626f9d04a06ed3fee"}, - {file = "safetensors-0.4.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f74c86b25615cb24ad4cff765a2eefc09d71bf0fed97588cf585aad9c38fbb4"}, - {file = "safetensors-0.4.2-cp312-none-win32.whl", hash = "sha256:8523b9c5777d771bcde5c2389c03f1cdf7ebe8797432a1bd5e345efe25c55987"}, - {file = "safetensors-0.4.2-cp312-none-win_amd64.whl", hash = "sha256:dcff0243e1737a21f83d664c63fed89d1f532c23fc6830d0427279fabd789ccb"}, - {file = "safetensors-0.4.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:96ad3d7d472612e26cbe413922b4fb13933310f0511d346ea5cc9a1e856e52eb"}, - {file = "safetensors-0.4.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:88250922401b5ae4e37de929178caf46be47ed16c817b2237b81679bec07c120"}, - {file = "safetensors-0.4.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d40443554142fc0ab30652d5cc8554c4b7a613513bde00373e18afd5de8cbe4b"}, - {file = "safetensors-0.4.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:27f53f70106224d32d874aacecbeb4a6e4c5b16a1d2006d0e876d97229086d71"}, - {file = "safetensors-0.4.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cc068afe23734dfb26ce19db0a7877499ddf73b1d55ceb762417e8da4a1b05fb"}, - {file = "safetensors-0.4.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9be1918eb8d43a11a6f8806759fccfa0eeb0542b12924caba66af8a7800ad01a"}, - {file = "safetensors-0.4.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41911087d20a7bbd78cb4ad4f98aab0c431533107584df6635d8b54b99945573"}, - {file = "safetensors-0.4.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:50771c662aab909f31e94d048e76861fd027d66076ea773eef2e66c717766e24"}, - {file = "safetensors-0.4.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:13f2e57be007b7ea9329133d2399e6bdfcf1910f655440a4da17df3a45afcd30"}, - {file = "safetensors-0.4.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c772147e6395bc829842e0a98e1b30c67fe25d816299c28196488511d5a5e951"}, - {file = "safetensors-0.4.2-cp37-cp37m-macosx_10_12_x86_64.whl", hash = "sha256:36239a0060b537a3e8c473df78cffee14c3ec4f51d5f1a853af99371a2fb2a35"}, - {file = "safetensors-0.4.2-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:d0cbb7664fad2c307f95195f951b7059e95dc23e0e1822e5978c8b500098543c"}, - {file = "safetensors-0.4.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2b3e55adb6bd9dc1c2a341e72f48f075953fa35d173dd8e29a95b3b02d0d1462"}, - {file = "safetensors-0.4.2-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42f743b3cca863fba53ca57a193f510e5ec359b97f38c282437716b6768e4a25"}, - {file = "safetensors-0.4.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:04e6af4a6dbeb06c4e6e7d46cf9c716cbc4cc5ef62584fd8a7c0fe558562df45"}, - {file = "safetensors-0.4.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a492ba21b5c8f14ee5ec9b20f42ba969e53ca1f909a4d04aad736b66a341dcc2"}, - {file = "safetensors-0.4.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b25b8233a1a85dc67e39838951cfb01595d792f3b7b644add63edb652992e030"}, - {file = "safetensors-0.4.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fd27e063fbdafe776f7b1714da59110e88f270e86db00788a8fd65f4eacfeba7"}, - {file = "safetensors-0.4.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1b6fa399f251bbeb52029bf5a0ac2878d7705dd3612a2f8895b48e9c11f0367d"}, - {file = "safetensors-0.4.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:de642d46b459e4afd5c2020b26c0d6d869a171ea00411897d5776c127cac74f0"}, - {file = "safetensors-0.4.2-cp37-none-win32.whl", hash = "sha256:77b72d17754c93bb68f3598182f14d78776e0b9b31682ca5bb2c7c5bd9a75267"}, - {file = "safetensors-0.4.2-cp37-none-win_amd64.whl", hash = "sha256:d36ee3244d461cd655aeef493792c3bccf4875282f8407fd9af99e9a41cf2530"}, - {file = "safetensors-0.4.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:16b6b3884f7876c6b3b23a742428223a7170a5a9dac819d8c12a1569422c4b5a"}, - {file = "safetensors-0.4.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ee25d311493fbbe0be9d395faee46e9d79e8948f461e388ff39e59875ed9a350"}, - {file = "safetensors-0.4.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eed8097968585cd752a1171f86fce9aa1d89a29033e5cd8bec5a502e29f6b7af"}, - {file = "safetensors-0.4.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:880e6865cf72cb67f9ab8d04a3c4b49dd95ae92fb1583929ce65aed94e1f685f"}, - {file = "safetensors-0.4.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91290f83daf80ce6d1a7f629b244443c200060a80f908b29d879021409e5ea94"}, - {file = "safetensors-0.4.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3517d568486ab3508a7acc360b82d7a4a3e26b86efdf210a9ecd9d233c40708a"}, - {file = "safetensors-0.4.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1f43a77eb38540f782999e5dc5645164fe9027d3f0194f6c9a5126168017efa"}, - {file = "safetensors-0.4.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b684d9818aa5d63fddc65f7d0151968037d255d91adf74eba82125b41c680aaa"}, - {file = "safetensors-0.4.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ab1f5d84185f9fefaf21413efb764e4908057b8a9a0b987ede890c353490fd70"}, - {file = "safetensors-0.4.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2bd979642e6c3a517ef4b84ff36c2fee4015664fea05a61154fc565978347553"}, - {file = "safetensors-0.4.2-cp38-none-win32.whl", hash = "sha256:11be6e7afed29e5a5628f0aa6214e34bc194da73f558dc69fc7d56e07037422a"}, - {file = "safetensors-0.4.2-cp38-none-win_amd64.whl", hash = "sha256:2f7a6e5d29bd2cc340cffaa391fa437b1be9d21a2bd8b8724d2875d13a6ef2a9"}, - {file = "safetensors-0.4.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a5a921b4fe6925f9942adff3ebae8c16e0487908c54586a5a42f35b59fd69794"}, - {file = "safetensors-0.4.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b691727228c28f2d82d8a92b2bc26e7a1f129ee40b2f2a3185b5974e038ed47c"}, - {file = "safetensors-0.4.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91ca1056decc4e981248786e87b2a202d4841ee5f99d433f1adf3d44d4bcfa0e"}, - {file = "safetensors-0.4.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:55969fd2e6fdb38dc221b0ab380668c21b0efa12a7562db9924759faa3c51757"}, - {file = "safetensors-0.4.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6ae429bfaecc10ab5fe78c93009b3d1656c1581da560041e700eadb497dbe7a4"}, - {file = "safetensors-0.4.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4ff88f194fe4ac50b463a4a6f0c03af9ad72eb5d24ec6d6730af59522e37fedb"}, - {file = "safetensors-0.4.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a80cb48d0a447f8dd18e61813efa7d3f8f8d52edf0f05806abc0c59b83431f57"}, - {file = "safetensors-0.4.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b286fb7adfee70a4189898ac2342b8a67d5f493e6b21b0af89ca8eac1b967cbf"}, - {file = "safetensors-0.4.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0ceeff9ddbab4f78738489eb6682867ae946178776f33699737b2129b5394dc1"}, - {file = "safetensors-0.4.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a26fae748a7488cb3aac381eddfa818c42052c87b5e689fb4c6e82ed58cec209"}, - {file = "safetensors-0.4.2-cp39-none-win32.whl", hash = "sha256:039a42ab33c9d68b39706fd38f1922ace26866eff246bf20271edb619f5f848b"}, - {file = "safetensors-0.4.2-cp39-none-win_amd64.whl", hash = "sha256:b3a3e1f5b85859e398773f064943b62a4059f225008a2a8ee6add1edcf77cacf"}, - {file = "safetensors-0.4.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:4e70d442ad17e8b153ef9095bf48ea64f15a66bf26dc2b6ca94660c154edbc24"}, - {file = "safetensors-0.4.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b90f1d9809caf4ff395951b4703295a68d12907f6945bbc3129e934ff8ae46f6"}, - {file = "safetensors-0.4.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c7ac9ad3728838006598e296b3ae9f27d80b489effd4685b92d97b3fc4c98f6"}, - {file = "safetensors-0.4.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de5730d77e6ff7f4c7039e20913661ad0ea2f86c09e71c039e73dfdd1f394f08"}, - {file = "safetensors-0.4.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:44feb8cb156d6803dcd19fc6b81b27235f29b877660605a6ac35e1da7d64f0e4"}, - {file = "safetensors-0.4.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:523a241c33e7c827ab9a3a23760d75c7d062f43dfe55b6b019409f89b0fb52d1"}, - {file = "safetensors-0.4.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:fb18300e8eb74291225214f26c9a8ae2110fd61a6c9b5a2ff4c4e0eb1bb9a998"}, - {file = "safetensors-0.4.2-pp37-pypy37_pp73-macosx_10_12_x86_64.whl", hash = "sha256:fe5437ff9fb116e44f2ab558981249ae63f978392b4576e62fcfe167d353edbc"}, - {file = "safetensors-0.4.2-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9304a0934ced5a5d272f39de36291dc141dfc152d277f03fb4d65f2fb2ffa7c"}, - {file = "safetensors-0.4.2-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:160ba1b1e11cf874602c233ab80a14f588571d09556cbc3586900121d622b5ed"}, - {file = "safetensors-0.4.2-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04fcd6fcf7d9c13c7e5dc7e08de5e492ee4daa8f4ad74b4d8299d3eb0224292f"}, - {file = "safetensors-0.4.2-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:906d14c4a677d35834fb0f3a5455ef8305e1bba10a5e0f2e0f357b3d1ad989f2"}, - {file = "safetensors-0.4.2-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:df3fcdec0cd543084610d1f09c65cdb10fb3079f79bceddc092b0d187c6a265b"}, - {file = "safetensors-0.4.2-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5ca76f13fb1cef242ea3ad2cb37388e7d005994f42af8b44bee56ba48b2d45ce"}, - {file = "safetensors-0.4.2-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:278a1a3414c020785decdcd741c578725721274d2f9f787fcc930882e83b89cc"}, - {file = "safetensors-0.4.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05b5a461cc68ecd42d9d546e5e1268a39d8ede7934a68d1ce17c3c659cb829d6"}, - {file = "safetensors-0.4.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c2341411412a41671d25e26bed59ec121e46bf4fadb8132895e610411c4b9681"}, - {file = "safetensors-0.4.2-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3497ac3895acf17c5f98197f1fa4769f09c5e7ede07fcb102f1c201e663e052c"}, - {file = "safetensors-0.4.2-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:01b5e71d3754d2201294f1eb7a6d59cce3a5702ff96d83d226571b2ca2183837"}, - {file = "safetensors-0.4.2-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:3627dbd1ea488dd8046a0491de5087f3c0d641e7acc80c0189a33c69398f1cd1"}, - {file = "safetensors-0.4.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:9d56f0ef53afad26ec54ceede78a43e9a23a076dadbbda7b44d304c591abf4c1"}, - {file = "safetensors-0.4.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:b259ca73d42daf658a1bda463f1f83885ae4d93a60869be80d7f7dfcc9d8bbb5"}, - {file = "safetensors-0.4.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ebc3cd401e4eb54e7c0a70346be565e81942d9a41fafd5f4bf7ab3a55d10378"}, - {file = "safetensors-0.4.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5bc384a0309b706aa0425c93abb0390508a61bf029ce99c7d9df4220f25871a5"}, - {file = "safetensors-0.4.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:af2d8f7235d8a08fbccfb8394387890e7fa38942b349a94e6eff13c52ac98087"}, - {file = "safetensors-0.4.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:0911315bbcc5289087d063c2c2c7ccd711ea97a7e557a7bce005ac2cf80146aa"}, - {file = "safetensors-0.4.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:1efe31673be91832d73439a2af426743e1395fc9ef7b081914e9e1d567bd7b5f"}, - {file = "safetensors-0.4.2.tar.gz", hash = "sha256:acc85dcb09ec5e8aa787f588d7ad4d55c103f31e4ff060e17d92cc0e8b8cac73"}, -] - -[package.extras] -all = ["safetensors[jax]", "safetensors[numpy]", "safetensors[paddlepaddle]", "safetensors[pinned-tf]", "safetensors[quality]", "safetensors[testing]", "safetensors[torch]"] -dev = ["safetensors[all]"] -jax = ["flax (>=0.6.3)", "jax (>=0.3.25)", "jaxlib (>=0.3.25)", "safetensors[numpy]"] -mlx = ["mlx (>=0.0.9)"] -numpy = ["numpy (>=1.21.6)"] -paddlepaddle = ["paddlepaddle (>=2.4.1)", "safetensors[numpy]"] -pinned-tf = ["safetensors[numpy]", "tensorflow (==2.11.0)"] -quality = ["black (==22.3)", "click (==8.0.4)", "flake8 (>=3.8.3)", "isort (>=5.5.4)"] -tensorflow = ["safetensors[numpy]", "tensorflow (>=2.11.0)"] -testing = ["h5py (>=3.7.0)", "huggingface_hub (>=0.12.1)", "hypothesis (>=6.70.2)", "pytest (>=7.2.0)", "pytest-benchmark (>=4.0.0)", "safetensors[numpy]", "setuptools_rust (>=1.5.2)"] -torch = ["safetensors[numpy]", "torch (>=1.10)"] - [[package]] name = "scikit-image" version = "0.22.0" @@ -2135,48 +1713,6 @@ docs = ["PyWavelets (>=1.1.1)", "dask[array] (>=2022.9.2)", "ipykernel", "ipywid optional = ["PyWavelets (>=1.1.1)", "SimpleITK", "astropy (>=5.0)", "cloudpickle (>=0.2.1)", "dask[array] (>=2021.1.0)", "matplotlib (>=3.5)", "pooch (>=1.6.0)", "pyamg", "scikit-learn (>=1.1)"] test = ["asv", "matplotlib (>=3.5)", "numpydoc (>=1.5)", "pooch (>=1.6.0)", "pytest (>=7.0)", "pytest-cov (>=2.11.0)", "pytest-faulthandler", "pytest-localserver"] -[[package]] -name = "scikit-learn" -version = "1.4.1.post1" -description = "A set of python modules for machine learning and data mining" -optional = false -python-versions = ">=3.9" -files = [ - {file = "scikit-learn-1.4.1.post1.tar.gz", hash = "sha256:93d3d496ff1965470f9977d05e5ec3376fb1e63b10e4fda5e39d23c2d8969a30"}, - {file = "scikit_learn-1.4.1.post1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c540aaf44729ab5cd4bd5e394f2b375e65ceaea9cdd8c195788e70433d91bbc5"}, - {file = "scikit_learn-1.4.1.post1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:4310bff71aa98b45b46cd26fa641309deb73a5d1c0461d181587ad4f30ea3c36"}, - {file = "scikit_learn-1.4.1.post1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f43dd527dabff5521af2786a2f8de5ba381e182ec7292663508901cf6ceaf6e"}, - {file = "scikit_learn-1.4.1.post1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c02e27d65b0c7dc32f2c5eb601aaf5530b7a02bfbe92438188624524878336f2"}, - {file = "scikit_learn-1.4.1.post1-cp310-cp310-win_amd64.whl", hash = "sha256:629e09f772ad42f657ca60a1a52342eef786218dd20cf1369a3b8d085e55ef8f"}, - {file = "scikit_learn-1.4.1.post1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6145dfd9605b0b50ae72cdf72b61a2acd87501369a763b0d73d004710ebb76b5"}, - {file = "scikit_learn-1.4.1.post1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:1afed6951bc9d2053c6ee9a518a466cbc9b07c6a3f9d43bfe734192b6125d508"}, - {file = "scikit_learn-1.4.1.post1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce03506ccf5f96b7e9030fea7eb148999b254c44c10182ac55857bc9b5d4815f"}, - {file = "scikit_learn-1.4.1.post1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ba516fcdc73d60e7f48cbb0bccb9acbdb21807de3651531208aac73c758e3ab"}, - {file = "scikit_learn-1.4.1.post1-cp311-cp311-win_amd64.whl", hash = "sha256:78cd27b4669513b50db4f683ef41ea35b5dddc797bd2bbd990d49897fd1c8a46"}, - {file = "scikit_learn-1.4.1.post1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a1e289f33f613cefe6707dead50db31930530dc386b6ccff176c786335a7b01c"}, - {file = "scikit_learn-1.4.1.post1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:0df87de9ce1c0140f2818beef310fb2e2afdc1e66fc9ad587965577f17733649"}, - {file = "scikit_learn-1.4.1.post1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:712c1c69c45b58ef21635360b3d0a680ff7d83ac95b6f9b82cf9294070cda710"}, - {file = "scikit_learn-1.4.1.post1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1754b0c2409d6ed5a3380512d0adcf182a01363c669033a2b55cca429ed86a81"}, - {file = "scikit_learn-1.4.1.post1-cp312-cp312-win_amd64.whl", hash = "sha256:1d491ef66e37f4e812db7e6c8286520c2c3fc61b34bf5e59b67b4ce528de93af"}, - {file = "scikit_learn-1.4.1.post1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:aa0029b78ef59af22cfbd833e8ace8526e4df90212db7ceccbea582ebb5d6794"}, - {file = "scikit_learn-1.4.1.post1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:14e4c88436ac96bf69eb6d746ac76a574c314a23c6961b7d344b38877f20fee1"}, - {file = "scikit_learn-1.4.1.post1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7cd3a77c32879311f2aa93466d3c288c955ef71d191503cf0677c3340ae8ae0"}, - {file = "scikit_learn-1.4.1.post1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a3ee19211ded1a52ee37b0a7b373a8bfc66f95353af058a210b692bd4cda0dd"}, - {file = "scikit_learn-1.4.1.post1-cp39-cp39-win_amd64.whl", hash = "sha256:234b6bda70fdcae9e4abbbe028582ce99c280458665a155eed0b820599377d25"}, -] - -[package.dependencies] -joblib = ">=1.2.0" -numpy = ">=1.19.5,<2.0" -scipy = ">=1.6.0" -threadpoolctl = ">=2.0.0" - -[package.extras] -benchmark = ["matplotlib (>=3.3.4)", "memory-profiler (>=0.57.0)", "pandas (>=1.1.5)"] -docs = ["Pillow (>=7.1.2)", "matplotlib (>=3.3.4)", "memory-profiler (>=0.57.0)", "numpydoc (>=1.2.0)", "pandas (>=1.1.5)", "plotly (>=5.14.0)", "pooch (>=1.6.0)", "scikit-image (>=0.17.2)", "seaborn (>=0.9.0)", "sphinx (>=6.0.0)", "sphinx-copybutton (>=0.5.2)", "sphinx-gallery (>=0.15.0)", "sphinx-prompt (>=1.3.0)", "sphinxext-opengraph (>=0.4.2)"] -examples = ["matplotlib (>=3.3.4)", "pandas (>=1.1.5)", "plotly (>=5.14.0)", "pooch (>=1.6.0)", "scikit-image (>=0.17.2)", "seaborn (>=0.9.0)"] -tests = ["black (>=23.3.0)", "matplotlib (>=3.3.4)", "mypy (>=1.3)", "numpydoc (>=1.2.0)", "pandas (>=1.1.5)", "polars (>=0.19.12)", "pooch (>=1.6.0)", "pyamg (>=4.0.0)", "pyarrow (>=12.0.0)", "pytest (>=7.1.2)", "pytest-cov (>=2.9.0)", "ruff (>=0.0.272)", "scikit-image (>=0.17.2)"] - [[package]] name = "scipy" version = "1.12.0" @@ -2219,27 +1755,6 @@ dev = ["click", "cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy", "pycodestyl doc = ["jupytext", "matplotlib (>2)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (==0.9.0)", "sphinx (!=4.1.0)", "sphinx-design (>=0.2.0)"] test = ["asv", "gmpy2", "hypothesis", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] -[[package]] -name = "sentence-transformers" -version = "2.6.0" -description = "Multilingual text embeddings" -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "sentence-transformers-2.6.0.tar.gz", hash = "sha256:cf519d311ddcc8ff84d78d18fae051985bef348716354e069e3d6d670e4db604"}, - {file = "sentence_transformers-2.6.0-py3-none-any.whl", hash = "sha256:8807db6db0cf0a92f02be799b7c8260029ff91315d18f7b4b51c30b10d6b4fdb"}, -] - -[package.dependencies] -huggingface-hub = ">=0.15.1" -numpy = "*" -Pillow = "*" -scikit-learn = "*" -scipy = "*" -torch = ">=1.11.0" -tqdm = "*" -transformers = ">=4.32.0,<5.0.0" - [[package]] name = "setuptools" version = "68.2.2" @@ -2278,20 +1793,6 @@ files = [ {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, ] -[[package]] -name = "sympy" -version = "1.12" -description = "Computer algebra system (CAS) in Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "sympy-1.12-py3-none-any.whl", hash = "sha256:c3588cd4295d0c0f603d0f2ae780587e64e2efeedb3521e46b9bb1d08d184fa5"}, - {file = "sympy-1.12.tar.gz", hash = "sha256:ebf595c8dac3e0fdc4152c51878b498396ec7f30e7a914d6071e674d49420fb8"}, -] - -[package.dependencies] -mpmath = ">=0.19" - [[package]] name = "tabulate" version = "0.9.0" @@ -2306,17 +1807,6 @@ files = [ [package.extras] widechars = ["wcwidth"] -[[package]] -name = "threadpoolctl" -version = "3.4.0" -description = "threadpoolctl" -optional = false -python-versions = ">=3.8" -files = [ - {file = "threadpoolctl-3.4.0-py3-none-any.whl", hash = "sha256:8f4c689a65b23e5ed825c8436a92b818aac005e0f3715f6a1664d7c7ee29d262"}, - {file = "threadpoolctl-3.4.0.tar.gz", hash = "sha256:f11b491a03661d6dd7ef692dd422ab34185d982466c49c8f98c8f716b5c93196"}, -] - [[package]] name = "tifffile" version = "2024.2.12" @@ -2334,133 +1824,6 @@ numpy = "*" [package.extras] all = ["defusedxml", "fsspec", "imagecodecs (>=2023.8.12)", "lxml", "matplotlib", "zarr"] -[[package]] -name = "tokenizers" -version = "0.15.2" -description = "" -optional = false -python-versions = ">=3.7" -files = [ - {file = "tokenizers-0.15.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:52f6130c9cbf70544287575a985bf44ae1bda2da7e8c24e97716080593638012"}, - {file = "tokenizers-0.15.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:054c1cc9c6d68f7ffa4e810b3d5131e0ba511b6e4be34157aa08ee54c2f8d9ee"}, - {file = "tokenizers-0.15.2-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a9b9b070fdad06e347563b88c278995735292ded1132f8657084989a4c84a6d5"}, - {file = "tokenizers-0.15.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea621a7eef4b70e1f7a4e84dd989ae3f0eeb50fc8690254eacc08acb623e82f1"}, - {file = "tokenizers-0.15.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cf7fd9a5141634fa3aa8d6b7be362e6ae1b4cda60da81388fa533e0b552c98fd"}, - {file = "tokenizers-0.15.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:44f2a832cd0825295f7179eaf173381dc45230f9227ec4b44378322d900447c9"}, - {file = "tokenizers-0.15.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8b9ec69247a23747669ec4b0ca10f8e3dfb3545d550258129bd62291aabe8605"}, - {file = "tokenizers-0.15.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40b6a4c78da863ff26dbd5ad9a8ecc33d8a8d97b535172601cf00aee9d7ce9ce"}, - {file = "tokenizers-0.15.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:5ab2a4d21dcf76af60e05af8063138849eb1d6553a0d059f6534357bce8ba364"}, - {file = "tokenizers-0.15.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a47acfac7e511f6bbfcf2d3fb8c26979c780a91e06fb5b9a43831b2c0153d024"}, - {file = "tokenizers-0.15.2-cp310-none-win32.whl", hash = "sha256:064ff87bb6acdbd693666de9a4b692add41308a2c0ec0770d6385737117215f2"}, - {file = "tokenizers-0.15.2-cp310-none-win_amd64.whl", hash = "sha256:3b919afe4df7eb6ac7cafd2bd14fb507d3f408db7a68c43117f579c984a73843"}, - {file = "tokenizers-0.15.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:89cd1cb93e4b12ff39bb2d626ad77e35209de9309a71e4d3d4672667b4b256e7"}, - {file = "tokenizers-0.15.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cfed5c64e5be23d7ee0f0e98081a25c2a46b0b77ce99a4f0605b1ec43dd481fa"}, - {file = "tokenizers-0.15.2-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a907d76dcfda37023ba203ab4ceeb21bc5683436ebefbd895a0841fd52f6f6f2"}, - {file = "tokenizers-0.15.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20ea60479de6fc7b8ae756b4b097572372d7e4032e2521c1bbf3d90c90a99ff0"}, - {file = "tokenizers-0.15.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:48e2b9335be2bc0171df9281385c2ed06a15f5cf121c44094338306ab7b33f2c"}, - {file = "tokenizers-0.15.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:112a1dd436d2cc06e6ffdc0b06d55ac019a35a63afd26475205cb4b1bf0bfbff"}, - {file = "tokenizers-0.15.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4620cca5c2817177ee8706f860364cc3a8845bc1e291aaf661fb899e5d1c45b0"}, - {file = "tokenizers-0.15.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ccd73a82751c523b3fc31ff8194702e4af4db21dc20e55b30ecc2079c5d43cb7"}, - {file = "tokenizers-0.15.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:107089f135b4ae7817affe6264f8c7a5c5b4fd9a90f9439ed495f54fcea56fb4"}, - {file = "tokenizers-0.15.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0ff110ecc57b7aa4a594396525a3451ad70988e517237fe91c540997c4e50e29"}, - {file = "tokenizers-0.15.2-cp311-none-win32.whl", hash = "sha256:6d76f00f5c32da36c61f41c58346a4fa7f0a61be02f4301fd30ad59834977cc3"}, - {file = "tokenizers-0.15.2-cp311-none-win_amd64.whl", hash = "sha256:cc90102ed17271cf0a1262babe5939e0134b3890345d11a19c3145184b706055"}, - {file = "tokenizers-0.15.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f86593c18d2e6248e72fb91c77d413a815153b8ea4e31f7cd443bdf28e467670"}, - {file = "tokenizers-0.15.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0774bccc6608eca23eb9d620196687c8b2360624619623cf4ba9dc9bd53e8b51"}, - {file = "tokenizers-0.15.2-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:d0222c5b7c9b26c0b4822a82f6a7011de0a9d3060e1da176f66274b70f846b98"}, - {file = "tokenizers-0.15.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3835738be1de66624fff2f4f6f6684775da4e9c00bde053be7564cbf3545cc66"}, - {file = "tokenizers-0.15.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0143e7d9dcd811855c1ce1ab9bf5d96d29bf5e528fd6c7824d0465741e8c10fd"}, - {file = "tokenizers-0.15.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db35825f6d54215f6b6009a7ff3eedee0848c99a6271c870d2826fbbedf31a38"}, - {file = "tokenizers-0.15.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3f5e64b0389a2be47091d8cc53c87859783b837ea1a06edd9d8e04004df55a5c"}, - {file = "tokenizers-0.15.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e0480c452217edd35eca56fafe2029fb4d368b7c0475f8dfa3c5c9c400a7456"}, - {file = "tokenizers-0.15.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a33ab881c8fe70474980577e033d0bc9a27b7ab8272896e500708b212995d834"}, - {file = "tokenizers-0.15.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a308a607ca9de2c64c1b9ba79ec9a403969715a1b8ba5f998a676826f1a7039d"}, - {file = "tokenizers-0.15.2-cp312-none-win32.whl", hash = "sha256:b8fcfa81bcb9447df582c5bc96a031e6df4da2a774b8080d4f02c0c16b42be0b"}, - {file = "tokenizers-0.15.2-cp312-none-win_amd64.whl", hash = "sha256:38d7ab43c6825abfc0b661d95f39c7f8af2449364f01d331f3b51c94dcff7221"}, - {file = "tokenizers-0.15.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:38bfb0204ff3246ca4d5e726e8cc8403bfc931090151e6eede54d0e0cf162ef0"}, - {file = "tokenizers-0.15.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9c861d35e8286a53e06e9e28d030b5a05bcbf5ac9d7229e561e53c352a85b1fc"}, - {file = "tokenizers-0.15.2-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:936bf3842db5b2048eaa53dade907b1160f318e7c90c74bfab86f1e47720bdd6"}, - {file = "tokenizers-0.15.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:620beacc3373277700d0e27718aa8b25f7b383eb8001fba94ee00aeea1459d89"}, - {file = "tokenizers-0.15.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2735ecbbf37e52db4ea970e539fd2d450d213517b77745114f92867f3fc246eb"}, - {file = "tokenizers-0.15.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:473c83c5e2359bb81b0b6fde870b41b2764fcdd36d997485e07e72cc3a62264a"}, - {file = "tokenizers-0.15.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:968fa1fb3c27398b28a4eca1cbd1e19355c4d3a6007f7398d48826bbe3a0f728"}, - {file = "tokenizers-0.15.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:865c60ae6eaebdde7da66191ee9b7db52e542ed8ee9d2c653b6d190a9351b980"}, - {file = "tokenizers-0.15.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7c0d8b52664ab2d4a8d6686eb5effc68b78608a9008f086a122a7b2996befbab"}, - {file = "tokenizers-0.15.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:f33dfbdec3784093a9aebb3680d1f91336c56d86cc70ddf88708251da1fe9064"}, - {file = "tokenizers-0.15.2-cp37-cp37m-macosx_10_12_x86_64.whl", hash = "sha256:d44ba80988ff9424e33e0a49445072ac7029d8c0e1601ad25a0ca5f41ed0c1d6"}, - {file = "tokenizers-0.15.2-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:dce74266919b892f82b1b86025a613956ea0ea62a4843d4c4237be2c5498ed3a"}, - {file = "tokenizers-0.15.2-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0ef06b9707baeb98b316577acb04f4852239d856b93e9ec3a299622f6084e4be"}, - {file = "tokenizers-0.15.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c73e2e74bbb07910da0d37c326869f34113137b23eadad3fc00856e6b3d9930c"}, - {file = "tokenizers-0.15.2-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4eeb12daf02a59e29f578a865f55d87cd103ce62bd8a3a5874f8fdeaa82e336b"}, - {file = "tokenizers-0.15.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9ba9f6895af58487ca4f54e8a664a322f16c26bbb442effd01087eba391a719e"}, - {file = "tokenizers-0.15.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ccec77aa7150e38eec6878a493bf8c263ff1fa8a62404e16c6203c64c1f16a26"}, - {file = "tokenizers-0.15.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3f40604f5042ff210ba82743dda2b6aa3e55aa12df4e9f2378ee01a17e2855e"}, - {file = "tokenizers-0.15.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:5645938a42d78c4885086767c70923abad047163d809c16da75d6b290cb30bbe"}, - {file = "tokenizers-0.15.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:05a77cbfebe28a61ab5c3891f9939cc24798b63fa236d84e5f29f3a85a200c00"}, - {file = "tokenizers-0.15.2-cp37-none-win32.whl", hash = "sha256:361abdc068e8afe9c5b818769a48624687fb6aaed49636ee39bec4e95e1a215b"}, - {file = "tokenizers-0.15.2-cp37-none-win_amd64.whl", hash = "sha256:7ef789f83eb0f9baeb4d09a86cd639c0a5518528f9992f38b28e819df397eb06"}, - {file = "tokenizers-0.15.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:4fe1f74a902bee74a3b25aff180fbfbf4f8b444ab37c4d496af7afd13a784ed2"}, - {file = "tokenizers-0.15.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4c4b89038a684f40a6b15d6b09f49650ac64d951ad0f2a3ea9169687bbf2a8ba"}, - {file = "tokenizers-0.15.2-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:d05a1b06f986d41aed5f2de464c003004b2df8aaf66f2b7628254bcbfb72a438"}, - {file = "tokenizers-0.15.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:508711a108684111ec8af89d3a9e9e08755247eda27d0ba5e3c50e9da1600f6d"}, - {file = "tokenizers-0.15.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:daa348f02d15160cb35439098ac96e3a53bacf35885072611cd9e5be7d333daa"}, - {file = "tokenizers-0.15.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:494fdbe5932d3416de2a85fc2470b797e6f3226c12845cadf054dd906afd0442"}, - {file = "tokenizers-0.15.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c2d60f5246f4da9373f75ff18d64c69cbf60c3bca597290cea01059c336d2470"}, - {file = "tokenizers-0.15.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93268e788825f52de4c7bdcb6ebc1fcd4a5442c02e730faa9b6b08f23ead0e24"}, - {file = "tokenizers-0.15.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6fc7083ab404019fc9acafe78662c192673c1e696bd598d16dc005bd663a5cf9"}, - {file = "tokenizers-0.15.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:41e39b41e5531d6b2122a77532dbea60e171ef87a3820b5a3888daa847df4153"}, - {file = "tokenizers-0.15.2-cp38-none-win32.whl", hash = "sha256:06cd0487b1cbfabefb2cc52fbd6b1f8d4c37799bd6c6e1641281adaa6b2504a7"}, - {file = "tokenizers-0.15.2-cp38-none-win_amd64.whl", hash = "sha256:5179c271aa5de9c71712e31cb5a79e436ecd0d7532a408fa42a8dbfa4bc23fd9"}, - {file = "tokenizers-0.15.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:82f8652a74cc107052328b87ea8b34291c0f55b96d8fb261b3880216a9f9e48e"}, - {file = "tokenizers-0.15.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:02458bee6f5f3139f1ebbb6d042b283af712c0981f5bc50edf771d6b762d5e4f"}, - {file = "tokenizers-0.15.2-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c9a09cd26cca2e1c349f91aa665309ddb48d71636370749414fbf67bc83c5343"}, - {file = "tokenizers-0.15.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:158be8ea8554e5ed69acc1ce3fbb23a06060bd4bbb09029431ad6b9a466a7121"}, - {file = "tokenizers-0.15.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1ddba9a2b0c8c81633eca0bb2e1aa5b3a15362b1277f1ae64176d0f6eba78ab1"}, - {file = "tokenizers-0.15.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3ef5dd1d39797044642dbe53eb2bc56435308432e9c7907728da74c69ee2adca"}, - {file = "tokenizers-0.15.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:454c203164e07a860dbeb3b1f4a733be52b0edbb4dd2e5bd75023ffa8b49403a"}, - {file = "tokenizers-0.15.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0cf6b7f1d4dc59af960e6ffdc4faffe6460bbfa8dce27a58bf75755ffdb2526d"}, - {file = "tokenizers-0.15.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2ef09bbc16519f6c25d0c7fc0c6a33a6f62923e263c9d7cca4e58b8c61572afb"}, - {file = "tokenizers-0.15.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c9a2ebdd2ad4ec7a68e7615086e633857c85e2f18025bd05d2a4399e6c5f7169"}, - {file = "tokenizers-0.15.2-cp39-none-win32.whl", hash = "sha256:918fbb0eab96fe08e72a8c2b5461e9cce95585d82a58688e7f01c2bd546c79d0"}, - {file = "tokenizers-0.15.2-cp39-none-win_amd64.whl", hash = "sha256:524e60da0135e106b254bd71f0659be9f89d83f006ea9093ce4d1fab498c6d0d"}, - {file = "tokenizers-0.15.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:6a9b648a58281c4672212fab04e60648fde574877d0139cd4b4f93fe28ca8944"}, - {file = "tokenizers-0.15.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:7c7d18b733be6bbca8a55084027f7be428c947ddf871c500ee603e375013ffba"}, - {file = "tokenizers-0.15.2-pp310-pypy310_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:13ca3611de8d9ddfbc4dc39ef54ab1d2d4aaa114ac8727dfdc6a6ec4be017378"}, - {file = "tokenizers-0.15.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:237d1bf3361cf2e6463e6c140628e6406766e8b27274f5fcc62c747ae3c6f094"}, - {file = "tokenizers-0.15.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67a0fe1e49e60c664915e9fb6b0cb19bac082ab1f309188230e4b2920230edb3"}, - {file = "tokenizers-0.15.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:4e022fe65e99230b8fd89ebdfea138c24421f91c1a4f4781a8f5016fd5cdfb4d"}, - {file = "tokenizers-0.15.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:d857be2df69763362ac699f8b251a8cd3fac9d21893de129bc788f8baaef2693"}, - {file = "tokenizers-0.15.2-pp37-pypy37_pp73-macosx_10_12_x86_64.whl", hash = "sha256:708bb3e4283177236309e698da5fcd0879ce8fd37457d7c266d16b550bcbbd18"}, - {file = "tokenizers-0.15.2-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:64c35e09e9899b72a76e762f9854e8750213f67567787d45f37ce06daf57ca78"}, - {file = "tokenizers-0.15.2-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1257f4394be0d3b00de8c9e840ca5601d0a4a8438361ce9c2b05c7d25f6057b"}, - {file = "tokenizers-0.15.2-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02272fe48280e0293a04245ca5d919b2c94a48b408b55e858feae9618138aeda"}, - {file = "tokenizers-0.15.2-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:dc3ad9ebc76eabe8b1d7c04d38be884b8f9d60c0cdc09b0aa4e3bcf746de0388"}, - {file = "tokenizers-0.15.2-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:32e16bdeffa7c4f46bf2152172ca511808b952701d13e7c18833c0b73cb5c23f"}, - {file = "tokenizers-0.15.2-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:fb16ba563d59003028b678d2361a27f7e4ae0ab29c7a80690efa20d829c81fdb"}, - {file = "tokenizers-0.15.2-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:2277c36d2d6cdb7876c274547921a42425b6810d38354327dd65a8009acf870c"}, - {file = "tokenizers-0.15.2-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1cf75d32e8d250781940d07f7eece253f2fe9ecdb1dc7ba6e3833fa17b82fcbc"}, - {file = "tokenizers-0.15.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1b3b31884dc8e9b21508bb76da80ebf7308fdb947a17affce815665d5c4d028"}, - {file = "tokenizers-0.15.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b10122d8d8e30afb43bb1fe21a3619f62c3e2574bff2699cf8af8b0b6c5dc4a3"}, - {file = "tokenizers-0.15.2-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d88b96ff0fe8e91f6ef01ba50b0d71db5017fa4e3b1d99681cec89a85faf7bf7"}, - {file = "tokenizers-0.15.2-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:37aaec5a52e959892870a7c47cef80c53797c0db9149d458460f4f31e2fb250e"}, - {file = "tokenizers-0.15.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:e2ea752f2b0fe96eb6e2f3adbbf4d72aaa1272079b0dfa1145507bd6a5d537e6"}, - {file = "tokenizers-0.15.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:4b19a808d8799fda23504a5cd31d2f58e6f52f140380082b352f877017d6342b"}, - {file = "tokenizers-0.15.2-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:64c86e5e068ac8b19204419ed8ca90f9d25db20578f5881e337d203b314f4104"}, - {file = "tokenizers-0.15.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de19c4dc503c612847edf833c82e9f73cd79926a384af9d801dcf93f110cea4e"}, - {file = "tokenizers-0.15.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea09acd2fe3324174063d61ad620dec3bcf042b495515f27f638270a7d466e8b"}, - {file = "tokenizers-0.15.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:cf27fd43472e07b57cf420eee1e814549203d56de00b5af8659cb99885472f1f"}, - {file = "tokenizers-0.15.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:7ca22bd897537a0080521445d91a58886c8c04084a6a19e6c78c586e0cfa92a5"}, - {file = "tokenizers-0.15.2.tar.gz", hash = "sha256:e6e9c6e019dd5484be5beafc775ae6c925f4c69a3487040ed09b45e13df2cb91"}, -] - -[package.dependencies] -huggingface_hub = ">=0.16.4,<1.0" - -[package.extras] -dev = ["tokenizers[testing]"] -docs = ["setuptools_rust", "sphinx", "sphinx_rtd_theme"] -testing = ["black (==22.3)", "datasets", "numpy", "pytest", "requests"] - [[package]] name = "tomli" version = "2.0.1" @@ -2472,59 +1835,6 @@ files = [ {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] -[[package]] -name = "torch" -version = "2.1.2" -description = "Tensors and Dynamic neural networks in Python with strong GPU acceleration" -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "torch-2.1.2-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:3a871edd6c02dae77ad810335c0833391c1a4ce49af21ea8cf0f6a5d2096eea8"}, - {file = "torch-2.1.2-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:bef6996c27d8f6e92ea4e13a772d89611da0e103b48790de78131e308cf73076"}, - {file = "torch-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:0e13034fd5fb323cbbc29e56d0637a3791e50dd589616f40c79adfa36a5a35a1"}, - {file = "torch-2.1.2-cp310-none-macosx_10_9_x86_64.whl", hash = "sha256:d9b535cad0df3d13997dbe8bd68ac33e0e3ae5377639c9881948e40794a61403"}, - {file = "torch-2.1.2-cp310-none-macosx_11_0_arm64.whl", hash = "sha256:f9a55d55af02826ebfbadf4e9b682f0f27766bc33df8236b48d28d705587868f"}, - {file = "torch-2.1.2-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:a6ebbe517097ef289cc7952783588c72de071d4b15ce0f8b285093f0916b1162"}, - {file = "torch-2.1.2-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:8f32ce591616a30304f37a7d5ea80b69ca9e1b94bba7f308184bf616fdaea155"}, - {file = "torch-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:e0ee6cf90c8970e05760f898d58f9ac65821c37ffe8b04269ec787aa70962b69"}, - {file = "torch-2.1.2-cp311-none-macosx_10_9_x86_64.whl", hash = "sha256:76d37967c31c99548ad2c4d3f2cf191db48476f2e69b35a0937137116da356a1"}, - {file = "torch-2.1.2-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:e2d83f07b4aac983453ea5bf8f9aa9dacf2278a8d31247f5d9037f37befc60e4"}, - {file = "torch-2.1.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:f41fe0c7ecbf903a568c73486139a75cfab287a0f6c17ed0698fdea7a1e8641d"}, - {file = "torch-2.1.2-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:e3225f47d50bb66f756fe9196a768055d1c26b02154eb1f770ce47a2578d3aa7"}, - {file = "torch-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:33d59cd03cb60106857f6c26b36457793637512998666ee3ce17311f217afe2b"}, - {file = "torch-2.1.2-cp38-none-macosx_10_9_x86_64.whl", hash = "sha256:8e221deccd0def6c2badff6be403e0c53491805ed9915e2c029adbcdb87ab6b5"}, - {file = "torch-2.1.2-cp38-none-macosx_11_0_arm64.whl", hash = "sha256:05b18594f60a911a0c4f023f38a8bda77131fba5fd741bda626e97dcf5a3dd0a"}, - {file = "torch-2.1.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:9ca96253b761e9aaf8e06fb30a66ee301aecbf15bb5a303097de1969077620b6"}, - {file = "torch-2.1.2-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:d93ba70f67b08c2ae5598ee711cbc546a1bc8102cef938904b8c85c2089a51a0"}, - {file = "torch-2.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:255b50bc0608db177e6a3cc118961d77de7e5105f07816585fa6f191f33a9ff3"}, - {file = "torch-2.1.2-cp39-none-macosx_10_9_x86_64.whl", hash = "sha256:6984cd5057c0c977b3c9757254e989d3f1124f4ce9d07caa6cb637783c71d42a"}, - {file = "torch-2.1.2-cp39-none-macosx_11_0_arm64.whl", hash = "sha256:bc195d7927feabc0eb7c110e457c955ed2ab616f3c7c28439dd4188cf589699f"}, -] - -[package.dependencies] -filelock = "*" -fsspec = "*" -jinja2 = "*" -networkx = "*" -nvidia-cublas-cu12 = {version = "12.1.3.1", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -nvidia-cuda-cupti-cu12 = {version = "12.1.105", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -nvidia-cuda-nvrtc-cu12 = {version = "12.1.105", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -nvidia-cuda-runtime-cu12 = {version = "12.1.105", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -nvidia-cudnn-cu12 = {version = "8.9.2.26", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -nvidia-cufft-cu12 = {version = "11.0.2.54", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -nvidia-curand-cu12 = {version = "10.3.2.106", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -nvidia-cusolver-cu12 = {version = "11.4.5.107", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -nvidia-cusparse-cu12 = {version = "12.1.0.106", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -nvidia-nccl-cu12 = {version = "2.18.1", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -nvidia-nvtx-cu12 = {version = "12.1.105", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -sympy = "*" -triton = {version = "2.1.0", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -typing-extensions = "*" - -[package.extras] -dynamo = ["jinja2"] -opt-einsum = ["opt-einsum (>=3.3)"] - [[package]] name = "tqdm" version = "4.66.2" @@ -2545,99 +1855,6 @@ notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] telegram = ["requests"] -[[package]] -name = "transformers" -version = "4.39.1" -description = "State-of-the-art Machine Learning for JAX, PyTorch and TensorFlow" -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "transformers-4.39.1-py3-none-any.whl", hash = "sha256:df167e08b27ab254044a38bb7c439461cd3916332205416e9b6b1592b517a1a5"}, - {file = "transformers-4.39.1.tar.gz", hash = "sha256:ab9c1e1912843b9976e6cc62b27cd5434284fc0dab465e1b660333acfa81c6bc"}, -] - -[package.dependencies] -filelock = "*" -huggingface-hub = ">=0.19.3,<1.0" -numpy = ">=1.17" -packaging = ">=20.0" -pyyaml = ">=5.1" -regex = "!=2019.12.17" -requests = "*" -safetensors = ">=0.4.1" -tokenizers = ">=0.14,<0.19" -tqdm = ">=4.27" - -[package.extras] -accelerate = ["accelerate (>=0.21.0)"] -agents = ["Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "datasets (!=2.5.0)", "diffusers", "opencv-python", "sentencepiece (>=0.1.91,!=0.1.92)", "torch"] -all = ["Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "av (==9.2.0)", "codecarbon (==1.2.0)", "decord (==0.6.0)", "flax (>=0.4.1,<=0.7.0)", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "phonemizer", "protobuf", "pyctcdecode (>=0.4.0)", "ray[tune] (>=2.7.0)", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timm", "tokenizers (>=0.14,<0.19)", "torch", "torchaudio", "torchvision"] -audio = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)"] -codecarbon = ["codecarbon (==1.2.0)"] -deepspeed = ["accelerate (>=0.21.0)", "deepspeed (>=0.9.3)"] -deepspeed-testing = ["GitPython (<3.1.19)", "accelerate (>=0.21.0)", "beautifulsoup4", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "deepspeed (>=0.9.3)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder (>=0.3.0)", "nltk", "optuna", "parameterized", "protobuf", "psutil", "pydantic", "pytest (>=7.2.0,<8.0.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "sentencepiece (>=0.1.91,!=0.1.92)", "tensorboard", "timeout-decorator"] -dev = ["GitPython (<3.1.19)", "Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "av (==9.2.0)", "beautifulsoup4", "codecarbon (==1.2.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "decord (==0.6.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "flax (>=0.4.1,<=0.7.0)", "fugashi (>=1.0)", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "ipadic (>=1.0.0,<2.0)", "isort (>=5.5.4)", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "nltk", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pydantic", "pytest (>=7.2.0,<8.0.0)", "pytest-timeout", "pytest-xdist", "ray[tune] (>=2.7.0)", "rhoknp (>=1.1.0,<1.3.1)", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "tensorboard", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timeout-decorator", "timm", "tokenizers (>=0.14,<0.19)", "torch", "torchaudio", "torchvision", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)", "urllib3 (<2.0.0)"] -dev-tensorflow = ["GitPython (<3.1.19)", "Pillow (>=10.0.1,<=15.0)", "beautifulsoup4", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "isort (>=5.5.4)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "nltk", "onnxconverter-common", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pydantic", "pytest (>=7.2.0,<8.0.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "tensorboard", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timeout-decorator", "tokenizers (>=0.14,<0.19)", "urllib3 (<2.0.0)"] -dev-torch = ["GitPython (<3.1.19)", "Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "beautifulsoup4", "codecarbon (==1.2.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "fugashi (>=1.0)", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "ipadic (>=1.0.0,<2.0)", "isort (>=5.5.4)", "kenlm", "librosa", "nltk", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "optuna", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pydantic", "pytest (>=7.2.0,<8.0.0)", "pytest-timeout", "pytest-xdist", "ray[tune] (>=2.7.0)", "rhoknp (>=1.1.0,<1.3.1)", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "tensorboard", "timeout-decorator", "timm", "tokenizers (>=0.14,<0.19)", "torch", "torchaudio", "torchvision", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)", "urllib3 (<2.0.0)"] -docs = ["Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "av (==9.2.0)", "codecarbon (==1.2.0)", "decord (==0.6.0)", "flax (>=0.4.1,<=0.7.0)", "hf-doc-builder", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "phonemizer", "protobuf", "pyctcdecode (>=0.4.0)", "ray[tune] (>=2.7.0)", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timm", "tokenizers (>=0.14,<0.19)", "torch", "torchaudio", "torchvision"] -docs-specific = ["hf-doc-builder"] -flax = ["flax (>=0.4.1,<=0.7.0)", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "optax (>=0.0.8,<=0.1.4)"] -flax-speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)"] -ftfy = ["ftfy"] -integrations = ["optuna", "ray[tune] (>=2.7.0)", "sigopt"] -ja = ["fugashi (>=1.0)", "ipadic (>=1.0.0,<2.0)", "rhoknp (>=1.1.0,<1.3.1)", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)"] -modelcreation = ["cookiecutter (==1.7.3)"] -natten = ["natten (>=0.14.6,<0.15.0)"] -onnx = ["onnxconverter-common", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "tf2onnx"] -onnxruntime = ["onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)"] -optuna = ["optuna"] -quality = ["GitPython (<3.1.19)", "datasets (!=2.5.0)", "hf-doc-builder (>=0.3.0)", "isort (>=5.5.4)", "ruff (==0.1.5)", "urllib3 (<2.0.0)"] -ray = ["ray[tune] (>=2.7.0)"] -retrieval = ["datasets (!=2.5.0)", "faiss-cpu"] -sagemaker = ["sagemaker (>=2.31.0)"] -sentencepiece = ["protobuf", "sentencepiece (>=0.1.91,!=0.1.92)"] -serving = ["fastapi", "pydantic", "starlette", "uvicorn"] -sigopt = ["sigopt"] -sklearn = ["scikit-learn"] -speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)", "torchaudio"] -testing = ["GitPython (<3.1.19)", "beautifulsoup4", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder (>=0.3.0)", "nltk", "parameterized", "protobuf", "psutil", "pydantic", "pytest (>=7.2.0,<8.0.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "tensorboard", "timeout-decorator"] -tf = ["keras-nlp (>=0.3.1)", "onnxconverter-common", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx"] -tf-cpu = ["keras-nlp (>=0.3.1)", "onnxconverter-common", "tensorflow-cpu (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx"] -tf-speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)"] -timm = ["timm"] -tokenizers = ["tokenizers (>=0.14,<0.19)"] -torch = ["accelerate (>=0.21.0)", "torch"] -torch-speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)", "torchaudio"] -torch-vision = ["Pillow (>=10.0.1,<=15.0)", "torchvision"] -torchhub = ["filelock", "huggingface-hub (>=0.19.3,<1.0)", "importlib-metadata", "numpy (>=1.17)", "packaging (>=20.0)", "protobuf", "regex (!=2019.12.17)", "requests", "sentencepiece (>=0.1.91,!=0.1.92)", "tokenizers (>=0.14,<0.19)", "torch", "tqdm (>=4.27)"] -video = ["av (==9.2.0)", "decord (==0.6.0)"] -vision = ["Pillow (>=10.0.1,<=15.0)"] - -[[package]] -name = "triton" -version = "2.1.0" -description = "A language and compiler for custom Deep Learning operations" -optional = false -python-versions = "*" -files = [ - {file = "triton-2.1.0-0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:66439923a30d5d48399b08a9eae10370f6c261a5ec864a64983bae63152d39d7"}, - {file = "triton-2.1.0-0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:919b06453f0033ea52c13eaf7833de0e57db3178d23d4e04f9fc71c4f2c32bf8"}, - {file = "triton-2.1.0-0-cp37-cp37m-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ae4bb8a91de790e1866405211c4d618379781188f40d5c4c399766914e84cd94"}, - {file = "triton-2.1.0-0-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:39f6fb6bdccb3e98f3152e3fbea724f1aeae7d749412bbb1fa9c441d474eba26"}, - {file = "triton-2.1.0-0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:21544e522c02005a626c8ad63d39bdff2f31d41069592919ef281e964ed26446"}, - {file = "triton-2.1.0-0-pp37-pypy37_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:143582ca31dd89cd982bd3bf53666bab1c7527d41e185f9e3d8a3051ce1b663b"}, - {file = "triton-2.1.0-0-pp38-pypy38_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:82fc5aeeedf6e36be4e4530cbdcba81a09d65c18e02f52dc298696d45721f3bd"}, - {file = "triton-2.1.0-0-pp39-pypy39_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:81a96d110a738ff63339fc892ded095b31bd0d205e3aace262af8400d40b6fa8"}, -] - -[package.dependencies] -filelock = "*" - -[package.extras] -build = ["cmake (>=3.18)", "lit"] -tests = ["autopep8", "flake8", "isort", "numpy", "pytest", "scipy (>=1.7.1)"] -tutorials = ["matplotlib", "pandas", "tabulate"] - [[package]] name = "types-pillow" version = "9.5.0.6" @@ -2793,5 +2010,5 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" -python-versions = ">=3.9,<3.12" -content-hash = "37e5b5d42e2c18f1d5741fc2efd9aa4d31dbd4413d09a7d43462e6a1a669531d" +python-versions = ">=3.9" +content-hash = "5c57abb9e41b66ee6195875318971f2c2ce858879efca8f5edefb2226284ee6c" diff --git a/pyproject.toml b/pyproject.toml index 0670265f..9e37d2c1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "vision-agent" -version = "0.1.5" +version = "0.2.0" description = "Toolset for Vision Agent" authors = ["Landing AI "] readme = "README.md" @@ -16,16 +16,12 @@ packages = [{include = "vision_agent"}] "documentation" = "https://github.com/landing-ai/vision-agent" [tool.poetry.dependencies] # main dependency group -python = ">=3.9,<3.12" - +python = ">=3.9" numpy = ">=1.21.0,<2.0.0" pillow = "10.*" requests = "2.*" tqdm = ">=4.64.0,<5.0.0" pandas = "2.*" -faiss-cpu = "1.*" -torch = "2.1.*" # 2.2 causes sentence-transformers to seg fault -sentence-transformers = "2.*" openai = "1.*" typing_extensions = "4.*" moviepy = "1.*" diff --git a/tests/test_data.py b/tests/test_data.py deleted file mode 100644 index 046fc0fb..00000000 --- a/tests/test_data.py +++ /dev/null @@ -1,93 +0,0 @@ -import shutil -from pathlib import Path - -import numpy as np -import pandas as pd -import pytest - -from vision_agent.data import DataStore, build_data_store - - -@pytest.fixture(autouse=True) -def clean_up(): - yield - for p in Path(".").glob("test_save*"): - if p.is_dir(): - shutil.rmtree(p) - else: - p.unlink() - - -@pytest.fixture -def small_ds(): - df = pd.DataFrame({"image_paths": ["path1", "path2"]}) - ds = DataStore(df) - return ds - - -@pytest.fixture -def small_ds_with_index(small_ds): - small_ds.add_embedder(TestEmb()) - small_ds.add_lmm(TestLMM()) - small_ds.add_column("test", "test prompt") - small_ds.build_index("test") - return small_ds - - -class TestLMM: - def generate(self, _, **kwargs): - return "test" - - -class TestEmb: - def embed(self, _): - return np.random.randn(128).astype(np.float32) - - -def test_initialize_data_store(small_ds): - assert small_ds is not None - assert "image_id" in small_ds.df.columns - assert "image_paths" in small_ds.df.columns - - -def test_initialize_data_store_with_no_data(): - df = pd.DataFrame({"x": ["path1"]}) - with pytest.raises(ValueError): - DataStore(df) - - -def test_build_data_store(): - ds = build_data_store(["path1", "path2"]) - assert isinstance(ds, DataStore) - assert "image_id" in ds.df.columns - - -def test_add_index_no_emb(small_ds): - with pytest.raises(ValueError): - small_ds.build_index("test") - - -def test_add_column_no_lmm(small_ds): - with pytest.raises(ValueError): - small_ds.add_column("test", "test prompt") - - -def test_search(small_ds_with_index): - results = small_ds_with_index.search("test", top_k=1) - assert len(results) == 1 - - -def test_save(small_ds_with_index): - small_ds_with_index.save("test_save") - - assert Path("test_save").exists() - assert Path("test_save/data.csv").exists() - assert Path("test_save/data.index").exists() - - -def test_load(small_ds_with_index): - small_ds_with_index.save("test_save") - - second_ds = DataStore.load("test_save") - assert second_ds.df.equals(small_ds_with_index.df) - assert second_ds.index is not None diff --git a/vision_agent/__init__.py b/vision_agent/__init__.py index 360b8a78..bf71560f 100644 --- a/vision_agent/__init__.py +++ b/vision_agent/__init__.py @@ -1,5 +1,3 @@ from .agent import Agent -from .data import DataStore, build_data_store -from .emb import Embedder, OpenAIEmb, SentenceTransformerEmb, get_embedder from .llm import LLM, OpenAILLM from .lmm import LMM, LLaVALMM, OpenAILMM, get_lmm diff --git a/vision_agent/data/__init__.py b/vision_agent/data/__init__.py deleted file mode 100644 index 050da913..00000000 --- a/vision_agent/data/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .data import DataStore, build_data_store diff --git a/vision_agent/data/data.py b/vision_agent/data/data.py deleted file mode 100644 index 54125772..00000000 --- a/vision_agent/data/data.py +++ /dev/null @@ -1,142 +0,0 @@ -from __future__ import annotations - -import uuid -from pathlib import Path -from typing import Callable, Dict, List, Optional, Union, cast - -import faiss -import numpy as np -import numpy.typing as npt -import pandas as pd -from faiss import read_index, write_index -from tqdm import tqdm -from typing_extensions import Self - -from vision_agent.emb import Embedder -from vision_agent.lmm import LMM - -tqdm.pandas() - - -class DataStore: - r"""A class to store and manage image data along with its generated metadata from an LMM.""" - - def __init__(self, df: pd.DataFrame): - r"""Initializes the DataStore with a DataFrame containing image paths and image - IDs. If the image IDs are not present, they are generated using UUID4. The - DataFrame must contain an 'image_paths' column. - - Args: - df: The DataFrame containing "image_paths" and "image_id" columns. - """ - self.df = df - self.lmm: Optional[LMM] = None - self.emb: Optional[Embedder] = None - self.index: Optional[faiss.IndexFlatIP] = None # type: ignore - if "image_paths" not in self.df.columns: - raise ValueError("image_paths column must be present in DataFrame") - if "image_id" not in self.df.columns: - self.df["image_id"] = [str(uuid.uuid4()) for _ in range(len(df))] - - def add_embedder(self, emb: Embedder) -> Self: - self.emb = emb - return self - - def add_lmm(self, lmm: LMM) -> Self: - self.lmm = lmm - return self - - def add_column( - self, name: str, prompt: str, func: Optional[Callable[[str], str]] = None - ) -> Self: - r"""Adds a new column to the DataFrame containing the generated metadata from - the LMM. - - Args: - name: The name of the column to be added. - prompt: The prompt to be used to generate the metadata. - func: A Python function to be applied on the output of `lmm.generate`. - Defaults to None. - """ - if self.lmm is None: - raise ValueError("LMM not set yet") - - self.df[name] = self.df["image_paths"].progress_apply( # type: ignore - lambda x: ( - func(self.lmm.generate(prompt, images=[x])) - if func - else self.lmm.generate(prompt, images=[x]) - ) - ) - return self - - def build_index(self, target_col: str) -> Self: - r"""This will generate embeddings for the `target_col` and build a searchable - index over them, so next time you run search it will search over this index. - - Args: - target_col: The column name containing the data to be indexed.""" - if self.emb is None: - raise ValueError("Embedder not set yet") - - embeddings: pd.Series = self.df[target_col].progress_apply(lambda x: self.emb.embed(x)) # type: ignore - embeddings_np = np.array(embeddings.tolist()).astype(np.float32) - self.index = faiss.IndexFlatIP(embeddings_np.shape[1]) - self.index.add(embeddings_np) - return self - - def get_embeddings(self) -> npt.NDArray[np.float32]: - if self.index is None: - raise ValueError("Index not built yet") - - ntotal = self.index.ntotal - d: int = self.index.d - return cast( - npt.NDArray[np.float32], - faiss.rev_swig_ptr(self.index.get_xb(), ntotal * d).reshape(ntotal, d), - ) - - def search(self, query: str, top_k: int = 10) -> List[Dict]: - r"""Searches the index for the most similar images to the query and returns - the top_k results. - - Args: - query: The query to search for. - top_k: The number of results to return. Defaults to 10.""" - if self.index is None: - raise ValueError("Index not built yet") - if self.emb is None: - raise ValueError("Embedder not set yet") - - query_embedding: npt.NDArray[np.float32] = self.emb.embed(query) - _, idx = self.index.search(query_embedding.reshape(1, -1), top_k) - return cast(List[Dict], self.df.iloc[idx[0]].to_dict(orient="records")) - - def save(self, path: Union[str, Path]) -> None: - path = Path(path) - path.mkdir(parents=True) - self.df.to_csv(path / "data.csv") - if self.index is not None: - write_index(self.index, str(path / "data.index")) - - @classmethod - def load(cls, path: Union[str, Path]) -> DataStore: - path = Path(path) - df = pd.read_csv(path / "data.csv", index_col=0) - ds = DataStore(df) - if Path(path / "data.index").exists(): - ds.index = read_index(str(path / "data.index")) - return ds - - -def build_data_store(data: Union[str, Path, list[Union[str, Path]]]) -> DataStore: - if isinstance(data, Path) or isinstance(data, str): - data = Path(data) - data_files = list(Path(data).glob("*")) - elif isinstance(data, list): - data_files = [Path(d) for d in data] - - df = pd.DataFrame() - df["image_paths"] = data_files - df["image_id"] = [uuid.uuid4() for _ in range(len(data_files))] - return DataStore(df) diff --git a/vision_agent/emb/__init__.py b/vision_agent/emb/__init__.py deleted file mode 100644 index 729b96f8..00000000 --- a/vision_agent/emb/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .emb import Embedder, OpenAIEmb, SentenceTransformerEmb, get_embedder diff --git a/vision_agent/emb/emb.py b/vision_agent/emb/emb.py deleted file mode 100644 index 6186ddb4..00000000 --- a/vision_agent/emb/emb.py +++ /dev/null @@ -1,47 +0,0 @@ -from abc import ABC, abstractmethod -from typing import cast - -import numpy as np -import numpy.typing as npt - - -class Embedder(ABC): - @abstractmethod - def embed(self, text: str) -> npt.NDArray[np.float32]: - pass - - -class SentenceTransformerEmb(Embedder): - def __init__(self, model_name: str = "BAAI/bge-small-en-v1.5"): - from sentence_transformers import SentenceTransformer - - self.model = SentenceTransformer(model_name) - - def embed(self, text: str) -> npt.NDArray[np.float32]: - return cast( - npt.NDArray[np.float32], - self.model.encode([text]).flatten().astype(np.float32), - ) - - -class OpenAIEmb(Embedder): - def __init__(self, model_name: str = "text-embedding-3-small"): - from openai import OpenAI - - self.client = OpenAI() - self.model_name = model_name - - def embed(self, text: str) -> npt.NDArray[np.float32]: - response = self.client.embeddings.create(input=text, model=self.model_name) - return np.array(response.data[0].embedding).astype(np.float32) - - -def get_embedder(name: str) -> Embedder: - if name == "sentence-transformer": - return SentenceTransformerEmb() - elif name == "openai": - return OpenAIEmb() - else: - raise ValueError( - f"Unknown embedder name: {name}, currently support sentence-transformer, openai." - ) From 90ad1789899cd81e5af1e34ec7f988a2a26c595a Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot Date: Mon, 22 Apr 2024 21:17:08 +0000 Subject: [PATCH 08/16] [skip ci] chore(release): vision-agent 0.2.1 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 9e37d2c1..ec52ac3a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "vision-agent" -version = "0.2.0" +version = "0.2.1" description = "Toolset for Vision Agent" authors = ["Landing AI "] readme = "README.md" From 88af0b4a65be405a87759d531825c8067172f495 Mon Sep 17 00:00:00 2001 From: Dillon Laird Date: Mon, 22 Apr 2024 19:39:37 -0700 Subject: [PATCH 09/16] make it easier to use custom tools --- vision_agent/agent/vision_agent.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/vision_agent/agent/vision_agent.py b/vision_agent/agent/vision_agent.py index b02cdf72..240b47a1 100644 --- a/vision_agent/agent/vision_agent.py +++ b/vision_agent/agent/vision_agent.py @@ -8,7 +8,7 @@ from PIL import Image from tabulate import tabulate -from vision_agent.image_utils import overlay_bboxes, overlay_masks, overlay_heat_map +from vision_agent.image_utils import overlay_bboxes, overlay_heat_map, overlay_masks from vision_agent.llm import LLM, OpenAILLM from vision_agent.lmm import LMM, OpenAILMM from vision_agent.tools import TOOLS @@ -492,20 +492,20 @@ def chat_with_workflow( if image: question += f" Image name: {image}" if reference_data: - if not ( - "image" in reference_data - and ("mask" in reference_data or "bbox" in reference_data) - ): - raise ValueError( - f"Reference data must contain 'image' and a visual prompt which can be 'mask' or 'bbox'. but got {reference_data}" - ) - visual_prompt_data = ( - f"Reference mask: {reference_data['mask']}" + question += ( + f" Reference image: {reference_data['image']}" + if "image" in reference_data + else "" + ) + question += ( + f" Reference mask: {reference_data['mask']}" if "mask" in reference_data - else f"Reference bbox: {reference_data['bbox']}" + else "" ) question += ( - f" Reference image: {reference_data['image']}, {visual_prompt_data}" + f" Reference bbox: {reference_data['bbox']}" + if "bbox" in reference_data + else "" ) reflections = "" From e1779819ed2b96fe098fe6e89c228f83a81957d5 Mon Sep 17 00:00:00 2001 From: Dillon Laird Date: Mon, 22 Apr 2024 19:39:51 -0700 Subject: [PATCH 10/16] ran isort --- vision_agent/image_utils.py | 2 +- vision_agent/tools/__init__.py | 4 ++-- vision_agent/tools/tools.py | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/vision_agent/image_utils.py b/vision_agent/image_utils.py index 43da645f..5a28df1d 100644 --- a/vision_agent/image_utils.py +++ b/vision_agent/image_utils.py @@ -4,7 +4,7 @@ from importlib import resources from io import BytesIO from pathlib import Path -from typing import Dict, Tuple, Union, List +from typing import Dict, List, Tuple, Union import numpy as np from PIL import Image, ImageDraw, ImageFont diff --git a/vision_agent/tools/__init__.py b/vision_agent/tools/__init__.py index 13629122..450c0b26 100644 --- a/vision_agent/tools/__init__.py +++ b/vision_agent/tools/__init__.py @@ -11,10 +11,10 @@ GroundingDINO, GroundingSAM, ImageCaption, - ZeroShotCounting, - VisualPromptCounting, SegArea, SegIoU, Tool, + VisualPromptCounting, + ZeroShotCounting, register_tool, ) diff --git a/vision_agent/tools/tools.py b/vision_agent/tools/tools.py index 9e323715..06727fc2 100644 --- a/vision_agent/tools/tools.py +++ b/vision_agent/tools/tools.py @@ -11,10 +11,10 @@ from vision_agent.image_utils import ( convert_to_b64, + denormalize_bbox, get_image_size, - rle_decode, normalize_bbox, - denormalize_bbox, + rle_decode, ) from vision_agent.tools.video import extract_frames_from_video from vision_agent.type_defs import LandingaiAPIKey From 0f3a55c45a73047633e657408ceb57f68a609ded Mon Sep 17 00:00:00 2001 From: Dillon Laird Date: Tue, 23 Apr 2024 09:18:04 -0700 Subject: [PATCH 11/16] fix linting error --- vision_agent/tools/__init__.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/vision_agent/tools/__init__.py b/vision_agent/tools/__init__.py index 76045ec1..450c0b26 100644 --- a/vision_agent/tools/__init__.py +++ b/vision_agent/tools/__init__.py @@ -11,8 +11,6 @@ GroundingDINO, GroundingSAM, ImageCaption, - ZeroShotCounting, - VisualPromptCounting, SegArea, SegIoU, Tool, From 6af8d9eeabb0e1fbf5a30ccd6dad7992cd3a0ee0 Mon Sep 17 00:00:00 2001 From: Dillon Laird Date: Tue, 23 Apr 2024 15:42:41 -0700 Subject: [PATCH 12/16] added OCR --- README.md | 1 + vision_agent/agent/vision_agent.py | 1 + vision_agent/tools/__init__.py | 1 + vision_agent/tools/tools.py | 53 ++++++++++++++++++++++++++++++ 4 files changed, 56 insertions(+) diff --git a/README.md b/README.md index 7383af76..87db92ad 100644 --- a/README.md +++ b/README.md @@ -136,6 +136,7 @@ to pick it based on the tool description and use it based on the usage provided. | ExtractFrames | ExtractFrames extracts frames with motion from a video. | | ZeroShotCounting | ZeroShotCounting returns the total number of objects belonging to a single class in a given image | | VisualPromptCounting | VisualPromptCounting returns the total number of objects belonging to a single class given an image and visual prompt | +| OCR | OCR returns the text detected in an image along with the location. | It also has a basic set of calculate tools such as add, subtract, multiply and divide. diff --git a/vision_agent/agent/vision_agent.py b/vision_agent/agent/vision_agent.py index 9b02d4fd..76629f6a 100644 --- a/vision_agent/agent/vision_agent.py +++ b/vision_agent/agent/vision_agent.py @@ -377,6 +377,7 @@ def visualize_result(all_tool_results: List[Dict]) -> Sequence[Union[str, Path]] "dinov_", "zero_shot_counting_", "visual_prompt_counting_", + "ocr_", ]: continue diff --git a/vision_agent/tools/__init__.py b/vision_agent/tools/__init__.py index 450c0b26..67248156 100644 --- a/vision_agent/tools/__init__.py +++ b/vision_agent/tools/__init__.py @@ -1,6 +1,7 @@ from .prompts import CHOOSE_PARAMS, SYSTEM_PROMPT from .tools import ( # Counter, CLIP, + OCR, TOOLS, BboxArea, BboxIoU, diff --git a/vision_agent/tools/tools.py b/vision_agent/tools/tools.py index 06727fc2..64f97467 100644 --- a/vision_agent/tools/tools.py +++ b/vision_agent/tools/tools.py @@ -1,3 +1,4 @@ +import io import logging import tempfile from abc import ABC @@ -868,6 +869,57 @@ def __call__(self, video_uri: str) -> List[Tuple[str, float]]: return result +class OCR(Tool): + name = "ocr_" + description = "'ocr_' extracts text from an image." + usage = { + "required_parameters": [ + {"name": "image", "type": "str"}, + ], + "examples": [ + { + "scenario": "Can you extract the text from this image? Image name: image.png", + "parameters": {"image": "image.png"}, + }, + ], + } + _API_KEY = "land_sk_WVYwP00xA3iXely2vuar6YUDZ3MJT9yLX6oW5noUkwICzYLiDV" + _URL = "https://app.landing.ai/ocr/v1/detect-text" + + def __call__(self, image: str) -> dict: + pil_image = Image.open(image).convert("RGB") + image_size = pil_image.size[::-1] + image_buffer = io.BytesIO() + pil_image.save(image_buffer, format="PNG") + buffer_bytes = image_buffer.getvalue() + image_buffer.close() + + res = requests.post( + self._URL, + files={"images": buffer_bytes}, + data={"language": "en"}, + headers={"contentType": "multipart/form-data", "apikey": self._API_KEY}, + ) + if res.status_code != 200: + _LOGGER.error(f"Request failed: {res.text}") + raise ValueError(f"Request failed: {res.text}") + + data = res.json() + output = {"labels": [], "bboxes": [], "scores": []} + for det in data[0]: + output["labels"].append(det["text"]) + box = [ + det["location"][0]["x"], + det["location"][0]["y"], + det["location"][2]["x"], + det["location"][2]["y"], + ] + box = normalize_bbox(box, image_size) + output["bboxes"].append(box) + output["scores"].append(det["score"]) + return output + + class Calculator(Tool): r"""Calculator is a tool that can perform basic arithmetic operations.""" @@ -913,6 +965,7 @@ def __call__(self, equation: str) -> float: SegIoU, BboxContains, BoxDistance, + OCR, Calculator, ] ) From c5135c719f07fc3a132c155f8d30752f43bd7283 Mon Sep 17 00:00:00 2001 From: Dillon Laird Date: Tue, 23 Apr 2024 16:24:51 -0700 Subject: [PATCH 13/16] added example template matching use case --- examples/custom_tools/pid.png | Bin 0 -> 9070 bytes examples/custom_tools/pid_template.png | Bin 0 -> 4274 bytes examples/custom_tools/run_custom_tool.py | 49 ++++++++++++ examples/custom_tools/template_match.py | 96 +++++++++++++++++++++++ 4 files changed, 145 insertions(+) create mode 100644 examples/custom_tools/pid.png create mode 100644 examples/custom_tools/pid_template.png create mode 100644 examples/custom_tools/run_custom_tool.py create mode 100644 examples/custom_tools/template_match.py diff --git a/examples/custom_tools/pid.png b/examples/custom_tools/pid.png new file mode 100644 index 0000000000000000000000000000000000000000..713b731716a42104aaad5d17de26db26c053da67 GIT binary patch literal 9070 zcmch5Ra70_*5x@!2<{LdcyM=jcXx;2esBv1x8MYqgS)#+aM$1#+(~e6zI*R~yZfPE zd)KH@bIm>1TzgeL)Yv;hSy2iZ0UrSX03gdqi>m?v!0Go}@8dfG5EcOsy+2?qMHEB; zfZABZXA{_W9gMY@n6j;yl$fKPBS_83#LQgE+`$}VZ6*aW@scvJw>M!mVg&%SLkhLv z^b;3xx;KXb2{pyvYvRp?0|2aKY~WMUmT(!805sDNP`^bZu`BdGbJNmB>gr<$@Tx>< z9uHQc+LS`(O&J&~x-wwU%Flc*?z*1OJ>E724%S>I1rD-(puy*oG2&#RK!BHND?3^I z4?!A%AjLMg;hs-c&>oP9?a?n4_xGQMq52<81@CvgoS{iZU(+){RZ2&1_h_EJc(}Jz zCUn0?TD$-xJ3x{QX9`sw0Dj_D%Nc#Ec!V4Y=dgkzQh+DVZZ6U&EphqBu2d#$&=I<- zBDz3eV#-jiPn*x|PT_-&=!|8>tA7rEys0*q9hQ!RD*Ner?u$9UVhP5Rh;Q5&yj)-^ zyt88fGY8IZV}LSWgs&)BzY5wFRx1sCxB+R^R6=O6@aK-6J3!`D*vkASQ}c`HPwUdhav$j;pT?Xa`M;*H(?f)Ua`ES(gj&p%sh z2YV|>hp0-JMy^QBx_5C)@Cc2g&qBvVIsu4xgYYgVU`?mt4~0JjLxe->fN;CLl3_S4 zeK^3@{u&w5Fr?iw?gEHys^FL0Bxh(0=`lE+I4u~8u)!lRoTaiHt>s9V!b4$Zs~*Q7 z;rtVng z$TVq1Z3+=?`-JrqeL2ptg=Mm5sBb@ZXbZ?KMnMtsS)xaQL(q_ev*0G^Kz7qRv~e=H zDdzgyZX|N$ZyIWfuuZbVTu&#zuhZ$x%9I|;k4)bfxzxC2zG%o{F3s62kQdG#iJljl z`&Cj%DF9vu6A}-Ae$|R|ttJFVXP!Grwn@Jd{KJonoBTd6w8VSmkAB&p@`83lufkx& zBtol#<~{YNY`|>6eoAdtZOWg_KU-qYpSbY4Sy%A%NcZ5I5cs|m{!Fj2s6d|H)?#x< zuvN|NTvEB`yX4{{dt&1gO*2{RC4>}=!nru@8sZ(X*^09#J&W0ie!RzVc*F-b z>3bCcWxY(4Qn55jO$~CCU3HMthnJV~*z4F1b#KbgX#^j!_d}h;kstKW^86bXRUs8< zI)(j35mW*o2(iOf#kzqHIRhN2xejrrIE;azfFrFQAlF^G`YzAOcg^aDRNrA z+sELHnu%Pl_ZhN7zlMlP)PEewrGBNZG7v<bV$qg}65w zB_iEbAWb`tGkiqv$@Y70*|e&iZar}us3g88Am``jnGI>BfcJCjw#&N*{^%8=%VJ^0P`r}ZAg7rG14v1e*)@lvq^)n5vN zF%HiNBLtPf91*9GDnU)9j&1`V25)Jya8A}if)OFf%;am_ReR}_I{AfEdRPibaDc0-D5pzDu$32%vCWP0%eBip-3b*cKYRb&^G#8gHU zLS(2`hgM6r_tyQ^m+X=3$<}s@R=-*bW(rv#rR7H@c#yP;wER|Kmn@6UeVqxP^r^;% z2D=8|MvR7F-K)l5)@O^n#S5i3>3LGlMZwBN%2-K-Nm)sWNvlZ*>a+_1`0^8w(Neim zxB0nwxOpvhzjVH6g`JuGnKEnShVq8u75tUk75X#lm4OwFm9PdT>$_vCL+-=iLnqh$ zWAzjEqqX^?#f8P2>FBwMIfJ}*y}J&FW+Is>5hnTAVy&WPg^Pv_F+cfDO(F4|@@{4S z_E()3M(DhNeBdg{5M*|XASmjCU#NHJ4w4!&B62x$ES~!(6G;?FJM#D$*8CtzuJ0S4 z^gh*pe;AC4K8dcz?`Fp{$FS?;DrH`_oOSp+nB;(Ok#5`8cO8D@$F?@UOy6slylhcl zZ_$~LB>52gJErWDo6|g@%lz6h|BP?b1Lqaz)i*@BsE>#d1Kv?{IGxFo$-T)u$>j{O zdbip~da%0im7024HQw@E1@(tykGzj~-Z_n}ZUv2f-sLwECqM$J46F>*3_s30dk*`w zCY`2odp*0S(~48dl^;uIwe4orCQ}W#OVy2zjs8blhjIHg!`tCv&G`}JtF=qcu{#1( zWomJA^2PYYC;1WiY56Wvj`)7dcy6~K9BwT>Banzehe0r7hJIBGhQ6P{Kov(7*E+QW zeKSMxdyPlib7{F~?AhhE}dN#5)}&*w*{BR3Vd z9fHZcoW7?Wwb5od(JpvH#LZr73`~C25r$D6x*f0Aw||no7k%#Tmma=8+FiGfup1Au zr7%xDVE9tqPhJTeKdnryDxG^wUvT+zz3IQLzpn2P4qXj762CF`P=YaQI3VP4M5%c9 zZpKn^ZfH~`l!wK}tHy>-_LtNCs;L8zRji z%E7Oq-IA+qRVipFuqjrQsg(0e!%1&qtu&iWm2sgokmi!ZE#k6>V^w9dVSA(s zQ!r#}wT)a%`b)!A#H+}V>HRHznSG|gY_74`rHFX+%hw|F^GV;ah@E+-N6Q*ZyUdv( z1`IvdlT|r>FVNT3J^j#Vh>a7)9R7ndJ;g z{EaAKDPk<*)?2PqT91N#j1!5t8kre|gDXIb!nDCckTa3Bu4-yf2Ptqtv7P+YI=qJG zqPM?1Ntdz6A!Pbm1)Git!hO~rr8dxc9O`QbnJ~vOzZxU@hW=+D8>HLX@VrmTVnQwb=`)*h@f0ypv!c(D+924V}VUrh+bF1e=G`0wx zd*!@=PRHNvvWRkg%{eWtidVCVYmS5RK@EGI@>b2-CNqQaw!s_slay-zc9ELgPH)kh zuIPONTu0y5h~}f?{jG@`J^Chf2d}Hf%M(34@+QuC?s;{4atFGl+p*jEvr4{HzGIsS z8#>#!HJXj(S~};&G~S%Hw)Oq?lrxb#>f7tnth&3uT)CUfeVYH7e8k|Pq{Qp@BHx!5Wtl&f{UrGOG*?;i3-bVK zl2G8nqw5H6A61Ic)5yx|%7*Vbe=#smc&L>KnixXywREWgzx$z<=I4j zfR3Y#RvVSRf-|;^*6B)_BB(AmsWZDYKBw~&ra}rKQW=3W*K?D*K5`NHE z3tm-m$^WFkM*?J4uC7kJOiUgg9*iDrjE*2nCKetZ9wug1CRSF4cLjrsmxHT`Cxe3v z`M*v6$4A`U#SCQagl|a_!@0I`Y7i8i8m-7GO{!@pa>7U~N$7257>A%?bRs|9Gng09Q z1QGBIx8VQ)EOr@j5p_@CSyq($DQ%U+R9F7nTZ+qo9=L};7%^zpPxVu9+^>cjgVL{W zPfto+imF?0in5ZRhYKN~_mU2YFzlfT!sp}|^%8)9e8A7ycm!-n7>$!QuWD`>@MY8F zp(ATjC>eHQ)on|TYwaY?wse|w`8MkdHt$HNFVotB{ikuC={5&6H)Jl@!y4DZh!0A} zrDtn~2tgy#BNN8mcCA5u*v0Yu(Kk6ibu;;eNU(XUNpB&}$+l>cuf1=hAC?xC^}r}2 znyCd&g1wJ=QR-lvrSGoIm+Hg4=fo2Rxc9@e-(vK|InrFUwB zpr)iOYY-C)h^aJ@V5}rEZ*#AqmbuxoZ!N3q&l_iC>?noJ1SDgM%8-=Yeb-N}16yQYNQHxNf+{2EN_3q;-uMjw1?-3WTEGi;54$fgown{U z)ytAWl14ac_7dq+T;mk}pFA8${hFuOxFoqhthsKl7hFYgu=*i?TqXa<=}M<@IC5bs zj<4%XRAwr3u+%}}e64Y)5el=$e&p_~I2;DFNh1AO`qCkavs*2pAk9|w!!Oh8MTpZf zWSI*bc#+wR!aVA0!(o6I0i<7KDH&v%kkIH(l|bmZy8gA7x!s}BW1w8fuNyBSietK? zGGbQ$VMY_O}4@0jKH3cYl4VY$(o z+qZ?+Us!Y|Kwd<~7yJB<4;%_=sShM~Vx{_GmH~afuGp16YVB1oQ^|$ArY{Ky=0DV~ zOxHzyequs8Bh7DnnC9^sX!(D}*)L4g7vl4N9kWL(T@Qu{cK@$-KwITsmzTy+RLA`sSmTUPhmCnS{U~v$1LP z6d?OsVO#&_l~5~!}M35|gg1h}Q zun}}aBGqZ)rS@YlekZIImr~K}TycNK!2rcnE{_sZ-G<(TO5FtG1FmP9Vp3iP-#N%7 z`w~)mnFf3@U{MHP+0OHvf*vh>lqJmAz}|FR1|hDH=BmsQh~AnQc%c?}JiG4e-vwJJ$>D$m*(j0~NVzY~zm_+47G{VutN!(n20n<)bq zU>}cbob1^oU%lM%%*G8wV1|5XJl!mlc%9E}ghgzw zCV2hD+dIUvkOnP~+0!GlNGhxV;q@(vF_? zT?)(zf1kxyeiiWT;P0ZVjR0O2>a|S3&%tV+6D8b=Rgp72@2YS&kFS>kD=EOnLnP@T zbhRj?XD}bocc?3RE?__BV_nXV*mz^p0uj3nmtcdtae{`z^B%M&X z=ycR(g8Y7x@ihcJo>T&`Xao-M)qU~wvX zb`RSX5+2uJSq*v97o`9e7W)MAoS<5oVRVwdjf`*z8_ixFjIBX8xGcWxenTvt6A*59 zUynU+23#i}C^us_35Z`C*k?KZ*5LDQTw?MAl{_4Vg(V&RpXnp-nW2Eg+QKo z%1_W)q*hisZBltho%ca{Y*v(I%ubXvXqA zUy_vbm-~=DcSg|#co!Ld*i6N0S5&K>HU6ECXSH^{6u6h$Tid}Q-hLY;gyhrSJ6MTr zvp2h!w?fa_d|q7XPA<;`hma7^M$g{P|A!%6wA*b=!OfWaJOHLRj&=_A{f8(wPn7Mg zrY)upW(A(@w8oSG_JAv6E_gGm8<_{aDPE+W`+PQ_i^hGU`Xq#jEhJYoeu57AR<;BL zd*yG#;tToy)Ys9ZS^|k^%6IvqH#V!@tJCpmmW{P+wN%+kE4+K&L0UQba<|)txM_a& zV~sh9V@w~?Qrh{7VA9j&4-KIa_Wh6770x*#m<2aD^euj3Mg=Ye{H@kP+HHqUJb2o@ zR_Ag>RtP(leaLZ;MV?{Na^2)jq|7^0#f3Mp)1;e+8U4#vXbNaX{pt^8sv0L7662N4 zt+yViZ+`w<=||W(fUHuxaU>~hEBk9u)b6g)eXg)=ZzJpg4v)>wn)|p!H2UH`Q%$PO zD0V<>X==dUf-F&1HbfC&m?f)Tu}s*_?c5CtbU1Vrln5)QuK}T_3r~cD^`xV03mv3e z%~`bfKp9ktA=+*b^$}iM!4ldh$lvCi@+q12|4tlf8zX~6g;kRC&fa&#J zUI8=1Kg#$E0vh)zniYTPN#Ur@MX=O1IAt;Gc}s}W?*4T zTL(@_7sS|l2m#AyDbJ5dIZnvLQ#8QvM(X`L@CF(s%o+H@Qpgdd99BCxUqSZ09X3GD z5tQv0nI+ws(L{Q7iku351*^vg)#uMIVcBUlMBVZM)@Qx0+Wx!~aR^X0op|n{RVJlo zoST=FA(~PL9#$x{!E03xuMe>Up(U1!uEm14W*y!6QZVXF@E5m7Q>{I~A4RnhLHVan zq6E!1US+?d*zlvZX}070fVaoVvTfFBQqa_!du7TkLOtxC_sSx)9S1oQF!_1D>W4dF zYm^XaX^o%-@>N2rGX>;j;DX>xXR_K{b-kX?NKFmC6KC)xll*{dA98Q;uP|sEtCSF~ zOp;nS3HaOAF$I$bx7oq`qtFF^P!thY?utwxlma3k*zZmb3xeFcN?2;%ct@VfJ1mVz zF5`%eU{LFFqKfAzHNX8rl`l%#))#<67%SW4rh6zht$o;QkyA{E^%_!!H5@5t`v}c) zSM2S3p=(YCp?vNO3~|V*L)C_R`+8RV(gh4ql8D08S}qtWQ+mP4c|9BVWxi0s4DAL% ze(a_$5}~BKm{J&YnH%c#2NMW1eLZQy6nBK5J)q9vea^1y;7bn2(7Fe0k71F?>JA;NgqW7Ik8gcBd*`6UwN**x!nYz9)bDuv-K%sG;e0|T z7W*)vr7e<>UcID^YAnZC89Sj%!IgVs4asgPaail|$$*d3Nv0uv`85V|oh{}nxS-z|uAJXK)oDm))la|G z|5EF*4-gR@M7MVc8J{!Eg)LL&O^-1&@E5m`(aP2y!aps_oGIvfu5~=T+#%op9*NCc z7vuG%ydUwPto#Z6?bKzhG?`z{y&9T^Pm9pSL{_34MQSOjUi632F^&hl!RNiUCN0-v zS_I>*w4Ns$1g$KfA6xobou<`Xq#izlauewkcKKf@19X!h=6p&O739-2PXp=Bv7ZSq zI8dT`RZ6I^MU0H;7{_{bYR2{(HanU7#3gO+>l)l6Mj<_3wDxm5ksE|X*i0A5wHMUU zQ0(c^9|LIFv$GFuXgMxo_qRP<^8;Q`Of~SJv^36}TV=bvx8Vrs=1#;8@$t{s69;~e z)4j@bPV8eVT_8p8>qIIFB^;qrCecHTVyk^T#f0fZ)|iu~3FUP7O0#F=#xMh80?HP` zox&MuHy3JEZDa1xGtA7g8#(Obaro1S?W*aN!jX)`*0T&jRiYjzYRzfOHU^j$588~a za{eIeX@IZoowjr{(Rqe`L}pBYI2k9RcKiwcjd%rqtTqw3XJ z-pw%hCejVhd5(vwi{?0!e*cLE4H)7QNk5Rh%F6CM0pFeDt|y5FT=1Dv$jIC3LjzgiJGf?*g8pn1tV4RZ^yIPAH%BEXo)qi_@!X)W z1h4XEdloEa>!5SS|CB-I7#8!8#0}^OdRWc(mTDw+9%e1nNJ^(ox?_Bt;zUryW_62& zb#uk&fPB4N1)tx(R3Yre%JZYp^r+^VbWdEkhvg;6{6vrrL6K`d=qC&qC7qd+wF@c1SsWs5#euoVbV;V0CKE9dHvs z06?ZF0ygD9u|k}NCi#s8^Z$o7$v3*Ecnhub&BmOwv62hn48NvG>=d-h`bDnOV3ct8 zqTO7jyuIu%Y6pWg%0`}=Z08@?JhAlA>K2g!Z)0`q`))g?a=4HQHSEfSD;~c3+Ynio^?h3x&YdR>iztj;L<9inWA9 z4Ra2drcC;VG_ z4V`0R*$ukKEbZs{c0%PaIG2w?4H|Lt(U{j(MZXXT__&Q_-P*U+jP6!J9MzF)T&iWm z@hE3-SY#F0DZd}6l+|KhJ;fmSX{gFvugfPUhZDSg%2qF92O+&;dIV6F)a$`4>6=32 z>93tZXAY6n@axeS97Ru9oTdbvDQ2dS!^0~@)PdK!w1E!;`KGeW4Ezl zUq{_fixS?6kM4+LYi<%%^cddjCxY8HU(@XpxOX#)^uvqV=&vtRWG8sA-Ol$~z}_F@kD>6-&?r42^!@TE2UvE-kxRVw>d2?4mS(7Q zcr?t(&_Z%8V=4%ksf{8M($@wrh)v1+l&HTYrkV*z02KlR=aX z$ri^1p+lgqnPE}nq-fQ_L`6L&N75k((?7Ae=?P1ff!?W5VTI(_w8E%rTQ#l)qW|yH hy#Fz|W`?|>rjrp8w(Qm~{c{v6BcUi>C2Ab_zW~(r0Y3l$ literal 0 HcmV?d00001 diff --git a/examples/custom_tools/pid_template.png b/examples/custom_tools/pid_template.png new file mode 100644 index 0000000000000000000000000000000000000000..c736c6cb43dae2643c328e2ad5f691adbe7bfb8b GIT binary patch literal 4274 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 iU?qK}*4)5z^b^2(KA+xOiBOlT dict: + image_size = get_image_size(target_image) + matches = template_matching_with_rotation(target_image, template_image) + matches["bboxes"] = [ + normalize_bbox(box, image_size) for box in matches["bboxes"] + ] + return matches + + +if __name__ == "__main__": + agent = va.agent.VisionAgent(verbose=True) + resp, tools = agent.chat_with_workflow( + [ + { + "role": "user", + "content": "Can you find the locations of the pid_template.png in pid.png and tell me if any are nearby 'NOTE 5'?", + } + ], + image="pid.png", + reference_data={"image": "pid_template.png"}, + visualize_output=True, + ) diff --git a/examples/custom_tools/template_match.py b/examples/custom_tools/template_match.py new file mode 100644 index 00000000..1dd9fbe0 --- /dev/null +++ b/examples/custom_tools/template_match.py @@ -0,0 +1,96 @@ +import cv2 +import numpy as np +import torch +from torchvision.ops import nms + + +def rotate_image(mat, angle): + """ + Rotates an image (angle in degrees) and expands image to avoid cropping + """ + + height, width = mat.shape[:2] # image shape has 3 dimensions + image_center = ( + width / 2, + height / 2, + ) # getRotationMatrix2D needs coordinates in reverse order (width, height) compared to shape + + rotation_mat = cv2.getRotationMatrix2D(image_center, angle, 1.0) + + # rotation calculates the cos and sin, taking absolutes of those. + abs_cos = abs(rotation_mat[0, 0]) + abs_sin = abs(rotation_mat[0, 1]) + + # find the new width and height bounds + bound_w = int(height * abs_sin + width * abs_cos) + bound_h = int(height * abs_cos + width * abs_sin) + + # subtract old image center (bringing image back to origo) and adding the new image center coordinates + rotation_mat[0, 2] += bound_w / 2 - image_center[0] + rotation_mat[1, 2] += bound_h / 2 - image_center[1] + + # rotate image with the new bounds and translated rotation matrix + rotated_mat = cv2.warpAffine(mat, rotation_mat, (bound_w, bound_h)) + return rotated_mat + + +def template_matching_with_rotation( + main_image_path: str, + template_path: str, + max_rotation: int = 360, + step: int = 90, + threshold: float = 0.75, + visualize: bool = False, +) -> dict: + main_image = cv2.imread(main_image_path) + template = cv2.imread(template_path) + template_height, template_width = template.shape[:2] + + # Convert images to grayscale + main_image_gray = cv2.cvtColor(main_image, cv2.COLOR_BGR2GRAY) + template_gray = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY) + + boxes = [] + scores = [] + + for angle in range(0, max_rotation, step): + # Rotate the template + rotated_template = rotate_image(template_gray, angle) + + # Perform template matching + result = cv2.matchTemplate( + main_image_gray, + rotated_template, + cv2.TM_CCOEFF_NORMED, + ) + + y_coords, x_coords = np.where(result >= threshold) + for x, y in zip(x_coords, y_coords): + boxes.append( + (x, y, x + rotated_template.shape[1], y + rotated_template.shape[0]) + ) + scores.append(result[y, x]) + + indices = ( + nms( + torch.tensor(boxes).float(), + torch.tensor(scores).float(), + 0.2, + ) + .numpy() + .tolist() + ) + boxes = [boxes[i] for i in indices] + scores = [scores[i] for i in indices] + + if visualize: + # Draw a rectangle around the best match + for box in boxes: + cv2.rectangle(main_image, (box[0], box[1]), (box[2], box[3]), 255, 2) + + # Display the result + cv2.imshow("Best Match", main_image) + cv2.waitKey(0) + cv2.destroyAllWindows() + + return {"bboxes": boxes, "scores": scores} From 669a88b2b2fd8c078b834cc0d400648883e420fc Mon Sep 17 00:00:00 2001 From: Dillon Laird Date: Tue, 23 Apr 2024 16:29:03 -0700 Subject: [PATCH 14/16] formatting and typing fix --- examples/custom_tools/run_custom_tool.py | 4 ++-- vision_agent/tools/tools.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/custom_tools/run_custom_tool.py b/examples/custom_tools/run_custom_tool.py index 593b4959..beaa9eca 100644 --- a/examples/custom_tools/run_custom_tool.py +++ b/examples/custom_tools/run_custom_tool.py @@ -1,9 +1,9 @@ +from template_match import template_matching_with_rotation + import vision_agent as va from vision_agent.image_utils import get_image_size, normalize_bbox from vision_agent.tools import Tool, register_tool -from template_match import template_matching_with_rotation - @register_tool class TemplateMatch(Tool): diff --git a/vision_agent/tools/tools.py b/vision_agent/tools/tools.py index 64f97467..a3dab630 100644 --- a/vision_agent/tools/tools.py +++ b/vision_agent/tools/tools.py @@ -905,7 +905,7 @@ def __call__(self, image: str) -> dict: raise ValueError(f"Request failed: {res.text}") data = res.json() - output = {"labels": [], "bboxes": [], "scores": []} + output: Dict[str, List] = {"labels": [], "bboxes": [], "scores": []} for det in data[0]: output["labels"].append(det["text"]) box = [ From 0fc5d149000980bb2a643e3f0c78a29bad17367f Mon Sep 17 00:00:00 2001 From: Dillon Laird Date: Tue, 23 Apr 2024 17:14:48 -0700 Subject: [PATCH 15/16] round scores --- vision_agent/tools/tools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vision_agent/tools/tools.py b/vision_agent/tools/tools.py index a3dab630..a53e3c7f 100644 --- a/vision_agent/tools/tools.py +++ b/vision_agent/tools/tools.py @@ -916,7 +916,7 @@ def __call__(self, image: str) -> dict: ] box = normalize_bbox(box, image_size) output["bboxes"].append(box) - output["scores"].append(det["score"]) + output["scores"].append(round(det["score"], 2)) return output From 13482bce34d002669a1e70df9e5bca4a531bd033 Mon Sep 17 00:00:00 2001 From: Dillon Laird Date: Tue, 23 Apr 2024 17:20:58 -0700 Subject: [PATCH 16/16] fix readme typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 87db92ad..5ff3840f 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ You can also add your own custom tools for your vision agent to use: >>> } >>> ], >>> } ->>> def __call__(self, prompt: str) -> int: +>>> def __call__(self, prompt: list[str]) -> int: >>> return len(prompt) ``` This will register it with the list of tools Vision Agent has access to. It will be able