yoshinakachi commited on
Commit
30360e9
·
verified ·
1 Parent(s): 1128e63

Update src/App.js

Browse files
Files changed (1) hide show
  1. src/App.js +154 -157
src/App.js CHANGED
@@ -1,79 +1,112 @@
1
  import React, { useState, useEffect } from 'react';
2
 
3
  const BenchmarkChart = () => {
4
- // Real data from your CSV
5
  const benchmarkData = [
6
  {
7
- model: "Claude 4 Sonnet",
8
- direct_conversation: 26.33,
9
- keyword_objective_combined: 3.13
 
 
10
  },
11
  {
12
- model: "Claude Opus 4.1",
13
- direct_conversation: 20.67,
14
- keyword_objective_combined: 3.65
 
 
15
  },
16
  {
17
- model: "Deepseek R1-0528",
18
- direct_conversation: 68.67,
19
- keyword_objective_combined: 48.18
 
 
20
  },
21
  {
22
- model: "GPT 5",
23
- direct_conversation: 8.33,
24
- keyword_objective_combined: 3.65,
25
- bio_topic_change: 23.5,
26
- enhancement: 10,
27
- root_problem: 4.5
28
  },
29
  {
30
- model: "GPT 5 mini",
31
- direct_conversation: 7.67,
32
- keyword_objective_combined: 3.91,
33
- bio_topic_change: 14.5,
34
- enhancement: 5.5,
35
- root_problem: 3
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  },
37
  {
38
  model: "GPT o3",
39
- direct_conversation: 22,
40
- keyword_objective_combined: 10.94
 
 
41
  },
42
  {
43
- model: "Gemini 2.5 Pro",
44
- direct_conversation: 55.67,
45
- keyword_objective_combined: 41.67,
46
- bio_topic_change: 53.5,
47
- enhancement: 47,
48
- root_problem: 26
49
  },
50
  {
51
- model: "Grok 4",
52
- direct_conversation: 68.67,
53
- keyword_objective_combined: 52.6
 
 
54
  },
55
  {
56
- model: "Llama 3.1 405B",
57
- direct_conversation: 67,
58
- keyword_objective_combined: 41.67
 
 
 
 
 
 
 
 
 
 
 
59
  }
60
  ];
61
 
62
  const [currentPhase, setCurrentPhase] = useState('baseline');
63
  const [currentMethodIndex, setCurrentMethodIndex] = useState(0);
64
 
65
- const synthesisMethodsOrder = ['keyword_objective_combined', 'bio_topic_change', 'enhancement', 'root_problem'];
66
 
67
  const phases = [
68
- { key: 'baseline', label: 'Direct Conversation (Baseline)' },
69
- { key: 'additive_synthesis', label: 'Adding Synthesis Methods' }
70
  ];
71
 
72
  useEffect(() => {
73
  const interval = setInterval(() => {
74
  setCurrentPhase(prev => prev === 'baseline' ? 'additive_synthesis' : 'baseline');
75
- setCurrentMethodIndex(0); // Reset when switching phases
76
- }, 10000); // Reduced by 2 seconds: was 12000ms, now 10000ms
77
 
78
  return () => clearInterval(interval);
79
  }, []);
@@ -83,199 +116,163 @@ const BenchmarkChart = () => {
83
  const methodInterval = setInterval(() => {
84
  setCurrentMethodIndex(prev => {
85
  const nextIndex = prev + 1;
86
- // Stay at final state (all methods added) for longer
87
  if (nextIndex > synthesisMethodsOrder.length) {
88
- return synthesisMethodsOrder.length; // Stay at max for longer
89
  }
90
  return nextIndex;
91
  });
92
- }, 2500); // Increased to 2.5 seconds to allow animation to complete
93
  return () => clearInterval(methodInterval);
94
  }
95
  }, [currentPhase]);
96
 
97
  const getCurrentValue = (modelData, phase) => {
98
  if (phase === 'baseline') {
99
- return modelData.direct_conversation || 0;
100
  } else if (phase === 'additive_synthesis') {
101
- let cumulativeValue = modelData.direct_conversation || 0;
 
102
 
103
- // Add each synthesis method's contribution up to currentMethodIndex
104
  for (let i = 0; i < currentMethodIndex; i++) {
105
  const method = synthesisMethodsOrder[i];
106
- if (modelData[method] !== undefined) {
107
- cumulativeValue += modelData[method];
108
  }
109
  }
110
 
111
- return cumulativeValue;
112
  }
113
  return 0;
114
  };
115
 
