ivanovot commited on
Commit
6cc6c10
·
1 Parent(s): e5d6f4d

Add application file

Browse files
LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2024 ivanovot
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
app.py ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from model import model # Импортируем вашу модель
3
+
4
+ # Токсичные и нетоксичные комментарии для тестирования
5
+ examples = [
6
+ ["Страницу обнови, дебил. Это тоже не оскорбление, а доказанный факт - не-дебил про себя во множественном числе писать не будет. Или мы в тебя верим - это ты и твои воображаемые друзья?"],
7
+ ["УПАД Т! ТАМ НЕЛЬЗЯ СТРОИТЬ! ТЕХНОЛОГИЙ НЕТ! РАЗВОРУЮТ КАК ВСЕГДА! УЖЕ ТРЕЩИНАМИ ПОШ Л! ТУПЫЕ КИТАЗЫ НЕ МОГУТ НИЧЕГО НОРМАЛЬНО СДЕЛАТЬ!"],
8
+ ["хорош врать, ты террорист-торчёк-шизофреник пруф: а вот без костюма да чутка учёный, миллиардер, филантроп"],
9
+ ["Мне Вас очень жаль, если для Вас оскорбления - норма"],
10
+ ["Осторожней на сверхманёврах. В предыдущей методичке у вас было написано, что добрые арабы никогда ни с кем не воевали, только торговали пряностями, лел. Шапочку из фольги сними"],
11
+ ["Так то стоит около 12,5 тысяч, но мне вышло в 6636 рублей и бесплатная доставка"],
12
+ ["Ну хочешь я стану твоим другом? Как тебя зовут? Чем увлекаешься?"],
13
+ ["Ну так это в плане изготовления изделий своими руками,а вот готовить вроде умею.Короче буду сам на себе испытывать божественный напиток и куплю огнетушитель (промышленный на всякий случай)."],
14
+ ["Я согласен, что это хорошая идея! Давайте подумаем, как можно улучшить её еще больше."],
15
+ ["Очень полезная информация, спасибо за подробное объяснение! Я многому научился."],
16
+ ["Мне нравится, как вы объясняете! Это действительно помогает разобраться в теме."],
17
+ ["Отлично написано, теперь я лучше понимаю, как работать с этим инструментом."],
18
+ ["Классная идея! Надо попробовать и посмотреть, как это работает на практике."],
19
+ ["Ваши советы очень полезны. Это точно сэкономит мне время на следующий раз."],
20
+ ["Спасибо за ваши рекомендации! Я обязательно попробую это в будущем."],
21
+ ["Мне нравится ваше решение этой проблемы. Очень креативно и практично."],
22
+ ["Спасибо за помощь! Вы помогли мне разобраться в ситуации и сэкономить много времени."],
23
+ ["Согласен с вами, это действительно важный аспект, о котором стоит задуматься."],
24
+ ["Очень вдохновляющий пост! Я буду следовать вашим рекомендациям."],
25
+ ]
26
+
27
+ # Функция для предсказания токсичности текста
28
+ def predict_text(text):
29
+ word_count = len(text.split())
30
+ if word_count < 7:
31
+ return "Слишком короткий текст"
32
+
33
+ output = model.predict(text)
34
+ return "Токсичный" if output == 1 else "Не токсичный"
35
+
36
+ # Создаем интерфейс с улучшениями
37
+ demo = gr.Interface(
38
+ fn=predict_text, # Функция для предсказания
39
+ inputs=gr.Textbox(
40
+ label="Введите текст для проверки на токсичность", # Подпись для текстового поля
41
+ placeholder="Напишите комментарий для анализа", # Подсказка для поля ввода
42
+ lines=5, # Количество строк для текста
43
+ interactive=True, # Интерактивность для пользователя
44
+ ),
45
+ outputs=gr.Textbox(
46
+ label="Результат анализа", # Подпись для вывода
47
+ placeholder="Результат токсичности текста будет здесь", # Подсказка для вывода
48
+ ),
49
+ live=True, # Включаем live обновление
50
+ examples=examples, # Примеры для пользователей
51
+ title="Тестирование токсичности текста", # Заголовок интерфейса
52
+ description="Введите любой текст, чтобы проверить его на токсичность. Модель проанализирует, является ли текст токсичным или нет.", # Описание
53
+ )
54
+
55
+ # Запуск приложения с улучшенным интерфейсом
56
+ demo.launch(server_name="127.0.0.1", server_port=7860)
main.py ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, Query
2
+ from model import model # Импортируйте вашу модель
3
+
4
+ app = FastAPI()
5
+
6
+ @app.get("/", response_model=int)
7
+ async def predict(text: str = Query(...)):
8
+ """
9
+ Эндпоинт для предсказания. Принимает текстовый параметр в запросе.
10
+
11
+ :param text: текст для предсказания
12
+ :return: предсказание модели
13
+ """
14
+ # Получаем предсказание от модели
15
+ output = model.predict(text)
16
+
17
+ # Возвращаем результат
18
+ return output
19
+
20
+ if __name__ == "__main__":
21
+ import uvicorn
22
+ uvicorn.run(app, host="127.0.0.1", port=8000)
model.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d450dffd595a4046900b27864c6df703e62a658bf5e74e3a4230a2c86040f359
3
+ size 732509954
model/__init__.py ADDED
@@ -0,0 +1 @@
 
 
1
+ from .model import model
model/__pycache__/__init__.cpython-312.pyc ADDED
Binary file (176 Bytes). View file
 
