interp-engine 0.0.24__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.
@@ -0,0 +1,227 @@
1
+ import asyncio
2
+ from typing import Any
3
+
4
+ from neuron_explainer.explanations.explainer import (
5
+ TokenActivationPairExplainer,
6
+ TokenSpaceRepresentationExplainer,
7
+ )
8
+ from neuron_explainer.explanations.few_shot_examples import TEST_EXAMPLES, FewShotExampleSet
9
+ from neuron_explainer.explanations.prompt_builder import HarmonyMessage, PromptFormat, Role
10
+ from neuron_explainer.explanations.token_space_few_shot_examples import (
11
+ TokenSpaceFewShotExampleSet,
12
+ )
13
+
14
+
15
+ def setup_module(unused_module: Any) -> None:
16
+ # Make sure we have an event loop, since the attempt to create the Semaphore in
17
+ # ResearchApiClient will fail without it.
18
+ loop = asyncio.new_event_loop()
19
+ asyncio.set_event_loop(loop)
20
+
21
+
22
+ def test_if_formatting() -> None:
23
+ expected_prompt = """We're studying neurons in a neural network. Each neuron looks for some particular thing in a short document. Look at the parts of the document the neuron activates for and summarize in a single sentence what the neuron is looking for. Don't list examples of words.
24
+
25
+ The activation format is token<tab>activation. Activation values range from 0 to 10. A neuron finding what it's looking for is represented by a non-zero activation value. The higher the activation value, the stronger the match.
26
+
27
+ Neuron 1
28
+ Activations:
29
+ <start>
30
+ a 10
31
+ b 0
32
+ c 0
33
+ <end>
34
+ <start>
35
+ d 0
36
+ e 10
37
+ f 0
38
+ <end>
39
+
40
+ Explanation of neuron 1 behavior: the main thing this neuron does is find vowels.
41
+
42
+ Neuron 2
43
+ Activations:
44
+ <start>
45
+ a 10
46
+ b 0
47
+ c 0
48
+ <end>
49
+ <start>
50
+ d 0
51
+ e 10
52
+ f 0
53
+ <end>
54
+
55
+ Explanation of neuron 2 behavior:<|endofprompt|> the main thing this neuron does is find"""
56
+
57
+ explainer = TokenActivationPairExplainer(
58
+ model_name="text-davinci-003",
59
+ prompt_format=PromptFormat.INSTRUCTION_FOLLOWING,
60
+ few_shot_example_set=FewShotExampleSet.TEST,
61
+ )
62
+ prompt = explainer.make_explanation_prompt(
63
+ all_activation_records=TEST_EXAMPLES[0].activation_records,
64
+ max_activation=1.0,
65
+ max_tokens_for_completion=20,
66
+ )
67
+
68
+ assert prompt == expected_prompt
69
+
70
+
71
+ def test_harmony_format() -> None:
72
+ expected_prompt = [
73
+ HarmonyMessage(
74
+ role=Role.SYSTEM,
75
+ content="""We're studying neurons in a neural network. Each neuron looks for some particular thing in a short document. Look at the parts of the document the neuron activates for and summarize in a single sentence what the neuron is looking for. Don't list examples of words.
76
+
77
+ The activation format is token<tab>activation. Activation values range from 0 to 10. A neuron finding what it's looking for is represented by a non-zero activation value. The higher the activation value, the stronger the match.""",
78
+ ),
79
+ HarmonyMessage(
80
+ role=Role.USER,
81
+ content="""
82
+
83
+ Neuron 1
84
+ Activations:
85
+ <start>
86
+ a 10
87
+ b 0
88
+ c 0
89
+ <end>
90
+ <start>
91
+ d 0
92
+ e 10
93
+ f 0
94
+ <end>
95
+
96
+ Explanation of neuron 1 behavior: the main thing this neuron does is find""",
97
+ ),
98
+ HarmonyMessage(
99
+ role=Role.ASSISTANT,
100
+ content=" vowels.",
101
+ ),
102
+ HarmonyMessage(
103
+ role=Role.USER,
104
+ content="""
105
+
106
+ Neuron 2
107
+ Activations:
108
+ <start>
109
+ a 10
110
+ b 0
111
+ c 0
112
+ <end>
113
+ <start>
114
+ d 0
115
+ e 10
116
+ f 0
117
+ <end>
118
+
119
+ Explanation of neuron 2 behavior: the main thing this neuron does is find""",
120
+ ),
121
+ ]
122
+
123
+ explainer = TokenActivationPairExplainer(
124
+ model_name="gpt-4",
125
+ prompt_format=PromptFormat.HARMONY_V4,
126
+ few_shot_example_set=FewShotExampleSet.TEST,
127
+ )
128
+ prompt = explainer.make_explanation_prompt(
129
+ all_activation_records=TEST_EXAMPLES[0].activation_records,
130
+ max_activation=1.0,
131
+ max_tokens_for_completion=20,
132
+ )
133
+
134
+ assert isinstance(prompt, list)
135
+ assert isinstance(prompt[0], dict) # Really a HarmonyMessage
136
+ for actual_message, expected_message in zip(prompt, expected_prompt):
137
+ assert actual_message["role"] == expected_message["role"]
138
+ assert actual_message["content"] == expected_message["content"]
139
+ assert prompt == expected_prompt
140
+
141
+
142
+ def test_token_space_explainer_if_formatting() -> None:
143
+ expected_prompt = """We're studying neurons in a neural network. Each neuron looks for some particular kind of token (which can be a word, or part of a word). Look at the tokens the neuron activates for (listed below) and summarize in a single sentence what the neuron is looking for. Don't list examples of words.
144
+
145
+
146
+
147
+ Tokens:
148
+ 'these', ' are', ' tokens'
149
+
150
+ Explanation:
151
+ This neuron is looking for this is a test explanation.
152
+
153
+
154
+
155
+ Tokens:
156
+ 'foo', 'bar', 'baz'
157
+
158
+ Explanation:
159
+ <|endofprompt|>This neuron is looking for"""
160
+
161
+ explainer = TokenSpaceRepresentationExplainer(
162
+ model_name="text-davinci-002",
163
+ prompt_format=PromptFormat.INSTRUCTION_FOLLOWING,
164
+ use_few_shot=True,
165
+ few_shot_example_set=TokenSpaceFewShotExampleSet.TEST,
166
+ )
167
+ prompt = explainer.make_explanation_prompt(
168
+ tokens=["foo", "bar", "baz"],
169
+ max_tokens_for_completion=20,
170
+ )
171
+
172
+ assert prompt == expected_prompt
173
+
174
+
175
+ def test_token_space_explainer_harmony_formatting() -> None:
176
+ expected_prompt = [
177
+ HarmonyMessage(
178
+ role=Role.SYSTEM,
179
+ content="We're studying neurons in a neural network. Each neuron looks for some particular kind of token (which can be a word, or part of a word). Look at the tokens the neuron activates for (listed below) and summarize in a single sentence what the neuron is looking for. Don't list examples of words.",
180
+ ),
181
+ HarmonyMessage(
182
+ role=Role.USER,
183
+ content="""
184
+
185
+
186
+
187
+ Tokens:
188
+ 'these', ' are', ' tokens'
189
+
190
+ Explanation:
191
+ This neuron is looking for""",
192
+ ),
193
+ HarmonyMessage(
194
+ role=Role.ASSISTANT,
195
+ content=" this is a test explanation.",
196
+ ),
197
+ HarmonyMessage(
198
+ role=Role.USER,
199
+ content="""
200
+
201
+
202
+
203
+ Tokens:
204
+ 'foo', 'bar', 'baz'
205
+
206
+ Explanation:
207
+ This neuron is looking for""",
208
+ ),
209
+ ]
210
+
211
+ explainer = TokenSpaceRepresentationExplainer(
212
+ model_name="gpt-4",
213
+ prompt_format=PromptFormat.HARMONY_V4,
214
+ use_few_shot=True,
215
+ few_shot_example_set=TokenSpaceFewShotExampleSet.TEST,
216
+ )
217
+ prompt = explainer.make_explanation_prompt(
218
+ tokens=["foo", "bar", "baz"],
219
+ max_tokens_for_completion=20,
220
+ )
221
+
222
+ assert isinstance(prompt, list)
223
+ assert isinstance(prompt[0], dict) # Really a HarmonyMessage
224
+ for actual_message, expected_message in zip(prompt, expected_prompt):
225
+ assert actual_message["role"] == expected_message["role"]
226
+ assert actual_message["content"] == expected_message["content"]
227
+ assert prompt == expected_prompt
@@ -0,0 +1,269 @@
1
+ from neuron_explainer.explanations.few_shot_examples import FewShotExampleSet
2
+ from neuron_explainer.explanations.prompt_builder import HarmonyMessage, PromptFormat, Role
3
+ from neuron_explainer.explanations.simulator import (
4
+ ExplanationNeuronSimulator,
5
+ ExplanationTokenByTokenSimulator,
6
+ )
7
+
8
+
9
+ def test_make_explanation_simulation_prompt_if_format() -> None:
10
+ expected_prompt = """We're studying neurons in a neural network.
11
+ Each neuron looks for some particular thing in a short document.
12
+ Look at summary of what the neuron does, and try to predict how it will fire on each token.
13
+
14
+ The activation format is token<tab>activation, activations go from 0 to 10, "unknown" indicates an unknown activation. Most activations will be 0.
15
+
16
+
17
+ Neuron 1
18
+ Explanation of neuron 1 behavior: the main thing this neuron does is find vowels
19
+ Activations:
20
+ <start>
21
+ a 10
22
+ b 0
23
+ c 0
24
+ <end>
25
+ <start>
26
+ d unknown
27
+ e 10
28
+ f 0
29
+ <end>
30
+
31
+
32
+
33
+ Neuron 2
34
+ Explanation of neuron 2 behavior: the main thing this neuron does is find EXPLANATION<|endofprompt|>
35
+ Activations:
36
+ <start>
37
+ 0 unknown
38
+ 1 unknown
39
+ 2 unknown
40
+ <end>
41
+ """
42
+ prompt = ExplanationNeuronSimulator(
43
+ model_name="text-davinci-003",
44
+ explanation="EXPLANATION",
45
+ few_shot_example_set=FewShotExampleSet.TEST,
46
+ prompt_format=PromptFormat.INSTRUCTION_FOLLOWING,
47
+ ).make_simulation_prompt(
48
+ tokens=[str(x) for x in range(3)],
49
+ )
50
+ assert prompt == expected_prompt
51
+
52
+
53
+ def test_make_explanation_simulation_prompt_harmony_format() -> None:
54
+ expected_prompt = [
55
+ HarmonyMessage(
56
+ role=Role.SYSTEM,
57
+ content="""We're studying neurons in a neural network.
58
+ Each neuron looks for some particular thing in a short document.
59
+ Look at summary of what the neuron does, and try to predict how it will fire on each token.
60
+
61
+ The activation format is token<tab>activation, activations go from 0 to 10, "unknown" indicates an unknown activation. Most activations will be 0.
62
+ """,
63
+ ),
64
+ HarmonyMessage(
65
+ role=Role.USER,
66
+ content="""
67
+
68
+ Neuron 1
69
+ Explanation of neuron 1 behavior: the main thing this neuron does is find vowels""",
70
+ ),
71
+ HarmonyMessage(
72
+ role=Role.ASSISTANT,
73
+ content="""
74
+ Activations:
75
+ <start>
76
+ a 10
77
+ b 0
78
+ c 0
79
+ <end>
80
+ <start>
81
+ d unknown
82
+ e 10
83
+ f 0
84
+ <end>
85
+
86
+ """,
87
+ ),
88
+ HarmonyMessage(
89
+ role=Role.USER,
90
+ content="""
91
+
92
+ Neuron 2
93
+ Explanation of neuron 2 behavior: the main thing this neuron does is find EXPLANATION""",
94
+ ),
95
+ HarmonyMessage(
96
+ role=Role.ASSISTANT,
97
+ content="""
98
+ Activations:
99
+ <start>
100
+ 0 unknown
101
+ 1 unknown
102
+ 2 unknown
103
+ <end>
104
+ """,
105
+ ),
106
+ ]
107
+ prompt = ExplanationNeuronSimulator(
108
+ model_name="gpt-4",
109
+ explanation="EXPLANATION",
110
+ few_shot_example_set=FewShotExampleSet.TEST,
111
+ prompt_format=PromptFormat.HARMONY_V4,
112
+ ).make_simulation_prompt(
113
+ tokens=[str(x) for x in range(3)],
114
+ )
115
+
116
+ assert isinstance(prompt, list)
117
+ assert isinstance(prompt[0], dict) # Really a HarmonyMessage
118
+ for actual_message, expected_message in zip(prompt, expected_prompt):
119
+ assert actual_message["role"] == expected_message["role"]
120
+ assert actual_message["content"] == expected_message["content"]
121
+ assert prompt == expected_prompt
122
+
123
+
124
+ def test_make_token_by_token_simulation_prompt_if_format() -> None:
125
+ expected_prompt = """We're studying neurons in a neural network. Each neuron looks for some particular thing in a short document. Look at an explanation of what the neuron does, and try to predict its activations on a particular token.
126
+
127
+ The activation format is token<tab>activation, and activations range from 0 to 10. Most activations will be 0.
128
+
129
+ Neuron 1
130
+ Explanation of neuron 1 behavior: the main thing this neuron does is find vowels
131
+ Activations:
132
+ <start>
133
+ a 10
134
+ b 0
135
+ c 0
136
+ <end>
137
+ <start>
138
+ d 0
139
+ e 10
140
+ f 0
141
+ <end>
142
+
143
+
144
+ Now, we're going predict the activation of a new neuron on a single token, following the same rules as the examples above. Activations still range from 0 to 10.
145
+ Neuron 2
146
+ Explanation of neuron 2 behavior: the main thing this neuron does is find numbers and nothing else
147
+ Text:
148
+ ghi
149
+
150
+ Last token in the text:
151
+ i
152
+
153
+ Last token activation, considering the token in the context in which it appeared in the text:
154
+ 10
155
+
156
+
157
+ Neuron 3
158
+ Explanation of neuron 3 behavior: the main thing this neuron does is find numbers and nothing else
159
+ Text:
160
+ 01
161
+
162
+ Last token in the text:
163
+ 1
164
+
165
+ Last token activation, considering the token in the context in which it appeared in the text:
166
+ <|endofprompt|>"""
167
+ prompt = ExplanationTokenByTokenSimulator(
168
+ model_name="text-davinci-003",
169
+ explanation="EXPLANATION",
170
+ few_shot_example_set=FewShotExampleSet.TEST,
171
+ prompt_format=PromptFormat.INSTRUCTION_FOLLOWING,
172
+ ).make_single_token_simulation_prompt(
173
+ tokens=[str(x) for x in range(3)],
174
+ explanation="numbers and nothing else",
175
+ token_index_to_score=1,
176
+ )
177
+ assert prompt == expected_prompt
178
+
179
+
180
+ def test_make_token_by_token_simulation_prompt_harmony_format() -> None:
181
+ expected_prompt = [
182
+ HarmonyMessage(
183
+ role=Role.SYSTEM,
184
+ content="""We're studying neurons in a neural network. Each neuron looks for some particular thing in a short document. Look at an explanation of what the neuron does, and try to predict its activations on a particular token.
185
+
186
+ The activation format is token<tab>activation, and activations range from 0 to 10. Most activations will be 0.
187
+
188
+ """,
189
+ ),
190
+ HarmonyMessage(
191
+ role=Role.USER,
192
+ content="""Neuron 1
193
+ Explanation of neuron 1 behavior: the main thing this neuron does is find vowels
194
+ """,
195
+ ),
196
+ HarmonyMessage(
197
+ role=Role.ASSISTANT,
198
+ content="""Activations:
199
+ <start>
200
+ a 10
201
+ b 0
202
+ c 0
203
+ <end>
204
+ <start>
205
+ d 0
206
+ e 10
207
+ f 0
208
+ <end>
209
+
210
+
211
+ """,
212
+ ),
213
+ HarmonyMessage(
214
+ role=Role.SYSTEM,
215
+ content="Now, we're going predict the activation of a new neuron on a single token, following the same rules as the examples above. Activations still range from 0 to 10.",
216
+ ),
217
+ HarmonyMessage(
218
+ role=Role.USER,
219
+ content="""
220
+ Neuron 2
221
+ Explanation of neuron 2 behavior: the main thing this neuron does is find numbers and nothing else
222
+ Text:
223
+ ghi
224
+
225
+ Last token in the text:
226
+ i
227
+
228
+ Last token activation, considering the token in the context in which it appeared in the text:
229
+ """,
230
+ ),
231
+ HarmonyMessage(
232
+ role=Role.ASSISTANT,
233
+ content="""10
234
+
235
+ """,
236
+ ),
237
+ HarmonyMessage(
238
+ role=Role.USER,
239
+ content="""
240
+ Neuron 3
241
+ Explanation of neuron 3 behavior: the main thing this neuron does is find numbers and nothing else
242
+ Text:
243
+ 01
244
+
245
+ Last token in the text:
246
+ 1
247
+
248
+ Last token activation, considering the token in the context in which it appeared in the text:
249
+ """,
250
+ ),
251
+ ]
252
+
253
+ prompt = ExplanationTokenByTokenSimulator(
254
+ model_name="gpt-4",
255
+ explanation="EXPLANATION",
256
+ few_shot_example_set=FewShotExampleSet.TEST,
257
+ prompt_format=PromptFormat.HARMONY_V4,
258
+ ).make_single_token_simulation_prompt(
259
+ tokens=[str(x) for x in range(3)],
260
+ explanation="numbers and nothing else",
261
+ token_index_to_score=1,
262
+ )
263
+
264
+ assert isinstance(prompt, list)
265
+ assert isinstance(prompt[0], dict) # Really a HarmonyMessage
266
+ for actual_message, expected_message in zip(prompt, expected_prompt):
267
+ assert actual_message["role"] == expected_message["role"]
268
+ assert actual_message["content"] == expected_message["content"]
269
+ assert prompt == expected_prompt
@@ -0,0 +1,212 @@
1
+ from dataclasses import dataclass
2
+ from enum import Enum
3
+ from typing import List
4
+
5
+ from neuron_explainer.fast_dataclasses import FastDataclass
6
+
7
+
8
+ @dataclass
9
+ class Example(FastDataclass):
10
+ """
11
+ An example list of tokens as strings corresponding to top token space inputs of a neuron, with a
12
+ string explanation of the neuron's behavior on these tokens.
13
+ """
14
+
15
+ tokens: List[str]
16
+ explanation: str
17
+
18
+
19
+ class TokenSpaceFewShotExampleSet(Enum):
20
+ """Determines which few-shot examples to use when sampling explanations."""
21
+
22
+ ORIGINAL = "original"
23
+ TEST = "test"
24
+
25
+ def get_examples(self) -> list[Example]:
26
+ """Returns regular examples for use in a few-shot prompt."""
27
+ if self is TokenSpaceFewShotExampleSet.ORIGINAL:
28
+ return ORIGINAL_EXAMPLES
29
+ elif self is TokenSpaceFewShotExampleSet.TEST:
30
+ return TEST_EXAMPLES
31
+ else:
32
+ raise ValueError(f"Unhandled example set: {self}")
33
+
34
+
35
+ ORIGINAL_EXAMPLES = [
36
+ Example(
37
+ tokens=[
38
+ "actual",
39
+ " literal",
40
+ " actual",
41
+ " hyper",
42
+ " real",
43
+ " EX",
44
+ " Real",
45
+ "^",
46
+ "Full",
47
+ " full",
48
+ " optical",
49
+ " style",
50
+ "any",
51
+ "ALL",
52
+ "extreme",
53
+ " miniature",
54
+ " Optical",
55
+ " faint",
56
+ "~",
57
+ " Physical",
58
+ " REAL",
59
+ "*",
60
+ "virtual",
61
+ "TYPE",
62
+ " technical",
63
+ "otally",
64
+ " physic",
65
+ "Type",
66
+ "<",
67
+ "images",
68
+ "atic",
69
+ " sheer",
70
+ " Style",
71
+ " partial",
72
+ " natural",
73
+ "Hyper",
74
+ " Any",
75
+ " theoretical",
76
+ "|",
77
+ " ultimate",
78
+ "oing",
79
+ " constant",
80
+ "ANY",
81
+ "antically",
82
+ "ishly",
83
+ " ex",
84
+ " visual",
85
+ "special",
86
+ "omorphic",
87
+ "visual",
88
+ ],
89
+ explanation=" adjectives related to being real, or to physical properties and evidence",
90
+ ),
91
+ Example(
92
+ tokens=[
93
+ "cephal",
94
+ "aeus",
95
+ " coma",
96
+ "bered",
97
+ "abetes",
98
+ "inflamm",
99
+ "rugged",
100
+ "alysed",
101
+ "azine",
102
+ "hered",
103
+ "cells",
104
+ "aneously",
105
+ "fml",
106
+ "igm",
107
+ "culosis",
108
+ "iani",
109
+ "CTV",
110
+ "disabled",
111
+ "heric",
112
+ "ulo",
113
+ "geoning",
114
+ "awi",
115
+ "translation",
116
+ "iral",
117
+ "govtrack",
118
+ "mson",
119
+ "cloth",
120
+ "nesota",
121
+ " Dise",
122
+ " Lyme",
123
+ " dementia",
124
+ "agn",
125
+ " reversible",
126
+ " susceptibility",
127
+ "esthesia",
128
+ "orf",
129
+ " inflamm",
130
+ " Obesity",
131
+ " tox",
132
+ " Disorders",
133
+ "uberty",
134
+ "blind",
135
+ "ALTH",
136
+ "avier",
137
+ " Immunity",
138
+ " Hurt",
139
+ "ulet",
140
+ "ueless",
141
+ " sluggish",
142
+ "rosis",
143
+ ],
144
+ explanation=" words related to physical medical conditions",
145
+ ),
146
+ Example(
147
+ tokens=[
148
+ " January",
149
+ "terday",
150
+ "cember",
151
+ " April",
152
+ " July",
153
+ "September",
154
+ "December",
155
+ "Thursday",
156
+ "quished",
157
+ "November",
158
+ "Tuesday",
159
+ "uesday",
160
+ " Sept",
161
+ "ruary",
162
+ " March",
163
+ ";;;;;;;;;;;;",
164
+ " Monday",
165
+ "Wednesday",
166
+ " Saturday",
167
+ " Wednesday",
168
+ "Reloaded",
169
+ "aturday",
170
+ " August",
171
+ "Feb",
172
+ "Sunday",
173
+ "Reviewed",
174
+ "uggest",
175
+ " Dhabi",
176
+ "ACTED",
177
+ "tten",
178
+ "Year",
179
+ "August",
180
+ "alogue",
181
+ "MX",
182
+ " Janeiro",
183
+ "yss",
184
+ " Leilan",
185
+ " Fiscal",
186
+ " referen",
187
+ "semb",
188
+ "eele",
189
+ "wcs",
190
+ "detail",
191
+ "ertation",
192
+ " Reborn",
193
+ " Sunday",
194
+ "itially",
195
+ "aturdays",
196
+ " Dise",
197
+ "essage",
198
+ ],
199
+ explanation=" nouns related to time and dates",
200
+ ),
201
+ ]
202
+
203
+ TEST_EXAMPLES = [
204
+ Example(
205
+ tokens=[
206
+ "these",
207
+ " are",
208
+ " tokens",
209
+ ],
210
+ explanation=" this is a test explanation",
211
+ ),
212
+ ]
@@ -0,0 +1,3 @@
1
+ from .fast_dataclasses import FastDataclass, dumps, loads, register_dataclass
2
+
3
+ __all__ = ["FastDataclass", "dumps", "loads", "register_dataclass"]