ciyidogan commited on
Commit
016ba45
·
verified ·
1 Parent(s): 2a276b1

Update inference_test_turkcell_with_intents.py

Browse files
inference_test_turkcell_with_intents.py CHANGED
@@ -1,3 +1,4 @@
 
1
  import os, torch, threading, uvicorn, time, traceback, zipfile, random, json, shutil, asyncio, re
2
  from fastapi import FastAPI
3
  from fastapi.responses import HTMLResponse, JSONResponse
@@ -7,25 +8,18 @@ from peft import PeftModel
7
  from datasets import Dataset
8
  from datetime import datetime
9
 
10
- # === Ortam ve Ayarlar ===
11
  HF_TOKEN = os.getenv("HF_TOKEN")
12
  os.environ["TRANSFORMERS_NO_ADVISORY_WARNINGS"] = "true"
13
  os.environ["TORCH_HOME"] = "/app/.torch_cache"
14
  os.makedirs("/app/.torch_cache", exist_ok=True)
15
 
 
16
  MODEL_BASE = "TURKCELL/Turkcell-LLM-7b-v1"
17
  USE_FINE_TUNE = False
18
  FINE_TUNE_REPO = "UcsTurkey/trained-zips"
19
  FINE_TUNE_ZIP = "trained_model_000_009.zip"
20
  USE_SAMPLING = False
21
-
22
- INTENT_MODEL_PATH = "intent_model"
23
- INTENT_MODEL_ID = "dbmdz/bert-base-turkish-cased"
24
- INTENT_MODEL = None
25
- INTENT_TOKENIZER = None
26
- LABEL2ID = {}
27
- INTENT_DEFINITIONS = {}
28
-
29
  INTENT_CONFIDENCE_THRESHOLD = 0.5
30
  LLM_CONFIDENCE_THRESHOLD = 0.2
31
  TRAIN_CONFIDENCE_THRESHOLD = 0.7
@@ -35,7 +29,14 @@ FALLBACK_ANSWERS = [
35
  "Bu soruya şu an yanıt veremiyorum."
36
  ]
37
 
38
- # === FastAPI ===
 
 
 
 
 
 
 
39
  app = FastAPI()
40
  chat_history = []
41
  model = None
@@ -76,8 +77,182 @@ def root():
76
  </body></html>
77
  """
78
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  def log(message):
80
- timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
81
  print(f"[{timestamp}] {message}", flush=True)
82
 
83
  def setup_model():
@@ -86,22 +261,20 @@ def setup_model():
86
  log("🧠 setup_model() başladı")
87
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
88
  log(f"📡 Kullanılan cihaz: {device}")
89
-
90
- log("📥 Tokenizer indiriliyor...")
91
  tokenizer = AutoTokenizer.from_pretrained(MODEL_BASE, use_fast=False)
92
  log("📦 Tokenizer yüklendi.")
93
-
94
- log("🧠 Model indiriliyor...")
95
  model = AutoModelForCausalLM.from_pretrained(MODEL_BASE, torch_dtype=torch.float32).to(device)
96
- log("📦 Model yüklendi ve cihaza taşındı.")
97
-
98
  tokenizer.pad_token = tokenizer.pad_token or tokenizer.eos_token
99
  model.config.pad_token_id = tokenizer.pad_token_id
100
  eos_token_id = tokenizer("<|im_end|>", add_special_tokens=False)["input_ids"][0]
101
-
102
  model.eval()
103
- log("✅ Ana model eval() çağrıldı ve hazır.")
104
-
 
 
 
 
105
  except Exception as e:
106
  log(f"❌ setup_model() hatası: {e}")
107
  traceback.print_exc()
 
1
+ # fine_tune_inference_with_intent.py
2
  import os, torch, threading, uvicorn, time, traceback, zipfile, random, json, shutil, asyncio, re
3
  from fastapi import FastAPI
4
  from fastapi.responses import HTMLResponse, JSONResponse
 
8
  from datasets import Dataset
9
  from datetime import datetime
10
 
11
+ # === Ortam
12
  HF_TOKEN = os.getenv("HF_TOKEN")
13
  os.environ["TRANSFORMERS_NO_ADVISORY_WARNINGS"] = "true"
14
  os.environ["TORCH_HOME"] = "/app/.torch_cache"
15
  os.makedirs("/app/.torch_cache", exist_ok=True)
16
 
17
+ # === Ayarlar
18
  MODEL_BASE = "TURKCELL/Turkcell-LLM-7b-v1"
19
  USE_FINE_TUNE = False
20
  FINE_TUNE_REPO = "UcsTurkey/trained-zips"
21
  FINE_TUNE_ZIP = "trained_model_000_009.zip"
22
  USE_SAMPLING = False
 
 
 
 
 
 
 
 
23
  INTENT_CONFIDENCE_THRESHOLD = 0.5
24
  LLM_CONFIDENCE_THRESHOLD = 0.2
25
  TRAIN_CONFIDENCE_THRESHOLD = 0.7
 
29
  "Bu soruya şu an yanıt veremiyorum."
30
  ]
31
 
32
+ INTENT_MODEL_PATH = "intent_model"
33
+ INTENT_MODEL_ID = "dbmdz/bert-base-turkish-cased"
34
+ INTENT_MODEL = None
35
+ INTENT_TOKENIZER = None
36
+ LABEL2ID = {}
37
+ INTENT_DEFINITIONS = {}
38
+
39
+ # === FastAPI
40
  app = FastAPI()
41
  chat_history = []
42
  model = None
 
77
  </body></html>
78
  """
