psaiops 0.2.0__tar.gz → 0.2.1__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.
Potentially problematic release.
This version of psaiops might be problematic. Click here for more details.
- {psaiops-0.2.0 → psaiops-0.2.1}/PKG-INFO +1 -1
- {psaiops-0.2.0 → psaiops-0.2.1}/psaiops/compose/contrast/app.py +17 -3
- {psaiops-0.2.0 → psaiops-0.2.1}/psaiops/compose/contrast/lib.py +14 -10
- {psaiops-0.2.0 → psaiops-0.2.1}/pyproject.toml +1 -1
- {psaiops-0.2.0 → psaiops-0.2.1}/.github/README.md +0 -0
- {psaiops-0.2.0 → psaiops-0.2.1}/psaiops/__init__.py +0 -0
- {psaiops-0.2.0 → psaiops-0.2.1}/psaiops/combine/__init__.py +0 -0
- {psaiops-0.2.0 → psaiops-0.2.1}/psaiops/common/__init__.py +0 -0
- {psaiops-0.2.0 → psaiops-0.2.1}/psaiops/common/data.py +0 -0
- {psaiops-0.2.0 → psaiops-0.2.1}/psaiops/common/dropdown.py +0 -0
- {psaiops-0.2.0 → psaiops-0.2.1}/psaiops/compose/__init__.py +0 -0
- {psaiops-0.2.0 → psaiops-0.2.1}/psaiops/compose/contrast/__init__.py +0 -0
- {psaiops-0.2.0 → psaiops-0.2.1}/psaiops/edit/__init__.py +0 -0
- {psaiops-0.2.0 → psaiops-0.2.1}/psaiops/reverse/__init__.py +0 -0
- {psaiops-0.2.0 → psaiops-0.2.1}/psaiops/score/__init__.py +0 -0
- {psaiops-0.2.0 → psaiops-0.2.1}/psaiops/score/attention/__init__.py +0 -0
- {psaiops-0.2.0 → psaiops-0.2.1}/psaiops/score/attention/app.py +0 -0
- {psaiops-0.2.0 → psaiops-0.2.1}/psaiops/score/attention/lib.py +0 -0
- {psaiops-0.2.0 → psaiops-0.2.1}/psaiops/steer/__init__.py +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import functools
|
|
2
2
|
|
|
3
3
|
import gradio
|
|
4
|
+
import pandas
|
|
4
5
|
import torch
|
|
5
6
|
import torch.cuda
|
|
6
7
|
|
|
@@ -129,9 +130,22 @@ def create_layout(intro: str=INTRO) -> dict:
|
|
|
129
130
|
def update_layer_range(value: float, model: str) -> dict:
|
|
130
131
|
return gradio.update(maximum=35, value=min(35, int(value))) if '120b' in model else gradio.update(maximum=23, value=min(23, int(value)))
|
|
131
132
|
|
|
132
|
-
def update_table_data(positive: str, negative: str, prompt: str, output: str, tokenizer: object) ->
|
|
133
|
-
|
|
134
|
-
|
|
133
|
+
def update_table_data(positive: str, negative: str, prompt: str, output: str, tokenizer: object) -> pandas.DataFrame:
|
|
134
|
+
# array of token IDs
|
|
135
|
+
__outputs = tokenizer([positive, negative, prompt, output], return_tensors='pt', padding=True)
|
|
136
|
+
# array of token strings
|
|
137
|
+
__tokens = [tokenizer.convert_ids_to_tokens(__s) for __s in __outputs['input_ids']]
|
|
138
|
+
# shift the special characters
|
|
139
|
+
__tokens = [[__t.replace(chr(0x0120), ' ').replace(chr(0x010a), '\\n') for __t in __s] for __s in __tokens]
|
|
140
|
+
# mask the tokens that differ between positive and negative prompts
|
|
141
|
+
__masks = psaiops.compose.contrast.lib.compute_sequence_mask(tokens=__outputs['input_ids'])
|
|
142
|
+
# convert into a data frame
|
|
143
|
+
__data = pandas.DataFrame(__tokens)
|
|
144
|
+
# color the background in red for the positions marked by the mask
|
|
145
|
+
return __data.style.apply(update_table_style, masks=pandas.DataFrame(__masks), axis=None)
|
|
146
|
+
|
|
147
|
+
def update_table_style(data: pandas.DataFrame, masks: pandas.DataFrame) -> pandas.DataFrame:
|
|
148
|
+
return pandas.DataFrame(masks.replace({True: 'background-color: rgb(255, 0, 0, 64%)', False: 'background-color: rgb(0, 0, 0, 0%)',}))
|
|
135
149
|
|
|
136
150
|
# APP ##########################################################################
|
|
137
151
|
|
|
@@ -57,33 +57,37 @@ def capture_hidden_activation(
|
|
|
57
57
|
|
|
58
58
|
def compute_sequence_mask(
|
|
59
59
|
tokens: torch.Tensor, # (B, S)
|
|
60
|
-
masks: torch.Tensor, # (B, S)
|
|
60
|
+
# masks: torch.Tensor, # (B, S)
|
|
61
61
|
) -> torch.Tensor:
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
__shape = mlable.shapes.divide(tokens.shape, axis=0, factor=2, insert=True)
|
|
63
|
+
# group the samples two by two
|
|
64
|
+
__data = tokens.reshape(__shape)
|
|
65
|
+
# compare each sample with its neighbor
|
|
66
|
+
__masks = __data[:, :1] != __data[:, 1:]
|
|
67
|
+
# apply the same mask to both samples
|
|
68
|
+
return __masks.expand(__shape).reshape(tokens.shape)
|
|
66
69
|
|
|
67
70
|
# REDUCTION ####################################################################
|
|
68
71
|
|
|
69
72
|
def compute_delta_activation(
|
|
70
73
|
data: torch.Tensor, # (B, S, E)
|
|
71
|
-
masks: torch.Tensor, # (S,)
|
|
74
|
+
masks: torch.Tensor, # (B, S,)
|
|
72
75
|
signs: torch.Tensor, # (B,)
|
|
73
76
|
keepdim: bool=True,
|
|
74
77
|
) -> torch.Tensor:
|
|
75
78
|
__dtype = data.dtype
|
|
76
79
|
__device = data.device
|
|
80
|
+
__dim0, __dim1, __dim2 = tuple(data.shape)
|
|
77
81
|
# sign each sample along the batch axis
|
|
78
82
|
__shape = tuple(mlable.shapes.filter(data.shape, axes=[0]))
|
|
79
83
|
__signs = signs.to(dtype=__dtype, device=__device).view(__shape)
|
|
80
84
|
# combine along the batch axis to keep the shortest mask on the sequence axis
|
|
81
|
-
__shape = tuple(mlable.shapes.filter(data.shape, axes=[1]))
|
|
85
|
+
__shape = tuple(mlable.shapes.filter(data.shape, axes=[0, 1]))
|
|
82
86
|
__masks = masks.to(dtype=__dtype, device=__device).view(__shape)
|
|
83
87
|
# mean factor: half the signs size along the batch axis and the number of positions kept along the sequence axis
|
|
84
|
-
__factor = (0.5 * float(
|
|
88
|
+
__factor = (0.5 * float(__dim0) * __masks.sum(dim=1, keepdim=True)).clamp(min=1.0)
|
|
85
89
|
# take the difference along the batch axis and the average along the sequence axis
|
|
86
|
-
return (data * __signs * __masks).sum(dim=[0, 1], keepdim=keepdim)
|
|
90
|
+
return (data * __signs * __masks / __factor).sum(dim=[0, 1], keepdim=keepdim)
|
|
87
91
|
|
|
88
92
|
# DELTA ########################################################################
|
|
89
93
|
|
|
@@ -147,7 +151,7 @@ def steer_model_output(
|
|
|
147
151
|
# stop capturing activations
|
|
148
152
|
__handle.remove()
|
|
149
153
|
# select only the positions where the tokens differ
|
|
150
|
-
__masks = compute_sequence_mask(tokens=__inputs['input_ids']
|
|
154
|
+
__masks = compute_sequence_mask(tokens=__inputs['input_ids'])
|
|
151
155
|
# activation delta at layer L
|
|
152
156
|
__delta = compute_delta_activation(data=__captured[__index], masks=__masks, signs=torch.Tensor([1, -1]), keepdim=False)
|
|
153
157
|
# add the delta on every forward pass
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|