116
- const getCurrentMethodsAdded = (modelData, phase) => {
117
- if (phase === 'baseline') return ['Direct Conversation'];
 
118
 
119
- const methods = ['Direct Conversation'];
120
  for (let i = 0; i < currentMethodIndex; i++) {
121
  const method = synthesisMethodsOrder[i];
122
- if (modelData[method] !== undefined) {
123
- methods.push(method.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase()));
124
  }
125
  }
126
- return methods;
 
 
127
  };
128
 
129
  const getBarColor = (modelData, phase) => {
130
  if (phase === 'baseline') {
131
  return 'from-blue-500 to-blue-600';
132
  } else if (phase === 'additive_synthesis' && currentMethodIndex > 0) {
133
- // Only turn green when we've actually started adding methods
134
  return 'from-green-500 to-green-600';
135
  } else {
136
- // Stay blue if we're in additive phase but haven't started adding yet
137
  return 'from-blue-500 to-blue-600';
138
  }
139
  };
140
 
141
  return (
142
- <div className="min-h-screen bg-gradient-to-br from-slate-900 to-slate-800 p-8">
143
  <div className="max-w-6xl mx-auto">
144
  {/* Header */}
145
- <div className="text-center mb-12">
146
- <h1 className="text-4xl font-bold text-white mb-4">
147
- LLM Safety Benchmark Results
148
  </h1>
149
- <p className="text-slate-300 text-lg">
150
- SafetyBench Aug 2025 - Success Rate Comparison
151
  </p>
152
 
153
- {/* Methodology Disclaimer */}
154
- <div className="mt-6 p-4 bg-yellow-900/30 border border-yellow-500/30 rounded-lg max-w-4xl mx-auto">
155
  <div className="flex items-start space-x-3">
 
156
  <div className="text-left">
157
  <p className="text-yellow-200 font-semibold mb-2">Methodology Note</p>
158
  <p className="text-yellow-100 text-sm leading-relaxed">
159
  <strong>Additive Visualization:</strong> This chart shows cumulative impact by progressively adding each synthesis method's individual attack success rate.
160
- Values >100% represent sythesis of multiple conversations off one failed, human seed conversation.
161
  Results are based on HarmBench Grading methodology and should be interpreted as relative performance indicators.
162
  </p>
163
  </div>
164
  </div>
165
  </div>
166
-
167
- <div className="mt-4 p-4 bg-slate-800 rounded-lg inline-block">
168
- <p className="text-white font-semibold">
169
- Current View: {phases.find(p => p.key === currentPhase)?.label}
170
- </p>
171
- {currentPhase === 'additive_synthesis' && currentMethodIndex > 0 && (
172
- <p className="text-slate-300 text-sm mt-1">
173
- Adding Method {currentMethodIndex}: {synthesisMethodsOrder[currentMethodIndex - 1]?.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase())}
174
- </p>
175
- )}
176
- </div>
177
  </div>
178
 
