Update app.py
Browse files
app.py
CHANGED
|
@@ -2,71 +2,70 @@ import time
|
|
| 2 |
import gradio as gr
|
| 3 |
from transformers import pipeline
|
| 4 |
|
| 5 |
-
#
|
| 6 |
-
MAX_TEXT_LENGTH = 2000
|
| 7 |
-
HISTORY_SIZE = 5
|
| 8 |
|
| 9 |
-
#
|
| 10 |
MODELS = {
|
| 11 |
"Основная модель (rubert-base)": "blanchefort/rubert-base-cased-sentiment",
|
| 12 |
"Быстрая модель (rubert-tiny)": "seara/rubert-tiny2-russian-sentiment"
|
| 13 |
}
|
| 14 |
|
| 15 |
-
#
|
| 16 |
current_model = None
|
| 17 |
model_name = None
|
| 18 |
history = []
|
| 19 |
|
| 20 |
-
#
|
| 21 |
def load_model(selected_model_name):
|
| 22 |
global current_model, model_name
|
| 23 |
if model_name != selected_model_name:
|
| 24 |
model_name = selected_model_name
|
| 25 |
model_path = MODELS[selected_model_name]
|
| 26 |
-
print(f"Загружаем модель: {model_path}")
|
| 27 |
current_model = pipeline("sentiment-analysis", model=model_path)
|
| 28 |
return current_model
|
| 29 |
|
| 30 |
-
#
|
| 31 |
def analyze_sentiment(text, selected_model):
|
| 32 |
global history
|
| 33 |
|
| 34 |
-
#
|
| 35 |
if not text or not text.strip():
|
| 36 |
-
return "
|
| 37 |
|
| 38 |
-
#
|
| 39 |
text = text.strip()
|
| 40 |
if len(text) > MAX_TEXT_LENGTH:
|
| 41 |
text = text[:MAX_TEXT_LENGTH]
|
| 42 |
-
warning = f"
|
| 43 |
else:
|
| 44 |
warning = ""
|
| 45 |
|
| 46 |
-
#
|
| 47 |
start_time = time.time()
|
| 48 |
try:
|
| 49 |
model = load_model(selected_model)
|
| 50 |
result = model(text)[0]
|
| 51 |
elapsed_time = round((time.time() - start_time) * 1000, 1)
|
| 52 |
|
| 53 |
-
#
|
| 54 |
label_ru = {
|
| 55 |
-
"positive": "
|
| 56 |
-
"negative": "
|
| 57 |
-
"neutral": "
|
| 58 |
-
"LABEL_0": "
|
| 59 |
-
"LABEL_1": "
|
| 60 |
-
"LABEL_2": "
|
| 61 |
}.get(result['label'], result['label'])
|
| 62 |
|
| 63 |
score_percent = round(result['score'] * 100, 1)
|
| 64 |
-
result_text = f"
|
| 65 |
-
result_text += f"
|
| 66 |
-
result_text += f"
|
| 67 |
-
result_text += f"
|
| 68 |
|
| 69 |
-
#
|
| 70 |
history_entry = {
|
| 71 |
"text": text[:100] + ("..." if len(text) > 100 else ""),
|
| 72 |
"sentiment": label_ru,
|
|
@@ -75,88 +74,89 @@ def analyze_sentiment(text, selected_model):
|
|
| 75 |
"model": selected_model
|
| 76 |
}
|
| 77 |
|
| 78 |
-
history.insert(0, history_entry)
|
| 79 |
if len(history) > HISTORY_SIZE:
|
| 80 |
-
history.pop()
|
| 81 |
|
| 82 |
-
#
|
| 83 |
-
history_text = "
|
| 84 |
for i, entry in enumerate(history, 1):
|
| 85 |
-
history_text += f"{i}.
|
| 86 |
-
history_text += f"
|
| 87 |
-
history_text += f"
|
| 88 |
|
| 89 |
return warning, result_text, history_text
|
| 90 |
|
| 91 |
except Exception as e:
|
| 92 |
-
return f"
|
| 93 |
|
| 94 |
-
#
|
| 95 |
-
with gr.Blocks(title="
|
| 96 |
|
| 97 |
-
#
|
| 98 |
gr.Markdown("""
|
| 99 |
-
#
|
| 100 |
-
|
| 101 |
""")
|
| 102 |
|
| 103 |
-
#
|
| 104 |
with gr.Row():
|
| 105 |
with gr.Column(scale=2):
|
| 106 |
-
#
|
| 107 |
model_selector = gr.Dropdown(
|
| 108 |
choices=list(MODELS.keys()),
|
| 109 |
value=list(MODELS.keys())[0],
|
| 110 |
-
label="
|
| 111 |
)
|
| 112 |
|
|
|
|
| 113 |
text_input = gr.Textbox(
|
| 114 |
-
label="
|
| 115 |
-
placeholder="
|
| 116 |
lines=5,
|
| 117 |
max_lines=10
|
| 118 |
)
|
| 119 |
|
| 120 |
-
|
|
|
|
| 121 |
|
| 122 |
-
#
|
| 123 |
gr.Examples(
|
| 124 |
examples=[
|
| 125 |
-
["
|
| 126 |
-
["
|
| 127 |
-
["
|
| 128 |
-
["
|
| 129 |
-
["
|
| 130 |
],
|
| 131 |
inputs=text_input,
|
| 132 |
-
label="
|
| 133 |
)
|
| 134 |
|
| 135 |
with gr.Column(scale=3):
|
| 136 |
-
#
|
| 137 |
-
warning_output = gr.Markdown(label="
|
| 138 |
-
result_output = gr.Markdown(label="
|
| 139 |
-
history_output = gr.Markdown(label="
|
| 140 |
|
| 141 |
-
#
|
| 142 |
analyze_btn.click(
|
| 143 |
fn=analyze_sentiment,
|
| 144 |
inputs=[text_input, model_selector],
|
| 145 |
outputs=[warning_output, result_output, history_output]
|
| 146 |
)
|
| 147 |
|
| 148 |
-
#
|
| 149 |
gr.Markdown("---")
|
| 150 |
gr.Markdown("""
|
| 151 |
-
###
|
| 152 |
-
-
|
| 153 |
-
-
|
| 154 |
-
-
|
| 155 |
-
1.
|
| 156 |
-
2.
|
| 157 |
-
- **Технологии:** Hugging Face Transformers + Gradio
|
| 158 |
""")
|
| 159 |
|
| 160 |
-
#
|
| 161 |
if __name__ == "__main__":
|
| 162 |
-
demo.launch(
|
|
|
|
| 2 |
import gradio as gr
|
| 3 |
from transformers import pipeline
|
| 4 |
|
| 5 |
+
# настройки
|
| 6 |
+
MAX_TEXT_LENGTH = 2000
|
| 7 |
+
HISTORY_SIZE = 5
|
| 8 |
|
| 9 |
+
# модели для анализа
|
| 10 |
MODELS = {
|
| 11 |
"Основная модель (rubert-base)": "blanchefort/rubert-base-cased-sentiment",
|
| 12 |
"Быстрая модель (rubert-tiny)": "seara/rubert-tiny2-russian-sentiment"
|
| 13 |
}
|
| 14 |
|
| 15 |
+
# глобальные переменные
|
| 16 |
current_model = None
|
| 17 |
model_name = None
|
| 18 |
history = []
|
| 19 |
|
| 20 |
+
# загрузка модели
|
| 21 |
def load_model(selected_model_name):
|
| 22 |
global current_model, model_name
|
| 23 |
if model_name != selected_model_name:
|
| 24 |
model_name = selected_model_name
|
| 25 |
model_path = MODELS[selected_model_name]
|
|
|
|
| 26 |
current_model = pipeline("sentiment-analysis", model=model_path)
|
| 27 |
return current_model
|
| 28 |
|
| 29 |
+
# основная функция анализа
|
| 30 |
def analyze_sentiment(text, selected_model):
|
| 31 |
global history
|
| 32 |
|
| 33 |
+
# проверка ввода
|
| 34 |
if not text or not text.strip():
|
| 35 |
+
return "ошибка: введите текст для анализа", "", ""
|
| 36 |
|
| 37 |
+
# ограничение длины
|
| 38 |
text = text.strip()
|
| 39 |
if len(text) > MAX_TEXT_LENGTH:
|
| 40 |
text = text[:MAX_TEXT_LENGTH]
|
| 41 |
+
warning = f"текст обрезан до {MAX_TEXT_LENGTH} символов"
|
| 42 |
else:
|
| 43 |
warning = ""
|
| 44 |
|
| 45 |
+
# загрузка модели
|
| 46 |
start_time = time.time()
|
| 47 |
try:
|
| 48 |
model = load_model(selected_model)
|
| 49 |
result = model(text)[0]
|
| 50 |
elapsed_time = round((time.time() - start_time) * 1000, 1)
|
| 51 |
|
| 52 |
+
# перевод меток на русский
|
| 53 |
label_ru = {
|
| 54 |
+
"positive": "позитивный",
|
| 55 |
+
"negative": "негативный",
|
| 56 |
+
"neutral": "нейтральный",
|
| 57 |
+
"LABEL_0": "негативный",
|
| 58 |
+
"LABEL_1": "нейтральный",
|
| 59 |
+
"LABEL_2": "позитивный"
|
| 60 |
}.get(result['label'], result['label'])
|
| 61 |
|
| 62 |
score_percent = round(result['score'] * 100, 1)
|
| 63 |
+
result_text = f"результат: {label_ru}\n"
|
| 64 |
+
result_text += f"уверенность: {score_percent}%\n"
|
| 65 |
+
result_text += f"время анализа: {elapsed_time} мс\n"
|
| 66 |
+
result_text += f"модель: {selected_model}"
|
| 67 |
|
| 68 |
+
# добавление в историю
|
| 69 |
history_entry = {
|
| 70 |
"text": text[:100] + ("..." if len(text) > 100 else ""),
|
| 71 |
"sentiment": label_ru,
|
|
|
|
| 74 |
"model": selected_model
|
| 75 |
}
|
| 76 |
|
| 77 |
+
history.insert(0, history_entry)
|
| 78 |
if len(history) > HISTORY_SIZE:
|
| 79 |
+
history.pop()
|
| 80 |
|
| 81 |
+
# форматирование истории
|
| 82 |
+
history_text = "история запросов:\n"
|
| 83 |
for i, entry in enumerate(history, 1):
|
| 84 |
+
history_text += f"{i}. текст: {entry['text']}\n"
|
| 85 |
+
history_text += f" тональность: {entry['sentiment']} ({entry['confidence']})\n"
|
| 86 |
+
history_text += f" время: {entry['time']} мс | модель: {entry['model']}\n\n"
|
| 87 |
|
| 88 |
return warning, result_text, history_text
|
| 89 |
|
| 90 |
except Exception as e:
|
| 91 |
+
return f"ошибка: {str(e)}", "", ""
|
| 92 |
|
| 93 |
+
# создание интерфейса
|
| 94 |
+
with gr.Blocks(title="анализатор тональности", theme=gr.themes.Soft()) as demo:
|
| 95 |
|
| 96 |
+
# заголовок
|
| 97 |
gr.Markdown("""
|
| 98 |
+
# анализатор тональности текста
|
| 99 |
+
определение тональности: позитивный, негативный, нейтральный
|
| 100 |
""")
|
| 101 |
|
| 102 |
+
# основная часть
|
| 103 |
with gr.Row():
|
| 104 |
with gr.Column(scale=2):
|
| 105 |
+
# выбор модели
|
| 106 |
model_selector = gr.Dropdown(
|
| 107 |
choices=list(MODELS.keys()),
|
| 108 |
value=list(MODELS.keys())[0],
|
| 109 |
+
label="выберите модель"
|
| 110 |
)
|
| 111 |
|
| 112 |
+
# поле ввода
|
| 113 |
text_input = gr.Textbox(
|
| 114 |
+
label="введите текст на русском",
|
| 115 |
+
placeholder="введите текст здесь...",
|
| 116 |
lines=5,
|
| 117 |
max_lines=10
|
| 118 |
)
|
| 119 |
|
| 120 |
+
# кнопка
|
| 121 |
+
analyze_btn = gr.Button("анализировать", variant="primary")
|
| 122 |
|
| 123 |
+
# примеры
|
| 124 |
gr.Examples(
|
| 125 |
examples=[
|
| 126 |
+
["это просто прекрасный день, я так счастлив!"],
|
| 127 |
+
["ужасное обслуживание, никогда больше не приду."],
|
| 128 |
+
["ну, обычный день, ничего особенного."],
|
| 129 |
+
["товар соответствует описанию, доставка быстрая."],
|
| 130 |
+
["ожидал большего, качество оставляет желать лучшего."]
|
| 131 |
],
|
| 132 |
inputs=text_input,
|
| 133 |
+
label="примеры для теста"
|
| 134 |
)
|
| 135 |
|
| 136 |
with gr.Column(scale=3):
|
| 137 |
+
# вывод
|
| 138 |
+
warning_output = gr.Markdown(label="уведомления")
|
| 139 |
+
result_output = gr.Markdown(label="результат анализа")
|
| 140 |
+
history_output = gr.Markdown(label="история запросов", value="история запросов:\nздесь будет история ваших запросов")
|
| 141 |
|
| 142 |
+
# обработка нажатия
|
| 143 |
analyze_btn.click(
|
| 144 |
fn=analyze_sentiment,
|
| 145 |
inputs=[text_input, model_selector],
|
| 146 |
outputs=[warning_output, result_output, history_output]
|
| 147 |
)
|
| 148 |
|
| 149 |
+
# информация
|
| 150 |
gr.Markdown("---")
|
| 151 |
gr.Markdown("""
|
| 152 |
+
### информация о проекте
|
| 153 |
+
- максимальная длина текста: 2000 символов
|
| 154 |
+
- история запросов: последние 5 запросов
|
| 155 |
+
- доступные модели:
|
| 156 |
+
1. основная модель (rubert-base) - более точная
|
| 157 |
+
2. быстрая модель (rubert-tiny) - более быстрая
|
|
|
|
| 158 |
""")
|
| 159 |
|
| 160 |
+
# запуск
|
| 161 |
if __name__ == "__main__":
|
| 162 |
+
demo.launch()
|