Downloads · 30 days
7
20% of all-time downloads
ArtemBelogur/essay_scoring_model
essay_scoring_model is a machine learning model from ArtemBelogur. Use it for the machine learning task on the model card, and read the license before you ship it in a product. The card lists the license as mit.
The model is used to predict scores for 4 IELTS parameters:
Downloads · 30 days
7
20% of all-time downloads
All-time downloads
35
Public
Repo size
1.5 GB
Likes
0
Public
Click a slice to open those files.
.pt736 MB · 66%
From the Hugging Face model README
The model is used to predict scores for 4 IELTS parameters:
import torch
from torch import nn
from transformers import AutoTokenizer, AutoModel, AutoModelForSequenceClassification, TrOCRProcessor, VisionEncoderDecoderModel
from huggingface_hub import constants
constants.REQUESTS_TIMEOUT = 60 # Устанавливаем тайм-аут в 60 секунд
from typing import List, Union
from tqdm import tqdm
import numpy as np
from PIL import Image
import cv2
import os
import warnings
from huggingface_hub import hf_hub_download
from app.craft_text_detector import Craft
from openai import OpenAI
import re
warnings.filterwarnings('ignore')
class MeanPooling(nn.Module):
def forward(self, last_hidden_state, attention_mask):
input_mask_expanded = attention_mask.unsqueeze(-1).expand(last_hidden_state.size()).float()
sum_embeddings = torch.sum(last_hidden_state * input_mask_expanded, 1)
sum_mask = input_mask_expanded.sum(1)
return sum_embeddings / torch.clamp(sum_mask, min=1e-9)
class EssayScorer(nn.Module):
def __init__(self, model_name, num_labels):
super().__init__()
self.backbone = AutoModel.from_pretrained(model_name)
self.pool = MeanPooling()
self.dropout = nn.Dropout(0.3)
self.classifiers = nn.ModuleList([
nn.Linear(self.backbone.config.hidden_size, num_labels) for _ in range(4)
])
def forward(self, input_ids, attention_mask, token_type_ids=None):
outputs = self.backbone(input_ids=input_ids, attention_mask=attention_mask)
last_hidden_state = outputs.last_hidden_state
pooled_output = self.pool(last_hidden_state, attention_mask)
pooled_output = self.dropout(pooled_output)
logits = [classifier(pooled_output) for classifier in self.classifiers]
return logits
class EssayScoringService:
def __init__(
self,
model_path: str,
model_name: str = "microsoft/deberta-v3-base",
num_labels: int = 17, # scores from 1 to 9 -> 17 classes
device: Union[str, torch.device] = None
):
if not os.path.exists(model_path):
model_path = hf_hub_download(
repo_id="ArtemBelogur/essay_scoring_model",
filename="best_model1.pt",
local_dir="app/models"
)
self.device = device or ("cuda" if torch.cuda.is_available() else "cpu")
self.tokenizer = AutoTokenizer.from_pretrained(model_name, use_fast=False)
self.model = EssayScorer(model_name, num_labels)
self.model.load_state_dict(torch.load(model_path, map_location=self.device))
self.model.to(self.device)
self.model.eval()
self.id2label = {i: round(1.0 + 0.5 * i, 1) for i in range(num_labels)}
def predict(
self,
topics: List[str],
essays: List[str],
batch_size: int = 32
) -> List[List[float]]:
assert len(topics) == len(essays), "length of topics and essays lists must be the same"
results = []
for i in range(0, len(essays), batch_size):
batch_essays = essays[i:i + batch_size]
batch_topics = topics[i:i + batch_size]
batch_inputs = [
f"{topic} [SEP] {essay}" for topic, essay in zip(batch_topics, batch_essays)
]
encodings = self.tokenizer(
batch_inputs,
padding=True,
truncation=True,
return_tensors="pt",
max_length=512
).to(self.device)
with torch.no_grad():
logits = self.model(encodings["input_ids"], encodings["attention_mask"])
batch_preds = [
torch.argmax(logit, dim=1).cpu().tolist()
for logit in logits # list with 4 tensors
]
# транспонируем список: [4][batch] → [batch][4]
batch_preds = list(map(list, zip(*batch_preds)))
results.extend([[self.id2label[i] for i in row] for row in batch_preds])
return results
def get_scorer_single_essay(model_path="%path_to_best_model1%/best_model1.pt"): # Here you need to replace path
return EssayScoringService(model_path)
scorer = get_scorer_single_essay()
topics = [
'Imagine you can travel to any historical period for 24 hours. Where would you go and why? What would you do?'
]
full_text = [
'Travel to the past is a common plot in modern literature or movies. Sometimes, people do it with an aim to change present where they encountered with unstandable obstacles or to sutisfy own inquisitivity. When the first one has too many side effects, the second desire is very natural for me. However, if I’m limited by time and opportunities, there is not any point to do it.\n\nThe first problem for me is that twenty four hours is too short period to do anything. I do not think that in that time I would be able to understand or percept the age where I am. Therefore I would prefer to reject the idea. But it is only the first reason.\n\nThe second thing that seems me strage is our confidence in being able to be alive and have a possibility to explore the world of the chosen time. The farther time ago we take, the harder for us to live there. I am pretty sure that If I chase the sixteen century and travelled to there, it would be very difficult to make any contact with the people that could not even understand me normally. So I am not talking about earlier periods of human history.\n\nTo summarize, the trip to the past sounds amazing and fascinating but only with the several conditions. Firstly, I want to be unlimited in time to be able to spend more than twenty four hours there. Second, I want to be unlimited in space to be able to visit different places, because you can not percept the age if you see only one small point of land. Third, there should be some mechanism to supply my basics human needs that I can not sutisfy in that time. It might seem that I want too much, but I really think that without all the conditions, the time travelling would be useless or only one directional.'
]
scores = scorer.predict([topic], [full_text])[0]