Spaces:
Running
Running
Initial commit
Browse files- Dockerfile +19 -0
- requirements.txt +18 -0
- src/manage.py +22 -0
- src/templates/index.html +230 -0
- src/web/__init__.py +0 -0
- src/web/settings.py +123 -0
- src/web/tasks.py +48 -0
- src/web/urls.py +24 -0
- src/web/views.py +44 -0
- src/web/wsgi.py +16 -0
Dockerfile
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
FROM python:3.9.18
|
2 |
+
|
3 |
+
RUN useradd -m -u 1000 user
|
4 |
+
|
5 |
+
USER user
|
6 |
+
|
7 |
+
ENV HOME=/home/user \
|
8 |
+
PATH=/home/user/.local/bin:$PATH
|
9 |
+
|
10 |
+
WORKDIR $HOME/app
|
11 |
+
|
12 |
+
COPY --chown=user . $HOME/app
|
13 |
+
|
14 |
+
COPY requirements.txt requirements.txt
|
15 |
+
|
16 |
+
RUN pip install -r requirements.txt
|
17 |
+
EXPOSE 7860
|
18 |
+
|
19 |
+
ENTRYPOINT ["python", "src/manage.py", "runserver","0.0.0.0:7860"]
|
requirements.txt
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
absl-py==2.0.0
|
2 |
+
asgiref==3.7.2
|
3 |
+
click==8.1.7
|
4 |
+
colorama==0.4.6
|
5 |
+
Django==4.2.7
|
6 |
+
joblib==1.3.2
|
7 |
+
lxml==4.9.3
|
8 |
+
nltk==3.8.1
|
9 |
+
numpy==1.26.2
|
10 |
+
portalocker==2.8.2
|
11 |
+
regex==2023.10.3
|
12 |
+
rouge-score==0.1.2
|
13 |
+
sacrebleu==2.3.2
|
14 |
+
six==1.16.0
|
15 |
+
sqlparse==0.4.4
|
16 |
+
tabulate==0.9.0
|
17 |
+
tqdm==4.66.1
|
18 |
+
typing_extensions==4.8.0
|
src/manage.py
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env python
|
2 |
+
"""Django's command-line utility for administrative tasks."""
|
3 |
+
import os
|
4 |
+
import sys
|
5 |
+
|
6 |
+
|
7 |
+
def main():
|
8 |
+
"""Run administrative tasks."""
|
9 |
+
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "web.settings")
|
10 |
+
try:
|
11 |
+
from django.core.management import execute_from_command_line
|
12 |
+
except ImportError as exc:
|
13 |
+
raise ImportError(
|
14 |
+
"Couldn't import Django. Are you sure it's installed and "
|
15 |
+
"available on your PYTHONPATH environment variable? Did you "
|
16 |
+
"forget to activate a virtual environment?"
|
17 |
+
) from exc
|
18 |
+
execute_from_command_line(sys.argv)
|
19 |
+
|
20 |
+
|
21 |
+
if __name__ == "__main__":
|
22 |
+
main()
|
src/templates/index.html
ADDED
@@ -0,0 +1,230 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en">
|
3 |
+
|
4 |
+
<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
|
5 |
+
|
6 |
+
<script>
|
7 |
+
function computeFunction() {
|
8 |
+
var references = document.getElementById('references').value;
|
9 |
+
var predictions = document.getElementById('predictions').value;
|
10 |
+
var checkboxSentenceBleu = document.getElementById('checkbox-sentence-bleu').checked;
|
11 |
+
var checkboxCorpusBleu = document.getElementById('checkbox-corpus-bleu').checked;
|
12 |
+
var checkboxRouge1 = document.getElementById('checkbox-rouge1').checked;
|
13 |
+
var checkboxRouge2 = document.getElementById('checkbox-rouge2').checked;
|
14 |
+
var checkboxRougeL = document.getElementById('checkbox-rougeL').checked;
|
15 |
+
var checkboxTf1 = document.getElementById('checkbox-tf1').checked;
|
16 |
+
|
17 |
+
$.ajax({
|
18 |
+
type: 'POST',
|
19 |
+
url: '/compute/',
|
20 |
+
data: {
|
21 |
+
references: references,
|
22 |
+
predictions: predictions,
|
23 |
+
checkbox_sentence_bleu: checkboxSentenceBleu,
|
24 |
+
checkbox_corpus_bleu: checkboxCorpusBleu,
|
25 |
+
checkbox_rouge1: checkboxRouge1,
|
26 |
+
checkbox_rouge2: checkboxRouge2,
|
27 |
+
checkbox_rougeL: checkboxRougeL,
|
28 |
+
checkbox_tf1: checkboxTf1,
|
29 |
+
csrfmiddlewaretoken: '{{ csrf_token }}'
|
30 |
+
},
|
31 |
+
success: function (data) {
|
32 |
+
var resultsContainer = document.getElementById('results-container');
|
33 |
+
var resultHTML = '';
|
34 |
+
|
35 |
+
if (checkboxSentenceBleu && 'sentence_bleu' in data) {
|
36 |
+
resultHTML += '<p>Sentence BLEU: ' + data.sentence_bleu + '</p>';
|
37 |
+
}
|
38 |
+
if (checkboxCorpusBleu && 'corpus_bleu' in data) {
|
39 |
+
resultHTML += '<p>Corpus BLEU: ' + data.corpus_bleu + '</p>';
|
40 |
+
}
|
41 |
+
if (checkboxRouge1 && 'rouge1' in data) {
|
42 |
+
resultHTML += '<p>ROUGE-1: ' + data.rouge1 + '</p>';
|
43 |
+
}
|
44 |
+
if (checkboxRouge2 && 'rouge2' in data) {
|
45 |
+
resultHTML += '<p>ROUGE-2: ' + data.rouge2 + '</p>';
|
46 |
+
}
|
47 |
+
if (checkboxRougeL && 'rougeL' in data) {
|
48 |
+
resultHTML += '<p>ROUGE-L: ' + data.rougeL + '</p>';
|
49 |
+
}
|
50 |
+
if (checkboxTf1 && 'tf1' in data) {
|
51 |
+
resultHTML += '<p>TF1: ' + data.tf1 + '</p>';
|
52 |
+
}
|
53 |
+
|
54 |
+
resultsContainer.innerHTML = resultHTML || '<p>No results available</p>';
|
55 |
+
},
|
56 |
+
error: function () {
|
57 |
+
alert('Error computing results');
|
58 |
+
}
|
59 |
+
});
|
60 |
+
}
|
61 |
+
|
62 |
+
function handleFileDrop(event, textareaId) {
|
63 |
+
event.preventDefault();
|
64 |
+
var textarea = document.getElementById(textareaId);
|
65 |
+
var files = event.dataTransfer.files;
|
66 |
+
|
67 |
+
if (files.length > 0) {
|
68 |
+
var reader = new FileReader();
|
69 |
+
reader.onload = function (e) {
|
70 |
+
textarea.value = e.target.result;
|
71 |
+
};
|
72 |
+
|
73 |
+
reader.readAsText(files[0]);
|
74 |
+
}
|
75 |
+
}
|
76 |
+
|
77 |
+
function handleFileUpload(inputId, textareaId) {
|
78 |
+
var input = document.getElementById(inputId);
|
79 |
+
var textarea = document.getElementById(textareaId);
|
80 |
+
|
81 |
+
var files = input.files;
|
82 |
+
|
83 |
+
if (files.length > 0) {
|
84 |
+
var reader = new FileReader();
|
85 |
+
reader.onload = function (e) {
|
86 |
+
textarea.value = e.target.result;
|
87 |
+
};
|
88 |
+
|
89 |
+
reader.readAsText(files[0]);
|
90 |
+
}
|
91 |
+
}
|
92 |
+
|
93 |
+
function handleDragOver(event) {
|
94 |
+
event.preventDefault();
|
95 |
+
}
|
96 |
+
</script>
|
97 |
+
|
98 |
+
<head>
|
99 |
+
<meta charset="UTF-8">
|
100 |
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
101 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
102 |
+
<title>BLEU | ROUGE | TF1</title>
|
103 |
+
<style>
|
104 |
+
body {
|
105 |
+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
106 |
+
background-color: #f5f5f5;
|
107 |
+
margin: 0;
|
108 |
+
display: flex;
|
109 |
+
align-items: center;
|
110 |
+
justify-content: center;
|
111 |
+
height: 100vh;
|
112 |
+
}
|
113 |
+
|
114 |
+
#container {
|
115 |
+
background-color: #fff;
|
116 |
+
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
|
117 |
+
border-radius: 8px;
|
118 |
+
width: 80%;
|
119 |
+
max-width: 800px;
|
120 |
+
padding: 20px;
|
121 |
+
box-sizing: border-box;
|
122 |
+
}
|
123 |
+
|
124 |
+
header {
|
125 |
+
text-align: center;
|
126 |
+
margin-bottom: 20px;
|
127 |
+
}
|
128 |
+
|
129 |
+
.label-container {
|
130 |
+
width: 100%;
|
131 |
+
text-align: center;
|
132 |
+
margin-bottom: 20px;
|
133 |
+
}
|
134 |
+
|
135 |
+
textarea {
|
136 |
+
width: 100%;
|
137 |
+
padding: 10px;
|
138 |
+
box-sizing: border-box;
|
139 |
+
border: 1px solid #ccc;
|
140 |
+
border-radius: 4px;
|
141 |
+
resize: vertical;
|
142 |
+
}
|
143 |
+
|
144 |
+
.checkbox-container {
|
145 |
+
text-align: center;
|
146 |
+
margin-bottom: 20px;
|
147 |
+
}
|
148 |
+
|
149 |
+
label {
|
150 |
+
margin-right: 10px;
|
151 |
+
}
|
152 |
+
|
153 |
+
button {
|
154 |
+
background-color: #4caf50;
|
155 |
+
color: #fff;
|
156 |
+
border: none;
|
157 |
+
padding: 10px 20px;
|
158 |
+
text-align: center;
|
159 |
+
text-decoration: none;
|
160 |
+
display: inline-block;
|
161 |
+
font-size: 16px;
|
162 |
+
border-radius: 4px;
|
163 |
+
cursor: pointer;
|
164 |
+
transition: background-color 0.3s;
|
165 |
+
}
|
166 |
+
|
167 |
+
button:hover {
|
168 |
+
background-color: #45a049;
|
169 |
+
}
|
170 |
+
</style>
|
171 |
+
</head>
|
172 |
+
|
173 |
+
<body>
|
174 |
+
<div id="container">
|
175 |
+
<header>
|
176 |
+
<h1>How faithful are your predictions?</h1>
|
177 |
+
<p>You can write, drag-and-drop or upload your references and predictions. <br> End <span style="text-decoration:underline">all</span> of them with with a comma and a
|
178 |
+
newline.</p>
|
179 |
+
</header>
|
180 |
+
|
181 |
+
<div class="label-container" ondrop="handleFileDrop(event, 'references')" ondragover="handleDragOver(event)">
|
182 |
+
<label for="references">References</label>
|
183 |
+
<textarea id="references" rows="5" placeholder="a, b, c " draggable="true"
|
184 |
+
ondrop="handleFileDrop(event, 'references')" ondragover="handleDragOver(event)"></textarea>
|
185 |
+
<input type="file" id="file-references" accept=".txt"
|
186 |
+
onchange="handleFileUpload('file-references', 'references')">
|
187 |
+
</div>
|
188 |
+
|
189 |
+
<div class="label-container" ondrop="handleFileDrop(event, 'predictions')" ondragover="handleDragOver(event)">
|
190 |
+
<label for="predictions">Predictions</label>
|
191 |
+
<textarea id="predictions" rows="5" placeholder="a, d, c " draggable="true"
|
192 |
+
ondrop="handleFileDrop(event, 'predictions')" ondragover="handleDragOver(event)"></textarea>
|
193 |
+
<input type="file" id="file-predictions" accept=".txt"
|
194 |
+
onchange="handleFileUpload('file-predictions', 'predictions')">
|
195 |
+
</div>
|
196 |
+
|
197 |
+
<div class="checkbox-container">
|
198 |
+
<label for="checkbox-sentence-bleu">
|
199 |
+
<input type="checkbox" id="checkbox-sentence-bleu" name="checkbox-sentence-bleu"> <a href="https://aclanthology.org/P02-1040/">Sentence BLEU</a>
|
200 |
+
</label>
|
201 |
+
|
202 |
+
<label for="checkbox-corpus-bleu">
|
203 |
+
<input type="checkbox" id="checkbox-corpus-bleu" name="checkbox-corpus-bleu"> <a href="https://aclanthology.org/P02-1040/">Corpus BLEU</a>
|
204 |
+
</label>
|
205 |
+
|
206 |
+
<label for="checkbox-rouge1">
|
207 |
+
<input type="checkbox" id="checkbox-rouge1" name="checkbox-rouge1"> <a href="https://aclanthology.org/W04-1013/">ROUGE-1</a>
|
208 |
+
</label>
|
209 |
+
|
210 |
+
<label for="checkbox-rouge2">
|
211 |
+
<input type="checkbox" id="checkbox-rouge2" name="checkbox-rouge2"> <a href="https://aclanthology.org/W04-1013/">ROUGE-2</a>
|
212 |
+
</label>
|
213 |
+
|
214 |
+
<label for="checkbox-rougeL">
|
215 |
+
<input type="checkbox" id="checkbox-rougeL" name="checkbox-rougeL"> <a href="https://aclanthology.org/W04-1013/">ROUGE-L</a>
|
216 |
+
</label>
|
217 |
+
|
218 |
+
<label for="checkbox-tf1">
|
219 |
+
<input type="checkbox" id="checkbox-tf1" name="checkbox-tf1"> <a href="https://aclanthology.org/2020.acl-main.408/">TF1</a>
|
220 |
+
</label>
|
221 |
+
</div>
|
222 |
+
|
223 |
+
<div style="text-align: center;">
|
224 |
+
<button onclick="computeFunction()">Compute</button>
|
225 |
+
</div>
|
226 |
+
<div id="results-container" style="text-align: center; margin-top: 20px;"></div>
|
227 |
+
</div>
|
228 |
+
</body>
|
229 |
+
|
230 |
+
</html>
|
src/web/__init__.py
ADDED
File without changes
|
src/web/settings.py
ADDED
@@ -0,0 +1,123 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""
|
2 |
+
Django settings for web project.
|
3 |
+
|
4 |
+
Generated by 'django-admin startproject' using Django 4.2.7.
|
5 |
+
|
6 |
+
For more information on this file, see
|
7 |
+
https://docs.djangoproject.com/en/4.2/topics/settings/
|
8 |
+
|
9 |
+
For the full list of settings and their values, see
|
10 |
+
https://docs.djangoproject.com/en/4.2/ref/settings/
|
11 |
+
"""
|
12 |
+
import os
|
13 |
+
from pathlib import Path
|
14 |
+
|
15 |
+
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
16 |
+
BASE_DIR = Path(__file__).resolve().parent.parent
|
17 |
+
|
18 |
+
|
19 |
+
# Quick-start development settings - unsuitable for production
|
20 |
+
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/
|
21 |
+
|
22 |
+
# SECURITY WARNING: keep the secret key used in production secret!
|
23 |
+
SECRET_KEY = "django-insecure-*r6s+e#n%b*26gf($$x9g35=^)a2=9g+0i*$uukx1_%x)p)h@="
|
24 |
+
|
25 |
+
# SECURITY WARNING: don't run with debug turned on in production!
|
26 |
+
DEBUG = True
|
27 |
+
|
28 |
+
ALLOWED_HOSTS = []
|
29 |
+
|
30 |
+
|
31 |
+
# Application definition
|
32 |
+
|
33 |
+
INSTALLED_APPS = [
|
34 |
+
"django.contrib.admin",
|
35 |
+
"django.contrib.auth",
|
36 |
+
"django.contrib.contenttypes",
|
37 |
+
"django.contrib.sessions",
|
38 |
+
"django.contrib.messages",
|
39 |
+
"django.contrib.staticfiles",
|
40 |
+
]
|
41 |
+
|
42 |
+
MIDDLEWARE = [
|
43 |
+
"django.middleware.security.SecurityMiddleware",
|
44 |
+
"django.contrib.sessions.middleware.SessionMiddleware",
|
45 |
+
"django.middleware.common.CommonMiddleware",
|
46 |
+
"django.middleware.csrf.CsrfViewMiddleware",
|
47 |
+
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
48 |
+
"django.contrib.messages.middleware.MessageMiddleware",
|
49 |
+
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
50 |
+
]
|
51 |
+
|
52 |
+
ROOT_URLCONF = "web.urls"
|
53 |
+
|
54 |
+
TEMPLATES = [
|
55 |
+
{
|
56 |
+
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
57 |
+
"DIRS": [os.path.join(BASE_DIR, "templates")],
|
58 |
+
"APP_DIRS": True,
|
59 |
+
"OPTIONS": {
|
60 |
+
"context_processors": [
|
61 |
+
"django.template.context_processors.debug",
|
62 |
+
"django.template.context_processors.request",
|
63 |
+
"django.contrib.auth.context_processors.auth",
|
64 |
+
"django.contrib.messages.context_processors.messages",
|
65 |
+
],
|
66 |
+
},
|
67 |
+
},
|
68 |
+
]
|
69 |
+
|
70 |
+
WSGI_APPLICATION = "web.wsgi.application"
|
71 |
+
|
72 |
+
|
73 |
+
# Database
|
74 |
+
# https://docs.djangoproject.com/en/4.2/ref/settings/#databases
|
75 |
+
|
76 |
+
DATABASES = {
|
77 |
+
# 'default': {
|
78 |
+
# 'ENGINE': 'django.db.backends.sqlite3',
|
79 |
+
# 'NAME': BASE_DIR / 'db.sqlite3',
|
80 |
+
# }
|
81 |
+
}
|
82 |
+
|
83 |
+
|
84 |
+
# Password validation
|
85 |
+
# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators
|
86 |
+
|
87 |
+
AUTH_PASSWORD_VALIDATORS = [
|
88 |
+
{
|
89 |
+
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
|
90 |
+
},
|
91 |
+
{
|
92 |
+
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
|
93 |
+
},
|
94 |
+
{
|
95 |
+
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
|
96 |
+
},
|
97 |
+
{
|
98 |
+
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
|
99 |
+
},
|
100 |
+
]
|
101 |
+
|
102 |
+
|
103 |
+
# Internationalization
|
104 |
+
# https://docs.djangoproject.com/en/4.2/topics/i18n/
|
105 |
+
|
106 |
+
LANGUAGE_CODE = "en-us"
|
107 |
+
|
108 |
+
TIME_ZONE = "UTC"
|
109 |
+
|
110 |
+
USE_I18N = True
|
111 |
+
|
112 |
+
USE_TZ = True
|
113 |
+
|
114 |
+
|
115 |
+
# Static files (CSS, JavaScript, Images)
|
116 |
+
# https://docs.djangoproject.com/en/4.2/howto/static-files/
|
117 |
+
|
118 |
+
STATIC_URL = "static/"
|
119 |
+
|
120 |
+
# Default primary key field type
|
121 |
+
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
|
122 |
+
|
123 |
+
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
|
src/web/tasks.py
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import sacrebleu
|
2 |
+
import statistics
|
3 |
+
|
4 |
+
from rouge_score import rouge_scorer
|
5 |
+
|
6 |
+
|
7 |
+
def sentence_bleu(references, predictions):
|
8 |
+
scores = []
|
9 |
+
for ref, pred in zip(references, predictions):
|
10 |
+
scores.append(
|
11 |
+
sacrebleu.sentence_bleu(
|
12 |
+
pred,
|
13 |
+
[ref],
|
14 |
+
smooth_method="exp",
|
15 |
+
smooth_value=0.0,
|
16 |
+
lowercase=True,
|
17 |
+
tokenize="intl",
|
18 |
+
).score
|
19 |
+
)
|
20 |
+
|
21 |
+
return statistics.mean(scores)
|
22 |
+
|
23 |
+
|
24 |
+
def corpus_bleu(references, predictions):
|
25 |
+
return sacrebleu.corpus_bleu(
|
26 |
+
predictions,
|
27 |
+
[references],
|
28 |
+
smooth_method="exp",
|
29 |
+
smooth_value=0.0,
|
30 |
+
lowercase=True,
|
31 |
+
tokenize="intl",
|
32 |
+
).score
|
33 |
+
|
34 |
+
|
35 |
+
def rouge(scope, references, predictions):
|
36 |
+
rouge = f"rouge{scope}"
|
37 |
+
scorer = rouge_scorer.RougeScorer([rouge], use_stemmer=True)
|
38 |
+
|
39 |
+
scores_dict = {"precision": 0, "recall": 0, "f1": 0}
|
40 |
+
|
41 |
+
for reference, prediction in zip(references, predictions):
|
42 |
+
scores = scorer.score(reference, prediction)
|
43 |
+
|
44 |
+
scores_dict["precision"] += scores[rouge].precision
|
45 |
+
scores_dict["recall"] += scores[rouge].recall
|
46 |
+
scores_dict["f1"] += scores[rouge].fmeasure
|
47 |
+
|
48 |
+
return {k: v / len(references) for k, v in scores_dict.items()}
|
src/web/urls.py
ADDED
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""
|
2 |
+
URL configuration for web project.
|
3 |
+
|
4 |
+
The `urlpatterns` list routes URLs to views. For more information please see:
|
5 |
+
https://docs.djangoproject.com/en/4.2/topics/http/urls/
|
6 |
+
Examples:
|
7 |
+
Function views
|
8 |
+
1. Add an import: from my_app import views
|
9 |
+
2. Add a URL to urlpatterns: path('', views.home, name='home')
|
10 |
+
Class-based views
|
11 |
+
1. Add an import: from other_app.views import Home
|
12 |
+
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
|
13 |
+
Including another URLconf
|
14 |
+
1. Import the include() function: from django.urls import include, path
|
15 |
+
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
16 |
+
"""
|
17 |
+
from django.urls import path
|
18 |
+
|
19 |
+
from . import views
|
20 |
+
|
21 |
+
urlpatterns = [
|
22 |
+
path("", views.index, name="index"),
|
23 |
+
path("compute/", views.compute, name="compute"),
|
24 |
+
]
|
src/web/views.py
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from . import tasks
|
2 |
+
|
3 |
+
from django.http import JsonResponse
|
4 |
+
from django.shortcuts import render
|
5 |
+
from django.views.decorators.cache import cache_control
|
6 |
+
from django.views.decorators.csrf import csrf_exempt
|
7 |
+
|
8 |
+
|
9 |
+
@cache_control(no_cache=True, must_revalidate=True, no_store=True, max_age=0)
|
10 |
+
def index(request):
|
11 |
+
return render(request, "index.html", {})
|
12 |
+
|
13 |
+
|
14 |
+
@csrf_exempt
|
15 |
+
def compute(request):
|
16 |
+
|
17 |
+
def _format_rouge_result(rouge):
|
18 |
+
return "P: {:.1f} | R: {:.1f} | F1: {:.1f}".format(rouge['precision'], rouge['recall'], rouge['f1'])
|
19 |
+
|
20 |
+
if request.method == "POST":
|
21 |
+
references = list(filter(None, request.POST.get("references", "").split(",\n")))
|
22 |
+
predictions = list(filter(None, request.POST.get("predictions", "").split(",\n")))
|
23 |
+
|
24 |
+
print(references)
|
25 |
+
print(predictions)
|
26 |
+
|
27 |
+
result = {}
|
28 |
+
if request.POST.get("checkbox_sentence_bleu", False) == "true":
|
29 |
+
result["sentence_bleu"] = "{:.1f}".format(tasks.sentence_bleu(references, predictions))
|
30 |
+
if request.POST.get("checkbox_corpus_bleu", False) == "true":
|
31 |
+
result["corpus_bleu"] = "{:.1f}".format(tasks.corpus_bleu(references, predictions))
|
32 |
+
if request.POST.get("checkbox_rouge1", False) == "true":
|
33 |
+
result["rouge1"] = _format_rouge_result(tasks.rouge('1', references, predictions))
|
34 |
+
if request.POST.get("checkbox_rouge2", False) == "true":
|
35 |
+
result["rouge2"] = _format_rouge_result(tasks.rouge('2', references, predictions))
|
36 |
+
if request.POST.get("checkbox_rougeL", False) == "true":
|
37 |
+
result["rougeL"] = _format_rouge_result(tasks.rouge('L', references, predictions))
|
38 |
+
if request.POST.get("checkbox_tf1", False) == "true":
|
39 |
+
result["tf1"] = 0.90
|
40 |
+
|
41 |
+
print(result)
|
42 |
+
return JsonResponse(result)
|
43 |
+
|
44 |
+
return JsonResponse({"error": "Invalid request method"})
|
src/web/wsgi.py
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""
|
2 |
+
WSGI config for web project.
|
3 |
+
|
4 |
+
It exposes the WSGI callable as a module-level variable named ``application``.
|
5 |
+
|
6 |
+
For more information on this file, see
|
7 |
+
https://docs.djangoproject.com/en/4.2/howto/deployment/wsgi/
|
8 |
+
"""
|
9 |
+
|
10 |
+
import os
|
11 |
+
|
12 |
+
from django.core.wsgi import get_wsgi_application
|
13 |
+
|
14 |
+
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "web.settings")
|
15 |
+
|
16 |
+
application = get_wsgi_application()
|