79
 
80
+ @app.post("/train_intents", status_code=202)
81
+ def train_intents(train_input: TrainInput):
82
+ global INTENT_DEFINITIONS
83
+ log("📥 POST /train_intents çağrıldı.")
84
+ intents = train_input.intents
85
+ INTENT_DEFINITIONS = {intent["name"]: intent for intent in intents}
86
+ threading.Thread(target=lambda: background_training(intents), daemon=True).start()
87
+ return {"status": "accepted", "message": "Intent eğitimi arka planda başlatıldı."}
88
+
89
+ def background_training(intents):
90
+ try:
91
+ log("🔧 Intent eğitimi başlatıldı...")
92
+ texts, labels, label2id = [], [], {}
93
+ for idx, intent in enumerate(intents):
94
+ label2id[intent["name"]] = idx
95
+ for ex in intent["examples"]:
96
+ texts.append(ex)
97
+ labels.append(idx)
98
+
99
+ dataset = Dataset.from_dict({"text": texts, "label": labels})
100
+ tokenizer = AutoTokenizer.from_pretrained(INTENT_MODEL_ID)
101
+ config = AutoConfig.from_pretrained(INTENT_MODEL_ID)
102
+ config.problem_type = "single_label_classification"
103
+ config.num_labels = len(label2id)
104
+ model = AutoModelForSequenceClassification.from_pretrained(INTENT_MODEL_ID, config=config)
105
+
106
+ tokenized_data = {"input_ids": [], "attention_mask": [], "label": []}
107
+ for row in dataset:
108
+ out = tokenizer(row["text"], truncation=True, padding="max_length", max_length=128)
109
+ tokenized_data["input_ids"].append(out["input_ids"])
110
+ tokenized_data["attention_mask"].append(out["attention_mask"])
111
+ tokenized_data["label"].append(row["label"])
112
+
113
+ tokenized = Dataset.from_dict(tokenized_data)
114
+ tokenized.set_format(type="torch", columns=["input_ids", "attention_mask", "label"])
115
+
116
+ output_dir = "/app/intent_train_output"
117
+ os.makedirs(output_dir, exist_ok=True)
118
+ trainer = Trainer(
119
+ model=model,
120
+ args=TrainingArguments(output_dir, per_device_train_batch_size=4, num_train_epochs=3, logging_steps=10, save_strategy="no", report_to=[]),
121
+ train_dataset=tokenized,
122
+ data_collator=default_data_collator
123
+ )
124
+ trainer.train()
125
+
126
+ # ✅ Başarı raporu üret
127
+ predictions = model(tokenized["input_ids"]).logits.argmax(dim=-1).tolist()
128
+ actuals = tokenized["label"]
129
+ counts = {}
130
+ correct = {}
131
+ for pred, actual in zip(predictions, actuals):
132
+ intent = list(label2id.keys())[list(label2id.values()).index(actual)]
133
+ counts[intent] = counts.get(intent, 0) + 1
134
+ if pred == actual:
135
+ correct[intent] = correct.get(intent, 0) + 1
136
+ for intent, total in counts.items():
137
+ accuracy = correct.get(intent, 0) / total
138
+ log(f"📊 Intent '{intent}' doğruluk: {accuracy:.2f} — {total} örnek")
139
+ if accuracy < TRAIN_CONFIDENCE_THRESHOLD or total < 5:
140
+ log(f"⚠️ Yetersiz performanslı intent: '{intent}' — Doğruluk: {accuracy:.2f}, Örnek: {total}")
141
+
142
+ if os.path.exists(INTENT_MODEL_PATH):
143
+ shutil.rmtree(INTENT_MODEL_PATH)
144
+ model.save_pretrained(INTENT_MODEL_PATH)
145
+ tokenizer.save_pretrained(INTENT_MODEL_PATH)
146
+ with open(os.path.join(INTENT_MODEL_PATH, "label2id.json"), "w") as f:
147
+ json.dump(label2id, f)
148
+
149
+ log("✅ Intent eğitimi tamamlandı ve model kaydedildi.")
150
+
151
+ except Exception as e:
152
+ log(f"❌ Intent eğitimi hatası: {e}")
153
+ traceback.print_exc()
154
+
155
+ @app.post("/load_intent_model")
156
+ def load_intent_model():
157
+ global INTENT_MODEL, INTENT_TOKENIZER, LABEL2ID
158
+ try:
159
+ INTENT_TOKENIZER = AutoTokenizer.from_pretrained(INTENT_MODEL_PATH)
160
+ INTENT_MODEL = AutoModelForSequenceClassification.from_pretrained(INTENT_MODEL_PATH)
161
+ with open(os.path.join(INTENT_MODEL_PATH, "label2id.json")) as f:
162
+ LABEL2ID = json.load(f)
163
+ return {"status": "ok", "message": "Intent modeli yüklendi."}
164
+ except Exception as e:
165
+ return JSONResponse(content={"error": str(e)}, status_code=500)
166
+
167
+ async def detect_intent(text):
168
+ inputs = INTENT_TOKENIZER(text, return_tensors="pt")
169
+ outputs = INTENT_MODEL(**inputs)
170
+ probs = torch.nn.functional.softmax(outputs.logits, dim=-1)
171
+ confidence, pred_id = torch.max(probs, dim=-1)
172
+ id2label = {v: k for k, v in LABEL2ID.items()}
173
+ return id2label[pred_id.item()], confidence.item()
174
+
175
+ async def generate_response(text):
176
+ messages = [{"role": "user", "content": text}]
177
+ encodeds = tokenizer.apply_chat_template(messages, return_tensors="pt", add_generation_prompt=True)
178
+ eos_token = tokenizer("<|im_end|>", add_special_tokens=False)["input_ids"][0]
179
+ input_ids = encodeds.to(model.device)
180
+ attention_mask = (input_ids != tokenizer.pad_token_id).long()
181
+
182
+ with torch.no_grad():
183
+ output = model.generate(
184
+ input_ids=input_ids,
185
+ attention_mask=attention_mask,
186
+ max_new_tokens=128,
187
+ do_sample=USE_SAMPLING,
188
+ eos_token_id=eos_token,
189
+ pad_token_id=tokenizer.pad_token_id,
190
+ return_dict_in_generate=True,
191
+ output_scores=True
192
+ )
193
+
194
+ if not USE_SAMPLING:
195
+ scores = torch.stack(output.scores, dim=1)
196
+ probs = torch.nn.functional.softmax(scores[0], dim=-1)
197
+ top_conf = probs.max().item()
198
+ else:
199
+ top_conf = None
200
+
201
+ decoded = tokenizer.decode(output.sequences[0], skip_special_tokens=True).strip()
202
+ for tag in ["assistant", "<|im_start|>assistant"]:
203
+ start = decoded.find(tag)
204
+ if start != -1:
205
+ decoded = decoded[start + len(tag):].strip()
206
+ break
207
+ return decoded, top_conf
208
+
209
+ def extract_parameters(variables_list, user_input):
210
+ for pattern in variables_list:
211
+ regex = re.sub(r"(\w+):\{(.+?)\}", r"(?P<\1>.+?)", pattern)
212
+ match = re.match(regex, user_input)
213
+ if match:
214
+ return [{"key": k, "value": v} for k, v in match.groupdict().items()]
215
+ return []
216
+
217
+ def execute_intent(intent_name, user_input):
218
+ if intent_name in INTENT_DEFINITIONS:
219
+ definition = INTENT_DEFINITIONS[intent_name]
220
+ variables = extract_parameters(definition.get("variables", []), user_input)
221
+ log(f"🚀 execute_intent('{intent_name}', {variables})")
222
+ return {"intent": intent_name, "parameters": variables}
223
+ return {"intent": intent_name, "parameters": []}
224
+
225
+ @app.post("/chat")
226
+ async def chat(msg: Message):
227
+ user_input = msg.user_input.strip()
228
+ try:
229
+ if model is None or tokenizer is None:
230
+ return {"error": "Model yüklenmedi."}
231
+
232
+ if INTENT_MODEL:
233
+ intent_task = asyncio.create_task(detect_intent(user_input))
234
+ response_task = asyncio.create_task(generate_response(user_input))
235
+ intent, intent_conf = await intent_task
236
+ log(f"🎯 Intent: {intent} (conf={intent_conf:.2f})")
237
+ if intent_conf > INTENT_CONFIDENCE_THRESHOLD and intent in INTENT_DEFINITIONS:
238
+ result = execute_intent(intent, user_input)
239
+ return result
240
+ else:
241
+ response, response_conf = await response_task
242
+ if response_conf is not None and response_conf < LLM_CONFIDENCE_THRESHOLD:
243
+ return {"response": random.choice(FALLBACK_ANSWERS)}
244
+ return {"response": response}
245
+ else:
246
+ response, response_conf = await generate_response(user_input)
247
+ if response_conf is not None and response_conf < LLM_CONFIDENCE_THRESHOLD:
248
+ return {"response": random.choice(FALLBACK_ANSWERS)}
249
+ return {"response": response}
250
+ except Exception as e:
251
+ traceback.print_exc()
252
+ return JSONResponse(content={"error": str(e)}, status_code=500)
253
+
254
  def log(message):
