leilaghomashchi commited on
Commit
7d89455
·
verified ·
1 Parent(s): 74066c5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +104 -108
app.py CHANGED
@@ -2,169 +2,165 @@ import gradio as gr
2
  from transformers import AutoTokenizer, AutoModelForCausalLM
3
  import torch
4
 
5
- # پرامپت سیستم
6
- SYSTEM_PROMPT = """شما یک سیستم هوشمند ناشناس‌سازی متن هستید. وظیفه شما شناسایی و جایگزینی موجودیت‌های حساس در متون مالی و اقتصادی فارسی است.
7
 
8
- دستورالعمل‌های اصلی:
 
 
 
9
 
10
- انواع موجودیت‌ها:
 
 
 
 
11
 
12
- company-XX: نام شرکت‌ها، سازمان‌ها، بانک‌ها، هلدینگ‌ها، گروه‌های مالی (مثال: ایران خودرو، بانک ملی، گروه مالی صبا، سازمان حسابرسی)
 
 
13
 
14
- person-XX: نام و نام خانوادگی اشخاص (مثال: محمد رضایی، مهدی اخوان بهابادی، فرج‌اله قدمی)
15
-
16
- amount-XX: مبالغ مالی شامل ریال، تومان، همت، دلار، تن، دستگاه و واحدهای اندازه‌گیری (مثال: ۲۳ هزار و ۲۹۶ میلیارد تومان، ۵۰۰ میلیون دلار، ۷۳.۷ میلیون نفر، 636 ریال)
17
-
18
- percent-XX: درصدها و نسبت‌ها (مثال: ۴.۵۸ درصد، ۷۵ درصد، ۱۴٪، منفی 345 درصد)
19
-
20
- قوانین کلیدی:
21
-
22
- 1. ترتیب شماره‌گذاری: اولین باری که موجودیت ظاهر می‌شود، شماره می‌گیرد (01، 02، 03، ...)
23
-
24
- 2. حفظ هویت یکسان: اگر همان موجودیت دوباره آمد، از همان شماره استفاده کن. مثلا "ایران خودرو" در جمله اول و "این شرکت" در جمله دوم هر دو company-01 هستند.
25
-
26
- 3. تشخیص نام‌های مختلف: "فولاد مبارکه اصفهان" و "فولاد مبارکه" و "این شرکت" همه company-01 هستند. "همراه اول" و "گروه همراه اول" و "این اپراتور" همه company-01 هستند. اما "بانک پاسارگاد" و "سرزمین هوشمند پاد" دو company مختلف هستند.
27
-
28
- 4. مبالغ و درصدهای مختلف: هر عدد جدید، شماره جدید می‌گیرد
29
-
30
- 5. حفظ ساختار: ساختار جمله را حفظ کن، تاریخ‌ها را تغییر نده، کلمات توصیفی مثل "شرکت"، "بانک"، "گروه" را قبل از برچسب حفظ کن
31
-
32
- 6. هیچ توضیح اضافه‌ای نده: فقط متن ناشناس‌شده را برگردان، بدون توضیح یا تفسیر
33
-
34
- نمونه‌های آموزشی:
35
-
36
- نمونه ۱:
37
- متن اصلی: ایران خودرو در اسفندماه سال 1402 حدود 23 هزار و 296 میلیارد تومان درآمد کسب کرد که در مقایسه با بهمن 4.58 درصد افزایش داشت. زیان خالص ایران خودرو در این سال به بیش از 37 همت رساند.
38
- متن ناشناس‌شده: company-01 در اسفندماه سال 1402 حدود amount-01 درآمد کسب کرد که در مقایسه با بهمن percent-01 افزایش داشت. زیان خالص company-01 در این سال به بیش از amount-02 رساند.
39
-
40
- نمونه ۲:
41
- متن اصلی: بانک پاسارگاد با شناسایی سود خالص 155 هزار میلیارد ریالی در رده دوم سودآورترین بانک‌های کشور قرار گرفت و رقابت تنگاتنگی با بانک ملت داشت. در مقابل، بانک سرمایه با مدیرعاملی فرج‌اله قدمی وضعیت بحرانی دارد.
42
- متن ناشناس‌شده: company-01 با شناسایی سود خالص amount-01 در رده دوم سودآورترین بانک‌های کشور قرار گرفت و رقابت تنگاتنگی با company-02 دا��ت. در مقابل، company-03 با مدیرعاملی person-01 وضعیت بحرانی دارد.
43
-
44
- نمونه ۳:
45
- متن اصلی: مهدی اخوان بهابادی، مدیرعامل همراه اول، در مجمع عمومی عادی سالیانه اعلام کرد درآمد عملیاتی شرکت اصلی با رشد قابل توجه 37 درصدی نسبت به سال 1402، به 70 هزار و 677 میلیارد تومان رسیده است. سود خالص تلفیقی گروه همراه اول در پایان سال مالی 1403 به 8003 میلیارد تومان رسید.
46
- متن ناشناس‌شده: person-01، مدیرعامل company-01، در مجمع عمومی عادی سالیانه اعلام کرد درآمد عملیاتی شرکت اصلی با رشد قابل توجه percent-01 نسبت به سال 1402، به amount-01 رسیده است. سود خالص تلفیقی گروه company-01 در پایان سال مالی 1403 به amount-02 رسید.
47
-
48
- حالا وظیفه شما: متن زیر را طبق الگوی بالا ناشناس‌سازی کنید. فقط متن ناشناس‌شده را بدون هیچ توضیح اضافه برگردانید."""
49
-
50
- # بارگذاری مدل (فقط یک بار)
51
  print("در حال بارگذاری مدل...")