model/__pycache__/model.cpython-312.pyc ADDED
Binary file (3.69 kB). View file
 
model/model.py ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from transformers import BertTokenizer, BertModel
3
+ import torch.nn as nn
4
+
5
+ class PowerfulBinaryTextClassifier(nn.Module):
6
+ def __init__(self, model_name, lstm_hidden_size=256, num_layers=3, dropout_rate=0.2):
7
+ super(PowerfulBinaryTextClassifier, self).__init__()
8
+ self.bert = BertModel.from_pretrained(model_name)
9
+
10
+ # Добавляем несколько LSTM слоев с большим размером скрытого состояния
11
+ self.lstm = nn.LSTM(input_size=self.bert.config.hidden_size,
12
+ hidden_size=lstm_hidden_size,
13
+ num_layers=num_layers,
14
+ batch_first=True,
15
+ bidirectional=True,
16
+ dropout=dropout_rate if num_layers > 1 else 0)
17
+
18
+ # Полносвязный блок с увеличенным количеством нейронов и слоев Dropout
19
+ self.fc = nn.Sequential(
20
+ nn.Linear(lstm_hidden_size * 2, 2), # полносвязный слой
21
+ nn.Sigmoid()
22
+ )
23
+
24
+ self.tokenizer = BertTokenizer.from_pretrained(model_name) # Инициализация токенизатора
25
+
26
+ self.device = 'cuda' if torch.cuda.is_available() else 'cpu'
27
+
28
+ def forward(self, input_ids, attention_mask):
29
+ outputs = self.bert(input_ids=input_ids, attention_mask=attention_mask)
30
+ bert_outputs = outputs.last_hidden_state # (batch_size, sequence_length, hidden_size)
31
+
32
+ # Применяем LSTM
33
+ lstm_out, _ = self.lstm(bert_outputs) # (batch_size, sequence_length, lstm_hidden_size * 2)
34
+
35
+ # Берем выход последнего временного шага для классификации
36
+ last_time_step = lstm_out[:, -1, :] # (batch_size, lstm_hidden_size * 2)
37
+
38
+ logits = self.fc(last_time_step) # Применяем полносвязный блок
39
+
40
+ logits[:, 1] -= 0.995 # Умножаем логит для выбранного класса
41
+
42
+ return logits # Возвращаем логиты для двух классов
43
+
44
+ def predict(self, text):
45
+ self.to(self.device) # Переносим модель на выбранное устройство
46
+
47
+ # Токенизация текста
48
+ inputs = self.tokenizer(text, return_tensors="pt", padding=True, truncation=True, max_length=256)
49
+ input_ids = inputs['input_ids'].to(self.device) # Переносим на устройство
50
+ attention_mask = inputs['attention_mask'].to(self.device) # Переносим на устройство
51
+
52
+ # Получение предсказания
53
+ self.eval() # Переключаем модель в режим оценки
54
+ with torch.no_grad():
55
+ preds = self(input_ids, attention_mask) # Получаем логиты
56
+
57
+ # Возвращаем индекс класса с наибольшей вероятностью
58
+ return torch.argmax(preds, dim=1).item() # Возвращаем индекс класса
59
+
60
+ def load_weights(self, filepath):
61
+ # Загрузка весов модели
62
+ self.load_state_dict(torch.load(filepath, map_location=self.device, weights_only=True))
63
+
64
+ # Пример инициализации модели
65
+ model_name = "DeepPavlov/rubert-base-cased"
66
+ model = PowerfulBinaryTextClassifier(model_name)
67
+
68
+ model.load_weights('model.pth')
requirements.txt ADDED
Binary file (2.25 kB). View file