From 7b1e944abde9f56d4baaa45daab7fbb2ac1137a8 Mon Sep 17 00:00:00 2001 From: KAKornienko Date: Wed, 12 Oct 2022 15:54:02 +0500 Subject: [PATCH] =?UTF-8?q?=D0=A1=D0=B4=D0=B5=D0=BB=D0=B0=D0=BB=20=D1=82?= =?UTF-8?q?=D0=B5=D1=81=D1=82=D0=BE=D0=B2=D0=BE=D0=B5=20=D0=B7=D0=B0=D0=B4?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- python/Dockerfile | 18 +++++++++++ python/README.md | 58 ++++------------------------------ python/app/OutFormating.py | 6 ++++ python/app/emotion_analyzer.py | 16 ++++++++++ python/app/main.py | 12 +++++++ python/requirements.txt | 6 ++++ 6 files changed, 64 insertions(+), 52 deletions(-) create mode 100644 python/Dockerfile create mode 100644 python/app/OutFormating.py create mode 100644 python/app/emotion_analyzer.py create mode 100644 python/app/main.py create mode 100644 python/requirements.txt diff --git a/python/Dockerfile b/python/Dockerfile new file mode 100644 index 0000000..34d4d1d --- /dev/null +++ b/python/Dockerfile @@ -0,0 +1,18 @@ +# +FROM python:3.10 + +# +WORKDIR /code + +# +COPY ./requirements.txt /code/requirements.txt + +# +RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt + +# +COPY ./app /code/app +# +ENV PYTHONPATH="/code/app" +# +CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] \ No newline at end of file diff --git a/python/README.md b/python/README.md index c4abd13..b7cb3ef 100644 --- a/python/README.md +++ b/python/README.md @@ -1,53 +1,7 @@ -# Тестовое задание для Python разработчика -## Рекомендации по выполнению задания -1. Использовать python для выполнения задания -2. Применить для разработки API сервиса фреймворк FastAPI -4. Использовать библиотеки FastAPI, torch, transformers -5. Для запуска FastAPI использовать uvicorn +Для запуска приложения необходимо установить и включить Docker Desktop последней версии +Находясь в директории с Dockerfile запустить следующие команды: +docker build -t myimage . +docker run -d --name mycontainer -p 8000:8000 myimage -## Задание -1. Встроить модель (https://huggingface.co/Aniemore/rubert-tiny2-russian-emotion-detection) в API сервис. Модель выполняет анализ тональности (sentiment analysis) предложения. -2. В API сервисе нужно реализовать endpoint на который методом POST будет отправляться предложение для анализа. Название эндпоинта придумать самостоятельно. - ### Пример: - #### Запрос: -```` -{"text": "Это API сервис"} -```` - #### Ответ: -```` -{ - "results": [ - { - "label": "neutral", - "score": 0.9809684157371521 - }, - { - "label": "enthusiasm", - "score": 0.006884392816573381 - }, - { - "label": "anger", - "score": 0.006308802869170904 - }, - { - "label": "sadness", - "score": 0.006137280724942684 - }, - { - "label": "happiness", - "score": 0.004910049494355917 - }, - { - "label": "fear", - "score": 0.004772619344294071 - }, - { - "label": "disgust", - "score": 0.002789509715512395 - } - ] -} - ```` -3. В сервисе реализовать сборку документации(swagger) которая должны быть доступна по URL `/docs`. -4. Сделать ПР с кодом и Dockerfile для сборки контейнера с сервисом. После запуска контейнера сервис должен быть доступен на порту 8000. (localhost:8000). Версии пакетов зафиксировать в requirements.txt. -5. Написать краткую инструкцию по запуску. +Приложение принимает POST запросы по адресу localhost:8000/analyze/{text} +Документация доступная по localhost:8000/docs diff --git a/python/app/OutFormating.py b/python/app/OutFormating.py new file mode 100644 index 0000000..911d324 --- /dev/null +++ b/python/app/OutFormating.py @@ -0,0 +1,6 @@ +def decorate(dictionary): + output = {"results" : []} + for key, value in dictionary.items(): + output["results"].append({"label" : key, "score" : value}) + return output + diff --git a/python/app/emotion_analyzer.py b/python/app/emotion_analyzer.py new file mode 100644 index 0000000..2ddf8e7 --- /dev/null +++ b/python/app/emotion_analyzer.py @@ -0,0 +1,16 @@ +import torch +from transformers import BertForSequenceClassification, AutoTokenizer + +LABELS = ["neutral", "happiness", "sadness", "enthusiasm", "fear", "anger", "disgust"] +tokenizer = AutoTokenizer.from_pretrained('Aniemore/rubert-tiny2-russian-emotion-detection') +model = BertForSequenceClassification.from_pretrained('Aniemore/rubert-tiny2-russian-emotion-detection') + +@torch.no_grad() +def predict_emotions(text: str) -> list: + inputs = tokenizer(text, max_length=512, padding=True, truncation=True, return_tensors="pt") + outputs = model(**inputs) + predicted = torch.nn.functional.softmax(outputs.logits, dim=1) + emotions_list = {} + for i in range(len(predicted.numpy()[0].tolist())): + emotions_list[LABELS[i]] = predicted.numpy()[0].tolist()[i] + return emotions_list diff --git a/python/app/main.py b/python/app/main.py new file mode 100644 index 0000000..64a1730 --- /dev/null +++ b/python/app/main.py @@ -0,0 +1,12 @@ +from fastapi import FastAPI +import emotion_analyzer +import OutFormating + +app = FastAPI() + +@app.post("/analyze/{text}") +def analyze_text(text: str): + """ Принимает строку и возвращает анализ эмоций введённого сообщения """ + analysis_result = emotion_analyzer.predict_emotions(text) + return OutFormating.decorate(analysis_result) + diff --git a/python/requirements.txt b/python/requirements.txt new file mode 100644 index 0000000..7b85162 --- /dev/null +++ b/python/requirements.txt @@ -0,0 +1,6 @@ +fastapi==0.85.0 +huggingface-hub==0.10.0 +pydantic==1.10.2 +torch==1.12.1 +transformers==4.22.2 +uvicorn==0.18.3 \ No newline at end of file