Irishkaaa commited on
Commit
65d8bb0
·
verified ·
1 Parent(s): 919df04

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +80 -90
app.py CHANGED
@@ -5,7 +5,6 @@ from sumy.summarizers.lex_rank import LexRankSummarizer
5
  from sumy.summarizers.lsa import LsaSummarizer
6
  import nltk
7
  import re
8
- import requests
9
 
10
  # Скачиваем данные для nltk
11
  try:
@@ -16,64 +15,6 @@ except LookupError:
16
 
17
  history = []
18
 
19
- # ===== Hugging Face нейросеть (бесплатно, без VPN) =====
20
- def hf_summarize(text, num_sentences):
21
- """Суммаризация через Hugging Face (пересказ своими словами)"""
22
-
23
- # Ограничиваем текст для модели
24
- if len(text) > 1024:
25
- text = text[:1024]
26
-
27
- # API запрос к бесплатной модели
28
- API_URL = "https://api-inference.huggingface.co/models/facebook/bart-large-cnn"
29
- headers = {"Authorization": "Bearer hf_mock"} # публичный эндпоинт без ключа
30
-
31
- # Для русских текстов пробуем другую модель
32
- prompt = f"Summarize this text in {num_sentences} sentences, preserving key information:\n{text}"
33
-
34
- try:
35
- response = requests.post(
36
- API_URL,
37
- headers=headers,
38
- json={"inputs": prompt, "parameters": {"max_length": 500, "min_length": 50}},
39
- timeout=30
40
- )
41
-
42
- if response.status_code == 200:
43
- result = response.json()
44
- if isinstance(result, list) and len(result) > 0:
45
- return result[0].get('summary_text', result[0].get('generated_text', 'Ошибка'))
46
- return None
47
- except Exception as e:
48
- print(f"HuggingFace ошибка: {e}")
49
- return None
50
-
51
- # ===== Русскоязычная модель (лучше работает с русским) =====
52
- def russian_summarize(text, num_sentences):
53
- """Русскоязычная модель суммаризации"""
54
- if len(text) > 1024:
55
- text = text[:1024]
56
-
57
- API_URL = "https://api-inference.huggingface.co/models/IlyaGusev/mbart_ru_sum_gazeta"
58
- headers = {"Authorization": "Bearer hf_mock"}
59
-
60
- try:
61
- response = requests.post(
62
- API_URL,
63
- headers=headers,
64
- json={"inputs": text, "parameters": {"max_length": 500, "min_length": 50}},
65
- timeout=30
66
- )
67
-
68
- if response.status_code == 200:
69
- result = response.json()
70
- if isinstance(result, list) and len(result) > 0:
71
- return result[0].get('summary_text', str(result[0]))
72
- return None
73
- except Exception as e:
74
- print(f"Русская модель ошибка: {e}")
75
- return None
76
-
77
  def split_sentences(text):
78
  sentences = re.split(r'[.!?]+', text)
79
  sentences = [s.strip() for s in sentences if len(s.strip()) > 10]
@@ -88,14 +29,59 @@ def summarize_text(text, num_sentences):
88
  return result
89
 
90
  def clean_sentence(sent):
91
- skip_start = r'^(кроме того|более того|при этом|также|итак|во-первых|во-вторых|однако|следовательно|наконец|в общем)\s*,?\s*'
 
92
  sent = re.sub(skip_start, '', sent, flags=re.IGNORECASE)
 
 
93
  sent = re.sub(r'\b(\w+)\s+\1\b', r'\1', sent, flags=re.IGNORECASE)
 
 
 
 
 
 
 
94
  sent = sent.strip()
 
95
  if sent and not sent[0].isupper():
96
  sent = sent[0].upper() + sent[1:]
97
  return sent
98
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
  def summarize(text, num_sentences, method, file):
100
  # Загрузка файла
101
  if file is not None:
@@ -121,35 +107,39 @@ def summarize(text, num_sentences, method, file):
121
  if len(text) < 50:
122
  return warning + "❌ Текст слишком короткий. Введите минимум 50 символов.", format_history()
123
 
124
- # ===== ВЫБОР МЕТОДА =====
125
- if method == "Нейросеть (HF)":
126
- result = russian_summarize(text, num_sentences)
127
- if result is None:
128
- result = hf_summarize(text, num_sentences)
129
- if result is None:
130
- result = "⚠️ Нейросеть временно недоступна. Попробуйте позже или выберите LexRank/LSA."
131
- else:
132
- # LexRank или LSA
133
- try:
134
- parser = PlaintextParser.from_string(text, Tokenizer("russian"))
135
- if method == "LexRank":
136
- summarizer = LexRankSummarizer()
137
- else:
138
- summarizer = LsaSummarizer()
139
- summary_sentences = summarizer(parser.document, num_sentences)
140
- result = " ".join(str(s) for s in summary_sentences)
141
- except Exception as e:
142
- print(f"Ошибка в sumy: {e}")
143
- result = summarize_text(text, num_sentences)
144
-
145
- if not result or len(result.strip()) < 10:
146
- result = summarize_text(text, num_sentences)
147
-
148
- # Постобработка для очистки
149
- sentences_out = re.split(r'(?<=[.!?])\s+', result)
150
- cleaned = [clean_sentence(s) for s in sentences_out if len(clean_sentence(s)) > 15]
151
- if cleaned:
152
- result = ' '.join(cleaned)
 
 
 
 
153
 
154
  # Сохранение в историю
155
  history.append({"text": text[:150] + "...", "summary": result[:500]})
@@ -175,7 +165,7 @@ with gr.Blocks(title="Система суммаризации текста") as
175
  text_input = gr.Textbox(label="📝 Исходный текст", lines=12, placeholder="Вставьте текст сюда...")
176
  file_input = gr.File(label="📂 Или загрузите .txt файл", file_types=[".txt"])
177
  slider = gr.Slider(1, 10, value=3, step=1, label="📊 Количество предложений")
178
- method = gr.Radio(["LexRank", "LSA", "Нейросеть (HF)"], label="🔧 Метод суммаризации", value="LexRank")
179
  btn = gr.Button("🔍 Сумма��изировать", variant="primary")
180
  with gr.Column(scale=1):
181
  text_output = gr.Textbox(label="📋 Результат", lines=6)
 
5
  from sumy.summarizers.lsa import LsaSummarizer
6
  import nltk
7
  import re
 
8
 
9
  # Скачиваем данные для nltk
10
  try:
 
15
 
16
  history = []
17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  def split_sentences(text):
19
  sentences = re.split(r'[.!?]+', text)
20
  sentences = [s.strip() for s in sentences if len(s.strip()) > 10]
 
29
  return result
30
 
31
  def clean_sentence(sent):
32
+ # Убираем вводные слова в начале
33
+ skip_start = r'^(кроме того|более того|при этом|также|итак|во-первых|во-вторых|однако|следовательно|наконец|в общем|кстати|например)\s*,?\s*'
34
  sent = re.sub(skip_start, '', sent, flags=re.IGNORECASE)
35
+
36
+ # Убираем повторы слов
37
  sent = re.sub(r'\b(\w+)\s+\1\b', r'\1', sent, flags=re.IGNORECASE)
38
+
39
+ # Убираем лишние прилагательные и наречия (очень, крайне, весьма, достаточно)
40
+ sent = re.sub(r'\b(очень|крайне|весьма|достаточно|слишком)\s+', '', sent, flags=re.IGNORECASE)
41
+
42
+ # Сокращаем конструкции "которые", "что", "где" (упрощаем)
43
+ sent = re.sub(r', (который|которая|которое|которые|что|где|когда) [^,]*[,.]', ', ', sent)
44
+
45
  sent = sent.strip()
46
+ # Делаем первую букву заглавной
47
  if sent and not sent[0].isupper():
48
  sent = sent[0].upper() + sent[1:]
49
  return sent
50
 
