code5ecure commited on
Commit
372bc73
·
verified ·
1 Parent(s): eb7c0c6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +114 -44
app.py CHANGED
@@ -1,52 +1,122 @@
1
- from torch.utils.data import Dataset
2
- from transformers import BertTokenizer, BertForMaskedLM
3
  import torch
 
 
 
 
 
 
 
 
 
 
 
 
 
4
 
5
- # بارگذاری توکنایزر و مدل
6
- tokenizer = BertTokenizer.from_pretrained("HooshvareLab/bert-base-parsbert-uncased")
7
- model = BertForMaskedLM.from_pretrained("HooshvareLab/bert-base-parsbert-uncased")
 
8
 
9
- # اضافه کردن pad_token در صورت نیاز
10
- if tokenizer.pad_token is None:
11
- tokenizer.add_special_tokens({'pad_token': '[PAD]'})
12
- model.resize_token_embeddings(len(tokenizer))
13
 
14
- class TextDataset(Dataset):
15
- def __init__(self, file_path, tokenizer, max_length=128):
16
- # خواندن خطوط غیرخالی از فایل
17
- with open(file_path, 'r', encoding='utf-8') as f:
18
- self.texts = [line.strip() for line in f if line.strip()]
19
- self.tokenizer = tokenizer
20
- self.max_length = max_length
21
 
22
  def __len__(self):
23
- return len(self.texts)
24
 
25
  def __getitem__(self, idx):
26
- text = self.texts[idx]
27
- encoding = self.tokenizer(
28
- text,
29
- truncation=True,
30
- padding='max_length',
31
- max_length=self.max_length,
32
- return_tensors='pt'
33
- )
34
- input_ids = encoding['input_ids'].squeeze(0)
35
- attention_mask = encoding['attention_mask'].squeeze(0)
36
-
37
- # برای MaskedLM، label همان input_ids است، ولی padding با -100 نشانه‌گذاری می‌شود تا در loss حساب نشود
38
- labels = input_ids.clone()
39
- labels[input_ids == tokenizer.pad_token_id] = -100
40
-
41
- return {
42
- 'input_ids': input_ids,
43
- 'attention_mask': attention_mask,
44
- 'labels': labels
45
- }
46
-
47
- # نمونه‌سازی Dataset با فایل متنی آپلود شده
48
- dataset = TextDataset("training_data.txt", tokenizer)
49
-
50
- # بررسی دو نمونه
51
- for i in range(2):
52
- print(dataset[i])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import torch
2
+ from transformers import AutoModelForCausalLM, AutoTokenizer, TrainingArguments, Trainer
3
+ from datasets import load_dataset
4
+ import numpy as np
5
+ from flask import Flask, request, jsonify
6
+ from opacus import PrivacyEngine
7
+ from torch.utils.data import Dataset
8
+
9
+ app = Flask(__name__)
10
+
11
+ # Load ParsBERT model and tokenizer
12
+ model_name = "HooshvareLab/bert-base-parsbert-uncased"
13
+ tokenizer = AutoTokenizer.from_pretrained(model_name)
14
+ model = AutoModelForCausalLM.from_pretrained(model_name)
15
 
16
+ # Differential Privacy parameters
17
+ epsilon = 1.0 # Privacy budget
18
+ delta = 1e-5 # Privacy parameter
19
+ sensitivity = 1.0 # Sensitivity of the query
20
 
21
+ # Simple memory for conversation history
22
+ conversation_history = []
 
 
23
 
24
+ # Custom Dataset for training data
25
+ class ChatDataset(Dataset):
26
+ def __init__(self, data):
27
+ self.data = data
28
+ self.encodings = tokenizer(data, truncation=True, padding=True, return_tensors="pt")
 
 
29
 
30
  def __len__(self):
31
+ return len(self.data)
32
 
33
  def __getitem__(self, idx):
34
+ item = {key: val[idx] for key, val in self.encodings.items()}
35
+ item["labels"] = item["input_ids"].clone()
36
+ return item
37
+
38
+ # Load training data from Hugging Face
39
+ def load_training_data():
40
+ dataset = load_dataset("training_data.txt", split="train") # Replace with actual dataset path
41
+ texts = [item["text"] for item in dataset if "text" in item]
42
+ return texts
43
+
44
+ # Fine-tune model with differential privacy
45
+ def train_model():
46
+ texts = load_training_data()
47
+ train_dataset = ChatDataset(texts)
48
+
49
+ training_args = TrainingArguments(
50
+ output_dir="./results",
51
+ num_train_epochs=3,
52
+ per_device_train_batch_size=8,
53
+ save_steps=10_000,
54
+ save_total_limit=2,
55
+ )
56
+
57
+ trainer = Trainer(
58
+ model=model,
59
+ args=training_args,
60
+ train_dataset=train_dataset,
61
+ )
62
+
63
+ # Add differential privacy
64
+ privacy_engine = PrivacyEngine()
65
+ model, optimizer, train_dataloader = privacy_engine.make_private(
66
+ module=model,
67
+ optimizer=trainer.optimizer,
68
+ data_loader=trainer.get_train_dataloader(),
69
+ noise_multiplier=1.1,
70
+ max_grad_norm=1.0,
71
+ )
72
+
73
+ trainer.optimizer = optimizer
74
+ trainer.train_dataloader = train_dataloader
75
+
76
+ trainer.train()
77
+ model.save_pretrained("./fine_tuned_model")
78
+ tokenizer.save_pretrained("./fine_tuned_model")
79
+
80
+ def add_noise(tensor, sensitivity, epsilon, delta):
81
+ """Add Laplace noise for differential privacy."""
82
+ scale = sensitivity / epsilon
83
+ noise = np.random.laplace(0, scale, tensor.shape)
84
+ return tensor + torch.tensor(noise, dtype=tensor.dtype)
85
+
86
+ def update_model(user_input, response):
87
+ """Update conversation history."""
88
+ global conversation_history
89
+ conversation_history.append({"user": user_input, "bot": response})
90
+ if len(conversation_history) > 100: # Limit history size
91
+ conversation_history.pop(0)
92
+ print(f"Learning from: {user_input} -> {response}")
93
+
94
+ @app.route('/chat', methods=['POST'])
95
+ def chat():
96
+ data = request.json
97
+ user_input = data.get('message', '')
98
+
99
+ # Tokenize input
100
+ inputs = tokenizer(user_input, return_tensors="pt", padding=True, truncation=True)
101
+
102
+ # Generate response with model
103
+ with torch.no_grad():
104
+ outputs = model(**inputs)
105
+ logits = outputs.logits
106
+
107
+ # Apply differential privacy to logits
108
+ noisy_logits = add_noise(logits, sensitivity, epsilon, delta)
109
+
110
+ # Decode response
111
+ response_ids = torch.argmax(noisy_logits, dim=-1)
112
+ response = tokenizer.decode(response_ids[0], skip_special_tokens=True)
113
+
114
+ # Update conversation history
115
+ update_model(user_input, response)
116
+
117
+ return jsonify({"response": response})
118
+
119
+ if __name__ == '__main__':
120
+ # Train the model on startup
121
+ train_model()
122
+ app.run(debug=True)