Skip to content

Commit b7d18f4

Browse files
authored
[Fix] Support PromptBench package for prompt attack (#2555)
* [Fix] Support PromptBench package for prompt attack * [Fix] Correct prompt attack log path
1 parent b8f40be commit b7d18f4

3 files changed

Lines changed: 23 additions & 24 deletions

File tree

docs/en/advanced_guides/prompt_attack.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@ We support prompt attack following the idea of [PromptBench](https://github.com/
77
Some components are necessary to prompt attack experiment, therefore we need to set up environments.
88

99
```shell
10-
git clone https://github.com/microsoft/promptbench.git
11-
pip install textattack==0.3.8
12-
export PYTHONPATH=$PYTHONPATH:promptbench/
10+
pip install promptbench==0.0.4 textattack==0.3.8 lru-dict
1311
```
1412

1513
## How to attack
@@ -87,7 +85,7 @@ attack = dict(
8785

8886
### Run the experiment
8987

90-
Please use `--mode infer` when run the attack experiment, and set `PYTHONPATH` env.
88+
Please use `--mode infer` when running the attack experiment.
9189

9290
```shell
9391
python run.py examples/eval_attack.py --mode infer

docs/zh_cn/advanced_guides/prompt_attack.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@ OpenCompass 支持[PromptBench](https://github.com/microsoft/promptbench)的提
77
提示词攻击需要依赖 `PromptBench` 中的组件,所以需要先配置好环境。
88

99
```shell
10-
git clone https://github.com/microsoft/promptbench.git
11-
pip install textattack==0.3.8
12-
export PYTHONPATH=$PYTHONPATH:promptbench/
10+
pip install promptbench==0.0.4 textattack==0.3.8 lru-dict
1311
```
1412

1513
## 如何攻击
@@ -87,7 +85,7 @@ attack = dict(
8785

8886
### 运行试验
8987

90-
请当运行攻击实验的时候请使用 `--mode infer` 选项,并需要指定`PYTHONPATH`
88+
请在运行攻击实验时使用 `--mode infer` 选项。
9189

9290
```shell
9391
python run.py examples/eval_attack.py --mode infer

opencompass/tasks/openicl_attack.py

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -125,26 +125,20 @@ def _inference(self):
125125
osp.join(self.work_dir, 'attack'))
126126
out_dir, out_file = osp.split(out_path)
127127
mkdir_or_exist(out_dir)
128+
attack_log_path = osp.join(out_dir, 'attacklog.txt')
128129

129-
from config import LABEL_SET
130-
from prompt_attack.attack import create_attack
131-
from prompt_attack.goal_function import PromptGoalFunction
130+
from promptbench.prompt_attack import LABEL_SET, Attack, attack_config
132131

133132
inferencer.retriever = retriever
134133
inferencer.prompt_template = prompt_template
135134
inferencer.ice_template = ice_template
136135
inferencer.output_json_filepath = out_dir
137136
inferencer.output_json_filename = out_file
138-
goal_function = PromptGoalFunction(
139-
inference=inferencer,
140-
query_budget=self.cfg['attack'].query_budget,
141-
logger=self.logger,
142-
model_wrapper=None,
143-
verbose='True')
144137
if self.cfg['attack']['dataset'] not in LABEL_SET:
145138
# set default
146139
self.cfg['attack']['dataset'] = 'mmlu'
147-
attack = create_attack(self.cfg['attack'], goal_function)
140+
attack_config['goal_function']['query_budget'] = self.cfg[
141+
'attack'].query_budget
148142

149143
prompts = self.infer_cfg['inferencer']['original_prompt_list']
150144
sorted_prompts = self.prompt_selection(inferencer, prompts)
@@ -153,23 +147,32 @@ def _inference(self):
153147
for prompt, acc in sorted_prompts:
154148
self.logger.info('Prompt: {}, acc: {:.2f}%\n'.format(
155149
prompt, acc * 100))
156-
with open(out_dir + 'attacklog.txt', 'a+') as f:
150+
with open(attack_log_path, 'a+') as f:
157151
f.write('Prompt: {}, acc: {:.2f}%\n'.format(
158152
prompt, acc * 100))
159153

160154
for init_prompt, init_acc in sorted_prompts[:self.cfg['attack'].
161155
prompt_topk]:
162156
if init_acc > 0:
163-
init_acc, attacked_prompt, attacked_acc, dropped_acc = attack.attack( # noqa
164-
init_prompt)
157+
attack = Attack(
158+
model=self.model,
159+
attack_name=self.cfg['attack'].attack,
160+
dataset=self.cfg['attack'].dataset,
161+
prompt=init_prompt,
162+
eval_func=lambda prompt, _, __: inferencer.predict(prompt),
163+
verbose=True)
164+
attack_result = attack.attack()
165+
attacked_prompt = attack_result['attacked prompt']
166+
attacked_acc = attack_result['attacked score']
167+
dropped_acc = init_acc - attacked_acc
165168
self.logger.info('Original prompt: {}'.format(init_prompt))
166169
self.logger.info('Attacked prompt: {}'.format(
167170
attacked_prompt.encode('utf-8')))
168171
self.logger.info(
169172
'Original acc: {:.2f}%, attacked acc: {:.2f}%, dropped acc: {:.2f}%' # noqa
170173
.format(init_acc * 100, attacked_acc * 100,
171174
dropped_acc * 100))
172-
with open(out_dir + 'attacklog.txt', 'a+') as f:
175+
with open(attack_log_path, 'a+') as f:
173176
f.write('Original prompt: {}\n'.format(init_prompt))
174177
f.write('Attacked prompt: {}\n'.format(
175178
attacked_prompt.encode('utf-8')))
@@ -178,7 +181,7 @@ def _inference(self):
178181
.format(init_acc * 100, attacked_acc * 100,
179182
dropped_acc * 100))
180183
else:
181-
with open(out_dir + 'attacklog.txt', 'a+') as f:
184+
with open(attack_log_path, 'a+') as f:
182185
f.write('Init acc is 0, skip this prompt\n')
183186
f.write('Original prompt: {}\n'.format(init_prompt))
184187
f.write('Original acc: {:.2f}% \n\n'.format(init_acc *
@@ -204,4 +207,4 @@ def parse_args():
204207
inferencer = OpenICLAttackTask(cfg)
205208
inferencer.run()
206209
end_time = time.time()
207-
get_logger().info(f'time elapsed: {end_time - start_time:.2f}s')
210+
get_logger().info('time elapsed: {:.2f}s'.format(end_time - start_time))

0 commit comments

Comments
 (0)