51
+ def remove_duplicate_info(sentences):
52
+ """Удаляет предложения, которые несут одинаковую информацию"""
53
+ unique = []
54
+ for s in sentences:
55
+ # Проверяем, не дублирует ли предложение уже добавленные
56
+ is_duplicate = False
57
+ for existing in unique:
58
+ # Если предложения очень похожи (более 70%), считаем дубликатом
59
+ common_words = set(s.split()) & set(existing.split())
60
+ if len(common_words) > min(len(s.split()), len(existing.split())) * 0.7:
61
+ is_duplicate = True
62
+ break
63
+ if not is_duplicate and len(s) > 20:
64
+ unique.append(s)
65
+ return unique
66
+
67
+ def shorten_long_sentence(sent):
68
+ """Сокращает длинное предложение, оставляя только главную мысль"""
69
+ words = sent.split()
70
+ if len(words) <= 15:
71
+ return sent
72
+
73
+ # Ищем ключевые слова (показывают главную мысль)
74
+ keywords = ['важно', 'главное', 'ключевой', 'основной', 'результат', 'итог', 'цель', 'задача']
75
+ keyword_indices = [i for i, w in enumerate(words) if w.lower() in keywords]
76
+
77
+ if keyword_indices:
78
+ # Оставляем часть от ключевого слова
79
+ start = max(0, min(keyword_indices) - 3)
80
+ return ' '.join(words[start:start + 12]) + '...'
81
+
82
+ # Если ключевых слов нет, берем первые 12 слов
83
+ return ' '.join(words[:12]) + '...'
84
+
85
  def summarize(text, num_sentences, method, file):
86
  # Загрузка файла
87
  if file is not None:
 
107
  if len(text) < 50:
108
  return warning + "❌ Текст слишком короткий. Введите минимум 50 символов.", format_history()
109
 
110
+ # Суммаризация
111
+ try:
112
+ parser = PlaintextParser.from_string(text, Tokenizer("russian"))
113
+ if method == "LexRank":
114
+ summarizer = LexRankSummarizer()
115
+ else:
116
+ summarizer = LsaSummarizer()
117
+ summary_sentences = summarizer(parser.document, num_sentences)
118
+ result = " ".join(str(s) for s in summary_sentences)
119
+ except Exception as e:
120
+ print(f"Ошибка: {e}")
121
+ result = summarize_text(text, num_sentences)
122
+
123
+ if not result or len(result.strip()) < 10:
124
+ result = summarize_text(text, num_sentences)
125
+
126
+ # Постобработка: чистим каждое предложение
127
+ sentences_out = re.split(r'(?<=[.!?])\s+', result)
128
+
129
+ # Удаляем дублирующую информацию
130
+ sentences_out = remove_duplicate_info(sentences_out)
131
+
132
+ # Чистим и сокращаем длинные предложения
133
+ cleaned = []
134
+ for s in sentences_out:
135
+ cleaned_s = clean_sentence(s)
136
+ if len(cleaned_s.split()) > 20:
137
+ cleaned_s = shorten_long_sentence(cleaned_s)
138
+ if len(cleaned_s) > 15:
139
+ cleaned.append(cleaned_s)
140
+
141
+ if cleaned:
142
+ result = ' '.join(cleaned)
143
 
144
  # Сохранение в историю
145
  history.append({"text": text[:150] + "...", "summary": result[:500]})
 
165
  text_input = gr.Textbox(label="📝 Исходный текст", lines=12, placeholder="Вставьте текст сюда...")
166
  file_input = gr.File(label="📂 Или загрузите .txt файл", file_types=[".txt"])
167
  slider = gr.Slider(1, 10, value=3, step=1, label="📊 Количество предложений")
168
+ method = gr.Radio(["LexRank", "LSA"], label="🔧 Метод суммаризации", value="LexRank")
169
  btn = gr.Button("🔍 Сумма��изировать", variant="primary")
170
  with gr.Column(scale=1):
171
  text_output = gr.Textbox(label="📋 Результат", lines=6)