52
  model_name = "Qwen/Qwen2.5-7B-Instruct"
53
- tokenizer = AutoTokenizer.from_pretrained(model_name)
54
- model = AutoModelForCausalLM.from_pretrained(
55
- model_name,
56
- torch_dtype=torch.float16,
57
- device_map="auto",
58
- low_cpu_mem_usage=True
59
- )
60
- print("مدل بارگذاری شد!")
61
 
62
- def anonymize_text(text, temperature=0.2, max_tokens=2048):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  """تابع ناشناس‌سازی متن"""
64
  if not text.strip():
65
- return "لطفاً متنی وارد کنید"
66
 
67
  messages = [
68
  {"role": "system", "content": SYSTEM_PROMPT},
69
  {"role": "user", "content": f"متن اصلی:\n{text}\n\nمتن ناشناس‌شده:"}
70
  ]
71
 
72
- # تبدیل به فرمت مدل
73
- input_ids = tokenizer.apply_chat_template(
74
- messages,
75
- add_generation_prompt=True,
76
- return_tensors="pt"
77
- ).to(model.device)
78
-
79
- # تولید
80
- with torch.no_grad():
81
- outputs = model.generate(
82
- input_ids,
83
- max_new_tokens=int(max_tokens),
84
- temperature=float(temperature),
85
- top_p=0.9,
86
- do_sample=True,
87
- pad_token_id=tokenizer.eos_token_id,
88
- eos_token_id=tokenizer.eos_token_id
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  )
 
 
 
90
 
91
- # استخراج پاسخ
92
- response = tokenizer.decode(
93
- outputs[0][input_ids.shape[-1]:],
94
- skip_special_tokens=True
95
- )
96
-
97
- return response.strip()
98
 
99
  # نمونه‌های پیش‌فرض
100
  examples = [
101
- ["بانک ملی ایران در سال 1403 سود 50 هزار میلیارد تومانی کسب کرد. مدیرعامل بانک ملی، احمد رضایی، اعلام کرد این بانک 25 درصد رشد داشته است."],
102
- ["شرکت فولاد مبارکه اصفهان با سود 100 همتی در رده اول قرار گرفت. فولاد مبارکه 40 درصد رشد داشته است."],
103
- ["گروه مالی صبا تامین گزارش داد که صبا در سال 1403 سود 5000 میلیارد تومانی داشته است."]
104
  ]
105
 
106
- # ساخت رابط کاربری Gradio
107
- with gr.Blocks(title="ناشناس‌سازی متون مالی", theme=gr.themes.Soft()) as demo:
108
  gr.Markdown("""
109
- # 🔒 سیستم ناشناس‌سازی متون مالی فارسی
110
-
111
- این سیستم با استفاده از LLaMA 3.1-8B موجودیت‌های حساس (شرکت‌ها، اشخاص، مبالغ، درصدها) را شناسایی و ناشناس می‌کند.
112
 
113
- **نکته**: پردازش هر متن ممکن است ۵-۱۵ ثانیه طول بکشد.
 
114
  """)
115
 
116
  with gr.Row():
117
  with gr.Column():
118
  input_text = gr.Textbox(
119
  label="متن اصلی",
120
- placeholder="متن خود را اینجا وارد کنید...",
121
- lines=10,
122
  rtl=True
123
  )
124
 
125
- with gr.Row():
126
  temperature = gr.Slider(
127
  minimum=0.1,
128
- maximum=1.0,
129
  value=0.2,
130
  step=0.1,
131
- label="Temperature (پایین‌تر = پایدارتر)"
132
  )
