ASureevaA commited on
Commit
529a697
·
1 Parent(s): 2717a3f
Files changed (1) hide show
  1. app.py +8 -54
app.py CHANGED
@@ -14,30 +14,17 @@ from transformers import (
14
  AutoTokenizer,
15
  )
16
 
17
-
18
- # ============================
19
- # 1. Настройки устройства
20
- # ============================
21
-
22
- # Жёстко работаем на CPU: в Space нет доступа к GPU
23
  device_string: str = "cpu"
24
 
25
-
26
- # ============================
27
- # 2. OCR (easyocr, английский)
28
- # ============================
29
-
30
  ocr_reader = easyocr.Reader(
31
- ["en"], # язык OCR: английский
32
- gpu=False, # принудительно без GPU
33
  )
34
 
35
 
36
  def run_ocr(image_object: Image.Image) -> str:
37
  """
38
  OCR для печатного английского текста.
39
- Используем easyocr, который достаточно устойчив к
40
- реальным сканам и фотографиям документа на CPU.
41
  """
42
  if image_object is None:
43
  return ""
@@ -56,11 +43,6 @@ def run_ocr(image_object: Image.Image) -> str:
56
  recognized_text: str = "\n".join(text_parts).strip()
57
  return recognized_text
58
 
59
-
60
- # ============================
61
- # 3. Трансформер #1: классификация текста (английский)
62
- # ============================
63
-
64
  text_classifier_pipeline = pipeline(
65
  task="text-classification",
66
  model="distilbert-base-uncased-finetuned-sst-2-english",
@@ -69,12 +51,7 @@ text_classifier_pipeline = pipeline(
69
 
70
  def run_text_classification(input_text: str) -> str:
71
  """
72
- Анализ текста трансформером:
73
- используем sentiment-классификатор как пример.
74
- Возвращаем строку вида: "POSITIVE (score=0.982)".
75
-
76
- ВАЖНО: жёстко ограничиваем длину до 512 токенов, чтобы не ловить
77
- ошибку DistilBERT по max_position_embeddings.
78
  """
79
  cleaned_text: str = input_text.strip()
80
  if not cleaned_text:
@@ -93,9 +70,6 @@ def run_text_classification(input_text: str) -> str:
93
  classification_text: str = f"{label_value} (score={score_value:.3f})"
94
  return classification_text
95
 
96
- # ============================
97
- # 4. Трансформер #2: суммаризация (английский)
98
- # ============================
99
 
100
  summary_pipeline = pipeline(
101
  task="summarization",
@@ -109,7 +83,6 @@ def run_summarization(
109
  ) -> str:
110
  """
111
  Английская суммаризация.
112
- Без разбиения на чанки, поэтому очень длинные тексты лучше не подавать.
113
  """
114
  cleaned_text: str = input_text.strip()
115
  if not cleaned_text:
@@ -121,7 +94,6 @@ def run_summarization(
121
  max(32, word_count + 20),
122
  )
123
 
124
- # Для очень короткого текста суммаризация мало смысла
125
  if word_count < 8:
126
  return cleaned_text
127
 
@@ -136,10 +108,6 @@ def run_summarization(
136
  return summary_text
137
 
138
 
139
- # ============================
140
- # 5. Трансформер #3: TTS (английский, MMS VITS)
141
- # ============================
142
-
143
  tts_model: VitsModel = VitsModel.from_pretrained("facebook/mms-tts-eng")
144
  tts_tokenizer: AutoTokenizer = AutoTokenizer.from_pretrained("facebook/mms-tts-eng")
145
  tts_model.to(device_string)
@@ -148,9 +116,6 @@ tts_model.to(device_string)
148
  def run_tts(summary_text: str) -> Optional[str]:
149
  """
150
  Озвучка английского текста конспекта через VitsModel (facebook/mms-tts-eng).
151
-
152
- Если модель внутри упадёт на каком-то странном тексте (RuntimeError),
153
- просто вернём None и не будем ронять всё приложение.
154
  """
155
  cleaned_text: str = summary_text.strip()
156
  if not cleaned_text:
@@ -177,7 +142,6 @@ def run_tts(summary_text: str) -> Optional[str]:
177
  print(f"[WARN] TTS RuntimeError: {runtime_error}")
178
  return None
179
 
180
- # Приводим к numpy и ограничиваем амплитуды
181
  waveform_array = waveform_tensor.squeeze().cpu().numpy().astype("float32")
182
  waveform_array = numpy_module.clip(waveform_array, -1.0, 1.0)
183
 
@@ -195,20 +159,15 @@ def run_tts(summary_text: str) -> Optional[str]:
195
  return file_path
196
 
197
 
198
- # ============================
199
- # 6. Полный пайплайн
200
- # ============================
201
-
202
  def full_flow(
203
  image_object: Image.Image,
204
  max_summary_tokens: int = 128,
205
  ) -> Tuple[str, str, str, Optional[str]]:
206
  """
207
- Полный пайплайн:
208
- 1) OCR (easyocr): изображение -> исходный текст (английский)
209
- 2) Классификация текста трансформером (sentiment)
210
- 3) Суммаризация: текст -> конспект
211
- 4) TTS: конспект -> .wav файл (или None, если TTS не смог)
212
  """
213
  recognized_text: str = run_ocr(image_object=image_object)
214
 
@@ -224,10 +183,6 @@ def full_flow(
224
  return recognized_text, classification_text, summary_text, audio_file_path
225
 
226
 
227
- # ============================
228
- # 7. Gradio UI (на русском)
229
- # ============================
230
-
231
  gradio_interface = gradio_module.Interface(
232
  fn=full_flow,
233
  inputs=[
@@ -266,8 +221,7 @@ gradio_interface = gradio_module.Interface(
266
  "1) easyocr распознаёт печатный английский текст с картинки.\n"
267
  "2) Трансформер-классификатор (DistilBERT) оценивает тон текста.\n"
268
  "3) Трансформер-суммаризатор (DistilBART) делает краткий конспект.\n"
269
- "4) Трансформер TTS (MMS VITS) озвучивает конспект.\n"
270
- "В проекте используются три трансформера с Hugging Face, OCR сделан через easyocr."
271
  ),
272
  )
273
 
 
14
  AutoTokenizer,
15
  )
16
 
 
 
 
 
 
 
17
  device_string: str = "cpu"
18
 
 
 
 
 
 
19
  ocr_reader = easyocr.Reader(
20
+ ["en"],
21
+ gpu=False,
22
  )
23
 
24
 
25
  def run_ocr(image_object: Image.Image) -> str:
26
  """
27
  OCR для печатного английского текста.
 
 
28
  """
29
  if image_object is None:
30
  return ""
 
43
  recognized_text: str = "\n".join(text_parts).strip()
44
  return recognized_text
45
 
 
 
 
 
 
46
  text_classifier_pipeline = pipeline(
47
  task="text-classification",
48
  model="distilbert-base-uncased-finetuned-sst-2-english",
 
51
 
52
  def run_text_classification(input_text: str) -> str:
53
  """
54
+ Анализ текста трансформером.
 
 
 
 
 
55
  """
56
  cleaned_text: str = input_text.strip()
57
  if not cleaned_text:
 
70
  classification_text: str = f"{label_value} (score={score_value:.3f})"
71
  return classification_text
72
 
 
 
 
73
 
74
  summary_pipeline = pipeline(
75
  task="summarization",
 
83
  ) -> str:
84
  """
85
  Английская суммаризация.
 
86
  """
87
  cleaned_text: str = input_text.strip()
88
  if not cleaned_text:
 
94
  max(32, word_count + 20),
95
  )
96
 
 
97
  if word_count < 8:
98
  return cleaned_text
99
 
 
108
  return summary_text
109
 
110
 
 
 
 
 
111
  tts_model: VitsModel = VitsModel.from_pretrained("facebook/mms-tts-eng")
112
  tts_tokenizer: AutoTokenizer = AutoTokenizer.from_pretrained("facebook/mms-tts-eng")
113
  tts_model.to(device_string)
 
116
  def run_tts(summary_text: str) -> Optional[str]:
117
  """
118
  Озвучка английского текста конспекта через VitsModel (facebook/mms-tts-eng).
 
 
 
119
  """
120
  cleaned_text: str = summary_text.strip()
121
  if not cleaned_text:
 
142
  print(f"[WARN] TTS RuntimeError: {runtime_error}")
143
  return None
144
 
 
145
  waveform_array = waveform_tensor.squeeze().cpu().numpy().astype("float32")
146
  waveform_array = numpy_module.clip(waveform_array, -1.0, 1.0)
147
 
 
159
  return file_path
160
 
161
 
 
 
 
 
162
  def full_flow(
163
  image_object: Image.Image,
164
  max_summary_tokens: int = 128,
165
  ) -> Tuple[str, str, str, Optional[str]]:
166
  """
167
+ 1) OCR
168
+ 2) Классификация текста
169
+ 3) Суммаризация
170
+ 4) TTS
 
171
  """
172
  recognized_text: str = run_ocr(image_object=image_object)
173
 
 
183
  return recognized_text, classification_text, summary_text, audio_file_path
184
 
185
 
 
 
 
 
186
  gradio_interface = gradio_module.Interface(
187
  fn=full_flow,
188
  inputs=[
 
221
  "1) easyocr распознаёт печатный английский текст с картинки.\n"
222
  "2) Трансформер-классификатор (DistilBERT) оценивает тон текста.\n"
223
  "3) Трансформер-суммаризатор (DistilBART) делает краткий конспект.\n"
224
+ "4) Трансформер TTS (MMS VITS) озвучивает конспект."
 
225
  ),
226
  )
227