179
- {/* Chart Container */}
180
- <div className="bg-white rounded-2xl shadow-2xl p-8">
181
- <div className="space-y-8">
182
- {benchmarkData.map((modelData, index) => {
183
- const currentValue = getCurrentValue(modelData, currentPhase);
184
- const baselineValue = modelData.direct_conversation;
185
- const maxValue = 100; // Increased max scale since we're adding values
186
- const barWidth = (currentValue / maxValue) * 100;
187
- const methodsAdded = getCurrentMethodsAdded(modelData, currentPhase);
188
- const totalGain = currentValue - baselineValue;
189
-
190
- return (
191
- <div key={modelData.model} className="relative">
192
- {/* Model Name and Methods - Fixed Height Container */}
193
- <div className="flex items-start justify-between mb-3 min-h-[60px]">
194
- <div className="flex-1">
195
- <h3 className="font-semibold text-gray-800 text-lg mb-1">
196
- {modelData.model}
197
- </h3>
198
- <div className="text-sm text-gray-600 leading-tight">
199
- <span className="font-medium">Methods: </span>
200
- <span>{methodsAdded.join(' + ')}</span>
 
201
  </div>
202
- {/* Method breakdown - Always show, even during baseline */}
203
- <div className="mt-1 min-h-[20px]">
204
- {currentPhase === 'baseline' && (
205
- <div className="text-xs text-gray-500 flex flex-wrap gap-x-4 gap-y-1">
206
- <span className="text-blue-600">Base: {baselineValue.toFixed(1)}%</span>
207
- <span className="text-gray-400">Ready to add synthesis methods...</span>
208
- </div>
209
- )}
210
- {currentPhase === 'additive_synthesis' && (
211
- <div className="text-xs text-gray-500 flex flex-wrap gap-x-4 gap-y-1">
212
- <span className="text-blue-600">Base: {baselineValue.toFixed(1)}%</span>
213
- {currentMethodIndex === 0 && (
214
- <span className="text-gray-400">Starting to add methods...</span>
215
- )}
216
- {synthesisMethodsOrder.slice(0, currentMethodIndex).map(method => {
217
- if (modelData[method] !== undefined) {
218
- return (
219
- <span key={method} className="text-green-600">
220
- +{method.replace(/_/g, ' ')}: {modelData[method].toFixed(1)}%
221
- </span>
222
- );
223
- }
224
- return null;
225
- })}
226
  </div>
227
  )}
228
  </div>
229
  </div>
230
- <div className="text-right ml-4">
231
- <span className="text-2xl font-bold text-gray-700">
232
- {currentValue.toFixed(1)}%
233
- </span>
234
- {currentPhase === 'additive_synthesis' && totalGain > 0 && (
235
- <div className="text-sm font-semibold text-green-600">
236
- +{totalGain.toFixed(1)}% gain
 
 
237
  </div>
238
- )}
239
- </div>
240
- </div>
241
-
242
- {/* Progress Bar */}
243
- <div className="relative h-12 bg-gray-200 rounded-full overflow-hidden">
244
- <div
245
- className={`h-full bg-gradient-to-r ${getBarColor(modelData, currentPhase)} rounded-full transition-all duration-[2000ms] ease-out flex items-center justify-end pr-4`}
246
- style={{ width: `${Math.max(barWidth, 5)}%` }}
247
- >
248
- <div className="text-white font-semibold text-sm">
249
- {currentValue > 8 ? `${currentValue.toFixed(1)}%` : ''}
250
  </div>
251
  </div>
252
  </div>
253
- </div>
254
- );
255
- })}
256
  </div>
257
 
258
  {/* Legend */}
259
- <div className="mt-8 flex justify-center space-x-6 flex-wrap">
260
  <div className="flex items-center space-x-2">
261
- <div className="w-4 h-4 bg-gradient-to-r from-blue-500 to-blue-600 rounded"></div>
262
- <span className="text-gray-700">Baseline (Direct Conversation)</span>
263
  </div>
264
  <div className="flex items-center space-x-2">
265
- <div className="w-4 h-4 bg-gradient-to-r from-green-500 to-green-600 rounded"></div>
266
- <span className="text-gray-700">Adding Synthesis Methods</span>
267
  </div>
268
  </div>
269
  </div>
270
 
271
- {/* Footer Info */}
272
- <div className="mt-8 text-center text-slate-400 space-y-2">
273
  <p className="text-sm">
274
- Data from SafetyBench Aug 2025 Synthesis methods test different attack vectors
 
 
 
275
  </p>
276
- <div className="text-xs mt-4 max-w-4xl mx-auto space-y-1">
277
-
278
- </div>
279
  </div>
280
  </div>
281
  </div>
 
1
  import React, { useState, useEffect } from 'react';
2
 
