Rasha-83 commited on
Commit
ce9fbae
·
verified ·
1 Parent(s): e9ab8cc

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +213 -0
  2. requirements.txt +4 -0
app.py ADDED
@@ -0,0 +1,213 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from transformers import AutoTokenizer, AutoModel, PreTrainedTokenizerFast
3
+ import torch
4
+ import numpy as np
5
+ from typing import List, Dict
6
+
7
+ class SentenceEncoder:
8
+ def __init__(self, model_name="aubmindlab/bert-large-arabertv2", max_length=512):
9
+ self.tokenizer = AutoTokenizer.from_pretrained(model_name)
10
+ self.model = AutoModel.from_pretrained(model_name)
11
+ self.max_length = max_length
12
+ self.device = 'cuda' if torch.cuda.is_available() else 'cpu'
13
+ self.model.to(self.device)
14
+
15
+ def mean_pooling(self, model_output, attention_mask):
16
+ """تجميع متوسط التمثيل للجملة"""
17
+ token_embeddings = model_output[0]
18
+ input_mask_expanded = attention_mask.unsqueeze(-1).expand(token_embeddings.size()).float()
19
+ return torch.sum(token_embeddings * input_mask_expanded, 1) / torch.clamp(input_mask_expanded.sum(1), min=1e-9)
20
+
21
+ def encode(self, sentences: List[str]) -> np.ndarray:
22
+ """تحويل الجمل إلى متجهات"""
23
+ # تحويل النص إلى tokens
24
+ encoded_input = self.tokenizer(
25
+ sentences,
26
+ padding=True,
27
+ truncation=True,
28
+ max_length=self.max_length,
29
+ return_tensors='pt'
30
+ ).to(self.device)
31
+
32
+ # الحصول على التمثيلات
33
+ with torch.no_grad():
34
+ model_output = self.model(**encoded_input)
35
+
36
+ # تجميع المتوسط للحصول على تمثيل الجملة
37
+ sentence_embeddings = self.mean_pooling(model_output, encoded_input['attention_mask'])
38
+
39
+ # تطبيع المتجهات
40
+ sentence_embeddings = torch.nn.functional.normalize(sentence_embeddings, p=2, dim=1)
41
+
42
+ return sentence_embeddings.cpu().numpy()
43
+
44
+ class ContractAnalyzer:
45
+ def __init__(self):
46
+ print("جاري تحميل النموذج...")
47
+ self.encoder = SentenceEncoder()
48
+ print("تم تحميل النموذج بنجاح!")
49
+
50
+ self.legal_keywords = [
51
+ "يلتزم", "الزام", "يتعهد", "يحق", "لا يحق", "شرط جزائي",
52
+ "فسخ العقد", "إنهاء", "تعويض", "غرامة", "مدة العقد",
53
+ "طرف أول", "طرف ثاني", "قيمة العقد", "التزامات", "سداد",
54
+ "دفعات", "ينكل", "ضمان", "مخالفة", "إخلال", "قوة قاهرة"
55
+ ]
56
+
57
+ self.analysis_prompt = """
58
+ تحليل العقد القانوني:
59
+
60
+ 1. معلومات أساسية:
61
+ - تاريخ العقد: {date}
62
+ - الأطراف المتعاقدة: {parties}
63
+ - موضوع العقد: {subject}
64
+
65
+ 2. تحليل المحتوى (درجة التشابه): {similarity_score}
66
+
67
+ 3. المخاطر المحتملة:
68
+ {risks}
69
+
70
+ 4. العناصر المفقودة أو غير الواضحة:
71
+ {missing_elements}
72
+
73
+ 5. توصيات قانونية:
74
+ {recommendations}
75
+ """
76
+
77
+ def compute_similarity(self, sentences: List[str]) -> float:
78
+ """حساب درجة التشابه بين الجمل"""
79
+ if not sentences:
80
+ return 0.0
81
+
82
+ embeddings = self.encoder.encode(sentences)
83
+ if len(embeddings) < 2:
84
+ return 1.0
85
+
86
+ # حساب مصفوفة التشابه
87
+ similarity_matrix = np.dot(embeddings, embeddings.T)
88
+
89
+ # حساب متوسط التشابه
90
+ n = len(similarity_matrix)
91
+ similarity_sum = (similarity_matrix.sum() - n) / (n * (n - 1)) if n > 1 else 0
92
+
93
+ return float(similarity_sum)
94
+
95
+ def analyze_contract(self, contract_text: str) -> str:
96
+ try:
97
+ # تقسيم النص إلى جمل
98
+ sentences = [s.strip() for s in contract_text.split('.') if len(s.strip()) > 5]
99
+
100
+ # حساب درجة التشابه
101
+ similarity_score = self.compute_similarity(sentences)
102
+
103
+ # استخراج المعلومات وتحليل المخاطر
104
+ contract_info = self.extract_contract_info(contract_text)
105
+ results = self.analyze_content(sentences)
106
+
107
+ # تنسيق النتائج
108
+ formatted_results = self.analysis_prompt.format(
109
+ date=contract_info["date"],
110
+ parties="\n".join(contract_info["parties"]) or "غير محدد",
111
+ subject=contract_info["subject"],
112
+ similarity_score=f"{similarity_score:.2%}",
113
+ risks="\n".join([f"• {risk}" for risk in results["risks"]]) or "لا توجد مخاطر واضحة",
114
+ missing_elements="\n".join([f"• {element}" for element in results["missing_elements"]]) or "لا توجد عناصر مفقودة",
115
+ recommendations="\n".join([f"• {rec}" for rec in results["recommendations"]]) or "لا توجد توصيات إضافية"
116
+ )
117
+
118
+ return formatted_results
119
+
120
+ except Exception as e:
121
+ return f"حدث خطأ أثناء التحليل: {str(e)}"
122
+
123
+ def analyze_content(self, sentences: List[str]) -> Dict:
124
+ """تحليل محتوى العقد"""
125
+ results = {
126
+ "risks": [],
127
+ "missing_elements": [],
128
+ "recommendations": []
129
+ }
130
+
131
+ # تحليل المخاطر والعناصر المفقودة
132
+ for sentence in sentences:
133
+ # تحليل المخاطر
134
+ risk_words = ["مخالفة", "خرق", "نزاع", "خلاف", "إخلال", "فسخ"]
135
+ if any(word in sentence.lower() for word in risk_words):
136
+ results["risks"].append(sentence.strip())
137
+
138
+ # التحقق من العناصر المفقودة
139
+ required_elements = [
140
+ "مدة العقد", "قيمة العقد", "التزامات الطرفين",
141
+ "طريقة السداد", "الضمانات", "شروط الإنهاء"
142
+ ]
143
+
144
+ for element in required_elements:
145
+ if not any(element in s for s in sentences):
146
+ results["missing_elements"].append(element)
147
+ results["recommendations"].append(f"يجب إضافة {element} بشكل واضح في العقد")
148
+
149
+ return results
150
+
151
+ # باقي الكود (واجهة المستخدم) يبقى كما هو
152
+ # إنشاء كائن المحلل
153
+ analyzer = ContractAnalyzer()
154
+
155
+ # دالة التحليل لواجهة gradio
156
+ def analyze_text(text):
157
+ return analyzer.analyze_contract(text)
158
+
159
+ # تكوين واجهة gradio
160
+ iface = gr.Interface(
161
+ fn=analyze_text,
162
+ inputs=gr.Textbox(
163
+ placeholder="أدخل نص العقد هنا...",
164
+ label="نص العقد",
165
+ lines=30,
166
+ rtl=True, # إضافة دعم RTL للمدخلات
167
+ ),
168
+ outputs=gr.Textbox(
169
+ label="نتائج التحليل",
170
+ lines=30,
171
+ rtl=True, # إضافة دعم RTL للمخرجات
172
+ ),
173
+ title="محلل العقود القانونية ",
174
+ description="""
175
+ قم بإدخال نص العقد القانوني للحصول على تحليل شامل يتضمن:
176
+ • المعلومات الأساسية للعقد
177
+ • المخاطر المحتملة
178
+ • العناصر المفقودة
179
+ • التوصيات القانونية
180
+ """,
181
+ theme=gr.themes.Soft(
182
+ primary_hue="blue",
183
+ secondary_hue="blue",
184
+ neutral_hue="blue",
185
+
186
+ ),
187
+ css="""
188
+ .gradio-container {
189
+ direction: rtl !important;
190
+ text-align: right !important;
191
+ }
192
+ .output-markdown {
193
+ direction: rtl !important;
194
+ text-align: right !important;
195
+ }
196
+ .input-markdown {
197
+ direction: rtl !important;
198
+ text-align: right !important;
199
+ }
200
+ label {
201
+ text-align: right !important;
202
+ }
203
+ .prose {
204
+ direction: rtl !important;
205
+ text-align: right !important;
206
+ }
207
+ """
208
+ )
209
+
210
+ # تشغيل الواجهة
211
+ iface.launch(share=True, debug=True)
212
+
213
+
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ transformers
2
+ torch
3
+ gradio
4
+ numpy