pixeltable 0.2.26__py3-none-any.whl → 0.5.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pixeltable/__init__.py +83 -19
- pixeltable/_query.py +1444 -0
- pixeltable/_version.py +1 -0
- pixeltable/catalog/__init__.py +7 -4
- pixeltable/catalog/catalog.py +2394 -119
- pixeltable/catalog/column.py +225 -104
- pixeltable/catalog/dir.py +38 -9
- pixeltable/catalog/globals.py +53 -34
- pixeltable/catalog/insertable_table.py +265 -115
- pixeltable/catalog/path.py +80 -17
- pixeltable/catalog/schema_object.py +28 -43
- pixeltable/catalog/table.py +1270 -677
- pixeltable/catalog/table_metadata.py +103 -0
- pixeltable/catalog/table_version.py +1270 -751
- pixeltable/catalog/table_version_handle.py +109 -0
- pixeltable/catalog/table_version_path.py +137 -42
- pixeltable/catalog/tbl_ops.py +53 -0
- pixeltable/catalog/update_status.py +191 -0
- pixeltable/catalog/view.py +251 -134
- pixeltable/config.py +215 -0
- pixeltable/env.py +736 -285
- pixeltable/exceptions.py +26 -2
- pixeltable/exec/__init__.py +7 -2
- pixeltable/exec/aggregation_node.py +39 -21
- pixeltable/exec/cache_prefetch_node.py +87 -109
- pixeltable/exec/cell_materialization_node.py +268 -0
- pixeltable/exec/cell_reconstruction_node.py +168 -0
- pixeltable/exec/component_iteration_node.py +25 -28
- pixeltable/exec/data_row_batch.py +11 -46
- pixeltable/exec/exec_context.py +26 -11
- pixeltable/exec/exec_node.py +35 -27
- pixeltable/exec/expr_eval/__init__.py +3 -0
- pixeltable/exec/expr_eval/evaluators.py +365 -0
- pixeltable/exec/expr_eval/expr_eval_node.py +413 -0
- pixeltable/exec/expr_eval/globals.py +200 -0
- pixeltable/exec/expr_eval/row_buffer.py +74 -0
- pixeltable/exec/expr_eval/schedulers.py +413 -0
- pixeltable/exec/globals.py +35 -0
- pixeltable/exec/in_memory_data_node.py +35 -27
- pixeltable/exec/object_store_save_node.py +293 -0
- pixeltable/exec/row_update_node.py +44 -29
- pixeltable/exec/sql_node.py +414 -115
- pixeltable/exprs/__init__.py +8 -5
- pixeltable/exprs/arithmetic_expr.py +79 -45
- pixeltable/exprs/array_slice.py +5 -5
- pixeltable/exprs/column_property_ref.py +40 -26
- pixeltable/exprs/column_ref.py +254 -61
- pixeltable/exprs/comparison.py +14 -9
- pixeltable/exprs/compound_predicate.py +9 -10
- pixeltable/exprs/data_row.py +213 -72
- pixeltable/exprs/expr.py +270 -104
- pixeltable/exprs/expr_dict.py +6 -5
- pixeltable/exprs/expr_set.py +20 -11
- pixeltable/exprs/function_call.py +383 -284
- pixeltable/exprs/globals.py +18 -5
- pixeltable/exprs/in_predicate.py +7 -7
- pixeltable/exprs/inline_expr.py +37 -37
- pixeltable/exprs/is_null.py +8 -4
- pixeltable/exprs/json_mapper.py +120 -54
- pixeltable/exprs/json_path.py +90 -60
- pixeltable/exprs/literal.py +61 -16
- pixeltable/exprs/method_ref.py +7 -6
- pixeltable/exprs/object_ref.py +19 -8
- pixeltable/exprs/row_builder.py +238 -75
- pixeltable/exprs/rowid_ref.py +53 -15
- pixeltable/exprs/similarity_expr.py +65 -50
- pixeltable/exprs/sql_element_cache.py +5 -5
- pixeltable/exprs/string_op.py +107 -0
- pixeltable/exprs/type_cast.py +25 -13
- pixeltable/exprs/variable.py +2 -2
- pixeltable/func/__init__.py +9 -5
- pixeltable/func/aggregate_function.py +197 -92
- pixeltable/func/callable_function.py +119 -35
- pixeltable/func/expr_template_function.py +101 -48
- pixeltable/func/function.py +375 -62
- pixeltable/func/function_registry.py +20 -19
- pixeltable/func/globals.py +6 -5
- pixeltable/func/mcp.py +74 -0
- pixeltable/func/query_template_function.py +151 -35
- pixeltable/func/signature.py +178 -49
- pixeltable/func/tools.py +164 -0
- pixeltable/func/udf.py +176 -53
- pixeltable/functions/__init__.py +44 -4
- pixeltable/functions/anthropic.py +226 -47
- pixeltable/functions/audio.py +148 -11
- pixeltable/functions/bedrock.py +137 -0
- pixeltable/functions/date.py +188 -0
- pixeltable/functions/deepseek.py +113 -0
- pixeltable/functions/document.py +81 -0
- pixeltable/functions/fal.py +76 -0
- pixeltable/functions/fireworks.py +72 -20
- pixeltable/functions/gemini.py +249 -0
- pixeltable/functions/globals.py +208 -53
- pixeltable/functions/groq.py +108 -0
- pixeltable/functions/huggingface.py +1088 -95
- pixeltable/functions/image.py +155 -84
- pixeltable/functions/json.py +8 -11
- pixeltable/functions/llama_cpp.py +31 -19
- pixeltable/functions/math.py +169 -0
- pixeltable/functions/mistralai.py +50 -75
- pixeltable/functions/net.py +70 -0
- pixeltable/functions/ollama.py +29 -36
- pixeltable/functions/openai.py +548 -160
- pixeltable/functions/openrouter.py +143 -0
- pixeltable/functions/replicate.py +15 -14
- pixeltable/functions/reve.py +250 -0
- pixeltable/functions/string.py +310 -85
- pixeltable/functions/timestamp.py +37 -19
- pixeltable/functions/together.py +77 -120
- pixeltable/functions/twelvelabs.py +188 -0
- pixeltable/functions/util.py +7 -2
- pixeltable/functions/uuid.py +30 -0
- pixeltable/functions/video.py +1528 -117
- pixeltable/functions/vision.py +26 -26
- pixeltable/functions/voyageai.py +289 -0
- pixeltable/functions/whisper.py +19 -10
- pixeltable/functions/whisperx.py +179 -0
- pixeltable/functions/yolox.py +112 -0
- pixeltable/globals.py +716 -236
- pixeltable/index/__init__.py +3 -1
- pixeltable/index/base.py +17 -21
- pixeltable/index/btree.py +32 -22
- pixeltable/index/embedding_index.py +155 -92
- pixeltable/io/__init__.py +12 -7
- pixeltable/io/datarows.py +140 -0
- pixeltable/io/external_store.py +83 -125
- pixeltable/io/fiftyone.py +24 -33
- pixeltable/io/globals.py +47 -182
- pixeltable/io/hf_datasets.py +96 -127
- pixeltable/io/label_studio.py +171 -156
- pixeltable/io/lancedb.py +3 -0
- pixeltable/io/pandas.py +136 -115
- pixeltable/io/parquet.py +40 -153
- pixeltable/io/table_data_conduit.py +702 -0
- pixeltable/io/utils.py +100 -0
- pixeltable/iterators/__init__.py +8 -4
- pixeltable/iterators/audio.py +207 -0
- pixeltable/iterators/base.py +9 -3
- pixeltable/iterators/document.py +144 -87
- pixeltable/iterators/image.py +17 -38
- pixeltable/iterators/string.py +15 -12
- pixeltable/iterators/video.py +523 -127
- pixeltable/metadata/__init__.py +33 -8
- pixeltable/metadata/converters/convert_10.py +2 -3
- pixeltable/metadata/converters/convert_13.py +2 -2
- pixeltable/metadata/converters/convert_15.py +15 -11
- pixeltable/metadata/converters/convert_16.py +4 -5
- pixeltable/metadata/converters/convert_17.py +4 -5
- pixeltable/metadata/converters/convert_18.py +4 -6
- pixeltable/metadata/converters/convert_19.py +6 -9
- pixeltable/metadata/converters/convert_20.py +3 -6
- pixeltable/metadata/converters/convert_21.py +6 -8
- pixeltable/metadata/converters/convert_22.py +3 -2
- pixeltable/metadata/converters/convert_23.py +33 -0
- pixeltable/metadata/converters/convert_24.py +55 -0
- pixeltable/metadata/converters/convert_25.py +19 -0
- pixeltable/metadata/converters/convert_26.py +23 -0
- pixeltable/metadata/converters/convert_27.py +29 -0
- pixeltable/metadata/converters/convert_28.py +13 -0
- pixeltable/metadata/converters/convert_29.py +110 -0
- pixeltable/metadata/converters/convert_30.py +63 -0
- pixeltable/metadata/converters/convert_31.py +11 -0
- pixeltable/metadata/converters/convert_32.py +15 -0
- pixeltable/metadata/converters/convert_33.py +17 -0
- pixeltable/metadata/converters/convert_34.py +21 -0
- pixeltable/metadata/converters/convert_35.py +9 -0
- pixeltable/metadata/converters/convert_36.py +38 -0
- pixeltable/metadata/converters/convert_37.py +15 -0
- pixeltable/metadata/converters/convert_38.py +39 -0
- pixeltable/metadata/converters/convert_39.py +124 -0
- pixeltable/metadata/converters/convert_40.py +73 -0
- pixeltable/metadata/converters/convert_41.py +12 -0
- pixeltable/metadata/converters/convert_42.py +9 -0
- pixeltable/metadata/converters/convert_43.py +44 -0
- pixeltable/metadata/converters/util.py +44 -18
- pixeltable/metadata/notes.py +21 -0
- pixeltable/metadata/schema.py +185 -42
- pixeltable/metadata/utils.py +74 -0
- pixeltable/mypy/__init__.py +3 -0
- pixeltable/mypy/mypy_plugin.py +123 -0
- pixeltable/plan.py +616 -225
- pixeltable/share/__init__.py +3 -0
- pixeltable/share/packager.py +797 -0
- pixeltable/share/protocol/__init__.py +33 -0
- pixeltable/share/protocol/common.py +165 -0
- pixeltable/share/protocol/operation_types.py +33 -0
- pixeltable/share/protocol/replica.py +119 -0
- pixeltable/share/publish.py +349 -0
- pixeltable/store.py +398 -232
- pixeltable/type_system.py +730 -267
- pixeltable/utils/__init__.py +40 -0
- pixeltable/utils/arrow.py +201 -29
- pixeltable/utils/av.py +298 -0
- pixeltable/utils/azure_store.py +346 -0
- pixeltable/utils/coco.py +26 -27
- pixeltable/utils/code.py +4 -4
- pixeltable/utils/console_output.py +46 -0
- pixeltable/utils/coroutine.py +24 -0
- pixeltable/utils/dbms.py +92 -0
- pixeltable/utils/description_helper.py +11 -12
- pixeltable/utils/documents.py +60 -61
- pixeltable/utils/exception_handler.py +36 -0
- pixeltable/utils/filecache.py +38 -22
- pixeltable/utils/formatter.py +88 -51
- pixeltable/utils/gcs_store.py +295 -0
- pixeltable/utils/http.py +133 -0
- pixeltable/utils/http_server.py +14 -13
- pixeltable/utils/iceberg.py +13 -0
- pixeltable/utils/image.py +17 -0
- pixeltable/utils/lancedb.py +90 -0
- pixeltable/utils/local_store.py +322 -0
- pixeltable/utils/misc.py +5 -0
- pixeltable/utils/object_stores.py +573 -0
- pixeltable/utils/pydantic.py +60 -0
- pixeltable/utils/pytorch.py +20 -20
- pixeltable/utils/s3_store.py +527 -0
- pixeltable/utils/sql.py +32 -5
- pixeltable/utils/system.py +30 -0
- pixeltable/utils/transactional_directory.py +4 -3
- pixeltable-0.5.7.dist-info/METADATA +579 -0
- pixeltable-0.5.7.dist-info/RECORD +227 -0
- {pixeltable-0.2.26.dist-info → pixeltable-0.5.7.dist-info}/WHEEL +1 -1
- pixeltable-0.5.7.dist-info/entry_points.txt +2 -0
- pixeltable/__version__.py +0 -3
- pixeltable/catalog/named_function.py +0 -36
- pixeltable/catalog/path_dict.py +0 -141
- pixeltable/dataframe.py +0 -894
- pixeltable/exec/expr_eval_node.py +0 -232
- pixeltable/ext/__init__.py +0 -14
- pixeltable/ext/functions/__init__.py +0 -8
- pixeltable/ext/functions/whisperx.py +0 -77
- pixeltable/ext/functions/yolox.py +0 -157
- pixeltable/tool/create_test_db_dump.py +0 -311
- pixeltable/tool/create_test_video.py +0 -81
- pixeltable/tool/doc_plugins/griffe.py +0 -50
- pixeltable/tool/doc_plugins/mkdocstrings.py +0 -6
- pixeltable/tool/doc_plugins/templates/material/udf.html.jinja +0 -135
- pixeltable/tool/embed_udf.py +0 -9
- pixeltable/tool/mypy_plugin.py +0 -55
- pixeltable/utils/media_store.py +0 -76
- pixeltable/utils/s3.py +0 -16
- pixeltable-0.2.26.dist-info/METADATA +0 -400
- pixeltable-0.2.26.dist-info/RECORD +0 -156
- pixeltable-0.2.26.dist-info/entry_points.txt +0 -3
- {pixeltable-0.2.26.dist-info → pixeltable-0.5.7.dist-info/licenses}/LICENSE +0 -0
pixeltable/functions/image.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"""
|
|
2
|
-
Pixeltable
|
|
2
|
+
Pixeltable UDFs for `ImageType`.
|
|
3
3
|
|
|
4
4
|
Example:
|
|
5
5
|
```python
|
|
@@ -10,14 +10,15 @@ t.select(t.img_col.convert('L')).collect()
|
|
|
10
10
|
```
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
|
-
import
|
|
14
|
-
from typing import Optional
|
|
13
|
+
from typing import Any, Literal
|
|
15
14
|
|
|
16
15
|
import PIL.Image
|
|
17
16
|
|
|
18
17
|
import pixeltable as pxt
|
|
18
|
+
import pixeltable.type_system as ts
|
|
19
19
|
from pixeltable.exprs import Expr
|
|
20
20
|
from pixeltable.utils.code import local_public_names
|
|
21
|
+
from pixeltable.utils.image import to_base64
|
|
21
22
|
|
|
22
23
|
|
|
23
24
|
@pxt.udf(is_method=True)
|
|
@@ -29,45 +30,42 @@ def b64_encode(img: PIL.Image.Image, image_format: str = 'png') -> str:
|
|
|
29
30
|
img: image
|
|
30
31
|
image_format: image format [supported by PIL](https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html#fully-supported-formats)
|
|
31
32
|
"""
|
|
32
|
-
|
|
33
|
+
return to_base64(img, format=image_format)
|
|
33
34
|
|
|
34
|
-
bytes_arr = io.BytesIO()
|
|
35
|
-
img.save(bytes_arr, format=image_format)
|
|
36
|
-
b64_bytes = base64.b64encode(bytes_arr.getvalue())
|
|
37
|
-
return b64_bytes.decode('utf-8')
|
|
38
35
|
|
|
39
|
-
|
|
40
|
-
@pxt.udf(substitute_fn=PIL.Image.alpha_composite, is_method=True)
|
|
36
|
+
@pxt.udf(is_method=True)
|
|
41
37
|
def alpha_composite(im1: PIL.Image.Image, im2: PIL.Image.Image) -> PIL.Image.Image:
|
|
42
38
|
"""
|
|
43
39
|
Alpha composite `im2` over `im1`.
|
|
44
40
|
|
|
45
41
|
Equivalent to [`PIL.Image.alpha_composite()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.alpha_composite)
|
|
46
42
|
"""
|
|
47
|
-
|
|
43
|
+
return PIL.Image.alpha_composite(im1, im2)
|
|
48
44
|
|
|
49
45
|
|
|
50
|
-
@pxt.udf(
|
|
46
|
+
@pxt.udf(is_method=True)
|
|
51
47
|
def blend(im1: PIL.Image.Image, im2: PIL.Image.Image, alpha: float) -> PIL.Image.Image:
|
|
52
48
|
"""
|
|
53
49
|
Return a new image by interpolating between two input images, using a constant alpha.
|
|
54
50
|
|
|
55
51
|
Equivalent to [`PIL.Image.blend()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.blend)
|
|
56
52
|
"""
|
|
57
|
-
|
|
53
|
+
return PIL.Image.blend(im1, im2, alpha)
|
|
54
|
+
|
|
58
55
|
|
|
59
|
-
@pxt.udf(
|
|
56
|
+
@pxt.udf(is_method=True)
|
|
60
57
|
def composite(image1: PIL.Image.Image, image2: PIL.Image.Image, mask: PIL.Image.Image) -> PIL.Image.Image:
|
|
61
58
|
"""
|
|
62
59
|
Return a composite image by blending two images using a mask.
|
|
63
60
|
|
|
64
61
|
Equivalent to [`PIL.Image.composite()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.composite)
|
|
65
62
|
"""
|
|
66
|
-
|
|
63
|
+
return PIL.Image.composite(image1, image2, mask)
|
|
67
64
|
|
|
68
65
|
|
|
69
66
|
# PIL.Image.Image methods
|
|
70
67
|
|
|
68
|
+
|
|
71
69
|
# Image.convert()
|
|
72
70
|
@pxt.udf(is_method=True)
|
|
73
71
|
def convert(self: PIL.Image.Image, mode: str) -> PIL.Image.Image:
|
|
@@ -78,20 +76,22 @@ def convert(self: PIL.Image.Image, mode: str) -> PIL.Image.Image:
|
|
|
78
76
|
[`PIL.Image.Image.convert()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.convert).
|
|
79
77
|
|
|
80
78
|
Args:
|
|
81
|
-
mode: The mode to convert to. See the
|
|
79
|
+
mode: The mode to convert to. See the
|
|
80
|
+
[Pillow documentation](https://pillow.readthedocs.io/en/stable/handbook/concepts.html#concept-modes)
|
|
81
|
+
for a list of supported modes.
|
|
82
82
|
"""
|
|
83
83
|
return self.convert(mode)
|
|
84
84
|
|
|
85
85
|
|
|
86
86
|
@convert.conditional_return_type
|
|
87
|
-
def _(self: Expr, mode: str) ->
|
|
87
|
+
def _(self: Expr, mode: str) -> ts.ColumnType:
|
|
88
88
|
input_type = self.col_type
|
|
89
|
-
assert isinstance(input_type,
|
|
90
|
-
return
|
|
89
|
+
assert isinstance(input_type, ts.ImageType)
|
|
90
|
+
return ts.ImageType(size=input_type.size, mode=mode, nullable=input_type.nullable)
|
|
91
91
|
|
|
92
92
|
|
|
93
93
|
# Image.crop()
|
|
94
|
-
@pxt.udf(
|
|
94
|
+
@pxt.udf(is_method=True)
|
|
95
95
|
def crop(self: PIL.Image.Image, box: tuple[int, int, int, int]) -> PIL.Image.Image:
|
|
96
96
|
"""
|
|
97
97
|
Return a rectangular region from the image. The box is a 4-tuple defining the left, upper, right, and lower pixel
|
|
@@ -100,20 +100,20 @@ def crop(self: PIL.Image.Image, box: tuple[int, int, int, int]) -> PIL.Image.Ima
|
|
|
100
100
|
Equivalent to
|
|
101
101
|
[`PIL.Image.Image.crop()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.crop)
|
|
102
102
|
"""
|
|
103
|
-
|
|
103
|
+
return self.crop(box)
|
|
104
104
|
|
|
105
105
|
|
|
106
106
|
@crop.conditional_return_type
|
|
107
|
-
def _(self: Expr, box: tuple[int, int, int, int]) ->
|
|
107
|
+
def _(self: Expr, box: tuple[int, int, int, int]) -> ts.ColumnType:
|
|
108
108
|
input_type = self.col_type
|
|
109
|
-
assert isinstance(input_type,
|
|
110
|
-
if (isinstance(box, list
|
|
111
|
-
return
|
|
112
|
-
return
|
|
109
|
+
assert isinstance(input_type, ts.ImageType)
|
|
110
|
+
if (isinstance(box, (list, tuple))) and len(box) == 4 and all(isinstance(x, int) for x in box):
|
|
111
|
+
return ts.ImageType(size=(box[2] - box[0], box[3] - box[1]), mode=input_type.mode, nullable=input_type.nullable)
|
|
112
|
+
return ts.ImageType(mode=input_type.mode, nullable=input_type.nullable) # we can't compute the size statically
|
|
113
113
|
|
|
114
114
|
|
|
115
115
|
# Image.getchannel()
|
|
116
|
-
@pxt.udf(
|
|
116
|
+
@pxt.udf(is_method=True)
|
|
117
117
|
def getchannel(self: PIL.Image.Image, channel: int) -> PIL.Image.Image:
|
|
118
118
|
"""
|
|
119
119
|
Return an L-mode image containing a single channel of the original image.
|
|
@@ -124,7 +124,14 @@ def getchannel(self: PIL.Image.Image, channel: int) -> PIL.Image.Image:
|
|
|
124
124
|
Args:
|
|
125
125
|
channel: The channel to extract. This is a 0-based index.
|
|
126
126
|
"""
|
|
127
|
-
|
|
127
|
+
return self.getchannel(channel)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
@getchannel.conditional_return_type
|
|
131
|
+
def _(self: Expr) -> ts.ColumnType:
|
|
132
|
+
input_type = self.col_type
|
|
133
|
+
assert isinstance(input_type, ts.ImageType)
|
|
134
|
+
return ts.ImageType(size=input_type.size, mode='L', nullable=input_type.nullable)
|
|
128
135
|
|
|
129
136
|
|
|
130
137
|
@pxt.udf(is_method=True)
|
|
@@ -142,16 +149,9 @@ def get_metadata(self: PIL.Image.Image) -> dict:
|
|
|
142
149
|
}
|
|
143
150
|
|
|
144
151
|
|
|
145
|
-
@getchannel.conditional_return_type
|
|
146
|
-
def _(self: Expr) -> pxt.ColumnType:
|
|
147
|
-
input_type = self.col_type
|
|
148
|
-
assert isinstance(input_type, pxt.ImageType)
|
|
149
|
-
return pxt.ImageType(size=input_type.size, mode='L', nullable=input_type.nullable)
|
|
150
|
-
|
|
151
|
-
|
|
152
152
|
# Image.point()
|
|
153
153
|
@pxt.udf(is_method=True)
|
|
154
|
-
def point(self: PIL.Image.Image, lut: list[int], mode:
|
|
154
|
+
def point(self: PIL.Image.Image, lut: list[int], mode: str | None = None) -> PIL.Image.Image:
|
|
155
155
|
"""
|
|
156
156
|
Map image pixels through a lookup table.
|
|
157
157
|
|
|
@@ -177,10 +177,10 @@ def resize(self: PIL.Image.Image, size: tuple[int, int]) -> PIL.Image.Image:
|
|
|
177
177
|
|
|
178
178
|
|
|
179
179
|
@resize.conditional_return_type
|
|
180
|
-
def _(self: Expr, size: tuple[int, int]) ->
|
|
180
|
+
def _(self: Expr, size: tuple[int, int]) -> ts.ColumnType:
|
|
181
181
|
input_type = self.col_type
|
|
182
|
-
assert isinstance(input_type,
|
|
183
|
-
return
|
|
182
|
+
assert isinstance(input_type, ts.ImageType)
|
|
183
|
+
return ts.ImageType(size=size, mode=input_type.mode, nullable=input_type.nullable)
|
|
184
184
|
|
|
185
185
|
|
|
186
186
|
# Image.rotate()
|
|
@@ -198,7 +198,7 @@ def rotate(self: PIL.Image.Image, angle: int) -> PIL.Image.Image:
|
|
|
198
198
|
return self.rotate(angle)
|
|
199
199
|
|
|
200
200
|
|
|
201
|
-
@pxt.udf(
|
|
201
|
+
@pxt.udf(is_method=True)
|
|
202
202
|
def effect_spread(self: PIL.Image.Image, distance: int) -> PIL.Image.Image:
|
|
203
203
|
"""
|
|
204
204
|
Randomly spread pixels in an image.
|
|
@@ -209,11 +209,11 @@ def effect_spread(self: PIL.Image.Image, distance: int) -> PIL.Image.Image:
|
|
|
209
209
|
Args:
|
|
210
210
|
distance: The distance to spread pixels.
|
|
211
211
|
"""
|
|
212
|
-
|
|
212
|
+
return self.effect_spread(distance)
|
|
213
213
|
|
|
214
214
|
|
|
215
|
-
@pxt.udf(
|
|
216
|
-
def transpose(self: PIL.Image.Image, method:
|
|
215
|
+
@pxt.udf(is_method=True)
|
|
216
|
+
def transpose(self: PIL.Image.Image, method: Literal[0, 1, 2, 3, 4, 5, 6]) -> PIL.Image.Image:
|
|
217
217
|
"""
|
|
218
218
|
Transpose the image.
|
|
219
219
|
|
|
@@ -221,20 +221,22 @@ def transpose(self: PIL.Image.Image, method: int) -> PIL.Image.Image:
|
|
|
221
221
|
[`PIL.Image.Image.transpose()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.transpose)
|
|
222
222
|
|
|
223
223
|
Args:
|
|
224
|
-
method: The transpose method. See the
|
|
224
|
+
method: The transpose method. See the
|
|
225
|
+
[Pillow documentation](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.transpose)
|
|
226
|
+
for a list of supported methods.
|
|
225
227
|
"""
|
|
226
|
-
|
|
228
|
+
return self.transpose(method)
|
|
227
229
|
|
|
228
230
|
|
|
229
231
|
@rotate.conditional_return_type
|
|
230
232
|
@effect_spread.conditional_return_type
|
|
231
233
|
@transpose.conditional_return_type
|
|
232
|
-
def _(self: Expr) ->
|
|
234
|
+
def _(self: Expr) -> ts.ColumnType:
|
|
233
235
|
return self.col_type
|
|
234
236
|
|
|
235
237
|
|
|
236
|
-
@pxt.udf(
|
|
237
|
-
def entropy(self: PIL.Image.Image, mask:
|
|
238
|
+
@pxt.udf(is_method=True)
|
|
239
|
+
def entropy(self: PIL.Image.Image, mask: PIL.Image.Image | None = None, extrema: list | None = None) -> float:
|
|
238
240
|
"""
|
|
239
241
|
Returns the entropy of the image, optionally using a mask and extrema.
|
|
240
242
|
|
|
@@ -245,35 +247,36 @@ def entropy(self: PIL.Image.Image, mask: Optional[PIL.Image.Image] = None, extre
|
|
|
245
247
|
mask: An optional mask image.
|
|
246
248
|
extrema: An optional list of extrema.
|
|
247
249
|
"""
|
|
248
|
-
|
|
250
|
+
return self.entropy(mask, extrema) # type: ignore[arg-type]
|
|
249
251
|
|
|
250
252
|
|
|
251
|
-
@pxt.udf(
|
|
252
|
-
def getbands(self: PIL.Image.Image) -> tuple[str]:
|
|
253
|
+
@pxt.udf(is_method=True)
|
|
254
|
+
def getbands(self: PIL.Image.Image) -> tuple[str, ...]:
|
|
253
255
|
"""
|
|
254
256
|
Return a tuple containing the names of the image bands.
|
|
255
257
|
|
|
256
258
|
Equivalent to
|
|
257
259
|
[`PIL.Image.Image.getbands()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.getbands)
|
|
258
260
|
"""
|
|
259
|
-
|
|
261
|
+
return self.getbands()
|
|
260
262
|
|
|
261
263
|
|
|
262
|
-
@pxt.udf(
|
|
263
|
-
def getbbox(self: PIL.Image.Image, *, alpha_only: bool = True) -> tuple[int, int, int, int]:
|
|
264
|
+
@pxt.udf(is_method=True)
|
|
265
|
+
def getbbox(self: PIL.Image.Image, *, alpha_only: bool = True) -> tuple[int, int, int, int] | None:
|
|
264
266
|
"""
|
|
265
267
|
Return a bounding box for the non-zero regions of the image.
|
|
266
268
|
|
|
267
269
|
Equivalent to [`PIL.Image.Image.getbbox()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.getbbox)
|
|
268
270
|
|
|
269
271
|
Args:
|
|
270
|
-
alpha_only: If `True`, and the image has an alpha channel, trim transparent pixels. Otherwise,
|
|
272
|
+
alpha_only: If `True`, and the image has an alpha channel, trim transparent pixels. Otherwise,
|
|
273
|
+
trim pixels when all channels are zero.
|
|
271
274
|
"""
|
|
272
|
-
|
|
275
|
+
return self.getbbox(alpha_only=alpha_only)
|
|
273
276
|
|
|
274
277
|
|
|
275
|
-
@pxt.udf(
|
|
276
|
-
def getcolors(self: PIL.Image.Image, maxcolors: int = 256) ->
|
|
278
|
+
@pxt.udf(is_method=True)
|
|
279
|
+
def getcolors(self: PIL.Image.Image, maxcolors: int = 256) -> list[tuple[int, int]]:
|
|
277
280
|
"""
|
|
278
281
|
Return a list of colors used in the image, up to a maximum of `maxcolors`.
|
|
279
282
|
|
|
@@ -283,10 +286,10 @@ def getcolors(self: PIL.Image.Image, maxcolors: int = 256) -> tuple[tuple[int, i
|
|
|
283
286
|
Args:
|
|
284
287
|
maxcolors: The maximum number of colors to return.
|
|
285
288
|
"""
|
|
286
|
-
|
|
289
|
+
return self.getcolors(maxcolors)
|
|
287
290
|
|
|
288
291
|
|
|
289
|
-
@pxt.udf(
|
|
292
|
+
@pxt.udf(is_method=True)
|
|
290
293
|
def getextrema(self: PIL.Image.Image) -> tuple[int, int]:
|
|
291
294
|
"""
|
|
292
295
|
Return a 2-tuple containing the minimum and maximum pixel values of the image.
|
|
@@ -294,11 +297,11 @@ def getextrema(self: PIL.Image.Image) -> tuple[int, int]:
|
|
|
294
297
|
Equivalent to
|
|
295
298
|
[`PIL.Image.Image.getextrema()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.getextrema)
|
|
296
299
|
"""
|
|
297
|
-
|
|
300
|
+
return self.getextrema()
|
|
298
301
|
|
|
299
302
|
|
|
300
|
-
@pxt.udf(
|
|
301
|
-
def getpalette(self: PIL.Image.Image, mode:
|
|
303
|
+
@pxt.udf(is_method=True)
|
|
304
|
+
def getpalette(self: PIL.Image.Image, mode: str | None = None) -> list[int] | None:
|
|
302
305
|
"""
|
|
303
306
|
Return the palette of the image, optionally converting it to a different mode.
|
|
304
307
|
|
|
@@ -308,7 +311,7 @@ def getpalette(self: PIL.Image.Image, mode: Optional[str] = None) -> tuple[int]:
|
|
|
308
311
|
Args:
|
|
309
312
|
mode: The mode to convert the palette to.
|
|
310
313
|
"""
|
|
311
|
-
|
|
314
|
+
return self.getpalette(mode)
|
|
312
315
|
|
|
313
316
|
|
|
314
317
|
@pxt.udf(is_method=True)
|
|
@@ -326,21 +329,19 @@ def getpixel(self: PIL.Image.Image, xy: list) -> tuple[int]:
|
|
|
326
329
|
return self.getpixel(tuple(xy))
|
|
327
330
|
|
|
328
331
|
|
|
329
|
-
@pxt.udf(
|
|
330
|
-
def getprojection(self: PIL.Image.Image) -> tuple[int]:
|
|
332
|
+
@pxt.udf(is_method=True)
|
|
333
|
+
def getprojection(self: PIL.Image.Image) -> tuple[list[int], list[int]]:
|
|
331
334
|
"""
|
|
332
335
|
Return two sequences representing the horizontal and vertical projection of the image.
|
|
333
336
|
|
|
334
337
|
Equivalent to
|
|
335
338
|
[`PIL.Image.Image.getprojection()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.getprojection)
|
|
336
339
|
"""
|
|
337
|
-
|
|
340
|
+
return self.getprojection()
|
|
338
341
|
|
|
339
342
|
|
|
340
|
-
@pxt.udf(
|
|
341
|
-
def histogram(
|
|
342
|
-
self: PIL.Image.Image, mask: Optional[PIL.Image.Image] = None, extrema: Optional[list] = None
|
|
343
|
-
) -> list[int]:
|
|
343
|
+
@pxt.udf(is_method=True)
|
|
344
|
+
def histogram(self: PIL.Image.Image, mask: PIL.Image.Image | None = None, extrema: list | None = None) -> list[int]:
|
|
344
345
|
"""
|
|
345
346
|
Return a histogram for the image.
|
|
346
347
|
|
|
@@ -351,16 +352,16 @@ def histogram(
|
|
|
351
352
|
mask: An optional mask image.
|
|
352
353
|
extrema: An optional list of extrema.
|
|
353
354
|
"""
|
|
354
|
-
|
|
355
|
+
return self.histogram(mask, extrema) # type: ignore[arg-type]
|
|
355
356
|
|
|
356
357
|
|
|
357
|
-
@pxt.udf(
|
|
358
|
+
@pxt.udf(is_method=True)
|
|
358
359
|
def quantize(
|
|
359
360
|
self: PIL.Image.Image,
|
|
360
361
|
colors: int = 256,
|
|
361
|
-
method:
|
|
362
|
+
method: Literal[0, 1, 2, 3] | None = None,
|
|
362
363
|
kmeans: int = 0,
|
|
363
|
-
palette:
|
|
364
|
+
palette: PIL.Image.Image | None = None,
|
|
364
365
|
dither: int = PIL.Image.Dither.FLOYDSTEINBERG,
|
|
365
366
|
) -> PIL.Image.Image:
|
|
366
367
|
"""
|
|
@@ -371,16 +372,20 @@ def quantize(
|
|
|
371
372
|
|
|
372
373
|
Args:
|
|
373
374
|
colors: The number of colors to quantize to.
|
|
374
|
-
method: The quantization method. See the
|
|
375
|
+
method: The quantization method. See the
|
|
376
|
+
[Pillow documentation](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.quantize)
|
|
377
|
+
for a list of supported methods.
|
|
375
378
|
kmeans: The number of k-means clusters to use.
|
|
376
379
|
palette: The palette to use.
|
|
377
|
-
dither: The dithering method. See the
|
|
378
|
-
|
|
379
|
-
|
|
380
|
+
dither: The dithering method. See the
|
|
381
|
+
[Pillow documentation](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.quantize)
|
|
382
|
+
for a list of supported methods.
|
|
383
|
+
"""
|
|
384
|
+
return self.quantize(colors, method, kmeans, palette, dither)
|
|
380
385
|
|
|
381
386
|
|
|
382
|
-
@pxt.udf(
|
|
383
|
-
def reduce(self: PIL.Image.Image, factor: int, box:
|
|
387
|
+
@pxt.udf(is_method=True)
|
|
388
|
+
def reduce(self: PIL.Image.Image, factor: int, box: tuple[int, int, int, int] | None = None) -> PIL.Image.Image:
|
|
384
389
|
"""
|
|
385
390
|
Reduce the image by the given factor.
|
|
386
391
|
|
|
@@ -389,28 +394,94 @@ def reduce(self: PIL.Image.Image, factor: int, box: Optional[tuple[int, int, int
|
|
|
389
394
|
|
|
390
395
|
Args:
|
|
391
396
|
factor: The reduction factor.
|
|
392
|
-
box: An optional 4-tuple of ints providing the source image region to be reduced. The values must be within
|
|
397
|
+
box: An optional 4-tuple of ints providing the source image region to be reduced. The values must be within
|
|
398
|
+
(0, 0, width, height) rectangle. If omitted or None, the entire source is used.
|
|
399
|
+
"""
|
|
400
|
+
return self.reduce(factor, box)
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
@pxt.udf(is_method=True)
|
|
404
|
+
def thumbnail(
|
|
405
|
+
self: PIL.Image.Image,
|
|
406
|
+
size: tuple[int, int],
|
|
407
|
+
resample: int = PIL.Image.Resampling.LANCZOS,
|
|
408
|
+
reducing_gap: float | None = 2.0,
|
|
409
|
+
) -> PIL.Image.Image:
|
|
393
410
|
"""
|
|
394
|
-
|
|
411
|
+
Create a thumbnail of the image.
|
|
412
|
+
|
|
413
|
+
Equivalent to
|
|
414
|
+
[`PIL.Image.Image.thumbnail()`](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.thumbnail)
|
|
415
|
+
|
|
416
|
+
Args:
|
|
417
|
+
size: The size of the thumbnail, as a tuple of (width, height).
|
|
418
|
+
resample: The resampling filter to use. See the
|
|
419
|
+
[Pillow documentation](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.thumbnail)
|
|
420
|
+
for a list of supported filters.
|
|
421
|
+
reducing_gap: The reducing gap to use.
|
|
422
|
+
"""
|
|
423
|
+
result = self.copy()
|
|
424
|
+
result.thumbnail(size, PIL.Image.Resampling(resample), reducing_gap)
|
|
425
|
+
return result
|
|
395
426
|
|
|
396
427
|
|
|
397
428
|
@pxt.udf(is_property=True)
|
|
398
429
|
def width(self: PIL.Image.Image) -> int:
|
|
430
|
+
"""
|
|
431
|
+
Return the width of the image.
|
|
432
|
+
"""
|
|
399
433
|
return self.width
|
|
400
434
|
|
|
401
435
|
|
|
402
436
|
@pxt.udf(is_property=True)
|
|
403
437
|
def height(self: PIL.Image.Image) -> int:
|
|
438
|
+
"""
|
|
439
|
+
Return the height of the image.
|
|
440
|
+
"""
|
|
404
441
|
return self.height
|
|
405
442
|
|
|
406
443
|
|
|
407
444
|
@pxt.udf(is_property=True)
|
|
408
445
|
def mode(self: PIL.Image.Image) -> str:
|
|
446
|
+
"""
|
|
447
|
+
Return the image mode.
|
|
448
|
+
"""
|
|
409
449
|
return self.mode
|
|
410
450
|
|
|
411
451
|
|
|
452
|
+
def tile_iterator(
|
|
453
|
+
image: Any, tile_size: tuple[int, int], *, overlap: tuple[int, int] = (0, 0)
|
|
454
|
+
) -> tuple[type[pxt.iterators.ComponentIterator], dict[str, Any]]:
|
|
455
|
+
"""
|
|
456
|
+
Iterator over tiles of an image. Each image will be divided into tiles of size `tile_size`, and the tiles will be
|
|
457
|
+
iterated over in row-major order (left-to-right, then top-to-bottom). An optional `overlap` parameter may be
|
|
458
|
+
specified. If the tiles do not exactly cover the image, then the rightmost and bottommost tiles will be padded with
|
|
459
|
+
blackspace, so that the output images all have the exact size `tile_size`.
|
|
460
|
+
|
|
461
|
+
Args:
|
|
462
|
+
image: Image to split into tiles.
|
|
463
|
+
tile_size: Size of each tile, as a pair of integers `[width, height]`.
|
|
464
|
+
overlap: Amount of overlap between adjacent tiles, as a pair of integers `[width, height]`.
|
|
465
|
+
|
|
466
|
+
Examples:
|
|
467
|
+
This example assumes an existing table `tbl` with a column `img` of type `pxt.Image`.
|
|
468
|
+
|
|
469
|
+
Create a view that splits all images into 256x256 tiles with 32 pixels of overlap:
|
|
470
|
+
|
|
471
|
+
>>> pxt.create_view(
|
|
472
|
+
... 'image_tiles',
|
|
473
|
+
... tbl,
|
|
474
|
+
... iterator=image_tile_iterator(tbl.img, tile_size=(256, 256), overlap=(32, 32))
|
|
475
|
+
... )
|
|
476
|
+
"""
|
|
477
|
+
kwargs: dict[str, Any] = {}
|
|
478
|
+
if overlap != (0, 0):
|
|
479
|
+
kwargs['overlap'] = overlap
|
|
480
|
+
return pxt.iterators.image.TileIterator._create(image=image, tile_size=tile_size, **kwargs)
|
|
481
|
+
|
|
482
|
+
|
|
412
483
|
__all__ = local_public_names(__name__)
|
|
413
484
|
|
|
414
485
|
|
|
415
|
-
def __dir__():
|
|
486
|
+
def __dir__() -> list[str]:
|
|
416
487
|
return __all__
|
pixeltable/functions/json.py
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
"""
|
|
2
|
-
Pixeltable
|
|
2
|
+
Pixeltable UDFs for `JsonType`.
|
|
3
3
|
|
|
4
4
|
Example:
|
|
5
5
|
```python
|
|
6
6
|
import pixeltable as pxt
|
|
7
|
+
import pixeltable.functions as pxtf
|
|
7
8
|
|
|
8
9
|
t = pxt.get_table(...)
|
|
9
|
-
t.select(
|
|
10
|
+
t.select(pxtf.json.make_list(t.json_col)).collect()
|
|
10
11
|
```
|
|
11
12
|
"""
|
|
12
13
|
|
|
@@ -16,20 +17,16 @@ import pixeltable as pxt
|
|
|
16
17
|
from pixeltable.utils.code import local_public_names
|
|
17
18
|
|
|
18
19
|
|
|
19
|
-
@pxt.uda
|
|
20
|
-
update_types=[pxt.JsonType(nullable=True)],
|
|
21
|
-
value_type=pxt.JsonType(),
|
|
22
|
-
requires_order_by=False,
|
|
23
|
-
allows_window=False,
|
|
24
|
-
)
|
|
20
|
+
@pxt.uda
|
|
25
21
|
class make_list(pxt.Aggregator):
|
|
26
22
|
"""
|
|
27
23
|
Collects arguments into a list.
|
|
28
24
|
"""
|
|
29
|
-
|
|
25
|
+
|
|
26
|
+
def __init__(self) -> None:
|
|
30
27
|
self.output: list[Any] = []
|
|
31
28
|
|
|
32
|
-
def update(self, obj:
|
|
29
|
+
def update(self, obj: pxt.Json) -> None:
|
|
33
30
|
if obj is None:
|
|
34
31
|
return
|
|
35
32
|
self.output.append(obj)
|
|
@@ -41,5 +38,5 @@ class make_list(pxt.Aggregator):
|
|
|
41
38
|
__all__ = local_public_names(__name__)
|
|
42
39
|
|
|
43
40
|
|
|
44
|
-
def __dir__():
|
|
41
|
+
def __dir__() -> list[str]:
|
|
45
42
|
return __all__
|
|
@@ -1,5 +1,12 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Pixeltable UDFs for llama.cpp models.
|
|
3
|
+
|
|
4
|
+
Provides integration with llama.cpp for running quantized language models locally,
|
|
5
|
+
supporting chat completions and embeddings with GGUF format models.
|
|
6
|
+
"""
|
|
7
|
+
|
|
1
8
|
from pathlib import Path
|
|
2
|
-
from typing import TYPE_CHECKING, Any
|
|
9
|
+
from typing import TYPE_CHECKING, Any
|
|
3
10
|
|
|
4
11
|
import pixeltable as pxt
|
|
5
12
|
import pixeltable.exceptions as excs
|
|
@@ -14,10 +21,10 @@ if TYPE_CHECKING:
|
|
|
14
21
|
def create_chat_completion(
|
|
15
22
|
messages: list[dict],
|
|
16
23
|
*,
|
|
17
|
-
model_path:
|
|
18
|
-
repo_id:
|
|
19
|
-
repo_filename:
|
|
20
|
-
|
|
24
|
+
model_path: str | None = None,
|
|
25
|
+
repo_id: str | None = None,
|
|
26
|
+
repo_filename: str | None = None,
|
|
27
|
+
model_kwargs: dict[str, Any] | None = None,
|
|
21
28
|
) -> dict:
|
|
22
29
|
"""
|
|
23
30
|
Generate a chat completion from a list of messages.
|
|
@@ -35,14 +42,14 @@ def create_chat_completion(
|
|
|
35
42
|
repo_id: The Hugging Face model repo id (if using a pretrained model).
|
|
36
43
|
repo_filename: A filename or glob pattern to match the model file in the repo (optional, if using a
|
|
37
44
|
pretrained model).
|
|
38
|
-
|
|
39
|
-
`top_p`, and `top_k`. For details, see the
|
|
45
|
+
model_kwargs: Additional keyword args for the llama_cpp `create_chat_completions` API, such as `max_tokens`,
|
|
46
|
+
`temperature`, `top_p`, and `top_k`. For details, see the
|
|
40
47
|
[llama_cpp create_chat_completions documentation](https://llama-cpp-python.readthedocs.io/en/latest/api-reference/#llama_cpp.Llama.create_chat_completion).
|
|
41
48
|
"""
|
|
42
49
|
Env.get().require_package('llama_cpp', min_version=[0, 3, 1])
|
|
43
50
|
|
|
44
|
-
if
|
|
45
|
-
|
|
51
|
+
if model_kwargs is None:
|
|
52
|
+
model_kwargs = {}
|
|
46
53
|
|
|
47
54
|
if (model_path is None) == (repo_id is None):
|
|
48
55
|
raise excs.Error('Exactly one of `model_path` or `repo_id` must be provided.')
|
|
@@ -56,13 +63,13 @@ def create_chat_completion(
|
|
|
56
63
|
else:
|
|
57
64
|
Env.get().require_package('huggingface_hub')
|
|
58
65
|
llm = _lookup_pretrained_model(repo_id, repo_filename, n_gpu_layers)
|
|
59
|
-
return llm.create_chat_completion(messages, **
|
|
66
|
+
return llm.create_chat_completion(messages, **model_kwargs) # type: ignore
|
|
60
67
|
|
|
61
68
|
|
|
62
69
|
def _is_gpu_available() -> bool:
|
|
63
70
|
import llama_cpp
|
|
64
71
|
|
|
65
|
-
global _IS_GPU_AVAILABLE
|
|
72
|
+
global _IS_GPU_AVAILABLE # noqa: PLW0603
|
|
66
73
|
if _IS_GPU_AVAILABLE is None:
|
|
67
74
|
llama_cpp_path = Path(llama_cpp.__file__).parent
|
|
68
75
|
lib = llama_cpp.llama_cpp.load_shared_library('llama', llama_cpp_path / 'lib')
|
|
@@ -81,27 +88,32 @@ def _lookup_local_model(model_path: str, n_gpu_layers: int) -> 'llama_cpp.Llama'
|
|
|
81
88
|
return _model_cache[key]
|
|
82
89
|
|
|
83
90
|
|
|
84
|
-
def _lookup_pretrained_model(repo_id: str, filename:
|
|
91
|
+
def _lookup_pretrained_model(repo_id: str, filename: str | None, n_gpu_layers: int) -> 'llama_cpp.Llama':
|
|
85
92
|
import llama_cpp
|
|
86
93
|
|
|
87
94
|
key = (repo_id, filename, n_gpu_layers)
|
|
88
95
|
if key not in _model_cache:
|
|
89
96
|
llm = llama_cpp.Llama.from_pretrained(
|
|
90
|
-
repo_id=repo_id,
|
|
91
|
-
filename=filename,
|
|
92
|
-
n_gpu_layers=n_gpu_layers,
|
|
93
|
-
verbose=False,
|
|
97
|
+
repo_id=repo_id, filename=filename, n_gpu_layers=n_gpu_layers, verbose=False
|
|
94
98
|
)
|
|
95
99
|
_model_cache[key] = llm
|
|
96
100
|
return _model_cache[key]
|
|
97
101
|
|
|
98
102
|
|
|
99
|
-
_model_cache: dict[tuple[str, str, int],
|
|
100
|
-
_IS_GPU_AVAILABLE:
|
|
103
|
+
_model_cache: dict[tuple[str, str, int], 'llama_cpp.Llama'] = {}
|
|
104
|
+
_IS_GPU_AVAILABLE: bool | None = None
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def cleanup() -> None:
|
|
108
|
+
for model in _model_cache.values():
|
|
109
|
+
if model._sampler is not None:
|
|
110
|
+
model._sampler.close()
|
|
111
|
+
model.close()
|
|
112
|
+
_model_cache.clear()
|
|
101
113
|
|
|
102
114
|
|
|
103
115
|
__all__ = local_public_names(__name__)
|
|
104
116
|
|
|
105
117
|
|
|
106
|
-
def __dir__():
|
|
118
|
+
def __dir__() -> list[str]:
|
|
107
119
|
return __all__
|