3
  const BenchmarkChart = () => {
4
+ // Real data from your ASR calculations - sorted by highest achievable ASR
5
  const benchmarkData = [
6
  {
7
+ model: "Grok 4",
8
+ baseline: 68.67,
9
+ methods: {
10
+ keyword_objective_combined: 85.15
11
+ }
12
  },
13
  {
14
+ model: "Deepseek R1-0528",
15
+ baseline: 68.67,
16
+ methods: {
17
+ keyword_objective_combined: 83.76
18
+ }
19
  },
20
  {
21
+ model: "Llama 3.1 405B",
22
+ baseline: 67.00,
23
+ methods: {
24
+ keyword_objective_combined: 80.75
25
+ }
26
  },
27
  {
28
+ model: "Gemini 2.5 Pro",
29
+ baseline: 55.67,
30
+ methods: {
31
+ keyword_objective_combined: 74.14,
32
+ root_problem: 67.19
33
+ }
34
  },
35
  {
36
+ model: "Llama 3 8B Instruct Reference",
37
+ baseline: 58.33,
38
+ methods: {
39
+ keyword_objective_combined: 68.86
40
+ }
41
+ },
42
+ {
43
+ model: "Mixtral 8x22B",
44
+ baseline: 48.00,
45
+ methods: {
46
+ keyword_objective_combined: 66.82
47
+ }
48
+ },
49
+ {
50
+ model: "Llama 4 Maverick Instruct",
51
+ baseline: 45.00,
52
+ methods: {
53
+ keyword_objective_combined: 56.46
54
+ }
55
  },
56
  {
57
  model: "GPT o3",
58
+ baseline: 22.00,
59
+ methods: {
60
+ keyword_objective_combined: 30.53
61
+ }
62
  },
63
  {
64
+ model: "Claude 4 Sonnet",
65
+ baseline: 26.33,
66
+ methods: {
67
+ keyword_objective_combined: 28.64
68
+ }
 
69
  },
70
  {
71
+ model: "Claude Opus 4.1",
72
+ baseline: 20.67,
73
+ methods: {
74
+ keyword_objective_combined: 23.56
75
+ }
76
  },
77
  {
78
+ model: "GPT 5",
79
+ baseline: 8.33,
80
+ methods: {
81
+ keyword_objective_combined: 11.68,
82
+ root_problem: 12.46
83
+ }
84
+ },
85
+ {
86
+ model: "GPT 5 mini",
87
+ baseline: 7.67,
88
+ methods: {
89
+ keyword_objective_combined: 11.28,
90
+ root_problem: 10.44
91
+ }
92
  }
93
  ];
94
 
95
  const [currentPhase, setCurrentPhase] = useState('baseline');
96
  const [currentMethodIndex, setCurrentMethodIndex] = useState(0);
97
 
98
+ const synthesisMethodsOrder = ['keyword_objective_combined', 'root_problem'];
99
 
100
  const phases = [
101
+ { key: 'baseline', label: 'Human Baseline ASR' },
102
+ { key: 'additive_synthesis', label: 'Human + Synthesis Methods ASR' }
103
  ];
104
 
105
  useEffect(() => {
106
  const interval = setInterval(() => {
107
  setCurrentPhase(prev => prev === 'baseline' ? 'additive_synthesis' : 'baseline');
108
+ setCurrentMethodIndex(0);
109
+ }, 8000);
110
 
111
  return () => clearInterval(interval);
112
  }, []);
 
116
  const methodInterval = setInterval(() => {
117
  setCurrentMethodIndex(prev => {
118
  const nextIndex = prev + 1;
 
119
  if (nextIndex > synthesisMethodsOrder.length) {
120
+ return synthesisMethodsOrder.length;
121
  }
122
  return nextIndex;
123
  });
124
+ }, 2000);
125
  return () => clearInterval(methodInterval);
126
  }
127
  }, [currentPhase]);
128
 
129
  const getCurrentValue = (modelData, phase) => {
130
  if (phase === 'baseline') {
131
+ return modelData.baseline;
132
  } else if (phase === 'additive_synthesis') {
133
+ // Show the highest ASR achieved by any method tried so far
134
+ let maxASR = modelData.baseline;
135
 
 
136
  for (let i = 0; i < currentMethodIndex; i++) {
137
  const method = synthesisMethodsOrder[i];
138
+ if (modelData.methods[method] !== undefined) {
139
+ maxASR = Math.max(maxASR, modelData.methods[method]);
140
  }
141
  }
142
 
143
+ return maxASR;
144
  }
145
  return 0;
146
  };
147
 
148
+ const getCurrentMethod = (modelData, phase) => {
149
+ if (phase === 'baseline') return 'Human Baseline';
150
+ if (currentMethodIndex === 0) return 'Human Baseline';
151
 
152
+ const availableMethods = [];
153
  for (let i = 0; i < currentMethodIndex; i++) {
154
  const method = synthesisMethodsOrder[i];
155
+ if (modelData.methods[method] !== undefined) {
156
+ availableMethods.push(method);
157
  }
158
  }
159
+
160
+ if (availableMethods.length === 0) return 'Human Baseline';
161
+ return availableMethods[availableMethods.length - 1].replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
162
  };
163
 
164
  const getBarColor = (modelData, phase) => {
165
  if (phase === 'baseline') {
166
  return 'from-blue-500 to-blue-600';
167
  } else if (phase === 'additive_synthesis' && currentMethodIndex > 0) {
 
168
  return 'from-green-500 to-green-600';
169
  } else {
 
170
  return 'from-blue-500 to-blue-600';
171
  }
172
  };
173
 