133
  max_tokens = gr.Slider(
134
- minimum=512,
135
- maximum=4096,
136
- value=2048,
137
- step=256,
138
  label="حداکثر طول خروجی"
139
  )
140
 
141
- submit_btn = gr.Button("ناشناس‌سازی متن", variant="primary", size="lg")
142
 
143
  with gr.Column():
144
  output_text = gr.Textbox(
145
  label="متن ناشناس‌شده",
146
- lines=10,
147
  rtl=True
148
  )
149
 
150
  gr.Examples(
151
  examples=examples,
152
  inputs=input_text,
153
- label="نمونه‌های آزمایشی"
154
  )
155
 
156
  gr.Markdown("""
157
- ### راهنمای استفاده:
158
- 1. متن خود را در کادر سمت چپ وارد کنید
159
- 2. در صورت نیاز، تنظیمات را تغییر دهید
160
- 3. روی دکمه "ناشناسسازی متن" کلیک کنید
161
- 4. منتظر بمانید تا پردازش تکمیل شود
162
-
163
- ### انواع موجودیت‌های قابل شناسایی:
164
- - **company-XX**: نام شرکت‌ها، بانک‌ها، سازمان‌ها
165
- - **person-XX**: نام اشخاص
166
- - **amount-XX**: مبالغ مالی (ریال، تومان، همت، دلار و...)
167
- - **percent-XX**: درصدها و نسبت‌ها
168
  """)
169
 
