alphaprep commited on
Commit
0c9965a
·
verified ·
1 Parent(s): 71bcad8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +62 -29
app.py CHANGED
@@ -14,20 +14,20 @@ tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
14
  model.eval()
15
 
16
  # -------------------------------
17
- # Scoring function
18
  # -------------------------------
19
  def score_essay(essay: str):
20
- # Empty essay → zero scores
21
- if not essay or not essay.strip():
22
  return {
23
  "Task Achievement": 0.0,
24
  "Coherence & Cohesion": 0.0,
25
  "Vocabulary": 0.0,
26
  "Grammar": 0.0,
27
  "Overall": 0.0,
 
28
  }
29
 
30
- # Tokenize input, truncate to 512 tokens
31
  inputs = tokenizer(
32
  essay,
33
  return_tensors="pt",
@@ -39,45 +39,79 @@ def score_essay(essay: str):
39
  with torch.no_grad():
40
  outputs = model(**inputs)
41
 
42
- # Raw logits from the model
43
  preds = outputs.logits.squeeze().cpu().numpy()
44
 
45
  # -------------------------------
46
- # CORRECT CALIBRATION
47
  # -------------------------------
48
- # Clip logits to 0-9 (IELTS band)
49
- scores = np.clip(preds, 0, 9)
 
 
 
 
 
 
 
 
50
 
51
- # Round to nearest 0.5
 
 
 
 
 
 
 
 
 
 
 
 
52
  rounded = np.round(scores * 2) / 2
53
 
54
- # Optional: Penalize very short essays (like IELTS examiners)
55
- word_count = len(essay.split())
56
- if word_count < 150:
57
- rounded -= 1.0
58
- elif word_count < 250:
59
- rounded -= 0.5
60
 
61
- rounded = np.clip(rounded, 0, 9)
 
 
 
 
 
 
62
 
63
- labels = [
64
- "Task Achievement",
65
- "Coherence & Cohesion",
66
- "Vocabulary",
67
- "Grammar",
68
- "Overall"
69
- ]
70
 
71
- return {label: float(score) for label, score in zip(labels, rounded)}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
 
73
  # -------------------------------
74
  # Gradio UI
75
  # -------------------------------
76
  with gr.Blocks() as demo:
77
- gr.Markdown("## 📝 Automated IELTS Writing Scorer")
78
  gr.Markdown(
79
  "Paste your IELTS Task 2 essay below. "
80
- "The system will estimate band scores for all four criteria and the overall band."
81
  )
82
 
83
  essay_input = gr.Textbox(
@@ -85,10 +119,9 @@ with gr.Blocks() as demo:
85
  placeholder="Paste your IELTS essay here..."
86
  )
87
 
88
- score_output = gr.JSON(label="Estimated IELTS Band Scores")
89
 
90
  submit_btn = gr.Button("Score Essay")
91
-
92
  submit_btn.click(
93
  fn=score_essay,
94
  inputs=essay_input,
@@ -96,7 +129,7 @@ with gr.Blocks() as demo:
96
  )
97
 
98
  gr.Markdown(
99
- "⚠️ **Note:** This is an AI-based estimator, not an official IELTS examiner score."
100
  )
101
 
102
  # -------------------------------
 
14
  model.eval()
15
 
16
  # -------------------------------
17
+ # Scoring + Feedback function
18
  # -------------------------------
19
  def score_essay(essay: str):
20
+ if not essay.strip():
 
21
  return {
22
  "Task Achievement": 0.0,
23
  "Coherence & Cohesion": 0.0,
24
  "Vocabulary": 0.0,
25
  "Grammar": 0.0,
26
  "Overall": 0.0,
27
+ "Feedback": "Please write an essay to get a score."
28
  }
29
 
30
+ # Tokenize input
31
  inputs = tokenizer(
32
  essay,
33
  return_tensors="pt",
 
39
  with torch.no_grad():
40
  outputs = model(**inputs)
41
 
 
42
  preds = outputs.logits.squeeze().cpu().numpy()
43
 
44
  # -------------------------------
45
+ # Refined piecewise scaling
46
  # -------------------------------
47
+ scores = preds.copy()
48
+ for i in range(len(scores)):
49
+ if scores[i] < 4.0: # very weak essays
50
+ scores[i] = scores[i]*1.25 + 0.3
51
+ elif scores[i] < 6.0: # medium essays
52
+ scores[i] = scores[i]*1.1 + 0.2
53
+ elif scores[i] < 8.0: # good essays
54
+ scores[i] = scores[i]*1.05 + 0.1
55
+ else: # very strong essays
56
+ scores[i] = scores[i] # keep unchanged
57
 
58
+ # -------------------------------
59
+ # Word count bonus
60
+ # -------------------------------
61
+ wc = len(essay.split())
62
+ if wc >= 250:
63
+ scores += 0.3
64
+ elif wc >= 200:
65
+ scores += 0.15
66
+
67
+ # -------------------------------
68
+ # Clamp and round to 0.5
69
+ # -------------------------------
70
+ scores = np.clip(scores, 0, 9)
71
  rounded = np.round(scores * 2) / 2
72
 
73
+ ta, cc, vocab, gram, overall_dummy = rounded # we will compute weighted overall
 
 
 
 
 
74
 
75
+ # -------------------------------
76
+ # Weighted overall band
77
+ # -------------------------------
78
+ overall = 0.3*ta + 0.25*cc + 0.2*vocab + 0.25*gram
79
+ overall = np.clip(overall, 0, 9)
80
+ overall = np.round(overall * 2) / 2
81
+ rounded[-1] = overall # replace last element
82
 
83
+ labels = ["Task Achievement", "Coherence & Cohesion", "Vocabulary", "Grammar", "Overall"]
 
 
 
 
 
 
84
 
85
+ # -------------------------------
86
+ # Dynamic mini feedback
87
+ # -------------------------------
88
+ feedback_lines = []
89
+
90
+ if ta < 5:
91
+ feedback_lines.append("Task: Ideas are underdeveloped; give examples and elaboration.")
92
+ if cc < 5:
93
+ feedback_lines.append("Coherence: Improve transitions; use connectors like 'however', 'moreover'.")
94
+ if vocab < 5:
95
+ feedback_lines.append("Vocabulary: Use a wider range of words and avoid repetition.")
96
+ if gram < 5:
97
+ feedback_lines.append("Grammar: Check articles, plurals, tenses, and sentence structures.")
98
+ if overall >= 5:
99
+ feedback_lines.append("Overall: Good attempt! Refine grammar and vocabulary to increase your band.")
100
+
101
+ feedback = "\n".join(feedback_lines[:4]) # max 4 lines
102
+
103
+ result = {label: float(score) for label, score in zip(labels, rounded)}
104
+ result["Feedback"] = feedback
105
+ return result
106
 
107
  # -------------------------------
108
  # Gradio UI
109
  # -------------------------------
110
  with gr.Blocks() as demo:
111
+ gr.Markdown("## 📝 Refined Automated IELTS Writing Scorer")
112
  gr.Markdown(
113
  "Paste your IELTS Task 2 essay below. "
114
+ "The system estimates band scores with mini feedback."
115
  )
116
 
117
  essay_input = gr.Textbox(
 
119
  placeholder="Paste your IELTS essay here..."
120
  )
121
 
122
+ score_output = gr.JSON(label="Estimated IELTS Band Scores + Feedback")
123
 
124
  submit_btn = gr.Button("Score Essay")
 
125
  submit_btn.click(
126
  fn=score_essay,
127
  inputs=essay_input,
 
129
  )
130
 
131
  gr.Markdown(
132
+ "⚠️ Note: AI-based estimator; not an official IELTS score."
133
  )
134
 
135
  # -------------------------------