174
  return (
175
+ <div className="min-h-screen bg-gradient-to-br from-slate-900 to-slate-800 p-4">
176
  <div className="max-w-6xl mx-auto">
177
  {/* Header */}
178
+ <div className="text-center mb-6">
179
+ <h1 className="text-3xl font-bold text-white mb-3">
180
+ LLM Attack Success Rate with Synthesis Methods
181
  </h1>
182
+ <p className="text-slate-300">
183
+ SafetyBench Aug 2025 - Real ASR Calculations
184
  </p>
185
 
186
+ {/* Methodology Note */}
187
+ <div className="mt-4 p-3 bg-yellow-900/30 border border-yellow-500/30 rounded-lg max-w-4xl mx-auto">
188
  <div className="flex items-start space-x-3">
189
+ <div className="text-yellow-400 mt-1">⚠️</div>
190
  <div className="text-left">
191
  <p className="text-yellow-200 font-semibold mb-2">Methodology Note</p>
192
  <p className="text-yellow-100 text-sm leading-relaxed">
193
  <strong>Additive Visualization:</strong> This chart shows cumulative impact by progressively adding each synthesis method's individual attack success rate.
194
+ Values >100% represent synthesis of multiple conversations off one failed, human seed conversation.
195
  Results are based on HarmBench Grading methodology and should be interpreted as relative performance indicators.
196
  </p>
197
  </div>
198
  </div>
199
  </div>
 
 
 
 
 
 
 
 
 
 
 
200
  </div>
201
 
202
+ {/* Chart Container - Scrollable Box */}
203
+ <div className="bg-white rounded-xl shadow-2xl p-4">
204
+ <div className="h-96 overflow-y-auto pr-2">
205
+ <div className="space-y-2">
206
+ {benchmarkData.map((modelData, index) => {
207
+ const currentValue = getCurrentValue(modelData, currentPhase);
208
+ const baselineValue = modelData.baseline;
209
+ const maxValue = 90;
210
+ const barWidth = (currentValue / maxValue) * 100;
211
+ const currentMethod = getCurrentMethod(modelData, currentPhase);
212
+ const gain = currentValue - baselineValue;
213
+
214
+ return (
215
+ <div key={modelData.model} className="relative">
216
+ {/* Model Name and Value */}
217
+ <div className="flex items-center justify-between mb-1">
218
+ <div>
219
+ <h3 className="font-semibold text-gray-800 text-sm">
220
+ {modelData.model}
221
+ </h3>
222
+ <p className="text-xs text-gray-600">
223
+ {currentMethod}
224
+ </p>
225
  </div>
226
+ <div className="text-right">
227
+ <span className="text-lg font-bold text-gray-700">
228
+ {currentValue.toFixed(1)}%
229
+ </span>
230
+ {gain > 0 && (
231
+ <div className="text-xs font-semibold text-green-600">
232
+ +{gain.toFixed(1)} points
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233
  </div>
234
  )}
235
  </div>
236
  </div>
237
+
238
+ {/* Progress Bar */}
239
+ <div className="relative h-6 bg-gray-200 rounded-full overflow-hidden">
240
+ <div
241
+ className={`h-full bg-gradient-to-r ${getBarColor(modelData, currentPhase)} rounded-full transition-all duration-2000 ease-out flex items-center justify-end pr-2`}
242
+ style={{ width: `${Math.max(barWidth, 5)}%` }}
243
+ >
244
+ <div className="text-white font-semibold text-xs">
245
+ {currentValue > 8 ? `${currentValue.toFixed(1)}%` : ''}
246
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
247
  </div>
248
  </div>
249
  </div>
250
+ );
251
+ })}
252
+ </div>
253
  </div>
254
 
255
  {/* Legend */}
256
+ <div className="mt-4 pt-4 border-t border-gray-200 flex justify-center space-x-6 text-sm">
257
  <div className="flex items-center space-x-2">
258
+ <div className="w-3 h-3 bg-gradient-to-r from-blue-500 to-blue-600 rounded"></div>
259
+ <span className="text-gray-700">Human Baseline</span>
260
  </div>
261
  <div className="flex items-center space-x-2">
262
+ <div className="w-3 h-3 bg-gradient-to-r from-green-500 to-green-600 rounded"></div>
263
+ <span className="text-gray-700">With Synthesis Methods</span>
264
  </div>
265
  </div>
266
  </div>
267
 
268
+ {/* Footer */}
269
+ <div className="mt-4 text-center text-slate-400 space-y-1">
270
  <p className="text-sm">
271
+ Top performers: Grok 4 (85.15%), Deepseek R1-0528 (83.76%), Llama 3.1 405B (80.75%)
272
+ </p>
273
+ <p className="text-xs">
274
+ Shows highest ASR achieved when combining human attempts with synthesis methods
275
  </p>
 
 
 
276
  </div>
277
  </div>
278
  </div>