170
  submit_btn.click(
 
2
  from transformers import AutoTokenizer, AutoModelForCausalLM
3
  import torch
4
 
5
+ # پرامپت سیستم (کوتاه شده برای کاهش مصرف)
6
+ SYSTEM_PROMPT = """شما یک سیستم ناشناس‌سازی متن هستید. موجودیت‌های حساس را شناسایی و جایگزین کنید:
7
 
8
+ - company-XX: شرکت‌ها، بانک‌ها (مثال: ایران خودرو → company-01)
9
+ - person-XX: اشخاص (مثال: احمد رضایی → person-01)
10
+ - amount-XX: مبالغ مالی (مثال: 50 هزار میلیارد تومان → amount-01)
11
+ - percent-XX: درصدها (مثال: 25 درصد → percent-01)
12
 
13
+ قوانین:
14
+ 1. شماره‌گذاری به ترتیب ظهور (01، 02، 03...)
15
+ 2. موجودیت تکراری = همان شماره
16
+ 3. ساختار جمله را حفظ کنید
17
+ 4. فقط متن ناشناس‌شده را برگردانید
18
 
19
+ نمونه:
20
+ متن اصلی: بانک ملی ایران در سال 1403 سود 50 هزار میلیارد تومانی کسب کرد. مدیرعامل بانک ملی، احمد رضایی، گفت این بانک 25 درصد رشد داشت.
21
+ متن ناشناس‌شده: company-01 در سال 1403 سود amount-01 کسب کرد. مدیرعامل company-01، person-01، گفت این بانک percent-01 رشد داشت."""
22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  print("در حال بارگذاری مدل...")
24
  model_name = "Qwen/Qwen2.5-7B-Instruct"
 
 
 
 
 
 
 
 
25
 
26
+ # تشخیص دستگاه (GPU یا CPU)
27
+ device = "cuda" if torch.cuda.is_available() else "cpu"
28
+ print(f"استفاده از دستگاه: {device}")
29
+
30
+ # تنظیم dtype بر اساس دستگاه
31
+ if device == "cuda":
32
+ torch_dtype = torch.float16
33
+ else:
34
+ torch_dtype = torch.float32 # CPU فقط float32 پشتیبانی می‌کند
35
+
36
+ try:
37
+ tokenizer = AutoTokenizer.from_pretrained(model_name)
38
+ model = AutoModelForCausalLM.from_pretrained(
39
+ model_name,
40
+ torch_dtype=torch_dtype,
41
+ device_map="auto" if device == "cuda" else None,
42
+ low_cpu_mem_usage=True
43
+ )
44
+
45
+ # اگر CPU است، مدل را صریحاً روی CPU بگذار
46
+ if device == "cpu":
47
+ model = model.to(device)
48
+
49
+ print(f"✅ مدل با موفقیت بارگذاری شد! (دستگاه: {device}, dtype: {torch_dtype})")
50
+ except Exception as e:
51
+ print(f"❌ خطا در بارگذاری مدل: {e}")
52
+ raise e
53
+
54
+ def anonymize_text(text, temperature=0.2, max_tokens=1024):
55
  """تابع ناشناس‌سازی متن"""
56
  if not text.strip():
57
+ return "⚠️ لطفاً متنی وارد کنید"
58
 
59
  messages = [
60
  {"role": "system", "content": SYSTEM_PROMPT},
61
  {"role": "user", "content": f"متن اصلی:\n{text}\n\nمتن ناشناس‌شده:"}
62
  ]
63
 
64
+ try:
65
+ # تبدیل به فرمت مدل
66
+ input_ids = tokenizer.apply_chat_template(
67
+ messages,
68
+ add_generation_prompt=True,
69
+ return_tensors="pt"
70
+ ).to(device)
71
+
72
+ # اضافه کردن attention_mask
73
+ attention_mask = torch.ones_like(input_ids)
74
+
75
+ print(f"🔄 در حال پردازش... (طول ورودی: {input_ids.shape[1]} توکن)")
76
+
77
+ # تولید
78
+ with torch.no_grad():
79
+ outputs = model.generate(
80
+ input_ids,
81
+ attention_mask=attention_mask,
82
+ max_new_tokens=int(max_tokens),
83
+ temperature=float(temperature),
84
+ top_p=0.9,
85
+ do_sample=True if temperature > 0 else False,
86
+ pad_token_id=tokenizer.eos_token_id,
87
+ eos_token_id=tokenizer.eos_token_id
88
+ )
89
+
90
+ # استخراج پاسخ
91
+ response = tokenizer.decode(
92
+ outputs[0][input_ids.shape[-1]:],
93
+ skip_special_tokens=True
94
  )
95
+
96
+ print("✅ پردازش تکمیل شد")
97
+ return response.strip()
98
 
99
+ except Exception as e:
100
+ error_msg = f"❌ خطا در پردازش: {str(e)}"
101
+ print(error_msg)
102
+ return error_msg
 
 
 
103
 
104
  # نمونه‌های پیش‌فرض
105
  examples = [
106
+ ["بانک ملی ایران در سال 1403 سود 50 هزار میلیارد تومانی کسب کرد."],
107
+ ["شرکت فولاد مبارکه با سود 100 همتی در رده اول قرار گرفت."],
 
108
  ]
109
 
110
+ # ساخت رابط کاربری
111
+ with gr.Blocks(title="ناشناس‌سازی متون", theme=gr.themes.Soft()) as demo:
112
  gr.Markdown("""
113
+ # 🔒 ناشناس‌سازی متون مالی فارسی
 
 
114
 
115
+ ⚠️ **توجه**: این نسخه روی CPU اجرا می‌شود و کند است (30-60 ثانیه برای هر متن).
116
+ برای سرعت بیشتر، GPU را در Settings فعال کنید.
117
  """)
118
 
119
  with gr.Row():
120
  with gr.Column():
121
  input_text = gr.Textbox(
122
  label="متن اصلی",
123
+ placeholder="متن خود را اینجا وارد کنید (حداکثر 200 کلمه)...",
124
+ lines=8,
125
  rtl=True
126
  )
127
 
128
+ with gr.Accordion("⚙️ تنظیمات پیشرفته", open=False):
129
  temperature = gr.Slider(
130
  minimum=0.1,
131
+ maximum=0.5,
132
  value=0.2,
133
  step=0.1,
134
+ label="Temperature"
135
  )
136
  max_tokens = gr.Slider(
137
+ minimum=256,
138
+ maximum=1024,
139
+ value=512,
140
+ step=128,
141
  label="حداکثر طول خروجی"
142
  )
143
 
144
+ submit_btn = gr.Button("🚀 ناشناس‌سازی", variant="primary", size="lg")
145
 
146
  with gr.Column():
147
  output_text = gr.Textbox(
148
  label="متن ناشناس‌شده",
149
+ lines=8,
150
  rtl=True
151
  )
152
 
153
  gr.Examples(
154
  examples=examples,
155
  inputs=input_text,
156
+ label="📝 نمونه‌های آزمایشی (کلیک کنید)"
157
  )
158
 
159
  gr.Markdown("""
160
+ ### 📌 نکات:
161
+ - متن‌های کوتاه (کمتر از 100 کلمه) سریع‌تر پردازش می‌شوند
162
+ - برای متن‌های طولانی، به چند دقیقه زمان نیاز است
163
+ - اگر خطا گرفتید، متن کوتاهتری امتحان کنید
 
 
 
 
 
 
 
164
  """)
165
 
166
  submit_btn.click(