pynight 0.2.2__tar.gz → 0.2.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pynight-0.2.2 → pynight-0.2.3}/PKG-INFO +3 -3
- pynight-0.2.3/pynight/batched_iterable.py +101 -0
- pynight-0.2.3/pynight/common_anthropic.py +33 -0
- pynight-0.2.3/pynight/common_arxiv.py +21 -0
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_async.py +1 -0
- pynight-0.2.3/pynight/common_attr.py +225 -0
- pynight-0.2.3/pynight/common_base64.py +44 -0
- pynight-0.2.3/pynight/common_bells.py +21 -0
- pynight-0.2.3/pynight/common_clip.py +4 -0
- pynight-0.2.3/pynight/common_clipboard.py +34 -0
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_combinatorics.py +1 -0
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_condition.py +14 -6
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_csv.py +1 -0
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_datasets.py +47 -20
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_datetime.py +1 -1
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_debugging.py +2 -19
- pynight-0.2.3/pynight/common_debugging2.py +157 -0
- pynight-0.2.3/pynight/common_deepseek.py +35 -0
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_dict.py +35 -0
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_dynamic.py +40 -7
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_executing.py +4 -2
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_external.py +1 -0
- pynight-0.2.3/pynight/common_faith.py +154 -0
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_fastapi.py +2 -3
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_files.py +84 -7
- pynight-0.2.3/pynight/common_fzf.py +84 -0
- pynight-0.2.3/pynight/common_groq.py +34 -0
- pynight-0.2.3/pynight/common_health.py +19 -0
- pynight-0.2.3/pynight/common_hosts.py +23 -0
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_ipython.py +2 -5
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_iterable.py +23 -28
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_jax.py +1 -0
- pynight-0.2.3/pynight/common_json.py +196 -0
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_jupyter.py +14 -6
- pynight-0.2.3/pynight/common_latex.py +23 -0
- pynight-0.2.3/pynight/common_llm.py +76 -0
- pynight-0.2.3/pynight/common_model_name.py +27 -0
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_networking.py +1 -3
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_numpy.py +35 -4
- pynight-0.2.3/pynight/common_openai.py +702 -0
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_package.py +7 -1
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_plt.py +2 -1
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_proxy.py +15 -13
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_random.py +3 -3
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_redirections.py +3 -3
- pynight-0.2.3/pynight/common_regex.py +43 -0
- pynight-0.2.3/pynight/common_rtl.py +24 -0
- pynight-0.2.3/pynight/common_seg.py +121 -0
- pynight-0.2.3/pynight/common_shell.py +24 -0
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_sort.py +17 -4
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_ss.py +14 -10
- pynight-0.2.3/pynight/common_str.py +89 -0
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_telegram.py +29 -6
- pynight-0.2.3/pynight/common_threading.py +19 -0
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_timm.py +163 -19
- pynight-0.2.3/pynight/common_together.py +46 -0
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_torch.py +666 -30
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_tqdm.py +43 -14
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_tui.py +17 -13
- {pynight-0.2.2 → pynight-0.2.3}/pyproject.toml +3 -3
- {pynight-0.2.2 → pynight-0.2.3}/setup.py +3 -3
- pynight-0.2.2/pynight/common_bells.py +0 -8
- pynight-0.2.2/pynight/common_clipboard.py +0 -5
- pynight-0.2.2/pynight/common_json.py +0 -71
- pynight-0.2.2/pynight/common_openai.py +0 -162
- pynight-0.2.2/pynight/common_regex.py +0 -20
- pynight-0.2.2/pynight/common_str.py +0 -24
- {pynight-0.2.2 → pynight-0.2.3}/pynight/__init__.py +0 -0
- {pynight-0.2.2 → pynight-0.2.3}/pynight/async_url.py +0 -0
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_benchmark.py +0 -0
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_evaluate.py +0 -0
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_feed.py +1 -1
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_functional.py +0 -0
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_hash.py +0 -0
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_hf.py +0 -0
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_icecream.py +0 -0
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_lock_async.py +0 -0
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_obj.py +0 -0
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_print.py +0 -0
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_spacy.py +0 -0
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_torch.org +0 -0
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_tqdm2.py +0 -0
- {pynight-0.2.2 → pynight-0.2.3}/pynight/common_uvicorn.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pynight
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: My Python utility library.
|
|
5
5
|
License: MIT
|
|
6
6
|
Author: NightMachinary
|
|
@@ -17,7 +17,7 @@ Requires-Dist: brish (>=0.3.3,<0.4.0)
|
|
|
17
17
|
Requires-Dist: dnspython (>=2.1.0,<3.0.0)
|
|
18
18
|
Requires-Dist: executing (>=1.2.0,<2.0.0)
|
|
19
19
|
Requires-Dist: matplotlib (>=3.7.1,<4.0.0)
|
|
20
|
-
Requires-Dist: openai (>=
|
|
20
|
+
Requires-Dist: openai (>=1.14.2,<2.0.0)
|
|
21
21
|
Requires-Dist: pyperclip (>=1.8.2,<2.0.0)
|
|
22
22
|
Requires-Dist: spacy (>=3.5.1,<4.0.0)
|
|
23
|
-
Requires-Dist: tiktoken (>=0.
|
|
23
|
+
Requires-Dist: tiktoken (>=0.6,<0.7)
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
from collections.abc import Mapping
|
|
2
|
+
from pynight.common_icecream import ic
|
|
3
|
+
from pynight.common_dict import (
|
|
4
|
+
SimpleObject,
|
|
5
|
+
simple_obj,
|
|
6
|
+
BatchedDict,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class BatchedIterable:
|
|
11
|
+
def __init__(
|
|
12
|
+
self,
|
|
13
|
+
data,
|
|
14
|
+
batch_size,
|
|
15
|
+
drop_last_batch=False,
|
|
16
|
+
skip_none_p=True,
|
|
17
|
+
autoadjust_batch_size_mode=False,
|
|
18
|
+
# autoadjust_batch_size_mode=True,
|
|
19
|
+
):
|
|
20
|
+
self.data = data
|
|
21
|
+
self.batch_size = batch_size
|
|
22
|
+
self.drop_last_batch = drop_last_batch
|
|
23
|
+
self.skip_none_p = skip_none_p
|
|
24
|
+
self.autoadjust_batch_size_mode = autoadjust_batch_size_mode
|
|
25
|
+
self.extras = []
|
|
26
|
+
#: We will drop the default empty `extras`, which might not be summable with `res`. Its only purpose is to make using `len(self.extras)` easy without having to check for None.
|
|
27
|
+
|
|
28
|
+
def __iter__(self):
|
|
29
|
+
length = len(self.data)
|
|
30
|
+
i = 0
|
|
31
|
+
|
|
32
|
+
while i < length or len(self.extras) >= self.batch_size:
|
|
33
|
+
# ic(type(self.extras))
|
|
34
|
+
|
|
35
|
+
if len(self.extras) >= self.batch_size:
|
|
36
|
+
#: Yield a batch from extras
|
|
37
|
+
res = self.extras[: self.batch_size]
|
|
38
|
+
self.extras = self.extras[self.batch_size :]
|
|
39
|
+
yield res
|
|
40
|
+
continue
|
|
41
|
+
|
|
42
|
+
advance_by = self.batch_size - len(self.extras)
|
|
43
|
+
res = self.data[i : i + advance_by]
|
|
44
|
+
# ic(type(res))
|
|
45
|
+
# ic(len(res), advance_by, len(self.extras))
|
|
46
|
+
|
|
47
|
+
i += advance_by
|
|
48
|
+
|
|
49
|
+
if self.skip_none_p and res is None:
|
|
50
|
+
continue
|
|
51
|
+
|
|
52
|
+
if self.autoadjust_batch_size_mode:
|
|
53
|
+
res_size = len(res)
|
|
54
|
+
if res_size < self.batch_size and self.autoadjust_batch_size_mode in [
|
|
55
|
+
True,
|
|
56
|
+
"grow",
|
|
57
|
+
]:
|
|
58
|
+
#: Merge with extras
|
|
59
|
+
if len(self.extras) >= 1:
|
|
60
|
+
res = self.extras + res
|
|
61
|
+
|
|
62
|
+
if len(res) >= self.batch_size:
|
|
63
|
+
self.extras = res[self.batch_size :]
|
|
64
|
+
res = res[: self.batch_size]
|
|
65
|
+
else:
|
|
66
|
+
self.extras = res
|
|
67
|
+
continue
|
|
68
|
+
elif res_size > self.batch_size and self.autoadjust_batch_size_mode in [
|
|
69
|
+
True,
|
|
70
|
+
"shrink",
|
|
71
|
+
]:
|
|
72
|
+
#: Keep extras for the next batch
|
|
73
|
+
if len(self.extras) >= 1:
|
|
74
|
+
self.extras += res[self.batch_size :]
|
|
75
|
+
else:
|
|
76
|
+
self.extras = res[self.batch_size :]
|
|
77
|
+
|
|
78
|
+
res = res[: self.batch_size]
|
|
79
|
+
|
|
80
|
+
#: This assertion should be true, you can enable it for debugging:
|
|
81
|
+
# if self.autoadjust_batch_size_mode is True:
|
|
82
|
+
# assert (
|
|
83
|
+
# len(res) == self.batch_size
|
|
84
|
+
# ), f"autoadjust_batch_size_mode has not adjusted the size: len={len(res)}, should_be={self.batch_size}"
|
|
85
|
+
|
|
86
|
+
# ic(len(res), self.batch_size, self.autoadjust_batch_size_mode)
|
|
87
|
+
yield res
|
|
88
|
+
|
|
89
|
+
if not self.drop_last_batch and len(self.extras) > 0:
|
|
90
|
+
#: Yield the remaining extras as the last batch
|
|
91
|
+
yield self.extras
|
|
92
|
+
|
|
93
|
+
def __len__(self):
|
|
94
|
+
length = len(self.data)
|
|
95
|
+
num_batches = length // self.batch_size
|
|
96
|
+
if not self.drop_last_batch:
|
|
97
|
+
num_batches += length % self.batch_size != 0
|
|
98
|
+
return num_batches
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
##
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import anthropic
|
|
2
|
+
from brish import z, zp
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
anthropic_client = None
|
|
6
|
+
##
|
|
7
|
+
anthropic_key = None
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def setup_anthropic_key():
|
|
11
|
+
global anthropic_key
|
|
12
|
+
global anthropic_client
|
|
13
|
+
|
|
14
|
+
anthropic_key = z("var-get anthropic_api_key").outrs
|
|
15
|
+
assert anthropic_key, "setup_anthropic_key: could not get Anthropic API key!"
|
|
16
|
+
|
|
17
|
+
anthropic_client = anthropic.Anthropic(
|
|
18
|
+
# defaults to os.environ.get("ANTHROPIC_API_KEY")
|
|
19
|
+
api_key=anthropic_key,
|
|
20
|
+
)
|
|
21
|
+
return anthropic_client
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def anthropic_key_get():
|
|
25
|
+
global anthropic_key
|
|
26
|
+
|
|
27
|
+
if anthropic_key is None:
|
|
28
|
+
setup_anthropic_key()
|
|
29
|
+
|
|
30
|
+
return anthropic_key
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
##
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import re
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def normalize_path_for_arxiv(
|
|
5
|
+
path,
|
|
6
|
+
*,
|
|
7
|
+
disallowed_regex=r"[ :&\\\"]",
|
|
8
|
+
):
|
|
9
|
+
"""
|
|
10
|
+
Normalize a file path by replacing spaces, slashes, colons, ampersands,
|
|
11
|
+
and backslashes with underscores.
|
|
12
|
+
|
|
13
|
+
Args:
|
|
14
|
+
path (str): The file path to normalize
|
|
15
|
+
|
|
16
|
+
Returns:
|
|
17
|
+
str: The normalized file path
|
|
18
|
+
"""
|
|
19
|
+
path = re.sub(disallowed_regex, "_", path)
|
|
20
|
+
|
|
21
|
+
return path
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import torch
|
|
2
|
+
import torch.nn.functional as F
|
|
3
|
+
import re
|
|
4
|
+
|
|
5
|
+
from pynight.common_icecream import ic
|
|
6
|
+
from pynight.common_iterable import to_iterable
|
|
7
|
+
from pynight.common_dict import simple_obj
|
|
8
|
+
from pynight.common_datasets import (
|
|
9
|
+
TransformResult,
|
|
10
|
+
)
|
|
11
|
+
from pynight.common_torch import (
|
|
12
|
+
rank_tensor,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
##
|
|
17
|
+
def normalize_map(
|
|
18
|
+
attributions,
|
|
19
|
+
normalize,
|
|
20
|
+
# outlier_quantile=0.1,
|
|
21
|
+
outlier_quantile=0,
|
|
22
|
+
num_prefix_tokens=0,
|
|
23
|
+
bias_token_p=False,
|
|
24
|
+
clone_p=True,
|
|
25
|
+
pixel_p=False,
|
|
26
|
+
):
|
|
27
|
+
if pixel_p:
|
|
28
|
+
attributions_skipped = attributions
|
|
29
|
+
else:
|
|
30
|
+
attributions_skipped = attributions[..., num_prefix_tokens:] #: Skips CLS
|
|
31
|
+
if bias_token_p:
|
|
32
|
+
attributions_skipped = attributions_skipped[..., :-1]
|
|
33
|
+
#: Skips the bias token
|
|
34
|
+
|
|
35
|
+
# ic(num_prefix_tokens, attributions.shape, attributions_skipped.shape)
|
|
36
|
+
|
|
37
|
+
attributions_normalized = attributions_skipped
|
|
38
|
+
if clone_p:
|
|
39
|
+
attributions_normalized = attributions_normalized.clone()
|
|
40
|
+
|
|
41
|
+
normalize = to_iterable(normalize)
|
|
42
|
+
|
|
43
|
+
if normalize:
|
|
44
|
+
for normalizer in normalize:
|
|
45
|
+
#: Computing these quantiles is expensive, so we do it only when needed.
|
|
46
|
+
if normalizer in [
|
|
47
|
+
"scale_by_max_signed_attr",
|
|
48
|
+
]:
|
|
49
|
+
#: higher outlier_quantile makes discerning the attributions in the middle easier, but the higher attributions become the same
|
|
50
|
+
if outlier_quantile == 0:
|
|
51
|
+
max_attr = torch.max(
|
|
52
|
+
attributions_normalized,
|
|
53
|
+
dim=-1,
|
|
54
|
+
keepdim=True,
|
|
55
|
+
).values
|
|
56
|
+
else:
|
|
57
|
+
max_attr = torch.quantile(
|
|
58
|
+
attributions_normalized,
|
|
59
|
+
1 - outlier_quantile,
|
|
60
|
+
dim=-1,
|
|
61
|
+
keepdim=True,
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
# max_attr = torch.max(attributions_normalized).item()
|
|
65
|
+
else:
|
|
66
|
+
max_attr = None
|
|
67
|
+
|
|
68
|
+
if normalizer in [
|
|
69
|
+
"scale_by_max_signed_attr",
|
|
70
|
+
"shift_min_to_zero",
|
|
71
|
+
]:
|
|
72
|
+
if outlier_quantile == 0:
|
|
73
|
+
min_attr = torch.min(
|
|
74
|
+
attributions_normalized,
|
|
75
|
+
dim=-1,
|
|
76
|
+
keepdim=True,
|
|
77
|
+
).values
|
|
78
|
+
else:
|
|
79
|
+
min_attr = torch.quantile(
|
|
80
|
+
attributions_normalized,
|
|
81
|
+
outlier_quantile,
|
|
82
|
+
dim=-1,
|
|
83
|
+
keepdim=True,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
# min_attr = torch.min(attributions_normalized).item()
|
|
87
|
+
else:
|
|
88
|
+
min_attr = None
|
|
89
|
+
|
|
90
|
+
if normalizer in [
|
|
91
|
+
"scale_by_max_abs_attr",
|
|
92
|
+
]:
|
|
93
|
+
if outlier_quantile == 0:
|
|
94
|
+
max_abs_attr = torch.max(
|
|
95
|
+
torch.abs(attributions_normalized),
|
|
96
|
+
dim=-1,
|
|
97
|
+
keepdim=True,
|
|
98
|
+
).values
|
|
99
|
+
else:
|
|
100
|
+
max_abs_attr = torch.quantile(
|
|
101
|
+
torch.abs(attributions_normalized),
|
|
102
|
+
1 - outlier_quantile,
|
|
103
|
+
dim=-1,
|
|
104
|
+
keepdim=True,
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
# max_abs_attr = torch.max(torch.abs(attributions_normalized)).item()
|
|
108
|
+
else:
|
|
109
|
+
max_abs_attr = None
|
|
110
|
+
|
|
111
|
+
# ic(
|
|
112
|
+
# attributions_normalized.shape,
|
|
113
|
+
# max_attr.shape,
|
|
114
|
+
# min_attr.shape,
|
|
115
|
+
# max_abs_attr.shape,
|
|
116
|
+
# )
|
|
117
|
+
# attributions_normalized.shape: torch.Size([10, 196])
|
|
118
|
+
# max_attr.shape: torch.Size([10, 1])
|
|
119
|
+
# min_attr.shape: torch.Size([10, 1])
|
|
120
|
+
# max_abs_attr.shape: torch.Size([10, 1])
|
|
121
|
+
|
|
122
|
+
if normalizer == "scale_by_max_abs_attr":
|
|
123
|
+
attributions_normalized /= max_abs_attr
|
|
124
|
+
|
|
125
|
+
elif normalizer.lower() == "relu":
|
|
126
|
+
attributions_normalized = F.relu(attributions_normalized)
|
|
127
|
+
|
|
128
|
+
elif normalizer == "scale_by_max_signed_attr":
|
|
129
|
+
attributions_normalized = torch.where(
|
|
130
|
+
attributions_normalized < 0,
|
|
131
|
+
attributions_normalized / torch.abs(min_attr),
|
|
132
|
+
attributions_normalized / max_attr,
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
elif normalizer == "shift_min_to_zero":
|
|
136
|
+
attributions_normalized -= min_attr
|
|
137
|
+
attributions_normalized = torch.relu(attributions_normalized)
|
|
138
|
+
|
|
139
|
+
elif normalizer == "rank_uniform":
|
|
140
|
+
ranks_top_is_1 = rank_tensor(
|
|
141
|
+
attributions_normalized,
|
|
142
|
+
dim=-1,
|
|
143
|
+
descending=True,
|
|
144
|
+
increment=1,
|
|
145
|
+
)
|
|
146
|
+
#: The most important patch is turned into =1=, and the least important patch is turned into =len(attr)=.
|
|
147
|
+
|
|
148
|
+
attributions_normalized = 1.0 - (
|
|
149
|
+
(ranks_top_is_1 - 1.0) / (ranks_top_is_1.shape[-1] - 1.0)
|
|
150
|
+
)
|
|
151
|
+
#: =ranks_top_is_1 - 1= makes the ranks_top_is_1 start from zero.
|
|
152
|
+
#: =ranks_top_is_1.shape[-1] - 1= adjusts the denominator for the above change.
|
|
153
|
+
#: =1 - ...= reverses the order of the ranking, so that the first rank becomes 1, and the last rank becomes 0.
|
|
154
|
+
|
|
155
|
+
else:
|
|
156
|
+
raise ValueError(f"Unsupported normalizer: {normalizer}")
|
|
157
|
+
|
|
158
|
+
return simple_obj(
|
|
159
|
+
attributions_skipped=attributions_skipped,
|
|
160
|
+
attributions_normalized=attributions_normalized,
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
##
|
|
165
|
+
def transform_attr_threshold(
|
|
166
|
+
batch,
|
|
167
|
+
*,
|
|
168
|
+
attr_name,
|
|
169
|
+
normalize_opts=None,
|
|
170
|
+
gt_threshold=None,
|
|
171
|
+
lt_threshold=None,
|
|
172
|
+
device=None,
|
|
173
|
+
return_mode="mutate",
|
|
174
|
+
):
|
|
175
|
+
attr = batch[attr_name]
|
|
176
|
+
attr_new = attr # .clone()
|
|
177
|
+
#: =normalize_map= clones its input, so we don't need to do so.
|
|
178
|
+
|
|
179
|
+
if device is not None:
|
|
180
|
+
attr_new = attr_new.to(device)
|
|
181
|
+
|
|
182
|
+
attr_name_new = attr_name
|
|
183
|
+
|
|
184
|
+
attr_name_new = re.sub(r"^attributions_s_", "attributions_p_", attr_name_new)
|
|
185
|
+
#: _s stands for "signed scalar", and _p stands for "per-patch".
|
|
186
|
+
|
|
187
|
+
# ic(attr_name, attr_name_new)
|
|
188
|
+
|
|
189
|
+
if normalize_opts is not None:
|
|
190
|
+
normalize = normalize_opts["normalize"]
|
|
191
|
+
normalize = to_iterable(normalize)
|
|
192
|
+
attr_new = normalize_map(
|
|
193
|
+
attr_new,
|
|
194
|
+
**normalize_opts,
|
|
195
|
+
).attributions_normalized
|
|
196
|
+
attr_name_new += f"""_N:{'->'.join(normalize)}"""
|
|
197
|
+
|
|
198
|
+
if gt_threshold is not None:
|
|
199
|
+
attr_name_new += f"_GT{gt_threshold}"
|
|
200
|
+
|
|
201
|
+
mask = attr_new > gt_threshold
|
|
202
|
+
attr_new = mask * attr_new
|
|
203
|
+
|
|
204
|
+
if lt_threshold is not None:
|
|
205
|
+
attr_name_new += f"_LT{lt_threshold}"
|
|
206
|
+
|
|
207
|
+
mask = attr_name < lt_threshold
|
|
208
|
+
attr_new = mask * attr_new
|
|
209
|
+
|
|
210
|
+
if return_mode == "mutate":
|
|
211
|
+
batch[attr_name_new] = attr_new
|
|
212
|
+
elif return_mode == "new_only":
|
|
213
|
+
batch = dict()
|
|
214
|
+
batch[attr_name_new] = attr_new
|
|
215
|
+
else:
|
|
216
|
+
raise ValueError(f"Unsupported return_mode: {return_mode}")
|
|
217
|
+
|
|
218
|
+
return TransformResult(
|
|
219
|
+
result=batch,
|
|
220
|
+
name=attr_name_new,
|
|
221
|
+
#: =name= is used in =segment_by_attr=.
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
##
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import base64
|
|
2
|
+
import tempfile
|
|
3
|
+
import os
|
|
4
|
+
from PIL import Image
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
##
|
|
8
|
+
def base64_encode_file(file_path):
|
|
9
|
+
with open(file_path, "rb") as file_file:
|
|
10
|
+
return base64.b64encode(file_file.read()).decode("utf-8")
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def convert_to_jpeg_and_base64_encode(file_path, url_p=True):
|
|
14
|
+
if os.path.exists(file_path):
|
|
15
|
+
with Image.open(file_path) as img:
|
|
16
|
+
if img.format.lower() not in ["jpg", "jpeg"]:
|
|
17
|
+
#: I don't know if =format= is normalized first or not, so I took the safest approach above.
|
|
18
|
+
|
|
19
|
+
rgb_im = img.convert(
|
|
20
|
+
"RGB"
|
|
21
|
+
) # Convert to RGB if necessary (e.g., RGBA, P mode)
|
|
22
|
+
|
|
23
|
+
# Save the image to a temporary file
|
|
24
|
+
with tempfile.NamedTemporaryFile(
|
|
25
|
+
suffix=".jpeg", delete=True
|
|
26
|
+
) as tmpfile:
|
|
27
|
+
temp_path = tmpfile.name
|
|
28
|
+
rgb_im.save(temp_path, format="JPEG")
|
|
29
|
+
|
|
30
|
+
# Use the temporary file for base64 encoding
|
|
31
|
+
file_base64 = base64_encode_file(temp_path)
|
|
32
|
+
else:
|
|
33
|
+
#: If the image is already a JPEG, encode it directly
|
|
34
|
+
file_base64 = base64_encode_file(file_path)
|
|
35
|
+
|
|
36
|
+
if url_p:
|
|
37
|
+
return f"data:image/jpeg;base64,{file_base64}"
|
|
38
|
+
else:
|
|
39
|
+
return file_base64
|
|
40
|
+
else:
|
|
41
|
+
raise FileNotFoundError(f"The file {file_path} does not exist.")
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
##
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from brish import (
|
|
2
|
+
z,
|
|
3
|
+
z_background,
|
|
4
|
+
)
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def bello():
|
|
8
|
+
z("bello")
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def bell_gpt():
|
|
12
|
+
z("bell-gpt")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def bell_call_remote(bell_name):
|
|
16
|
+
try:
|
|
17
|
+
if bell_name:
|
|
18
|
+
z_background("bell-call-remote {bell_name}")
|
|
19
|
+
|
|
20
|
+
except Exception as e:
|
|
21
|
+
print(f"Error remote-calling bell:\n bell_name: {bell_name}\n {e}")
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import pyperclip
|
|
2
|
+
import threading
|
|
3
|
+
import time
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def clipboard_copy(
|
|
7
|
+
obj,
|
|
8
|
+
*,
|
|
9
|
+
ignore_errors=True,
|
|
10
|
+
):
|
|
11
|
+
try:
|
|
12
|
+
return pyperclip.copy(obj)
|
|
13
|
+
except:
|
|
14
|
+
if ignore_errors:
|
|
15
|
+
return None
|
|
16
|
+
else:
|
|
17
|
+
raise
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def clipboard_copy_multi_sync(
|
|
21
|
+
texts,
|
|
22
|
+
sleep=0.5,
|
|
23
|
+
):
|
|
24
|
+
for text in texts:
|
|
25
|
+
if text: #: Check if the text is not empty or None
|
|
26
|
+
clipboard_copy(text)
|
|
27
|
+
time.sleep(sleep)
|
|
28
|
+
#: to allow polling-based clipboard managers to capture the text
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def clipboard_copy_multi(*args):
|
|
32
|
+
copy_thread = threading.Thread(target=clipboard_copy_multi_sync, args=(args,))
|
|
33
|
+
|
|
34
|
+
copy_thread.start()
|
|
@@ -1,24 +1,32 @@
|
|
|
1
1
|
import os
|
|
2
2
|
from os import getenv
|
|
3
3
|
|
|
4
|
+
|
|
4
5
|
##
|
|
5
6
|
def jupyter_p():
|
|
6
7
|
return jupyter_p_v1() or jupyter_p_v2()
|
|
7
|
-
|
|
8
|
+
|
|
9
|
+
|
|
8
10
|
def jupyter_p_v1():
|
|
9
|
-
return getenv(
|
|
11
|
+
return getenv("INSIDE_JUPYTER_NOTEBOOK_P", default="") == "y"
|
|
12
|
+
|
|
10
13
|
|
|
11
14
|
def jupyter_p_v2():
|
|
12
15
|
#: [[https://stackoverflow.com/questions/15411967/how-can-i-check-if-code-is-executed-in-the-ipython-notebook][python - How can I check if code is executed in the IPython notebook? - Stack Overflow]]
|
|
13
16
|
##
|
|
14
17
|
try:
|
|
15
18
|
shell = get_ipython().__class__.__name__
|
|
16
|
-
if shell ==
|
|
17
|
-
return True
|
|
18
|
-
|
|
19
|
+
if shell == "ZMQInteractiveShell":
|
|
20
|
+
return True # Jupyter notebook or qtconsole
|
|
21
|
+
|
|
22
|
+
elif shell == "TerminalInteractiveShell":
|
|
19
23
|
return False # Terminal running IPython
|
|
24
|
+
|
|
20
25
|
else:
|
|
21
26
|
return False # Other type (?)
|
|
27
|
+
|
|
22
28
|
except NameError:
|
|
23
|
-
return False
|
|
29
|
+
return False # Probably standard Python interpreter
|
|
30
|
+
|
|
31
|
+
|
|
24
32
|
##
|