psaiops 0.2.0__py3-none-any.whl → 0.2.2__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.

Potentially problematic release.


This version of psaiops might be problematic. Click here for more details.

@@ -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
 
@@ -39,7 +40,7 @@ def create_model_block() -> dict:
39
40
  # SAMPLING #####################################################################
40
41
 
41
42
  def create_sampling_block() -> dict:
42
- __tokens = gradio.Slider(label='Tokens', value=16, minimum=1, maximum=128, step=1, scale=1, interactive=True)
43
+ __tokens = gradio.Slider(label='Tokens', value=32, minimum=1, maximum=128, step=1, scale=1, interactive=True)
43
44
  __topk = gradio.Slider(label='Top K', value=4, minimum=1, maximum=8, step=1, scale=1, interactive=True)
44
45
  __topp = gradio.Slider(label='Top P', value=0.9, minimum=0.0, maximum=1.0, step=0.1, scale=1, interactive=True)
45
46
  return {
@@ -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) -> list:
133
- __outputs = tokenizer([positive, negative, prompt, output], padding=True)
134
- return [tokenizer.convert_ids_to_tokens(__s) for __s in __outputs['input_ids']]
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
- # keep the intersection of the masks
63
- __masks = masks.prod(dim=0, keepdim=False)
64
- # and only the positions that differ between positive and negative prompts
65
- return __masks * (tokens[0] != tokens[1])
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(len(__signs)) * __masks.sum()).clamp(min=1e-8)
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) / __factor
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'], masks=__inputs['attention_mask'])
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: psaiops
3
- Version: 0.2.0
3
+ Version: 0.2.2
4
4
  Summary: Web apps to inspect & engineer NN activations.
5
5
  License: .github/LICENSE.md
6
6
  Author: apehex
@@ -5,8 +5,8 @@ psaiops/common/data.py,sha256=vGYeMN11uP9gs8rV6aSDffE_TeIX5PmdzWGwUpdGE2Y,906
5
5
  psaiops/common/dropdown.py,sha256=KA3wrfz4UlCpeoDvFAeURGK3YmVg6TBVhybaqTZa1M0,1332
6
6
  psaiops/compose/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  psaiops/compose/contrast/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- psaiops/compose/contrast/app.py,sha256=hecqh2yuUpAQMaesjIVlG-QxSJhm595Thm0CHEirZ64,8737
9
- psaiops/compose/contrast/lib.py,sha256=lBw-0VNvmEiY_zs9-e1TFYmOdlIbvEc7aB-9ZiZFyBU,6543
8
+ psaiops/compose/contrast/app.py,sha256=VRg98HONjoHLfTcWLhriT2AIcB2DvM01VHlmdC-3_RA,9626
9
+ psaiops/compose/contrast/lib.py,sha256=S5uXvnHdOA4bSbMY8Mj23KsZtIQ-zvdr4uPSUCBp-0U,6704
10
10
  psaiops/edit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
11
  psaiops/reverse/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
12
  psaiops/score/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -14,6 +14,6 @@ psaiops/score/attention/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
14
14
  psaiops/score/attention/app.py,sha256=7MwFp70W0zpIcxllM2hKHN7TW3WH-BGFNK3r9a1ISr0,13444
15
15
  psaiops/score/attention/lib.py,sha256=j9p7ZXhkh5Y9VDeIe6TPUUrHRkwp1Y6P22iciaaKdL4,6932
16
16
  psaiops/steer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
- psaiops-0.2.0.dist-info/METADATA,sha256=JQ_Pu17L6AwFA3J_dxVggdzHk_iMDiLc78TDAHT9sUM,1318
18
- psaiops-0.2.0.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
19
- psaiops-0.2.0.dist-info/RECORD,,
17
+ psaiops-0.2.2.dist-info/METADATA,sha256=pZttqPtKdiI5oln701Rw-1a9mPGX8lC5oPUwabP7kYI,1318
18
+ psaiops-0.2.2.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
19
+ psaiops-0.2.2.dist-info/RECORD,,