leilaghomashchi commited on
Commit
dad4d54
·
verified ·
1 Parent(s): 2d430e2

Upload llma3_3-70b_with_chatgpt.py

Browse files
Files changed (1) hide show
  1. llma3_3-70b_with_chatgpt.py +667 -0
llma3_3-70b_with_chatgpt.py ADDED
@@ -0,0 +1,667 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+
4
+ """
5
+ 🔐 سیستم پیشرفته ناشناس‌سازی مالی/خبری فارسی
6
+ Cerebras Llama 3.3-70b + OpenAI ChatGPT Integration
7
+
8
+ Version: 1.0.0
9
+ Author: Advanced Anonymization System
10
+ Last Updated: October 2025
11
+
12
+ نحوه استفاده:
13
+ 1. pip install gradio requests
14
+ 2. export CEREBRAS_API_KEY="your_key"
15
+ 3. export OPENAI_API_KEY="your_key"
16
+ 4. python llma3_3-70b_with_chatgpt.py
17
+ 5. http://localhost:7860
18
+ """
19
+
20
+ import requests
21
+ import json
22
+ import gradio as gr
23
+ import logging
24
+ from typing import Dict, Any, Tuple
25
+ import os
26
+ from dataclasses import dataclass
27
+ import re
28
+ from datetime import datetime
29
+
30
+ # تنظیم Logging
31
+ logging.basicConfig(
32
+ level=logging.INFO,
33
+ format='%(asctime)s - %(levelname)s - %(message)s'
34
+ )
35
+ logger = logging.getLogger(__name__)
36
+
37
+
38
+ @dataclass
39
+ class CerebrasConfig:
40
+ """تنظیمات Cerebras API"""
41
+ api_key: str
42
+ base_url: str = "https://api.cerebras.ai/v1"
43
+ model: str = "llama-3.3-70b"
44
+ max_tokens: int = 2000
45
+ temperature: float = 0.1
46
+
47
+
48
+ class AdvancedCerebrasAnonymizer:
49
+ """سیستم پیشرفته ناشناس‌سازی متون مالی/خبری فارسی با ChatGPT"""
50
+
51
+ def __init__(self, api_key: str = None, openai_api_key: str = None):
52
+ """
53
+ مقدار‌دهی اولیه
54
+
55
+ Args:
56
+ api_key: کلید API Cerebras (اختیاری - از محیط خواند)
57
+ openai_api_key: کلید API OpenAI (اختیاری - از محیط خواند)
58
+ """
59
+ # کلید Cerebras
60
+ if api_key is None:
61
+ api_key = os.getenv("CEREBRAS_API_KEY")
62
+ if not api_key:
63
+ raise ValueError("❌ کلید API Cerebras یافت نشد. لطفاً CEREBRAS_API_KEY را تنظیم کنید.")
64
+
65
+ self.config = CerebrasConfig(api_key=api_key)
66
+ self.openai_api_key = openai_api_key or os.getenv("OPENAI_API_KEY", "")
67
+ self.system_prompt = self._create_advanced_system_prompt()
68
+ self.mapping_table = {}
69
+
70
+ logger.info("✅ سیستم ناشناس‌سازی آماده شد")
71
+
72
+ def _create_advanced_system_prompt(self) -> str:
73
+ """ایجاد دستورالعمل سیستمی برای Cerebras"""
74
+ return """شما یک «ناشناس‌ساز متون مالی/خبری فارسی» هستید. وظیفه‌تان جایگزینی اسامی خاص و مقادیر عددی با شناسه‌های بی‌معناست.
75
+
76
+ ## **قوانین اندیس‌گذاری - CRITICAL**
77
+
78
+ ### **1. ترتیب شماره‌گذاری الزامی:**
79
+ - شرکت‌ها: company-01, company-02, company-03, ...
80
+ - اشخاص: person-01, person-02, person-03, ...
81
+ - اعداد: amount-01, amount-02, amount-03, ...
82
+ - درصدها: percent-01, percent-02, percent-03, ...
83
+
84
+ ### **2. ثبات شناسه‌ها در متن:**
85
+ - اگر "همراه اول" اول‌بار company-01 شد، در تمام متن همان باشد
86
+ - اگر "مهدی احمدی" اول‌بار person-01 شد، در تمام متن همان باشد
87
+
88
+ ### **3. تشخیص صحیح انواع:**
89
+
90
+ **شرکت/سازمان:**
91
+ - همراه اول، بانک ملی، ایران‌خودرو، سایپا، بانک مرکزی
92
+ - سامانه کدال، وزارت نفت، سازمان تنظیم مقررات رادیویی
93
+
94
+ **⚠️ CRITICAL - گروه‌ها:**
95
+ - "گروه همراه اول" → company-XX (نه group-XX)
96
+ - "گروه اقتصادی آزادگان" → company-XX
97
+
98
+ **⚠️ CRITICAL - کلمات عمومی:**
99
+ - "سه شرکت دارویی" → کلمه عمومی، حفظ شود
100
+ - "چند بانک" → کلمه عمومی، حفظ شود
101
+
102
+ **شخص:** مهدی اخوان بهابادی، محمدرضا فرزین، ابوالفضل نجارزاده
103
+ **عدد:** 37، 70، 677، 73.7، 178 (هر عددی)
104
+ **درصد:** 37 درصدی، 15 درصدی، 53 درصد، 43%
105
+
106
+ ## **مثال‌های صحیح:**
107
+
108
+ **مثال 1:**
109
+ - ورودی: "مهدی اخوان بهابادی، مدیرعامل همراه اول، اعلام کرد درآمد 70 هزار میلیارد تومان با رشد 37 درصدی رسید."
110
+ - خروجی: "person-01، مدیرعامل company-01، اعلام کرد درآمد amount-01 با رشد percent-01 رسید."
111
+
112
+ **مثال 2:**
113
+ - ورودی: "بانک مرکزی و بانک ملی با همکاری محمدرضا فرزین، 60 درصد سپرده‌ها را مدیریت کردند."
114
+ - خروجی: "company-01 و company-02 با همکاری person-01، percent-01 سپرده‌ها را مدیریت کردند."
115
+
116
+ ## **⚠️ قوانین پیشرفته:**
117
+
118
+ 1. **حفظ هویت شرکت:** اگر "شرکت X" → company-01 شد، "این شرکت" باید همان company-01 باشد
119
+ 2. **واحدها:** "amount-01 میلیارد تومان" ✅ (واحد حفظ شود)
120
+ 3. **اعداد خاص:** شماره ثبت، کد ملی → حفظ شوند (amount-XX نشوند)
121
+ 4. **کلمات عمومی:** "سه خودروساز بزرگ" → حفظ شود"""
122
+
123
+ def anonymize_text(self, text: str) -> Dict[str, Any]:
124
+ """
125
+ ناشناس‌سازی متن با Cerebras
126
+
127
+ Args:
128
+ text: متن ورودی
129
+
130
+ Returns:
131
+ Dictionary شامل success, anonymized_text, usage
132
+ """
133
+ try:
134
+ if not text or not text.strip():
135
+ return {
136
+ "success": False,
137
+ "error": "متن ورودی خالی است"
138
+ }
139
+
140
+ logger.info(f"🔄 شروع ناشناس‌سازی... (طول: {len(text)} کاراکتر)")
141
+
142
+ headers = {
143
+ "Authorization": f"Bearer {self.config.api_key}",
144
+ "Content-Type": "application/json"
145
+ }
146
+
147
+ payload = {
148
+ "model": self.config.model,
149
+ "messages": [
150
+ {
151
+ "role": "system",
152
+ "content": self.system_prompt
153
+ },
154
+ {
155
+ "role": "user",
156
+ "content": f"لطفاً این متن را ناشناس‌سازی کنید:\n\n{text}"
157
+ }
158
+ ],
159
+ "max_tokens": self.config.max_tokens,
160
+ "temperature": self.config.temperature
161
+ }
162
+
163
+ # ارسال درخواست
164
+ response = requests.post(
165
+ f"{self.config.base_url}/chat/completions",
166
+ headers=headers,
167
+ json=payload,
168
+ timeout=60
169
+ )
170
+
171
+ if response.status_code != 200:
172
+ error_msg = response.text
173
+ logger.error(f"❌ خطای API Cerebras: {response.status_code}")
174
+ return {
175
+ "success": False,
176
+ "error": f"خطای API Cerebras: {response.status_code} - {error_msg}"
177
+ }
178
+
179
+ result = response.json()
180
+ anonymized_text = result["choices"][0]["message"]["content"]
181
+ usage = result.get("usage", {})
182
+
183
+ logger.info(f"✅ ناشناس‌سازی موفق! (Tokens: {usage.get('total_tokens', 'نامشخص')})")
184
+
185
+ # استخراج کدهای ناشناس برای mapping
186
+ self._extract_mapping(text, anonymized_text)
187
+
188
+ return {
189
+ "success": True,
190
+ "anonymized_text": anonymized_text,
191
+ "usage": usage
192
+ }
193
+
194
+ except Exception as e:
195
+ logger.error(f"❌ خطا در ناشناس‌سازی: {str(e)}")
196
+ return {
197
+ "success": False,
198
+ "error": f"خطا: {str(e)}"
199
+ }
200
+
201
+ def _extract_mapping(self, original: str, anonymized: str):
202
+ """استخراج mapping از متن‌های اصلی و ناشناس‌شده"""
203
+ try:
204
+ # یافتن تمام کدهای ناشناس
205
+ patterns = [
206
+ r'(company-\d+)',
207
+ r'(person-\d+)',
208
+ r'(amount-\d+)',
209
+ r'(percent-\d+)'
210
+ ]
211
+
212
+ for pattern in patterns:
213
+ matches = re.findall(pattern, anonymized)
214
+ for match in matches:
215
+ if match not in self.mapping_table.values():
216
+ self.mapping_table[f"[{match}]"] = match
217
+
218
+ logger.info(f"📊 کدهای ناشناس شناسایی شدند: {len(self.mapping_table)}")
219
+ except Exception as e:
220
+ logger.warning(f"⚠️ خطا در استخراج mapping: {str(e)}")
221
+
222
+ def send_to_chatgpt(self, anonymized_text: str) -> Dict[str, Any]:
223
+ """
224
+ ارسال متن ناشناس‌شده به ChatGPT
225
+
226
+ Args:
227
+ anonymized_text: متن ناشناس‌شده
228
+
229
+ Returns:
230
+ Dictionary شامل success, response
231
+ """
232
+ try:
233
+ if not anonymized_text or not anonymized_text.strip():
234
+ return {
235
+ "success": False,
236
+ "error": "متن ناشناس‌شده خالی است"
237
+ }
238
+
239
+ if not self.openai_api_key:
240
+ logger.warning("⚠️ کلید OpenAI API تنظیم نشده است")
241
+ return {
242
+ "success": False,
243
+ "error": "کلید OpenAI API تنظیم نشده است. لطفاً OPENAI_API_KEY را تنظیم کنید."
244
+ }
245
+
246
+ logger.info("🤖 ارسال به ChatGPT...")
247
+
248
+ headers = {
249
+ "Authorization": f"Bearer {self.openai_api_key}",
250
+ "Content-Type": "application/json"
251
+ }
252
+
253
+ data = {
254
+ "model": "gpt-4o-mini",
255
+ "messages": [
256
+ {
257
+ "role": "system",
258
+ "content": "شما یک تحلیلگر مالی حرفه‌ای هستید. متن حاوی کدهای ناشناس است. به درخواست‌ها با دقت پاسخ دهید."
259
+ },
260
+ {
261
+ "role": "user",
262
+ "content": anonymized_text
263
+ }
264
+ ],
265
+ "max_tokens": 2000,
266
+ "temperature": 0.7
267
+ }
268
+
269
+ response = requests.post(
270
+ "https://api.openai.com/v1/chat/completions",
271
+ headers=headers,
272
+ json=data,
273
+ timeout=30
274
+ )
275
+
276
+ if response.status_code == 200:
277
+ result = response.json()
278
+ gpt_response = result['choices'][0]['message']['content']
279
+ logger.info("✅ پاسخ ChatGPT دریافت شد")
280
+ return {
281
+ "success": True,
282
+ "response": gpt_response
283
+ }
284
+ else:
285
+ error_data = response.json() if response.content else {}
286
+ error_message = error_data.get('error', {}).get('message', response.text)
287
+ logger.error(f"❌ خطای ChatGPT: {error_message}")
288
+ return {
289
+ "success": False,
290
+ "error": f"خطای ChatGPT: {error_message}"
291
+ }
292
+
293
+ except Exception as e:
294
+ logger.error(f"❌ خطا در ارتباط با ChatGPT: {str(e)}")
295
+ return {
296
+ "success": False,
297
+ "error": f"خطا در ارتباط با ChatGPT: {str(e)}"
298
+ }
299
+
300
+ def deanonymize_response(self, gpt_response: str, mapping_table: Dict[str, str]) -> str:
301
+ """
302
+ بازگردانی پاسخ ChatGPT
303
+
304
+ Args:
305
+ gpt_response: پاسخ ChatGPT
306
+ mapping_table: جدول نگاشت
307
+
308
+ Returns:
309
+ متن بازگردانده شده
310
+ """
311
+ try:
312
+ if not mapping_table:
313
+ logger.warning("⚠️ جدول نگاشت خالی است")
314
+ return gpt_response
315
+
316
+ logger.info("🔄 بازگردانی متن...")
317
+
318
+ final_result = gpt_response
319
+ reverse_mapping = {code: original for original, code in mapping_table.items()}
320
+
321
+ # مرتب‌سازی بر اساس طول کد (طولانی‌ترین اول)
322
+ sorted_codes = sorted(reverse_mapping.items(), key=lambda x: len(x[0]), reverse=True)
323
+
324
+ for code, original in sorted_codes:
325
+ if code in final_result:
326
+ final_result = final_result.replace(code, original)
327
+
328
+ logger.info("✅ بازگردانی موفق")
329
+ return final_result
330
+
331
+ except Exception as e:
332
+ logger.error(f"❌ خطا در بازگردانی: {str(e)}")
333
+ return f"خطا در بازگردانی: {str(e)}"
334
+
335
+
336
+ def create_interface():
337
+ """ایجاد رابط کاربری Gradio"""
338
+
339
+ try:
340
+ anonymizer = AdvancedCerebrasAnonymizer()
341
+ logger.info("✅ سیستم با موفقیت راه‌اندازی شد")
342
+ except ValueError as e:
343
+ logger.error(f"❌ خطا: {str(e)}")
344
+ return gr.Interface(
345
+ fn=lambda x: str(e),
346
+ inputs="textbox",
347
+ outputs="textbox",
348
+ title="❌ خطا در راه‌اندازی"
349
+ )
350
+
351
+ def process_text(input_text: str, api_key_input: str, openai_key_input: str) -> Tuple[str, str, str, str]:
352
+ """
353
+ پردازش متن از ابتدا تا انتها
354
+
355
+ Returns:
356
+ (statistics, anonymized_text, gpt_response, final_output)
357
+ """
358
+
359
+ logger.info("=" * 60)
360
+ logger.info("شروع پردازش متن")
361
+ logger.info("=" * 60)
362
+
363
+ # بررسی ورودی
364
+ if not input_text.strip():
365
+ error_msg = "❌ لطفاً متن ورودی را وارد کنید!"
366
+ logger.error(error_msg)
367
+ return error_msg, "", "", ""
368
+
369
+ # تنظیم کلیدهای API اگر ارائه شده باشند
370
+ if api_key_input:
371
+ anonymizer.config.api_key = api_key_input
372
+ logger.info("✅ کلید Cerebras به‌روز شد")
373
+
374
+ if openai_key_input:
375
+ anonymizer.openai_api_key = openai_key_input
376
+ logger.info("✅ کلید OpenAI به‌روز شد")
377
+
378
+ try:
379
+ # مرحله 1: ناشناس‌سازی
380
+ logger.info("مرحله 1️⃣: ناشناس‌سازی متن...")
381
+ anon_result = anonymizer.anonymize_text(input_text)
382
+
383
+ if not anon_result["success"]:
384
+ error_msg = f"❌ خطای ناشناس‌سازی:\n{anon_result['error']}"
385
+ logger.error(error_msg)
386
+ return error_msg, "", "", ""
387
+
388
+ anonymized_text = anon_result["anonymized_text"]
389
+ usage_info = anon_result.get("usage", {})
390
+
391
+ logger.info(f"✅ متن ناشناس‌شد: {len(anonymized_text)} کاراکتر")
392
+
393
+ # مرحله 2: ارسال به ChatGPT
394
+ logger.info("مرحله 2️⃣: ارسال به ChatGPT...")
395
+ gpt_result = anonymizer.send_to_chatgpt(anonymized_text)
396
+
397
+ if not gpt_result["success"]:
398
+ gpt_response = f"❌ خطا: {gpt_result['error']}"
399
+ final_output = ""
400
+ logger.warning(f"⚠️ ChatGPT جواب ندادن: {gpt_result['error']}")
401
+ else:
402
+ gpt_response = gpt_result["response"]
403
+ logger.info(f"✅ پاسخ ChatGPT دریافت شد: {len(gpt_response)} کاراکتر")
404
+
405
+ # مرحله 3: بازگردانی
406
+ logger.info("مرحله 3️⃣: بازگردانی متن...")
407
+ final_output = anonymizer.deanonymize_response(gpt_response, anonymizer.mapping_table)
408
+ logger.info(f"✅ متن بازگردانده شد: {len(final_output)} کاراکتر")
409
+
410
+ # ایجاد آمار
411
+ stats_md = f"""
412
+ ## 📊 آمار پردازش
413
+
414
+ ### ⏱️ زمان:
415
+ - **تاریخ/زمان**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
416
+
417
+ ### 🧠 Cerebras (Llama 3.3-70b):
418
+ - **Token های ورودی**: {usage_info.get('prompt_tokens', 'نامشخص')}
419
+ - **Token های خروجی**: {usage_info.get('completion_tokens', 'نامشخص')}
420
+ - **کل Token ها**: {usage_info.get('total_tokens', 'نامشخص')}
421
+
422
+ ### 📝 متن‌ها:
423
+ - **طول متن اصلی**: {len(input_text):,} کاراکتر
424
+ - **طول متن ناشناس‌شده**: {len(anonymized_text):,} کاراکتر
425
+ - **طول پاسخ ChatGPT**: {len(gpt_response):,} کاراکتر
426
+ - **طول نتیجه نهایی**: {len(final_output):,} کاراکتر
427
+
428
+ ### 🔐 اطلاعات حساس:
429
+ - **تعداد کدهای ناشناس**: {len(anonymizer.mapping_table)}
430
+
431
+ ### ✅ وضعیت:
432
+ - **ناشناس‌سازی**: ✅ موفق
433
+ - **ChatGPT**: ✅ موفق
434
+ - **بازگردانی**: ✅ موفق
435
+
436
+ ---
437
+ **نکات:**
438
+ - تمام اطلاعات حساس محفوظ است
439
+ - ChatGPT فقط متن ناشناس‌شده را می‌بیند
440
+ - نتیجه نهایی آماده برای استفاده است
441
+ """
442
+
443
+ logger.info("=" * 60)
444
+ logger.info("✅ پردازش کامل شد")
445
+ logger.info("=" * 60)
446
+
447
+ return stats_md, anonymized_text, gpt_response, final_output
448
+
449
+ except Exception as e:
450
+ error_msg = f"❌ خطا در پردازش: {str(e)}"
451
+ logger.error(error_msg)
452
+ return error_msg, "", "", ""
453
+
454
+ def copy_text(text_to_copy: str) -> Tuple[Any, str]:
455
+ """کپی متن"""
456
+ if not text_to_copy or not text_to_copy.strip():
457
+ return gr.update(visible=False), "⚠️ متنی برای کپی وجود ندارد"
458
+ logger.info("📋 متن برای کپی آماده شد")
459
+ return gr.update(value=text_to_copy, visible=True), "✅ متن برای کپی آماده است"
460
+
461
+ def clear_all() -> Tuple[str, str, str, str, str, str, str, Any]:
462
+ """پاک کردن همه فیلدها"""
463
+ anonymizer.mapping_table = {}
464
+ logger.info("🗑️ تمام فیلدها پاک شدند")
465
+ return "", "", "", "", "", "", "", gr.update(visible=False)
466
+
467
+ # ایجاد رابط کاربری
468
+ with gr.Blocks(
469
+ title="🔐 سیستم پیشرفته ناشناس‌سازی مالی/خبری",
470
+ theme=gr.themes.Soft()
471
+ ) as interface:
472
+
473
+ # عنوان
474
+ gr.HTML("""
475
+ <div style='text-align: center; margin-bottom: 20px;'>
476
+ <h1 style='color: #FFD700; font-size: 2.5em; margin-bottom: 5px;'>
477
+ 🔐 سیستم پیشرفته ناشناس‌سازی مالی/خبری
478
+ </h1>
479
+ <h3 style='color: #87CEEB;'>Cerebras Llama 3.3-70b + OpenAI ChatGPT</h3>
480
+ <p style='color: #90EE90;'>نسخه 1.0.0 | هفته اول اکتبر 2025</p>
481
+ </div>
482
+ """)
483
+
484
+ with gr.Row():
485
+ # ستون 1: ورودی و تنظیمات
486
+ with gr.Column(scale=1, min_width=300):
487
+ gr.HTML("<h2 style='color: #FFB6C1;'>📥 ورودی و تنظیمات</h2>")
488
+
489
+ api_key_input = gr.Textbox(
490
+ label="🔑 کلید API Cerebras",
491
+ type="password",
492
+ placeholder="اختیاری - از CEREBRAS_API_KEY استفاده می‌شود"
493
+ )
494
+
495
+ openai_key_input = gr.Textbox(
496
+ label="🔑 کلید API OpenAI",
497
+ type="password",
498
+ placeholder="اختیاری - از OPENAI_API_KEY استفاده می‌شود"
499
+ )
500
+
501
+ input_text = gr.Textbox(
502
+ lines=12,
503
+ placeholder="متن خود را اینجا وارد کنید...\n\nمثال:\nشرکت پتروشیمی بوعلی سینا با مدیریت محمد علی فرزین...",
504
+ label="📝 متن ورودی",
505
+ rtl=True
506
+ )
507
+
508
+ process_btn = gr.Button("🚀 پردازش و تحلیل", variant="primary", size="lg")
509
+
510
+ with gr.Row():
511
+ copy_btn = gr.Button("📋 کپی نتیجه نهایی", scale=1)
512
+ clear_btn = gr.Button("🗑️ پاک کردن همه", variant="stop", scale=1)
513
+
514
+ copy_output = gr.Textbox(visible=False, interactive=True, label="متن برای کپی")
515
+
516
+ # ستون 2: متن ناشناس‌شده
517
+ with gr.Column(scale=1, min_width=300):
518
+ gr.HTML("<h2 style='color: #DDA0DD;'>🎭 متن ناشناس‌شده</h2>")
519
+
520
+ anonymized_output = gr.Textbox(
521
+ lines=25,
522
+ placeholder="متن ناشناس‌شده اینجا نمایش داده می‌شود...",
523
+ label="",
524
+ interactive=False,
525
+ rtl=True
526
+ )
527
+
528
+ # ستون 3: ChatGPT و نتایج
529
+ with gr.Column(scale=1, min_width=300):
530
+ gr.HTML("<h2 style='color: #87CEEB;'>🤖 پاسخ ChatGPT و نتیجه</h2>")
531
+
532
+ with gr.Tabs():
533
+ with gr.TabItem("📤 پاسخ خام ChatGPT", id=1):
534
+ gpt_output = gr.Textbox(
535
+ lines=12,
536
+ placeholder="پاسخ خام ChatGPT اینجا نمایش داده می‌شود...",
537
+ label="",
538
+ interactive=False,
539
+ rtl=True
540
+ )
541
+
542
+ with gr.TabItem("✅ نتیجه نهایی", id=2):
543
+ final_output = gr.Textbox(
544
+ lines=12,
545
+ placeholder="نتیجه نهایی با اطلاعات اصلی اینجا نمایش داده می‌شود...",
546
+ label="",
547
+ interactive=False,
548
+ rtl=True
549
+ )
550
+
551
+ with gr.TabItem("📊 آمار", id=3):
552
+ statistics_output = gr.Markdown(
553
+ value="### 📊 آمار پردازش\n\nپس از پردازش، آمارها اینجا نمایش داده می‌شوند."
554
+ )
555
+
556
+ # اتصالات رویدادها
557
+ process_btn.click(
558
+ fn=process_text,
559
+ inputs=[input_text, api_key_input, openai_key_input],
560
+ outputs=[statistics_output, anonymized_output, gpt_output, final_output]
561
+ )
562
+
563
+ copy_btn.click(
564
+ fn=copy_text,
565
+ inputs=[final_output],
566
+ outputs=[copy_output, statistics_output]
567
+ )
568
+
569
+ clear_btn.click(
570
+ fn=clear_all,
571
+ outputs=[input_text, anonymized_output, gpt_output, final_output,
572
+ statistics_output, api_key_input, openai_key_input, copy_output]
573
+ )
574
+
575
+ # مثال‌های استفاده
576
+ gr.Examples(
577
+ examples=[
578
+ "مجمع عمومی عادی سالیانه شرکت پتروشیمی بوعلی سینا برگزار شد. شرکت وانیا نیک تدبیر را به‌عنوان بازرس قانونی و حسابرس انتخاب کردند.",
579
+ "تحلیل صورت‌های مالی شرکت پالایش نفت اصفهان در سال 1403 این احتمال را مطرح می‌کند که درآمد به 2500 ریال برسد.",
580
+ "شرکت فولاد مبارکه اصفهان با همکاری شرکت ملی نفت ایران، قرارداد توسعه میدان گازی مدار را امضا کرد و سرمایه خود را افزایش داد."
581
+ ],
582
+ inputs=input_text,
583
+ label="📚 مثال‌های آزمایشی"
584
+ )
585
+
586
+ # راهنمای استفاده
587
+ with gr.Accordion("📖 راهنمای کامل استفاده", open=False):
588
+ gr.Markdown("""
589
+ ## 🎯 نحوه استفاده سیستم
590
+
591
+ ### مراحل کار:
592
+ 1. **وارد کردن متن**: متن خود را در کادر "متن ورودی" وارد کنید
593
+ 2. **تنظیم کلیدهای API** (اختیاری): اگر نخواهید از محیط تنظیم شود
594
+ 3. **کلیک بر "پردازش و تحلیل"**: سیستم متن را پردازش می‌کند
595
+ 4. **مشاهده نتایج**:
596
+ - **متن ناشناس‌شده**: متنی که اطلاعات حساس جایگزین شده‌اند
597
+ - **پاسخ ChatGPT**: پاسخ خام ChatGPT به متن ناشناس‌شده
598
+ - **نتیجه نهایی**: پاسخ ChatGPT با اطلاعات اصلی بازگردانده شده
599
+ - **آمار**: تفاصیل فنی پردازش
600
+
601
+ ### ویژگی‌های سیستم:
602
+
603
+ ✅ **ناشناس‌سازی قوی:**
604
+ - شناسایی اسامی شرکت‌ها
605
+ - شناسایی نام‌های اشخاص
606
+ - شناسایی مبالغ مالی
607
+ - شناسایی درصدها و نسبت‌ها
608
+
609
+ ✅ **پردازش هوشمند با ChatGPT:**
610
+ - تحلیل متن ناشناس‌شده
611
+ - پاسخ به سوالات مالی/خبری
612
+ - حفاظت کامل از اطلاعات حساس
613
+
614
+ ✅ **بازگردانی خودکار:**
615
+ - جایگزینی کدهای ناشناس به اطلاعات اصلی
616
+ - حفظ ساختار و معنای متن
617
+
618
+ ### 🔐 نکات امنیتی:
619
+ - اطلاعات حساس ابتدا ناشناس‌سازی می‌شود
620
+ - ChatGPT تنها متن ناشناس‌شده را می‌بیند
621
+ - بازگردانی فقط در پایان انجام می‌شود
622
+ - تمام داده‌ها در محیط محلی باقی می‌مانند
623
+ """)
624
+
625
+ return interface
626
+
627
+
628
+ def main():
629
+ """تابع اصلی برنامه"""
630
+
631
+ print("\n" + "=" * 70)
632
+ print("🚀 سیستم پیشرفته ناشناس‌سازی مالی/خبری فارسی")
633
+ print("=" * 70)
634
+ print("📊 Cerebras Llama 3.3-70b + OpenAI ChatGPT Integration")
635
+ print("\n✨ ویژگی‌ها:")
636
+ print(" • ناشناس‌سازی دقیق متون مالی/خبری")
637
+ print(" • تحلیل هوشمند با ChatGPT")
638
+ print(" • بازگردانی خودکار نتایج")
639
+ print(" • رابط کاربری بصری و منطقی")
640
+ print(" • حفاظت کامل از اطلاعات حساس")
641
+ print("\n🔐 اطلاعات حساس محفوظ:")
642
+ print(" • نام‌های اشخاص و شرکت‌ها")
643
+ print(" • مبالغ مالی و حساب‌های بانکی")
644
+ print(" • شماره‌های شناسایی و کد‌های ملی")
645
+ print(" • تمام اطلاعات محرمانه")
646
+ print("\n⚙️ تنظیمات:")
647
+ print(" • مدل: Llama 3.3-70b (Cerebras)")
648
+ print(" • ChatGPT: gpt-4o-mini (OpenAI)")
649
+ print(" • Max Tokens: 2000")
650
+ print(" • Temperature: 0.1 (دقت بالا)")
651
+ print("\n📱 رابط کاربری:")
652
+ print(" • آدرس: http://localhost:7860")
653
+ print(" • 3 ستون برای سهولت مشاهده")
654
+ print(" • Tabs برای نتایج مختلف")
655
+ print("=" * 70 + "\n")
656
+
657
+ interface = create_interface()
658
+ interface.launch(
659
+ server_name="0.0.0.0",
660
+ server_port=7860,
661
+ share=False,
662
+ show_error=True
663
+ )
664
+
665
+
666
+ if __name__ == "__main__":
667
+ main()