255
+ timestamp = datetime.now().strftime("%H:%M:%S")
256
  print(f"[{timestamp}] {message}", flush=True)
257
 
258
  def setup_model():
 
261
  log("🧠 setup_model() başladı")
262
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
263
  log(f"📡 Kullanılan cihaz: {device}")
 
 
264
  tokenizer = AutoTokenizer.from_pretrained(MODEL_BASE, use_fast=False)
265
  log("📦 Tokenizer yüklendi.")
 
 
266
  model = AutoModelForCausalLM.from_pretrained(MODEL_BASE, torch_dtype=torch.float32).to(device)
267
+ log("📦 Model indirildi ve yüklendi.")
 
268
  tokenizer.pad_token = tokenizer.pad_token or tokenizer.eos_token
269
  model.config.pad_token_id = tokenizer.pad_token_id
270
  eos_token_id = tokenizer("<|im_end|>", add_special_tokens=False)["input_ids"][0]
 
271
  model.eval()
272
+ log("✅ Ana model eval() çağrıldı")
273
+ log(f"📦 Intent modeli indiriliyor: {INTENT_MODEL_ID}")
274
+ _ = AutoTokenizer.from_pretrained(INTENT_MODEL_ID)
275
+ _ = AutoModelForSequenceClassification.from_pretrained(INTENT_MODEL_ID)
276
+ log("✅ Intent modeli indirildi (önbelleğe alındı).")
277
+ log("✔️ Model başarıyla yüklendi ve sohbet için hazır.")
278
  except Exception as e:
279
  log(f"❌ setup_model() hatası: {e}")
280
  traceback.print_exc()