p7inc3 commited on
Commit
d317648
·
verified ·
1 Parent(s): 16add4f

Upload 9 files

Browse files
config.json ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "attention_probs_dropout_prob": 0.1,
3
+ "bos_token_id": null,
4
+ "eos_token_id": null,
5
+ "hidden_act": "gelu",
6
+ "hidden_dropout_prob": 0.1,
7
+ "hidden_size": 768,
8
+ "initializer_range": 0.02,
9
+ "intermediate_size": 3072,
10
+ "layer_norm_eps": 1e-07,
11
+ "legacy": true,
12
+ "max_position_embeddings": 512,
13
+ "max_relative_positions": -1,
14
+ "model_type": "deberta-v2",
15
+ "norm_rel_ebd": "layer_norm",
16
+ "num_attention_heads": 12,
17
+ "num_hidden_layers": 6,
18
+ "pad_token_id": 0,
19
+ "pooler_dropout": 0.0,
20
+ "pooler_hidden_act": "gelu",
21
+ "pooler_hidden_size": 768,
22
+ "pos_att_type": [
23
+ "p2c",
24
+ "c2p"
25
+ ],
26
+ "position_biased_input": false,
27
+ "position_buckets": 256,
28
+ "relative_attention": true,
29
+ "share_att_key": true,
30
+ "tie_word_embeddings": true,
31
+ "transformers_version": "5.8.1",
32
+ "type_vocab_size": 0,
33
+ "vocab_size": 128100
34
+ }
family_encoder.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:45f0ae7f709029f857550b7955aaf092392fb19426131d0705c63b4fcc0cb6a9
3
+ size 564
fine_encoder.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:025bf42a8d9aa15d15250157c2e90e8709f1bfd676a5db40e3c5c9c1f54833cd
3
+ size 706
handler.py ADDED
@@ -0,0 +1,333 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import torch
3
+ import torch.nn as nn
4
+ import torch.nn.functional as F
5
+ import joblib
6
+
7
+ from transformers import AutoTokenizer, AutoModel
8
+ from typing import Dict, List, Any
9
+
10
+
11
+ # =========================================================
12
+ # 1. Multi-Task Architecture
13
+ # =========================================================
14
+ class MultiTaskModel(nn.Module):
15
+
16
+ def __init__(self, model_name, num_fine, num_family):
17
+ super().__init__()
18
+
19
+ # Base Encoder
20
+ self.encoder = AutoModel.from_pretrained(model_name)
21
+
22
+ hidden = self.encoder.config.hidden_size
23
+
24
+ self.dropout = nn.Dropout(0.2)
25
+
26
+ # Binary Classification Head
27
+ self.binary_head = nn.Linear(hidden, 1)
28
+
29
+ # Fine-Grained Attack Type Head
30
+ self.multi_head = nn.Linear(hidden, num_fine)
31
+
32
+ # Attack Family Head
33
+ self.family_head = nn.Linear(hidden, num_family)
34
+
35
+ # =====================================================
36
+ # Mean Pooling
37
+ # =====================================================
38
+ def mean_pooling(self, hidden, attention_mask):
39
+
40
+ mask = attention_mask.unsqueeze(-1).float()
41
+
42
+ pooled = (
43
+ (hidden * mask).sum(1)
44
+ /
45
+ mask.sum(1).clamp(min=1e-9)
46
+ )
47
+
48
+ return pooled
49
+
50
+ # =====================================================
51
+ # Forward Pass
52
+ # =====================================================
53
+ def forward(self, input_ids, attention_mask):
54
+
55
+ outputs = self.encoder(
56
+ input_ids=input_ids,
57
+ attention_mask=attention_mask
58
+ )
59
+
60
+ pooled = self.mean_pooling(
61
+ outputs.last_hidden_state,
62
+ attention_mask
63
+ )
64
+
65
+ x = self.dropout(pooled)
66
+
67
+ binary_logits = self.binary_head(x)
68
+ multi_logits = self.multi_head(x)
69
+ family_logits = self.family_head(x)
70
+
71
+ return (
72
+ binary_logits,
73
+ multi_logits,
74
+ family_logits
75
+ )
76
+
77
+
78
+ # =========================================================
79
+ # 2. Hugging Face Endpoint Handler
80
+ # =========================================================
81
+ class EndpointHandler:
82
+
83
+ def __init__(self, path=""):
84
+
85
+ # =================================================
86
+ # Device
87
+ # =================================================
88
+ self.device = torch.device(
89
+ "cuda" if torch.cuda.is_available() else "cpu"
90
+ )
91
+
92
+ print(f"[INFO] Using device: {self.device}")
93
+
94
+ # =================================================
95
+ # Load Label Encoders
96
+ # =================================================
97
+ self.fine_le = joblib.load(
98
+ os.path.join(path, "fine_encoder.pkl")
99
+ )
100
+
101
+ self.family_le = joblib.load(
102
+ os.path.join(path, "family_encoder.pkl")
103
+ )
104
+
105
+ # =================================================
106
+ # Load Tokenizer
107
+ # =================================================
108
+ self.tokenizer = AutoTokenizer.from_pretrained(path)
109
+
110
+ # =================================================
111
+ # Initialize Model
112
+ # =================================================
113
+ self.model = MultiTaskModel(
114
+ model_name="microsoft/deberta-v3-small",
115
+ num_fine=len(self.fine_le.classes_),
116
+ num_family=len(self.family_le.classes_)
117
+ ).to(self.device)
118
+
119
+ # =================================================
120
+ # Load Weights
121
+ # =================================================
122
+ checkpoint_path = os.path.join(
123
+ path,
124
+ "multitask_model_FINAL.pt"
125
+ )
126
+
127
+ checkpoint = torch.load(
128
+ checkpoint_path,
129
+ map_location=self.device
130
+ )
131
+
132
+ state_dict = (
133
+ checkpoint["model_state"]
134
+ if "model_state" in checkpoint
135
+ else checkpoint
136
+ )
137
+
138
+ self.model.load_state_dict(state_dict)
139
+
140
+ self.model.eval()
141
+
142
+ print("[INFO] RedLockX loaded successfully")
143
+
144
+ # =================================================
145
+ # Detection Threshold
146
+ # =================================================
147
+ self.threshold = 0.75
148
+
149
+ # =====================================================
150
+ # Predict Single Input
151
+ # =====================================================
152
+ def predict_single(self, text: str):
153
+
154
+ # ================================================
155
+ # Tokenize
156
+ # ================================================
157
+ tokenized = self.tokenizer(
158
+ text,
159
+ return_tensors="pt",
160
+ truncation=True,
161
+ padding=True,
162
+ max_length=512
163
+ )
164
+
165
+ tokenized = {
166
+ k: v.to(self.device)
167
+ for k, v in tokenized.items()
168
+ }
169
+
170
+ # ================================================
171
+ # Inference
172
+ # ================================================
173
+ with torch.no_grad():
174
+
175
+ (
176
+ binary_logits,
177
+ multi_logits,
178
+ family_logits
179
+ ) = self.model(
180
+ tokenized["input_ids"],
181
+ tokenized["attention_mask"]
182
+ )
183
+
184
+ # ============================================
185
+ # Binary Probability
186
+ # ============================================
187
+ danger_prob = torch.sigmoid(
188
+ binary_logits
189
+ ).item()
190
+
191
+ is_dangerous = danger_prob > self.threshold
192
+
193
+ # ============================================
194
+ # Multi-Class Probabilities
195
+ # ============================================
196
+ multi_probs = F.softmax(
197
+ multi_logits,
198
+ dim=1
199
+ )
200
+
201
+ family_probs = F.softmax(
202
+ family_logits,
203
+ dim=1
204
+ )
205
+
206
+ fine_idx = torch.argmax(
207
+ multi_probs,
208
+ dim=1
209
+ ).item()
210
+
211
+ family_idx = torch.argmax(
212
+ family_probs,
213
+ dim=1
214
+ ).item()
215
+
216
+ fine_score = multi_probs[0][fine_idx].item()
217
+
218
+ family_score = family_probs[0][family_idx].item()
219
+
220
+ # ============================================
221
+ # SAFE Handling
222
+ # ============================================
223
+ if is_dangerous:
224
+
225
+ attack_type = self.fine_le.inverse_transform(
226
+ [fine_idx]
227
+ )[0]
228
+
229
+ attack_family = self.family_le.inverse_transform(
230
+ [family_idx]
231
+ )[0]
232
+
233
+ else:
234
+
235
+ attack_type = "none"
236
+ attack_family = "none"
237
+
238
+ fine_score = 0.0
239
+ family_score = 0.0
240
+
241
+ # ================================================
242
+ # Basic Explainability
243
+ # ================================================
244
+ suspicious_keywords = [
245
+ "ignore",
246
+ "override",
247
+ "reveal",
248
+ "system prompt",
249
+ "developer mode",
250
+ "bypass",
251
+ "disable",
252
+ "forget instructions",
253
+ "pretend",
254
+ "simulate",
255
+ "jailbreak"
256
+ ]
257
+
258
+ found_keywords = []
259
+
260
+ text_lower = text.lower()
261
+
262
+ for keyword in suspicious_keywords:
263
+
264
+ if keyword in text_lower:
265
+ found_keywords.append(keyword)
266
+
267
+ # ================================================
268
+ # Final Response
269
+ # ================================================
270
+ return {
271
+
272
+ "status": (
273
+ "DANGEROUS"
274
+ if is_dangerous
275
+ else "SAFE"
276
+ ),
277
+
278
+ "confidence": round(
279
+ danger_prob
280
+ if is_dangerous
281
+ else 1 - danger_prob,
282
+ 4
283
+ ),
284
+
285
+ "attack_type": {
286
+ "label": attack_type,
287
+ "score": round(fine_score, 4)
288
+ },
289
+
290
+ "attack_family": {
291
+ "label": attack_family,
292
+ "score": round(family_score, 4)
293
+ },
294
+
295
+ "trigger_words": found_keywords
296
+ }
297
+
298
+ # =====================================================
299
+ # Main Endpoint Entry
300
+ # =====================================================
301
+ def __call__(
302
+ self,
303
+ data: Dict[str, Any]
304
+ ) -> List[Dict[str, Any]]:
305
+
306
+ # ================================================
307
+ # Extract Inputs
308
+ # ================================================
309
+ inputs = (
310
+ data["inputs"]
311
+ if isinstance(data, dict)
312
+ else data
313
+ )
314
+
315
+ # ================================================
316
+ # Single Input → Convert to List
317
+ # ================================================
318
+ if isinstance(inputs, str):
319
+ inputs = [inputs]
320
+
321
+ # ================================================
322
+ # Batch Inference
323
+ # ================================================
324
+ results = []
325
+
326
+ for text in inputs:
327
+
328
+ result = self.predict_single(text)
329
+
330
+ results.append(result)
331
+
332
+ return results
333
+
multitask_model_FINAL.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7fa886a0b5a8d9e062d6a6a49b78e4250b33548c97f74c4536901cb4fcbc7ac9
3
+ size 565316387
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ torch
2
+ transformers
3
+ sentencepiece
4
+ joblib
5
+ scikit-learn==1.6.1
tokenizer.json ADDED
The diff for this file is too large to render. See raw diff
 
tokenizer_config.json ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "add_prefix_space": true,
3
+ "backend": "tokenizers",
4
+ "bos_token": "[CLS]",
5
+ "cls_token": "[CLS]",
6
+ "do_lower_case": false,
7
+ "eos_token": "[SEP]",
8
+ "extra_special_tokens": [
9
+ "[PAD]",
10
+ "[CLS]",
11
+ "[SEP]"
12
+ ],
13
+ "is_local": false,
14
+ "local_files_only": false,
15
+ "mask_token": "[MASK]",
16
+ "model_max_length": 1000000000000000019884624838656,
17
+ "pad_token": "[PAD]",
18
+ "sep_token": "[SEP]",
19
+ "split_by_punct": false,
20
+ "tokenizer_class": "DebertaV2Tokenizer",
21
+ "unk_id": 3,
22
+ "unk_token": "[UNK]",
23
+ "vocab_type": "spm"
24
+ }
tokenizer_meta.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"model": "microsoft/deberta-v3-small", "max_len": 512}