|
7 | 7 | "source": [ |
8 | 8 | "# Benchmark Scenarios\n", |
9 | 9 | "\n", |
10 | | - "Benchmark scenarios are a subset of scenarios that compare the effectiveness of attacks across an axis that varies within the scenario itself. The axis can be many things; currently, the only benchmark variant is the adversarial benchmark, whose axis of change is the adversarial model used in attacks." |
| 10 | + "Benchmark scenarios compare attack effectiveness across an axis that varies within the scenario\n", |
| 11 | + "itself. Currently the only benchmark variant is the adversarial benchmark, whose axis of change is\n", |
| 12 | + "the **adversarial chat helper model** used in attacks. For full configuration options see\n", |
| 13 | + "`pyrit_scan --help` and the [Scenarios Programming Guide](../code/scenarios/0_scenarios.ipynb)." |
11 | 14 | ] |
12 | 15 | }, |
13 | 16 | { |
|
16 | 19 | "metadata": {}, |
17 | 20 | "source": [ |
18 | 21 | "## Adversarial Benchmark\n", |
19 | | - "The adversarial benchmarking scenario (`AdversarialBenchmark`) compares the effectiveness of different adversarial models in successfully executing attacks against a target model." |
| 22 | + "\n", |
| 23 | + "`AdversarialBenchmark` holds the objective target and dataset constant and varies the adversarial\n", |
| 24 | + "chat model used to drive multi-turn attacks. Useful for evaluating which adversarial helper\n", |
| 25 | + "models produce stronger or weaker attack success rates against the same target.\n", |
| 26 | + "\n", |
| 27 | + "Adversarial targets are user-provided via the `adversarial_targets` scenario parameter. Each name\n", |
| 28 | + "must already be registered in `TargetRegistry` — typically by `TargetInitializer` from the\n", |
| 29 | + "`ADVERSARIAL_CHAT_*` env vars (see `.env_example`). Use `pyrit_scan --list-targets` to see every\n", |
| 30 | + "target currently registered.\n", |
| 31 | + "\n", |
| 32 | + "```bash\n", |
| 33 | + "pyrit_scan benchmark.adversarial \\\n", |
| 34 | + " --initializers target load_default_datasets \\\n", |
| 35 | + " --target openai_chat \\\n", |
| 36 | + " --adversarial-targets adversarial_chat_singleturn adversarial_chat_multiturn \\\n", |
| 37 | + " --max-dataset-size 4\n", |
| 38 | + "```\n", |
| 39 | + "\n", |
| 40 | + "Pass multiple `--adversarial-targets` values to compare across models in a single run.\n", |
| 41 | + "\n", |
| 42 | + "**Available strategies:** `light` (default — a quick snapshot using the cheaper techniques),\n", |
| 43 | + "`single_turn`, `multi_turn`, plus one member per adversarial-capable source technique\n", |
| 44 | + "(e.g. `red_teaming`, `tap`, `crescendo_simulated`). The `light` aggregate excludes `tap` and\n", |
| 45 | + "`crescendo_simulated`, which can take hours." |
| 46 | + ] |
| 47 | + }, |
| 48 | + { |
| 49 | + "cell_type": "markdown", |
| 50 | + "id": "2", |
| 51 | + "metadata": {}, |
| 52 | + "source": [ |
| 53 | + "## Setup" |
20 | 54 | ] |
21 | 55 | }, |
22 | 56 | { |
23 | 57 | "cell_type": "code", |
24 | 58 | "execution_count": null, |
25 | | - "id": "2", |
| 59 | + "id": "3", |
26 | 60 | "metadata": {}, |
27 | | - "outputs": [ |
28 | | - { |
29 | | - "name": "stdout", |
30 | | - "output_type": "stream", |
31 | | - "text": [ |
32 | | - "Found default environment files: ['./.pyrit/.env', './.pyrit/.env.local']\n", |
33 | | - "Loaded environment file: ./.pyrit/.env\n", |
34 | | - "Loaded environment file: ./.pyrit/.env.local\n" |
35 | | - ] |
36 | | - }, |
37 | | - { |
38 | | - "data": { |
39 | | - "application/vnd.jupyter.widget-view+json": { |
40 | | - "model_id": "8316db039ba1408499df0a2de6c8d6f6", |
41 | | - "version_major": 2, |
42 | | - "version_minor": 0 |
43 | | - }, |
44 | | - "text/plain": [ |
45 | | - "Executing AdversarialBenchmark: 0%| | 0/3 [00:00<?, ?attack/s]" |
46 | | - ] |
47 | | - }, |
48 | | - "metadata": {}, |
49 | | - "output_type": "display_data" |
50 | | - }, |
51 | | - { |
52 | | - "name": "stdout", |
53 | | - "output_type": "stream", |
54 | | - "text": [ |
55 | | - "Scenario result id: e01b35d2-c7f8-49bd-aafd-5d44ef7235f4\n", |
56 | | - "\n", |
57 | | - "\u001b[36m====================================================================================================\u001b[0m\n", |
58 | | - "\u001b[1m\u001b[36m 📊 SCENARIO RESULTS: AdversarialBenchmark \u001b[0m\n", |
59 | | - "\u001b[36m====================================================================================================\u001b[0m\n", |
60 | | - "\n", |
61 | | - "\u001b[1m\u001b[36m▼ Scenario Information\u001b[0m\n", |
62 | | - "\u001b[36m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n", |
63 | | - "\u001b[1m 📋 Scenario Details\u001b[0m\n", |
64 | | - "\u001b[36m • Name: AdversarialBenchmark\u001b[0m\n", |
65 | | - "\u001b[36m • Scenario Version: 1\u001b[0m\n", |
66 | | - "\u001b[36m • PyRIT Version: 0.14.0.dev0\u001b[0m\n", |
67 | | - "\u001b[36m • Description:\u001b[0m\n", |
68 | | - "\u001b[36m Benchmarking scenario that compares the attack success rate (ASR) of several different adversarial models.\u001b[0m\n", |
69 | | - "\n", |
70 | | - "\u001b[1m 🎯 Target Information\u001b[0m\n", |
71 | | - "\u001b[36m • Target Type: OpenAIChatTarget\u001b[0m\n", |
72 | | - "\u001b[36m • Target Model: gpt-4o-japan-nilfilter\u001b[0m\n", |
73 | | - "\u001b[36m • Target Endpoint: https://pyrit-japan-test.openai.azure.com/openai/v1\u001b[0m\n", |
74 | | - "\n", |
75 | | - "\u001b[1m 📊 Scorer Information\u001b[0m\n", |
76 | | - "\u001b[37m ▸ Scorer Identifier\u001b[0m\n", |
77 | | - "\u001b[36m • Scorer Type: TrueFalseInverterScorer\u001b[0m\n", |
78 | | - "\u001b[36m • scorer_type: true_false\u001b[0m\n", |
79 | | - "\u001b[36m • score_aggregator: OR_\u001b[0m\n", |
80 | | - "\u001b[36m └─ Composite of 1 scorer(s):\u001b[0m\n", |
81 | | - "\u001b[36m • Scorer Type: SelfAskRefusalScorer\u001b[0m\n", |
82 | | - "\u001b[36m • scorer_type: true_false\u001b[0m\n", |
83 | | - "\u001b[36m • score_aggregator: OR_\u001b[0m\n", |
84 | | - "\u001b[36m • model_name: gpt-4o-japan-nilfilter\u001b[0m\n", |
85 | | - "\n", |
86 | | - "\u001b[37m ▸ Performance Metrics\u001b[0m\n", |
87 | | - "\u001b[33m Official evaluation has not been run yet for this specific configuration\u001b[0m\n", |
88 | | - "\n", |
89 | | - "\u001b[1m\u001b[36m▼ Overall Statistics\u001b[0m\n", |
90 | | - "\u001b[36m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n", |
91 | | - "\u001b[1m 📈 Summary\u001b[0m\n", |
92 | | - "\u001b[32m • Total Strategies: 3\u001b[0m\n", |
93 | | - "\u001b[32m • Total Attack Results: 24\u001b[0m\n", |
94 | | - "\u001b[36m • Overall Success Rate: 25%\u001b[0m\n", |
95 | | - "\u001b[32m • Unique Objectives: 8\u001b[0m\n", |
96 | | - "\n", |
97 | | - "\u001b[1m\u001b[36m▼ Per-Group Breakdown\u001b[0m\n", |
98 | | - "\u001b[36m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n", |
99 | | - "\n", |
100 | | - "\u001b[1m 🔸 Group: gpt-4o-japan-nilfilter\u001b[0m\n", |
101 | | - "\u001b[33m • Number of Results: 24\u001b[0m\n", |
102 | | - "\u001b[36m • Success Rate: 25%\u001b[0m\n", |
103 | | - "\n", |
104 | | - "\u001b[36m====================================================================================================\u001b[0m\n", |
105 | | - "\n" |
106 | | - ] |
107 | | - } |
108 | | - ], |
| 61 | + "outputs": [], |
109 | 62 | "source": [ |
110 | 63 | "from pyrit.output import output_scenario_async\n", |
111 | 64 | "from pyrit.prompt_target import OpenAIChatTarget\n", |
| 65 | + "from pyrit.scenario import DatasetConfiguration\n", |
112 | 66 | "from pyrit.scenario.scenarios.benchmark import AdversarialBenchmark\n", |
113 | 67 | "from pyrit.setup import IN_MEMORY, initialize_pyrit_async\n", |
114 | | - "from pyrit.setup.initializers import LoadDefaultDatasets\n", |
| 68 | + "from pyrit.setup.initializers import LoadDefaultDatasets, ScorerInitializer, TargetInitializer\n", |
115 | 69 | "\n", |
116 | | - "await initialize_pyrit_async(memory_db_type=IN_MEMORY, initializers=[LoadDefaultDatasets()]) # type: ignore\n", |
117 | | - "\n", |
118 | | - "# Pass any number of adversarial PromptTarget instances (with chat-target\n", |
119 | | - "# capabilities \u2014 multi-turn and editable history) as a list; AdversarialBenchmark\n", |
120 | | - "# infers a label for each from its identifier and runs every benchmark-friendly\n", |
121 | | - "# attack technique against the objective target with each adversarial model.\n", |
122 | | - "adversarial_model = OpenAIChatTarget()\n", |
123 | | - "\n", |
124 | | - "benchmark_scenario = AdversarialBenchmark(adversarial_models=[adversarial_model])\n", |
125 | | - "\n", |
126 | | - "await benchmark_scenario.initialize_async( # type: ignore\n", |
127 | | - " objective_target=OpenAIChatTarget(), max_concurrency=2\n", |
| 70 | + "await initialize_pyrit_async( # type: ignore\n", |
| 71 | + " memory_db_type=IN_MEMORY,\n", |
| 72 | + " initializers=[TargetInitializer(), ScorerInitializer(), LoadDefaultDatasets()],\n", |
128 | 73 | ")\n", |
129 | 74 | "\n", |
130 | | - "baseline_result = await benchmark_scenario.run_async() # type: ignore\n", |
131 | | - "\n", |
132 | | - "# Resume handle: re-run with `AdversarialBenchmark(..., scenario_result_id=<this id>)` to pick\n", |
133 | | - "# up where this run left off (constructor args must match the original run).\n", |
134 | | - "print(f\"Scenario result id: {baseline_result.id}\")\n", |
| 75 | + "objective_target = OpenAIChatTarget()" |
| 76 | + ] |
| 77 | + }, |
| 78 | + { |
| 79 | + "cell_type": "code", |
| 80 | + "execution_count": null, |
| 81 | + "id": "4", |
| 82 | + "metadata": {}, |
| 83 | + "outputs": [], |
| 84 | + "source": [ |
| 85 | + "dataset_config = DatasetConfiguration(dataset_names=[\"harmbench\"], max_dataset_size=4)\n", |
135 | 86 | "\n", |
| 87 | + "scenario = AdversarialBenchmark()\n", |
| 88 | + "scenario.set_params_from_args(\n", |
| 89 | + " args={\"adversarial_targets\": [\"adversarial_chat_singleturn\", \"adversarial_chat_multiturn\"]}\n", |
| 90 | + ")\n", |
| 91 | + "await scenario.initialize_async( # type: ignore\n", |
| 92 | + " objective_target=objective_target,\n", |
| 93 | + " dataset_config=dataset_config,\n", |
| 94 | + ")\n", |
136 | 95 | "\n", |
137 | | - "await output_scenario_async(baseline_result)" |
| 96 | + "scenario_result = await scenario.run_async() # type: ignore" |
| 97 | + ] |
| 98 | + }, |
| 99 | + { |
| 100 | + "cell_type": "code", |
| 101 | + "execution_count": null, |
| 102 | + "id": "5", |
| 103 | + "metadata": {}, |
| 104 | + "outputs": [], |
| 105 | + "source": [ |
| 106 | + "await output_scenario_async(scenario_result)" |
138 | 107 | ] |
139 | 108 | } |
140 | 109 | ], |
141 | 110 | "metadata": { |
142 | 111 | "jupytext": { |
143 | 112 | "main_language": "python" |
144 | | - }, |
145 | | - "language_info": { |
146 | | - "codemirror_mode": { |
147 | | - "name": "ipython", |
148 | | - "version": 3 |
149 | | - }, |
150 | | - "file_extension": ".py", |
151 | | - "mimetype": "text/x-python", |
152 | | - "name": "python", |
153 | | - "nbconvert_exporter": "python", |
154 | | - "pygments_lexer": "ipython3", |
155 | | - "version": "3.13.13" |
156 | 113 | } |
157 | 114 | }, |
158 | 115 | "nbformat": 4, |
|
0 commit comments