KalanaPabasara commited on
Commit
1fed70a
·
1 Parent(s): f6f45d5

SinCode v3 — seq2seq pipeline, evaluation scripts, IndoNLP benchmark data

Browse files
.gitignore CHANGED
@@ -3,6 +3,8 @@
3
 
4
  # Model weights — hosted on Hugging Face Hub
5
  seq2seq/byt5-singlish-sinhala/
 
 
6
  seq2seq/tokenized_cache/
7
 
8
  # Large training data
@@ -23,6 +25,9 @@ __pycache__/
23
  # Evaluation outputs (optional — remove if you want these tracked)
24
  misc/v3_results_110.csv
25
 
 
 
 
26
  # Misc
27
  *.log
28
  .DS_Store
 
3
 
4
  # Model weights — hosted on Hugging Face Hub
5
  seq2seq/byt5-singlish-sinhala/
6
+ seq2seq/byt5-base-clean/
7
+ seq2seq/experiments/
8
  seq2seq/tokenized_cache/
9
 
10
  # Large training data
 
25
  # Evaluation outputs (optional — remove if you want these tracked)
26
  misc/v3_results_110.csv
27
 
28
+ # User feedback data — contains real submissions, do not expose
29
+ misc/feedback_submissions.jsonl
30
+
31
  # Misc
32
  *.log
33
  .DS_Store
IndoNLP-2025-Shared-Task/Images/sample.png ADDED
IndoNLP-2025-Shared-Task/Readme.md ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Romanized Indo-Aryan Language Reverse Transliterator
2
+
3
+ ## Overview
4
+
5
+ **Typing Romanized Indo-Aryan languages** (native languages written using English alphabets) using adhoc transliterations, with or without vowels, and achieving accurate native script output is often challenging. Existing keyboard systems frequently fail to provide accurate transliteration, resulting in a subpar user experience.
6
+
7
+ This project introduces a **real-time reverse transliterator**, designed to convert Romanized Indo-Aryan language input into its corresponding native script. By improving the accuracy of transliteration, we aim to enhance the typing experience for users who prefer using Romanized alphabets for Indo-Aryan languages.
8
+
9
+ ![Example Task](./Images/sample.png)
10
+
11
+
12
+ ## Task Objective
13
+
14
+ The primary goal of this project is to develop and evaluate a tool that:
15
+ - Accurately converts Romanized Indo-Aryan language text to native script in real-time.
16
+ - Handles transliterations with or without vowels, and resolves the ambiguities that arise from such variations.
17
+ - Provides a seamless typing experience for users by addressing the inaccuracies present in current keyboard systems.
18
+
19
+
20
+
21
+ ## Important Dates
22
+
23
+ - 1st Call for Registration :July 20, 2024
24
+ - 2nd Call for Registration : July 31, 2024
25
+ - Registration Closing : August 31, 2024
26
+ - Intial Briefing :September 2, 2024
27
+ - Test Data released: October 11, 2024 New
28
+ - Shared Task Completion :November 15, 2024
29
+ - Paper Submission Deadline :November 30, 2024
30
+
31
+ ## Language Test Sets
32
+
33
+ This Test dataset has been created and augmented specifically for the INdoNLP Shared Task 2025. Please note that some data records are a combination of existing datasets that are publicly available for the respective languages. The augmentation process involved generating new data samples based on these existing resources while ensuring data diversity and relevance to the task.
34
+
35
+ We want to give full credit to the authors and original creators of the datasets from which the data has been derived. Their contributions have been invaluable in the development of this dataset.
36
+
37
+
38
+ | Language | Test Set 1: General Typing Patterns | Test Set 2: Adhoc Typing Patterns |
39
+ |------------|--------------------------------------|------------------------------------|
40
+ | Sinhala | 10000 | 5000 |
41
+ | Bengali | 10000 | 5000 |
42
+ | Gujarati | 5000 | 5000 |
43
+ | Hindi | 5000 | 5000 |
44
+ | Malayalam | 10000 | 5000 |
45
+
46
+ ## Submission
47
+
48
+ - The developed transliteration model/code.
49
+ - A report detailing the approach, challenges faced, and solutions implemented.
50
+ - A detailed discussion about the evaluation techniques/frameworks used.
51
+ - A short paper (4 pages)
52
+
53
+ For any inquiries or concerns regarding this dataset, please contact us at: indonlp2025@gmail.com
IndoNLP-2025-Shared-Task/Test Dataset/Bengali/Bengali Test Set 1.txt ADDED
The diff for this file is too large to render. See raw diff
 
IndoNLP-2025-Shared-Task/Test Dataset/Bengali/Bengali Test Set 2.txt ADDED
The diff for this file is too large to render. See raw diff
 
IndoNLP-2025-Shared-Task/Test Dataset/Gujarati/Gujarati Test 1.txt ADDED
The diff for this file is too large to render. See raw diff
 
IndoNLP-2025-Shared-Task/Test Dataset/Gujarati/Gujarati Test 2.txt ADDED
The diff for this file is too large to render. See raw diff
 
IndoNLP-2025-Shared-Task/Test Dataset/Hindi/Hindi Test Set 1.txt ADDED
The diff for this file is too large to render. See raw diff
 
IndoNLP-2025-Shared-Task/Test Dataset/Hindi/Hindi Test Set 2.txt ADDED
The diff for this file is too large to render. See raw diff
 
IndoNLP-2025-Shared-Task/Test Dataset/Malayalam/Malayalam Test Set 1.txt ADDED
The diff for this file is too large to render. See raw diff
 
IndoNLP-2025-Shared-Task/Test Dataset/Malayalam/Malayalam Test Set 2.txt ADDED
The diff for this file is too large to render. See raw diff
 
IndoNLP-2025-Shared-Task/Test Dataset/Sinhala/Sinhala Test set 1.txt ADDED
The diff for this file is too large to render. See raw diff
 
IndoNLP-2025-Shared-Task/Test Dataset/Sinhala/Sinhala Test set 2.txt ADDED
The diff for this file is too large to render. See raw diff
 
app.py CHANGED
@@ -5,17 +5,31 @@ Architecture: ByT5-small (seq2seq candidate generation) +
5
  XLM-RoBERTa (MLM contextual reranking)
6
 
7
  Two transliteration modes:
8
- Code-Mixed — ByT5 + MLM; retains English words where contextually apt
9
- Full Sinhala — mBart50 sentence-level; transliterates everything to Sinhala
10
  """
11
 
 
 
 
 
12
  import streamlit as st
 
 
 
13
  from sincode_model import BeamSearchDecoder, SentenceTransliterator
14
 
15
- st.set_page_config(page_title="සිංCode v3", page_icon="🇱🇰", layout="centered")
16
 
17
- st.title("සිංCode v3")
18
- st.caption("ByT5 seq2seq + XLM-RoBERTa MLM reranking")
 
 
 
 
 
 
 
 
19
 
20
 
21
  @st.cache_resource(show_spinner="Loading models (ByT5 + XLM-RoBERTa)…")
@@ -28,20 +42,47 @@ def load_transliterator() -> SentenceTransliterator:
28
  return SentenceTransliterator()
29
 
30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  mode = st.radio(
32
  "Transliteration mode",
33
  options=["Code-Mixed Output", "Full Sinhala Output"],
34
  horizontal=True,
35
  help=(
36
- "**Code-Mixed**: keeps English technical/borrowed words where natural "
37
  "(e.g. *buffer*, *bit rate*). "
38
  "**Full Sinhala**: transliterates every word to Sinhala script "
39
- "(e.g. *business* ව්‍යාපාරය)."
40
  ),
41
  )
42
 
43
- sentence = st.text_input(
 
 
 
 
 
44
  "Enter Singlish sentence",
 
45
  placeholder="e.g. mema videowe bit rate eka godak wadi nisa buffer wenawa",
46
  )
47
 
@@ -57,19 +98,132 @@ if st.button("Transliterate", type="primary") and sentence.strip():
57
  with st.spinner("Transliterating (mBart50)…"):
58
  transliterator = load_transliterator()
59
  result = transliterator.transliterate(sentence.strip())
60
-
61
- st.markdown("### Result")
62
- st.success(result)
63
-
64
  else:
65
  with st.spinner("Transliterating…"):
66
  decoder = load_decoder()
67
- result, trace_logs = decoder.decode(sentence.strip())
68
-
69
- st.markdown("### Result")
70
- st.success(result)
71
-
72
- if show_trace:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  st.markdown("### Trace")
74
  for log in trace_logs:
75
  st.markdown(log)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  XLM-RoBERTa (MLM contextual reranking)
6
 
7
  Two transliteration modes:
8
+ - Code-Mixed — ByT5 + MLM; retains English words where contextually apt
9
+ - Full Sinhala — mBart50 sentence-level; transliterates everything to Sinhala
10
  """
11
 
12
+ from __future__ import annotations
13
+
14
+ import os
15
+
16
  import streamlit as st
17
+ from streamlit.errors import StreamlitSecretNotFoundError
18
+
19
+ from feedback_store import FeedbackStore, format_feedback_error
20
  from sincode_model import BeamSearchDecoder, SentenceTransliterator
21
 
 
22
 
23
+ st.set_page_config(page_title="සිංCode", page_icon="🇱🇰", layout="centered")
24
+
25
+
26
+ def _secret_or_env(name: str, default: str = "") -> str:
27
+ try:
28
+ if name in st.secrets:
29
+ return str(st.secrets[name])
30
+ except StreamlitSecretNotFoundError:
31
+ pass
32
+ return os.getenv(name, default)
33
 
34
 
35
  @st.cache_resource(show_spinner="Loading models (ByT5 + XLM-RoBERTa)…")
 
42
  return SentenceTransliterator()
43
 
44
 
45
+ @st.cache_resource
46
+ def load_feedback_store() -> FeedbackStore:
47
+ return FeedbackStore(
48
+ supabase_url=_secret_or_env("SUPABASE_URL"),
49
+ supabase_anon_key=_secret_or_env("SUPABASE_ANON_KEY"),
50
+ supabase_service_key=_secret_or_env("SUPABASE_SERVICE_ROLE_KEY"),
51
+ table_name=_secret_or_env("SUPABASE_FEEDBACK_TABLE", "feedback_submissions"),
52
+ )
53
+
54
+
55
+ st.title("සිංCode")
56
+
57
+ with st.sidebar:
58
+ st.markdown("### About")
59
+ st.write(
60
+ "A model-driven Singlish to Sinhala transliteration interface with "
61
+ "optional user feedback for future model refinement."
62
+ )
63
+ store = load_feedback_store()
64
+ st.caption(f"Feedback storage: {store.backend_label}")
65
+
66
  mode = st.radio(
67
  "Transliteration mode",
68
  options=["Code-Mixed Output", "Full Sinhala Output"],
69
  horizontal=True,
70
  help=(
71
+ "**Code-Mixed**: keeps English technical or borrowed words where natural "
72
  "(e.g. *buffer*, *bit rate*). "
73
  "**Full Sinhala**: transliterates every word to Sinhala script "
74
+ "(e.g. *business* -> ව්‍යාපාරය)."
75
  ),
76
  )
77
 
78
+ if mode == "Full Sinhala Output":
79
+ st.caption("mBart50 sentence-level transliteration")
80
+ else:
81
+ st.caption("ByT5 seq2seq + XLM-RoBERTa MLM reranking")
82
+
83
+ sentence = st.text_area(
84
  "Enter Singlish sentence",
85
+ height=120,
86
  placeholder="e.g. mema videowe bit rate eka godak wadi nisa buffer wenawa",
87
  )
88
 
 
98
  with st.spinner("Transliterating (mBart50)…"):
99
  transliterator = load_transliterator()
100
  result = transliterator.transliterate(sentence.strip())
101
+ trace_logs: list[str] = []
 
 
 
102
  else:
103
  with st.spinner("Transliterating…"):
104
  decoder = load_decoder()
105
+ decode_out = decoder.decode(sentence.strip())
106
+ if isinstance(decode_out, tuple) and len(decode_out) == 3:
107
+ result, trace_logs, word_candidates = decode_out
108
+ else:
109
+ # Backward compatibility for cached/older decoders returning (result, trace_logs)
110
+ result, trace_logs = decode_out
111
+ word_candidates = [(w, []) for w in str(result).split()]
112
+
113
+ st.session_state["last_input"] = sentence.strip()
114
+ st.session_state["last_mode"] = mode
115
+ st.session_state["last_result"] = result
116
+ st.session_state["last_trace_logs"] = trace_logs
117
+ st.session_state["last_word_candidates"] = word_candidates if mode == "Code-Mixed Output" else []
118
+ st.session_state["last_output_words"] = [w for w, _ in word_candidates] if word_candidates else result.split()
119
+ st.session_state["feedback_submitted_for"] = None
120
+
121
+ if st.session_state.get("last_result"):
122
+ current_input = st.session_state.get("last_input", "")
123
+ original_result = st.session_state["last_result"]
124
+ current_mode = st.session_state.get("last_mode", mode)
125
+ word_candidates = st.session_state.get("last_word_candidates", [])
126
+
127
+ # output_words may be mutated by alternative selection — keep in session state
128
+ if "last_output_words" not in st.session_state:
129
+ st.session_state["last_output_words"] = original_result.split()
130
+ output_words: list[str] = st.session_state["last_output_words"]
131
+ current_result = " ".join(output_words)
132
+
133
+ st.markdown("### Result")
134
+ st.success(current_result)
135
+ st.caption(f"Mode: {current_mode}")
136
+
137
+ # ── Alternative selection (Code-Mixed only) ───────────────────────────────
138
+ if current_mode == "Code-Mixed Output" and word_candidates:
139
+ swappable = [
140
+ (i, sel, alts)
141
+ for i, (sel, alts) in enumerate(word_candidates)
142
+ if len(alts) > 1
143
+ ]
144
+ if swappable:
145
+ st.markdown("##### Alternative transliterations")
146
+ st.caption("Click a word to pick an alternative.")
147
+ widths = [max(len(output_words[i]), 3) for i, _, _ in swappable]
148
+ cols = st.columns(widths, gap="small")
149
+ for col, (i, _sel, alts) in zip(cols, swappable):
150
+ current_word = output_words[i]
151
+ was_changed = current_word != word_candidates[i][0]
152
+ chip = (
153
+ f":green[**{current_word}**]"
154
+ if was_changed
155
+ else f":blue[**{current_word}**]"
156
+ )
157
+ with col:
158
+ with st.popover(chip, use_container_width=True):
159
+ st.markdown(f"**Alternatives for `{current_word}`:**")
160
+ for alt in alts:
161
+ is_sel = alt == current_word
162
+ if st.button(
163
+ f"{'✅ ' if is_sel else ''}{alt}",
164
+ key=f"alt_{i}_{alt}",
165
+ use_container_width=True,
166
+ type="primary" if is_sel else "secondary",
167
+ ):
168
+ st.session_state["last_output_words"][i] = alt
169
+ st.session_state["corrected_output"] = " ".join(
170
+ st.session_state["last_output_words"]
171
+ )
172
+ st.rerun()
173
+ st.markdown("---")
174
+ custom = st.text_input(
175
+ "Not listed? Type correct word:",
176
+ key=f"custom_{i}",
177
+ placeholder="Type Sinhala word",
178
+ )
179
+ if custom and st.button(
180
+ "Use this", key=f"custom_apply_{i}", use_container_width=True
181
+ ):
182
+ st.session_state["last_output_words"][i] = custom
183
+ st.session_state["corrected_output"] = " ".join(
184
+ st.session_state["last_output_words"]
185
+ )
186
+ st.rerun()
187
+
188
+ if current_mode == "Code-Mixed Output" and show_trace:
189
+ trace_logs = st.session_state.get("last_trace_logs", [])
190
+ if trace_logs:
191
  st.markdown("### Trace")
192
  for log in trace_logs:
193
  st.markdown(log)
194
+
195
+ with st.expander("Submit a correction", expanded=False):
196
+ st.caption(
197
+ "If the output is incorrect, submit a corrected sentence. "
198
+ "These feedback samples can be reviewed and used in future fine-tuning."
199
+ )
200
+ corrected_output = st.text_area(
201
+ "Corrected output",
202
+ value=current_result,
203
+ height=120,
204
+ key="corrected_output",
205
+ )
206
+ feedback_comment = st.text_area(
207
+ "Optional note",
208
+ placeholder="Example: In this sentence, this word should stay in English.",
209
+ key="feedback_comment",
210
+ )
211
+
212
+ submit_key = (current_input, original_result, corrected_output)
213
+ already_submitted = st.session_state.get("feedback_submitted_for") == submit_key
214
+
215
+ if already_submitted:
216
+ st.success("Correction submitted.")
217
+ elif st.button("Submit Feedback", use_container_width=True):
218
+ try:
219
+ load_feedback_store().save_submission(
220
+ input_sentence=current_input,
221
+ original_output=original_result,
222
+ corrected_output=corrected_output.strip(),
223
+ user_comment=feedback_comment,
224
+ decode_mode=current_mode,
225
+ )
226
+ st.session_state["feedback_submitted_for"] = submit_key
227
+ st.success("Feedback submitted successfully.")
228
+ except Exception as exc:
229
+ st.error(f"Could not submit feedback: {format_feedback_error(exc)}")
core/constants.py CHANGED
@@ -30,6 +30,11 @@ ENGLISH_CORPUS_URL = (
30
  # ─── Decoding Parameters ─────────────────────────────────────────────────────
31
  MAX_CANDIDATES: int = 5 # ByT5 beam=5 → 5 candidates per word
32
  MIN_ENGLISH_LEN: int = 3 # Min word length for English detection
 
 
 
 
 
33
 
34
  # ─── Regex ───────────────────────────────────────────────────────────────────
35
  PUNCT_PATTERN = re.compile(r"^(\W*)(.*?)(\W*)$")
 
30
  # ─── Decoding Parameters ─────────────────────────────────────────────────────
31
  MAX_CANDIDATES: int = 5 # ByT5 beam=5 → 5 candidates per word
32
  MIN_ENGLISH_LEN: int = 3 # Min word length for English detection
33
+ # Words >= this length that are in the English vocab are treated as unambiguous
34
+ # English loanwords and passed through without MLM scoring.
35
+ # Short words (< 6 chars) are kept in the MLM path because they may be
36
+ # Singlish homophones (e.g. 'mage'=wizard vs 'මගේ', 'mama'=mum vs 'mama'=uncle).
37
+ MIN_ENGLISH_PASSTHROUGH_LEN: int = 5
38
 
39
  # ─── Regex ───────────────────────────────────────────────────────────────────
40
  PUNCT_PATTERN = re.compile(r"^(\W*)(.*?)(\W*)$")
core/decoder.py CHANGED
@@ -17,7 +17,7 @@ from transformers import AutoTokenizer, AutoModelForMaskedLM
17
 
18
  from core.constants import (
19
  DEFAULT_MLM_MODEL, DEFAULT_BYT5_MODEL,
20
- MAX_CANDIDATES, MIN_ENGLISH_LEN,
21
  PUNCT_PATTERN,
22
  )
23
  from core.english import ENGLISH_VOCAB
@@ -27,6 +27,52 @@ logger = logging.getLogger(__name__)
27
 
28
  _SINHALA_RE = re.compile(r"[\u0D80-\u0DFF]")
29
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
 
31
  class ScoredCandidate:
32
  __slots__ = ("text", "mlm_score")
@@ -138,14 +184,18 @@ class BeamSearchDecoder:
138
 
139
  # ── Public decode ─────────────────────────────────────────────────────────
140
 
141
- def decode(self, sentence: str) -> Tuple[str, List[str]]:
142
  """
143
  Decode a Singlish sentence word-by-word using ByT5 + XLM-RoBERTa MLM.
144
- Returns (transliterated_sentence, trace_logs).
 
 
 
 
145
  """
146
  words = sentence.split()
147
  if not words:
148
- return "", []
149
 
150
  # ── Phase 1: batch ByT5 candidate generation ──────────────────────────
151
  # Collect only the words that need ByT5 (non-Sinhala), run in one pass
@@ -156,6 +206,9 @@ class BeamSearchDecoder:
156
  match = PUNCT_PATTERN.match(raw)
157
  prefix, core, suffix = match.groups() if match else ("", raw, "")
158
  if not _is_sinhala(core):
 
 
 
159
  cores.append(core)
160
  core_meta.append((i, prefix, core, suffix, core.lower()))
161
 
@@ -172,18 +225,31 @@ class BeamSearchDecoder:
172
  word_infos: List[dict] = []
173
  for i, raw in enumerate(words):
174
  match = PUNCT_PATTERN.match(raw)
175
- _, core, _ = match.groups() if match else ("", raw, "")
176
 
177
  if _is_sinhala(core):
178
  word_infos.append({"kind": "sinhala", "candidates": [raw]})
179
  continue
180
 
 
 
 
 
 
 
181
  prefix, suffix, core_lower, byt5_cands = byt5_map[i]
182
  sinhala_cands = [prefix + c + suffix for c in byt5_cands]
183
 
184
  if core_lower in ENGLISH_VOCAB and len(core_lower) >= MIN_ENGLISH_LEN:
185
- candidates = [raw] + [c for c in sinhala_cands if c != raw]
186
- word_infos.append({"kind": "english", "candidates": candidates[:MAX_CANDIDATES + 1]})
 
 
 
 
 
 
 
187
  else:
188
  word_infos.append({"kind": "singlish", "candidates": sinhala_cands})
189
 
@@ -193,6 +259,11 @@ class BeamSearchDecoder:
193
  selected_words: List[str] = []
194
 
195
  for t, info in enumerate(word_infos):
 
 
 
 
 
196
  candidates = info["candidates"]
197
  left_ctx = " ".join(selected_words)
198
  right_ctx = " ".join(stable_right[t + 1:])
@@ -209,12 +280,38 @@ class BeamSearchDecoder:
209
  # Right context is now the actual decoded output, not the pre-decode estimate
210
  trace_logs: List[str] = []
211
  final_words: List[str] = []
 
212
 
213
  for t, info in enumerate(word_infos):
214
  raw_word = words[t]
215
  kind = info["kind"]
216
  candidates = info["candidates"]
217
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
218
  left_ctx = " ".join(final_words)
219
  right_ctx = " ".join(selected_words[t + 1:])
220
 
@@ -232,17 +329,12 @@ class BeamSearchDecoder:
232
  )
233
  best = scored[0]
234
  final_words.append(best.text)
 
235
 
236
- if kind == "sinhala":
237
- trace_logs.append(
238
- f"**Step {t+1}: `{raw_word}`** → `{best.text}` "
239
- f"(Sinhala, MLM={best.mlm_score:.3f})\n"
240
- )
241
- else:
242
- trace_logs.append(
243
- f"**Step {t+1}: `{raw_word}`** → `{best.text}` "
244
- f"(MLM={best.mlm_score:.3f})\n"
245
- + "\n".join(f" - `{s.text}` {s.mlm_score:.3f}" for s in scored)
246
- )
247
 
248
- return " ".join(final_words), trace_logs
 
17
 
18
  from core.constants import (
19
  DEFAULT_MLM_MODEL, DEFAULT_BYT5_MODEL,
20
+ MAX_CANDIDATES, MIN_ENGLISH_LEN, MIN_ENGLISH_PASSTHROUGH_LEN,
21
  PUNCT_PATTERN,
22
  )
23
  from core.english import ENGLISH_VOCAB
 
27
 
28
  _SINHALA_RE = re.compile(r"[\u0D80-\u0DFF]")
29
 
30
+ # ── Numeric / special-token passthrough ──────────────────────────────────────
31
+ # These patterns detect tokens that must not go through ByT5 transliteration.
32
+ _RE_ORDINAL = re.compile(r"^\d+(st|nd|rd|th)$", re.IGNORECASE) # 1st, 2nd, 3rd
33
+ _RE_PURE_NUM = re.compile(r"^\d+(?:[.,]\d+)*$") # 5, 10.30, 9.00
34
+ _RE_NUM_RANGE = re.compile(r"^\d+-\d+$") # 2-3, 10-20
35
+ _RE_CURRENCY = re.compile(r"^\d+[/]-?$") # 500/-
36
+ _RE_AM_PM = re.compile(r"^[ap]\.?m\.?$", re.IGNORECASE) # a.m. p.m. am pm
37
+ _RE_NUM_PCT_K = re.compile(r"^(\d[\d,.]*%+)k$", re.IGNORECASE) # 100%k → 100%ක්
38
+ _RE_NUM_K = re.compile(r"^(\d[\d,.]*)k$", re.IGNORECASE) # 5000k → 5000ක්
39
+ _RE_NUM_TA = re.compile(r"^(\d[\d,.]*)ta$", re.IGNORECASE) # 10.30ta → 10.30ට
40
+
41
+
42
+ def _numeric_passthrough(core: str) -> Optional[str]:
43
+ """
44
+ Return a (possibly lightly-transformed) value for numeric/special tokens.
45
+ Returns None if the token should go through normal ByT5 + MLM processing.
46
+ """
47
+ # 100%k → 100%ක් (check before plain Nk to avoid consuming the %)
48
+ m = _RE_NUM_PCT_K.match(core)
49
+ if m:
50
+ return m.group(1) + "ක්"
51
+ # 5000k / 10k → 5000ක් / 10ක්
52
+ m = _RE_NUM_K.match(core)
53
+ if m:
54
+ return m.group(1) + "ක්"
55
+ # 10.30ta → 10.30ට
56
+ m = _RE_NUM_TA.match(core)
57
+ if m:
58
+ return m.group(1) + "ට"
59
+ # Ordinals: 1st, 2nd, 3rd … → keep as-is
60
+ if _RE_ORDINAL.match(core):
61
+ return core
62
+ # Pure numbers and decimals: 5, 100, 10.30, 9.00 → keep
63
+ if _RE_PURE_NUM.match(core):
64
+ return core
65
+ # Number ranges: 2-3 → keep
66
+ if _RE_NUM_RANGE.match(core):
67
+ return core
68
+ # Currency notation: 500/- → keep
69
+ if _RE_CURRENCY.match(core):
70
+ return core
71
+ # AM/PM markers: a.m. p.m. am pm → keep
72
+ if _RE_AM_PM.match(core):
73
+ return core
74
+ return None
75
+
76
 
77
  class ScoredCandidate:
78
  __slots__ = ("text", "mlm_score")
 
184
 
185
  # ── Public decode ─────────────────────────────────────────────────────────
186
 
187
+ def decode(self, sentence: str) -> Tuple[str, List[str], List[Tuple[str, List[str]]]]:
188
  """
189
  Decode a Singlish sentence word-by-word using ByT5 + XLM-RoBERTa MLM.
190
+ Returns (transliterated_sentence, trace_logs, word_candidates).
191
+
192
+ word_candidates is a list of (selected_word, [all_candidates]) per word,
193
+ in input word order. Single-candidate words (passthrough/sinhala) have an
194
+ empty alternatives list.
195
  """
196
  words = sentence.split()
197
  if not words:
198
+ return "", [], []
199
 
200
  # ── Phase 1: batch ByT5 candidate generation ──────────────────────────
201
  # Collect only the words that need ByT5 (non-Sinhala), run in one pass
 
206
  match = PUNCT_PATTERN.match(raw)
207
  prefix, core, suffix = match.groups() if match else ("", raw, "")
208
  if not _is_sinhala(core):
209
+ # Skip numeric/special tokens — they don't need ByT5
210
+ if _numeric_passthrough(core) is not None:
211
+ continue
212
  cores.append(core)
213
  core_meta.append((i, prefix, core, suffix, core.lower()))
214
 
 
225
  word_infos: List[dict] = []
226
  for i, raw in enumerate(words):
227
  match = PUNCT_PATTERN.match(raw)
228
+ raw_prefix, core, raw_suffix = match.groups() if match else ("", raw, "")
229
 
230
  if _is_sinhala(core):
231
  word_infos.append({"kind": "sinhala", "candidates": [raw]})
232
  continue
233
 
234
+ # Numeric/special passthrough — keep or lightly transform, skip MLM
235
+ passthrough_val = _numeric_passthrough(core)
236
+ if passthrough_val is not None:
237
+ word_infos.append({"kind": "passthrough", "candidates": [raw_prefix + passthrough_val + raw_suffix]})
238
+ continue
239
+
240
  prefix, suffix, core_lower, byt5_cands = byt5_map[i]
241
  sinhala_cands = [prefix + c + suffix for c in byt5_cands]
242
 
243
  if core_lower in ENGLISH_VOCAB and len(core_lower) >= MIN_ENGLISH_LEN:
244
+ if len(core_lower) >= MIN_ENGLISH_PASSTHROUGH_LEN:
245
+ # Long English loanwords (≥6 chars): unambiguously English in
246
+ # code-mixed Singlish — bypass MLM to avoid Sinhala-bias override.
247
+ word_infos.append({"kind": "english", "candidates": [raw]})
248
+ else:
249
+ # Short English vocab words (3–5 chars) may also be Singlish
250
+ # homophones (mage/mama/game/call) — let MLM disambiguate.
251
+ candidates = [raw] + [c for c in sinhala_cands if c != raw]
252
+ word_infos.append({"kind": "singlish", "candidates": candidates[:MAX_CANDIDATES + 1]})
253
  else:
254
  word_infos.append({"kind": "singlish", "candidates": sinhala_cands})
255
 
 
259
  selected_words: List[str] = []
260
 
261
  for t, info in enumerate(word_infos):
262
+ # English-detected words: always keep raw form — skip MLM (MLM Sinhala bias
263
+ # would otherwise score a Sinhala transliteration higher than the English token)
264
+ if info["kind"] in ("english", "passthrough", "sinhala"):
265
+ selected_words.append(info["candidates"][0])
266
+ continue
267
  candidates = info["candidates"]
268
  left_ctx = " ".join(selected_words)
269
  right_ctx = " ".join(stable_right[t + 1:])
 
280
  # Right context is now the actual decoded output, not the pre-decode estimate
281
  trace_logs: List[str] = []
282
  final_words: List[str] = []
283
+ word_candidates: List[Tuple[str, List[str]]] = [] # (selected, [all_cands])
284
 
285
  for t, info in enumerate(word_infos):
286
  raw_word = words[t]
287
  kind = info["kind"]
288
  candidates = info["candidates"]
289
 
290
+ # English-detected, Sinhala, and passthrough words bypass MLM scoring.
291
+ # For English: the MLM model is Sinhala-biased and would otherwise prefer
292
+ # a Sinhala transliteration over the correct English token.
293
+ if kind == "sinhala":
294
+ final_words.append(candidates[0])
295
+ word_candidates.append((candidates[0], []))
296
+ trace_logs.append(
297
+ f"**Step {t+1}: `{raw_word}`** → `{candidates[0]}` (Sinhala passthrough)\n"
298
+ )
299
+ continue
300
+ if kind == "passthrough":
301
+ final_words.append(candidates[0])
302
+ word_candidates.append((candidates[0], []))
303
+ trace_logs.append(
304
+ f"**Step {t+1}: `{raw_word}`** → `{candidates[0]}` (numeric/passthrough)\n"
305
+ )
306
+ continue
307
+ if kind == "english":
308
+ final_words.append(candidates[0])
309
+ word_candidates.append((candidates[0], []))
310
+ trace_logs.append(
311
+ f"**Step {t+1}: `{raw_word}`** → `{candidates[0]}` (English vocab passthrough)\n"
312
+ )
313
+ continue
314
+
315
  left_ctx = " ".join(final_words)
316
  right_ctx = " ".join(selected_words[t + 1:])
317
 
 
329
  )
330
  best = scored[0]
331
  final_words.append(best.text)
332
+ word_candidates.append((best.text, [s.text for s in scored]))
333
 
334
+ trace_logs.append(
335
+ f"**Step {t+1}: `{raw_word}`** → `{best.text}` "
336
+ f"(MLM={best.mlm_score:.3f})\n"
337
+ + "\n".join(f" - `{s.text}` {s.mlm_score:.3f}" for s in scored)
338
+ )
 
 
 
 
 
 
339
 
340
+ return " ".join(final_words), trace_logs, word_candidates
feedback_schema.sql ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ create table if not exists public.feedback_submissions (
2
+ id bigint generated by default as identity primary key,
3
+ created_at timestamptz not null default timezone('utc', now()),
4
+ input_sentence text not null,
5
+ original_output text not null,
6
+ corrected_output text not null,
7
+ user_comment text not null default '',
8
+ decode_mode text not null default '',
9
+ review_status text not null default 'pending'
10
+ check (review_status in ('pending', 'approved', 'rejected')),
11
+ admin_notes text not null default '',
12
+ source text not null default 'streamlit'
13
+ );
14
+
15
+ create index if not exists feedback_submissions_created_at_idx
16
+ on public.feedback_submissions (created_at desc);
17
+
18
+ create index if not exists feedback_submissions_review_status_idx
19
+ on public.feedback_submissions (review_status);
feedback_store.py ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ from datetime import datetime, timezone
5
+ from pathlib import Path
6
+ from typing import Any, Dict
7
+
8
+ import requests
9
+
10
+
11
+ LOCAL_FEEDBACK_PATH = Path(__file__).parent / "misc" / "feedback_submissions.jsonl"
12
+
13
+
14
+ class FeedbackStore:
15
+ def __init__(
16
+ self,
17
+ supabase_url: str = "",
18
+ supabase_anon_key: str = "",
19
+ supabase_service_key: str = "",
20
+ table_name: str = "feedback_submissions",
21
+ ) -> None:
22
+ self.supabase_url = supabase_url.rstrip("/")
23
+ self.supabase_anon_key = supabase_anon_key
24
+ self.supabase_service_key = supabase_service_key
25
+ self.table_name = table_name
26
+
27
+ @property
28
+ def is_remote_enabled(self) -> bool:
29
+ return bool(self.supabase_url and (self.supabase_service_key or self.supabase_anon_key))
30
+
31
+ @property
32
+ def backend_label(self) -> str:
33
+ if self.is_remote_enabled:
34
+ return "Supabase"
35
+ return f"Local file ({LOCAL_FEEDBACK_PATH.name})"
36
+
37
+ def save_submission(
38
+ self,
39
+ input_sentence: str,
40
+ original_output: str,
41
+ corrected_output: str,
42
+ user_comment: str = "",
43
+ decode_mode: str = "",
44
+ ) -> Dict[str, Any]:
45
+ payload = {
46
+ "created_at": datetime.now(timezone.utc).isoformat(),
47
+ "input_sentence": input_sentence,
48
+ "original_output": original_output,
49
+ "corrected_output": corrected_output,
50
+ "user_comment": user_comment.strip(),
51
+ "decode_mode": decode_mode,
52
+ "review_status": "pending",
53
+ "admin_notes": "",
54
+ "source": "streamlit",
55
+ }
56
+ if self.is_remote_enabled:
57
+ return self._insert_remote(payload)
58
+ return self._insert_local(payload)
59
+
60
+ def _insert_local(self, payload: Dict[str, Any]) -> Dict[str, Any]:
61
+ LOCAL_FEEDBACK_PATH.parent.mkdir(parents=True, exist_ok=True)
62
+ with LOCAL_FEEDBACK_PATH.open("a", encoding="utf-8") as f:
63
+ f.write(json.dumps(payload, ensure_ascii=False) + "\n")
64
+ return {"ok": True, "record": payload}
65
+
66
+ def _insert_remote(self, payload: Dict[str, Any]) -> Dict[str, Any]:
67
+ url = f"{self.supabase_url}/rest/v1/{self.table_name}"
68
+ response = requests.post(
69
+ url,
70
+ headers=self._headers(admin=False, prefer="return=representation"),
71
+ json=payload,
72
+ timeout=15,
73
+ )
74
+ response.raise_for_status()
75
+ rows = response.json()
76
+ row = rows[0] if rows else payload
77
+ return {"ok": True, "record": row}
78
+
79
+ def _headers(self, admin: bool, prefer: str = "") -> Dict[str, str]:
80
+ key = self.supabase_service_key if admin and self.supabase_service_key else self.supabase_anon_key or self.supabase_service_key
81
+ headers = {
82
+ "apikey": key,
83
+ "Authorization": f"Bearer {key}",
84
+ "Content-Type": "application/json",
85
+ }
86
+ if prefer:
87
+ headers["Prefer"] = prefer
88
+ return headers
89
+
90
+
91
+ def format_feedback_error(exc: Exception) -> str:
92
+ if isinstance(exc, requests.HTTPError) and exc.response is not None:
93
+ try:
94
+ payload = exc.response.json()
95
+ if isinstance(payload, dict):
96
+ message = payload.get("message") or payload.get("hint") or json.dumps(payload)
97
+ return f"{exc.response.status_code}: {message}"
98
+ except ValueError:
99
+ pass
100
+ return f"{exc.response.status_code}: {exc.response.text.strip()}"
101
+ return str(exc)
misc/eval_indo.py ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Evaluate ByT5 on Indo NLP test sets - file-based logging version."""
3
+
4
+ import sys
5
+ import os
6
+ from pathlib import Path
7
+
8
+ project_root = Path(__file__).parent.parent
9
+ sys.path.insert(0, str(project_root))
10
+
11
+ os.environ['PYTHONUNBUFFERED'] = '1'
12
+
13
+ import torch
14
+ import pandas as pd
15
+ import json
16
+ from datetime import datetime
17
+
18
+ from core.decoder import BeamSearchDecoder
19
+
20
+ # Redirect stderr to avoid tqdm issues
21
+ import io
22
+ sys.stderr = open(os.devnull, 'w')
23
+
24
+ LOG_FILE = Path("misc/eval_progress.log")
25
+
26
+ def log(msg):
27
+ """Log to file and stdout."""
28
+ with open(LOG_FILE, 'a', encoding='utf-8') as f:
29
+ timestamp = datetime.now().strftime("%H:%M:%S")
30
+ f.write(f"[{timestamp}] {msg}\n")
31
+ print(msg, flush=True)
32
+
33
+ def load_test_set(filepath, max_samples=None):
34
+ """Load Indo NLP test set."""
35
+ samples = []
36
+ with open(filepath, 'r', encoding='utf-8') as f:
37
+ lines = [line.strip() for line in f.readlines() if line.strip()]
38
+
39
+ for i in range(0, len(lines), 2):
40
+ if i + 1 < len(lines):
41
+ samples.append({'singlish': lines[i], 'expected': lines[i+1]})
42
+ if max_samples and len(samples) >= max_samples:
43
+ break
44
+ return samples
45
+
46
+ def compute_metrics(predicted, expected):
47
+ """Compute CER, WER, BLEU, EM."""
48
+ from difflib import SequenceMatcher
49
+
50
+ matcher_char = SequenceMatcher(None, predicted, expected)
51
+ cer = 1.0 - matcher_char.ratio() if expected else (1.0 if predicted else 0.0)
52
+
53
+ pred_words = predicted.split()
54
+ exp_words = expected.split()
55
+ matcher_word = SequenceMatcher(None, pred_words, exp_words)
56
+ wer = 1.0 - matcher_word.ratio() if exp_words else (1.0 if pred_words else 0.0)
57
+
58
+ if exp_words:
59
+ matches = sum(1 for t in pred_words if t in exp_words)
60
+ bleu = matches / len(exp_words)
61
+ else:
62
+ bleu = 1.0 if not pred_words else 0.0
63
+
64
+ em = 1 if predicted == expected else 0
65
+
66
+ return {'cer': cer, 'wer': wer, 'bleu': bleu, 'em': em}
67
+
68
+ def main():
69
+ # Clear log
70
+ LOG_FILE.write_text("")
71
+
72
+ device = "cuda" if torch.cuda.is_available() else "cpu"
73
+ log(f"Device: {device}")
74
+
75
+ max_formal = int(sys.argv[1]) if len(sys.argv) > 1 else None
76
+ max_informal = int(sys.argv[2]) if len(sys.argv) > 2 else None
77
+ log(f"Max formal: {max_formal}, Max informal: {max_informal}")
78
+
79
+ log("\nLoading decoder...")
80
+ try:
81
+ decoder = BeamSearchDecoder(device=device)
82
+ log("Decoder loaded!")
83
+ except Exception as e:
84
+ log(f"ERROR loading decoder: {e}")
85
+ return
86
+
87
+ # Load test sets
88
+ test_dir = Path("IndoNLP-2025-Shared-Task/Test Dataset/Sinhala")
89
+
90
+ log(f"\nLoading test sets...")
91
+ formal_samples = load_test_set(test_dir / "Sinhala Test set 1.txt", max_samples=max_formal)
92
+ informal_samples = load_test_set(test_dir / "Sinhala Test set 2.txt", max_samples=max_informal)
93
+ log(f"Formal: {len(formal_samples)}, Informal: {len(informal_samples)}")
94
+
95
+ all_results = []
96
+
97
+ # Evaluate formal
98
+ log(f"\n>>> EVALUATING FORMAL ({len(formal_samples)} samples)...")
99
+ for idx, sample in enumerate(formal_samples):
100
+ try:
101
+ predicted, _, _ = decoder.decode(sample['singlish'])
102
+ metrics = compute_metrics(predicted, sample['expected'])
103
+ result = {**sample, 'predicted': predicted, 'subset': 'formal', **metrics}
104
+ all_results.append(result)
105
+
106
+ if (idx+1) % 10 == 0:
107
+ log(f" Formal {idx+1}/{len(formal_samples)}: EM={metrics['em']} CER={metrics['cer']:.3f}")
108
+ except Exception as e:
109
+ log(f" ERROR at formal {idx+1}: {str(e)[:100]}")
110
+ result = {**sample, 'predicted': '[ERROR]', 'subset': 'formal', 'cer': 1.0, 'wer': 1.0, 'bleu': 0.0, 'em': 0}
111
+ all_results.append(result)
112
+
113
+ log(f"Formal complete: {len([r for r in all_results if r['subset']=='formal'])} results")
114
+
115
+ # Evaluate informal
116
+ log(f"\n>>> EVALUATING INFORMAL ({len(informal_samples)} samples)...")
117
+ formal_count = len(all_results)
118
+ for idx, sample in enumerate(informal_samples):
119
+ try:
120
+ predicted, _, _ = decoder.decode(sample['singlish'])
121
+ metrics = compute_metrics(predicted, sample['expected'])
122
+ result = {**sample, 'predicted': predicted, 'subset': 'informal', **metrics}
123
+ all_results.append(result)
124
+
125
+ if (idx+1) % 10 == 0:
126
+ log(f" Informal {idx+1}/{len(informal_samples)}: EM={metrics['em']} CER={metrics['cer']:.3f}")
127
+ except Exception as e:
128
+ log(f" ERROR at informal {idx+1}: {str(e)[:100]}")
129
+ result = {**sample, 'predicted': '[ERROR]', 'subset': 'informal', 'cer': 1.0, 'wer': 1.0, 'bleu': 0.0, 'em': 0}
130
+ all_results.append(result)
131
+
132
+ log(f"Informal complete: {len([r for r in all_results if r['subset']=='informal'])} results")
133
+
134
+ # Summary
135
+ log(f"\n>>> SUMMARY...")
136
+ all_df = pd.DataFrame(all_results)
137
+
138
+ for subset in ['formal', 'informal', None]:
139
+ if subset:
140
+ df = all_df[all_df['subset'] == subset]
141
+ label = subset.upper()
142
+ else:
143
+ df = all_df
144
+ label = f"OVERALL ({len(df)})"
145
+
146
+ cer_mean = df['cer'].mean()
147
+ wer_mean = df['wer'].mean()
148
+ bleu_mean = df['bleu'].mean()
149
+ em_sum = int(df['em'].sum())
150
+
151
+ log(f"{label:20s} n={len(df):5d} | CER={cer_mean:.4f} WER={wer_mean:.4f} BLEU={bleu_mean:.4f} EM={em_sum}/{len(df)}")
152
+
153
+ # Save
154
+ all_df.to_csv("misc/indo_nlp_results.csv", index=False)
155
+ log(f"\nResults saved: misc/indo_nlp_results.csv")
156
+
157
+ log("\nDONE!")
158
+
159
+ if __name__ == "__main__":
160
+ main()
misc/eval_internal_500.py ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Evaluate ByT5 + XLM-RoBERTa reranker on internal_test_set_500.csv.
4
+ CSV columns: id, category, input, code_mixed_reference
5
+
6
+ Usage:
7
+ python misc/eval_internal_500.py # full 500
8
+ python misc/eval_internal_500.py --max 10 # dry run
9
+ python misc/eval_internal_500.py --max 10 --cat colloquial
10
+ """
11
+
12
+ import sys
13
+ import os
14
+ import argparse
15
+ import csv
16
+ import time
17
+ from pathlib import Path
18
+ from collections import defaultdict
19
+
20
+ project_root = Path(__file__).parent.parent
21
+ sys.path.insert(0, str(project_root))
22
+
23
+ from core.decoder import BeamSearchDecoder
24
+
25
+
26
+ # ── Metrics ─────────────────────────────────────────────────────────────────
27
+
28
+ def levenshtein(a, b):
29
+ if not a: return len(b)
30
+ if not b: return len(a)
31
+ prev = list(range(len(b) + 1))
32
+ for i, ca in enumerate(a, 1):
33
+ curr = [i] + [0] * len(b)
34
+ for j, cb in enumerate(b, 1):
35
+ curr[j] = min(prev[j] + 1, curr[j-1] + 1, prev[j-1] + (0 if ca == cb else 1))
36
+ prev = curr
37
+ return prev[-1]
38
+
39
+ def cer(pred, ref):
40
+ if not ref: return 0.0 if not pred else 1.0
41
+ return levenshtein(pred, ref) / len(ref)
42
+
43
+ def wer(pred, ref):
44
+ pw, rw = pred.split(), ref.split()
45
+ if not rw: return 0.0 if not pw else 1.0
46
+ return levenshtein(pw, rw) / len(rw)
47
+
48
+ def bleu1(pred, ref):
49
+ pt, rt = pred.split(), ref.split()
50
+ if not rt: return 1.0 if not pt else 0.0
51
+ matches = sum(1 for t in pt if t in rt)
52
+ return matches / len(rt)
53
+
54
+ def exact_match(pred, ref):
55
+ return pred.strip() == ref.strip()
56
+
57
+
58
+ # ── Main ─────────────────────────────────────────────────────────────────────
59
+
60
+ def main():
61
+ parser = argparse.ArgumentParser()
62
+ parser.add_argument("--max", type=int, default=None, help="Max samples to evaluate")
63
+ parser.add_argument("--cat", type=str, default=None, help="Filter to one category")
64
+ parser.add_argument("--out", type=str, default="misc/internal_500_results.csv", help="Output CSV path")
65
+ args = parser.parse_args()
66
+
67
+ csv_path = project_root / "misc" / "internal_test_set_500.csv"
68
+
69
+ # Load samples
70
+ samples = []
71
+ with open(csv_path, newline="", encoding="utf-8-sig") as f:
72
+ reader = csv.DictReader(f)
73
+ for row in reader:
74
+ if args.cat and row["category"] != args.cat:
75
+ continue
76
+ samples.append(row)
77
+ if args.max and len(samples) >= args.max:
78
+ break
79
+
80
+ print(f"Loaded {len(samples)} samples" + (f" (category={args.cat})" if args.cat else ""))
81
+
82
+ # Load decoder
83
+ import torch
84
+ device = "cuda" if torch.cuda.is_available() else "cpu"
85
+ print(f"Loading BeamSearchDecoder on {device}...")
86
+ decoder = BeamSearchDecoder(device=device)
87
+ print("Ready.\n")
88
+
89
+ results = []
90
+ category_stats = defaultdict(list)
91
+
92
+ for i, row in enumerate(samples):
93
+ inp = row["input"].strip()
94
+ ref = row["code_mixed_reference"].strip()
95
+ cat = row["category"]
96
+ sid = row["id"]
97
+
98
+ t0 = time.time()
99
+ try:
100
+ pred, _, _ = decoder.decode(inp)
101
+ except Exception as e:
102
+ print(f" ERROR id={sid}: {e}")
103
+ pred = "[ERROR]"
104
+ elapsed = time.time() - t0
105
+
106
+ c = cer(pred, ref)
107
+ w = wer(pred, ref)
108
+ b = bleu1(pred, ref)
109
+ em = exact_match(pred, ref)
110
+
111
+ result = {
112
+ "id": sid,
113
+ "category": cat,
114
+ "input": inp,
115
+ "reference": ref,
116
+ "prediction": pred,
117
+ "cer": round(c, 4),
118
+ "wer": round(w, 4),
119
+ "bleu": round(b, 4),
120
+ "exact_match": em,
121
+ "time_s": round(elapsed, 3),
122
+ }
123
+ results.append(result)
124
+ category_stats[cat].append(result)
125
+
126
+ status = "PASS" if em else "FAIL"
127
+ print(f"[{i+1:>4}/{len(samples)}] {status} id={sid:>4} cat={cat:<15} CER={c:.3f} WER={w:.3f} BLEU={b:.3f}")
128
+ if not em:
129
+ print(f" IN: {inp}")
130
+ print(f" REF: {ref}")
131
+ print(f" GOT: {pred}")
132
+
133
+ # Write results CSV
134
+ out_path = project_root / args.out
135
+ with open(out_path, "w", newline="", encoding="utf-8") as f:
136
+ writer = csv.DictWriter(f, fieldnames=results[0].keys())
137
+ writer.writeheader()
138
+ writer.writerows(results)
139
+ print(f"\nResults saved to: {out_path}")
140
+
141
+ # Summary by category
142
+ print(f"\n{'='*70}")
143
+ print(f"{'CATEGORY':<18} {'n':>4} {'CER':>7} {'WER':>7} {'BLEU':>7} {'EM%':>7}")
144
+ print(f"{'='*70}")
145
+
146
+ all_results = results
147
+ for cat in sorted(category_stats):
148
+ rows = category_stats[cat]
149
+ n = len(rows)
150
+ avg_cer = sum(r["cer"] for r in rows) / n
151
+ avg_wer = sum(r["wer"] for r in rows) / n
152
+ avg_bleu = sum(r["bleu"] for r in rows) / n
153
+ em_pct = sum(1 for r in rows if r["exact_match"]) / n * 100
154
+ print(f"{cat:<18} {n:>4} {avg_cer:>7.4f} {avg_wer:>7.4f} {avg_bleu:>7.4f} {em_pct:>6.1f}%")
155
+
156
+ n = len(all_results)
157
+ print(f"{'─'*70}")
158
+ print(f"{'OVERALL':<18} {n:>4} "
159
+ f"{sum(r['cer'] for r in all_results)/n:>7.4f} "
160
+ f"{sum(r['wer'] for r in all_results)/n:>7.4f} "
161
+ f"{sum(r['bleu'] for r in all_results)/n:>7.4f} "
162
+ f"{sum(1 for r in all_results if r['exact_match'])/n*100:>6.1f}%")
163
+ print(f"{'='*70}")
164
+
165
+
166
+ if __name__ == "__main__":
167
+ main()
misc/evaluate_indo_nlp.py ADDED
@@ -0,0 +1,241 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Evaluate ByT5 + XLM-RoBERTa reranker on Indo NLP Sinhala test sets.
4
+ Test Set 1: 10K formal sentences
5
+ Test Set 2: 5K informal sentences (ad-hoc, colloquial)
6
+ """
7
+
8
+ import sys
9
+ import os
10
+ from pathlib import Path
11
+
12
+ # Add project root to path
13
+ project_root = Path(__file__).parent.parent
14
+ sys.path.insert(0, str(project_root))
15
+
16
+ import torch
17
+ import pandas as pd
18
+ import numpy as np
19
+ from collections import defaultdict
20
+
21
+ # Import our models
22
+ from core.decoder import BeamSearchDecoder
23
+
24
+ def load_test_set(filepath, max_samples=None):
25
+ """
26
+ Load Indo NLP test set.
27
+ Format: pairs of lines (Singlish, Sinhala expected output)
28
+ """
29
+ samples = []
30
+ with open(filepath, 'r', encoding='utf-8') as f:
31
+ lines = [line.strip() for line in f.readlines() if line.strip()]
32
+
33
+ for i in range(0, len(lines), 2):
34
+ if i + 1 < len(lines):
35
+ singlish_input = lines[i]
36
+ sinhala_expected = lines[i + 1]
37
+ samples.append({
38
+ 'singlish': singlish_input,
39
+ 'expected': sinhala_expected
40
+ })
41
+ if max_samples and len(samples) >= max_samples:
42
+ break
43
+
44
+ return samples
45
+
46
+ def compute_cer(predicted, expected):
47
+ """Character Error Rate"""
48
+ if not expected:
49
+ return 1.0 if predicted else 0.0
50
+
51
+ # Simple character-level edit distance
52
+ from difflib import SequenceMatcher
53
+ matcher = SequenceMatcher(None, predicted, expected)
54
+ ratio = matcher.ratio()
55
+ return 1.0 - ratio
56
+
57
+ def compute_wer(predicted, expected):
58
+ """Word Error Rate (space-separated tokens)"""
59
+ pred_words = predicted.split()
60
+ exp_words = expected.split()
61
+
62
+ if not exp_words:
63
+ return 1.0 if pred_words else 0.0
64
+
65
+ from difflib import SequenceMatcher
66
+ matcher = SequenceMatcher(None, pred_words, exp_words)
67
+ ratio = matcher.ratio()
68
+ return 1.0 - ratio
69
+
70
+ def compute_em(predicted, expected):
71
+ """Exact Match"""
72
+ return 1.0 if predicted == expected else 0.0
73
+
74
+ def compute_bleu(predicted, expected, n=4):
75
+ """Simple BLEU approximation (unigram overlap)"""
76
+ pred_tokens = predicted.split()
77
+ exp_tokens = expected.split()
78
+
79
+ if not exp_tokens:
80
+ return 1.0 if not pred_tokens else 0.0
81
+
82
+ # Count matching tokens
83
+ matches = sum(1 for t in pred_tokens if t in exp_tokens)
84
+ return matches / len(exp_tokens)
85
+
86
+ def evaluate_samples(decoder, samples, device, batch_size=8):
87
+ """
88
+ Evaluate ByT5 + MLM reranker on samples.
89
+ Returns: list of results with metrics
90
+ """
91
+ results = []
92
+ total = len(samples)
93
+
94
+ for idx, sample in enumerate(samples):
95
+ singlish_input = sample['singlish']
96
+ expected_output = sample['expected']
97
+
98
+ # Print progress every 10 samples
99
+ if idx % 10 == 0:
100
+ print(f" Progress: {idx}/{total}", flush=True)
101
+
102
+ try:
103
+ # Decode using BeamSearchDecoder (includes ByT5 + MLM reranking)
104
+ predicted, trace_logs, _ = decoder.decode(singlish_input)
105
+
106
+ # Compute metrics
107
+ cer = compute_cer(predicted, expected_output)
108
+ wer = compute_wer(predicted, expected_output)
109
+ bleu = compute_bleu(predicted, expected_output)
110
+ em = compute_em(predicted, expected_output)
111
+
112
+ results.append({
113
+ 'singlish': singlish_input,
114
+ 'expected': expected_output,
115
+ 'predicted': predicted,
116
+ 'cer': cer,
117
+ 'wer': wer,
118
+ 'bleu': bleu,
119
+ 'em': em
120
+ })
121
+
122
+ except Exception as e:
123
+ print(f" Error at {idx}/{total} processing '{singlish_input}': {e}")
124
+ results.append({
125
+ 'singlish': singlish_input,
126
+ 'expected': expected_output,
127
+ 'predicted': '[ERROR]',
128
+ 'cer': 1.0,
129
+ 'wer': 1.0,
130
+ 'bleu': 0.0,
131
+ 'em': 0
132
+ })
133
+
134
+ print(f" Completed: {total}/{total}", flush=True)
135
+ return results
136
+
137
+ def print_metrics(results, subset_name):
138
+ """Print metrics summary"""
139
+ if not results:
140
+ print(f"{subset_name}: No results")
141
+ return
142
+
143
+ df = pd.DataFrame(results)
144
+
145
+ print(f"\n{'='*60}")
146
+ print(f"Subset: {subset_name} (n={len(results)})")
147
+ print(f"{'='*60}")
148
+ print(f"CER (lower is better): {df['cer'].mean():.4f} ± {df['cer'].std():.4f}")
149
+ print(f"WER (lower is better): {df['wer'].mean():.4f} ± {df['wer'].std():.4f}")
150
+ print(f"BLEU (higher is better): {df['bleu'].mean():.4f} ± {df['bleu'].std():.4f}")
151
+ print(f"EM (higher is better): {df['em'].mean():.4f} ({int(df['em'].sum())} / {len(results)})")
152
+
153
+ # Show sample failures
154
+ failures = df[df['em'] == 0].head(3)
155
+ if len(failures) > 0:
156
+ print(f"\nSample Failures (first 3):")
157
+ for idx, row in failures.iterrows():
158
+ print(f" Input: {row['singlish']}")
159
+ print(f" Expected: {row['expected']}")
160
+ print(f" Got: {row['predicted']}")
161
+ print()
162
+
163
+ def main():
164
+ import sys
165
+
166
+ device = "cuda" if torch.cuda.is_available() else "cpu"
167
+ print(f"Using device: {device}")
168
+
169
+ # Parse command line args for sample limits
170
+ max_formal = int(sys.argv[1]) if len(sys.argv) > 1 else None
171
+ max_informal = int(sys.argv[2]) if len(sys.argv) > 2 else None
172
+
173
+ # Initialize model
174
+ print("Loading BeamSearchDecoder (ByT5 + MLM reranker)...")
175
+ decoder = BeamSearchDecoder(device=device)
176
+
177
+ # Load test sets
178
+ test_dir = Path("IndoNLP-2025-Shared-Task/Test Dataset/Sinhala")
179
+
180
+ print("\nLoading Test Set 1 (formal, 10K)...")
181
+ formal_samples = load_test_set(test_dir / "Sinhala Test set 1.txt", max_samples=max_formal)
182
+ print(f"Loaded {len(formal_samples)} formal samples")
183
+
184
+ print("Loading Test Set 2 (informal, 5K)...")
185
+ informal_samples = load_test_set(test_dir / "Sinhala Test set 2.txt", max_samples=max_informal)
186
+ print(f"Loaded {len(informal_samples)} informal samples")
187
+
188
+ # Evaluate
189
+ print("\n" + "="*60)
190
+ print(f"EVALUATING FORMAL SUBSET ({len(formal_samples)} samples)")
191
+ print("="*60)
192
+ formal_results = evaluate_samples(decoder, formal_samples, device)
193
+
194
+ print("\n" + "="*60)
195
+ print(f"EVALUATING INFORMAL SUBSET ({len(informal_samples)} samples)")
196
+ print("="*60)
197
+ informal_results = evaluate_samples(decoder, informal_samples, device)
198
+
199
+ # Print results
200
+ print_metrics(formal_results, f"Formal ({len(formal_results)})")
201
+ print_metrics(informal_results, f"Informal ({len(informal_results)})")
202
+
203
+ # Overall
204
+ all_results = formal_results + informal_results
205
+ print_metrics(all_results, f"OVERALL ({len(all_results)} samples)")
206
+
207
+ # Save detailed results
208
+ results_df = pd.DataFrame(all_results)
209
+ results_df.to_csv("misc/indo_nlp_eval_results.csv", index=False)
210
+ print(f"\nDetailed results saved to: misc/indo_nlp_eval_results.csv")
211
+
212
+ # Save summary
213
+ summary = {
214
+ 'Subset': [f'Formal ({len(formal_results)})', f'Informal ({len(informal_results)})', f'Overall ({len(all_results)})'],
215
+ 'CER': [
216
+ f"{pd.DataFrame(formal_results)['cer'].mean():.4f}",
217
+ f"{pd.DataFrame(informal_results)['cer'].mean():.4f}",
218
+ f"{results_df['cer'].mean():.4f}"
219
+ ],
220
+ 'WER': [
221
+ f"{pd.DataFrame(formal_results)['wer'].mean():.4f}",
222
+ f"{pd.DataFrame(informal_results)['wer'].mean():.4f}",
223
+ f"{results_df['wer'].mean():.4f}"
224
+ ],
225
+ 'BLEU': [
226
+ f"{pd.DataFrame(formal_results)['bleu'].mean():.4f}",
227
+ f"{pd.DataFrame(informal_results)['bleu'].mean():.4f}",
228
+ f"{results_df['bleu'].mean():.4f}"
229
+ ],
230
+ 'EM': [
231
+ f"{pd.DataFrame(formal_results)['em'].mean():.4f}",
232
+ f"{pd.DataFrame(informal_results)['em'].mean():.4f}",
233
+ f"{results_df['em'].mean():.4f}"
234
+ ]
235
+ }
236
+ summary_df = pd.DataFrame(summary)
237
+ summary_df.to_csv("misc/indo_nlp_eval_summary.csv", index=False)
238
+ print(f"Summary saved to: misc/indo_nlp_eval_summary.csv")
239
+
240
+ if __name__ == "__main__":
241
+ main()
misc/indo_nlp_eval_results.csv ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ singlish,expected,predicted,cer,wer,bleu,em
2
+ awankawama mata eya mathaka ethi akaraya eyayi namuth eya wikarayaki mama obata ashwaya kerehi wedi elmak nodakwana namuth eya mage wilasithawa nowe,අවංකවම මට එය මතක ඇති ආකාරය එයයි නමුත් එය විකාරයකි මම ඔබට අශ්වයා කෙරෙහි වැඩි ඇල්මක් නොදක්වන නමුත් එය මගේ විලාසිතාව නොවේ,අවංකවාම මට එය මතක ඇති ආකාරය එයයි නමුත් එය විකරයකි මම ඔබටා අශවය කෙරෙහි වැඩි ඇලීමක් නොදක්වාන නමුත් එය මගේ විලාසිතව නොවේ,0.03829787234042559,0.31818181818181823,0.6818181818181818,0.0
3
+ oba mage aneka yeyi adahas karanne kese ho oba ema wilasithawata andinne mandeyi mama asami,ඔබ මගේ අනෙකා යැයි අදහස් කරන්නේ කෙසේ හෝ ඔබ එම විලාසිතාවට අඳින්නේ මන්දැයි මම අසමි,ඔබ මගේ අණෙක යැයි අදහස් කරන්නේ කෙසේ හෝ ඔබ ඒම විලාසිතවට අඳින්නේ මන්දැයි මම අසමි,0.038461538461538436,0.19999999999999996,0.8,0.0
4
+ mama kiwa yuthuyi oba wedipura penenne obe mahalu athmayayi oba adahas karanne mage aneka bawayi,මම කිව යුතුයි ඔබ වැඩිපුර පෙනෙන්නේ ඔබේ මහලු ආත්මයයි ඔබ අදහස් කරන්නේ මගේ අනෙකා බවයි,මම කිව යුතුයි ඔබ වැඩිපුරා පෙනෙන්නේ ඔබේ ම ආතේමයයි ඔබ අදහස් කරන්නේ මගේ අනෙකා බවයි,0.03749999999999998,0.19999999999999996,0.8,0.0
5
+ kese ho oba ese andinne mandeyi mata eseemata ida etha mama shokayen sitina bawa pehedili yeyi mata sithiya yuthuwa thibuni,"කෙසේ හෝ ඔබ එසේ අඳින්නේ මන්දැයි මට ඇසීමට ඉඩ ඇත, මම ශෝකයෙන් සිටින බව පැහැදිලි යැයි මට සිතිය යුතුව තිබුණි",කෙසේ හෝ ඔබ එසේ අඳින්නේ මන්දැයි මට ඇසීමට ඉඩ ඇත මම ශෝකයෙන් සිටින බව පැහැදිලි යැයි මට සිතිය යුතුව තිබුණි,0.0049261083743842304,0.050000000000000044,0.95,0.0
6
+ mona hari adahas monada,මොනා හරි අදහස් මොනාද,මොන හරි අදහසේ මොනද,0.10526315789473684,0.75,0.25,0.0
7
+ ohu rajakeeya saththwa widya sangamaye samajikayek bawa ohuge sapaththuwe liya etha,ඔහු රාජකීය සත්ත්ව විද්‍යා සංගමයේ සාමාජිකයෙක් බව ඔහුගේ සපත්තුවේ ලියා ඇත,ඔහු රාජකීය සත්ත්ව වෛද්‍ය සංගමයේ සාමජිකයෙක් බව ඔහුගේ සපත්තුවේ ලියා ඇත,0.02898550724637683,0.18181818181818177,0.8181818181818182,0.0
8
+ onema adahasak hondayi ohu rajakeeya sathwa widya sangamaye sagayeki,"ඕනෑම අදහසක් හොඳයි, ඔහු රාජකීය සත්ව විද්‍යා සංගමයේ සගයෙකි",ඕනෑම අදහසක් හොඳායි ඔහු රාජකීය සතව විද්‍ය සංගමයේ සගයේකි,0.054545454545454564,0.4444444444444444,0.5555555555555556,0.0
9
+ samanya denuma misis peel ethana ege kate thibba,සාමාන්‍ය දැනුම මිසිස් පීල් එතන ඇගේ කටේ තිබ්බා,සමන්‍ය දෑනුම මිසිස් පීලා එතාන ඒගේ කටේ තිබෙබ,0.13636363636363635,0.75,0.25,0.0
10
+ oba wenuwen misis peel sthuthiyi mata awadanam helo kireemata ida deema gena oba adahas karanne kumakdeyi mama dakimi,ඔබ වෙනුවෙන් මිසිස් පීල් ස්තූතියි මට අවදානම් හෙලෝ කිරීමට ඉඩ දීම ගැන ඔබ අදහස් කරන්නේ කුමක්දැයි මම දකිමි,ඔබ වෙනුවෙන් මිසිසෝ පීළා සතූතියි මට ආවඩනම හේලෝ කිරීමට ඉඩ දීම ගැන ඔබ අදහස් කරන්නේ කුමක්දැයි මම දකිමි,0.07537688442211055,0.2777777777777778,0.7222222222222222,0.0
11
+ namuth kawuruhari kriyawaliya kuda kara ethnam api weda karamin sitiye eyayi,නමුත් කවුරුහරි ක්‍රියාවලිය කුඩා කර ඇත්නම් අපි වැඩ කරමින��� සිටියේ එයයි,නමුත් කවුරුහාරි ක්‍රියවලිය කුද ඛාර එතෙනම අපි වැඩ කරමින් සිටියෙ එයයි,0.11111111111111116,0.5454545454545454,0.45454545454545453,0.0
12
+ mta eka prshnyk ahanna puluwn nm awulak ne,මට එක ප්‍රශ්නයක් අහන්න පුළුවන් නම් අවුලක් නෑ,මට එක ප්‍රශ්නයක අහන්න පුළුවන් නම් අවුලක් නෑ,0.011494252873563204,0.125,0.875,0.0
13
+ hondyi eka modyi wge,"හොඳයි, ඒක මෝඩයි වගේ",හොඳයි ඒක මෝඩයි වගේ,0.027027027027026973,0.25,0.75,0.0
14
+ kmk nehe modyi wge,කමක් නැහැ මෝඩයි වගේ,කමක් නැහැ මෝදයි වගේ,0.052631578947368474,0.25,0.75,0.0
15
+ kmk nehe oba eyta kemthi nownu etha,කමක් නැහැ ඔබ එයට කැමති නොවනු ඇත,කමක් නැහැ ඔබ එයට කැමති නොවනු ඇත,0.0,0.0,1.0,1.0
16
+ oba eyta kemthi nownu etha eya asanna,"ඔබ එයට කැමති නොවනු ඇත, එය අසන්න",ඔබ එයට කැමති නොවනු ඇත එය අසන්න,0.016393442622950838,0.1428571428571429,0.8571428571428571,0.0
17
+ eya wda honda deyi asanna,එය වඩා හොඳ දැයි අසන්න,ඒය වෙද හොඳ දේයි අසනන,0.2195121951219512,0.8,0.2,0.0
18
+ mma hithnne ohu smnga lingikwa hesireema wda hondyi,මම හිතන්නේ ඔහු සමඟ ලිංගිකව හැසිරීම වඩා හොඳයි,මම හිතන්නේ ඔහු සමඟ ලිංගිකව හැසිරීමා වඩා හොඳයි,0.011235955056179803,0.125,0.875,0.0
19
+ hondyi lingikwa hesireema mma hithnne ohu smnga lingikwa ekweema wda honda jesus kristhu rob eyyi eththtma obta krdra krnne,හොඳයි ලිංගිකව හැසිරීම මම හිතන්නේ ඔහු සමඟ ලිංගිකව එක්වීම වඩා හොඳ ජේසුස් ක්‍රිස්තු රොබ් එයයි ඇත්තටම ඔබට කරදර කරන්නේ,හොඳායි ලිඟිකව හැසිරීමා මම හිතන්නේ ඔහු සමඟ ලිංගිකව එක්වීම වඩා හොඳ ජීසුස් කොරිස්තු රෝබ් එයයි ඇත්තටම ඔබට කරදර කරන්නේ,0.053097345132743334,0.3157894736842105,0.6842105263157895,0.0
20
+ eththa wshyenma eya oba sebwinma sithnne eya kese ho wensk wnu ethi bwyi,ඇත්ත වශයෙන්ම එය ඔබ සැබවින්ම සිතන්නේ එය කෙසේ හෝ වෙනසක් වනු ඇති බවයි,ඇත්ත වශයෙන්ම ඒය ඔබ සැබෑවින්ම සිතන්නේ එය කෙසේ හෝ වෙනසක් වනු ඇති බවයි,0.022556390977443663,0.15384615384615385,0.8461538461538461,0.0
21
+ oba eththtma sithnne eya mma nodnna akarayen wensk ethi kryi kiyya,ඔබ ඇත්තටම සිතන්නේ එය මම නොදන්න ආකාරයෙන් වෙනසක් ඇති කරයි කියාය,ඔබ ඇත්තටම සිතන්නේ එය මම නොදන්නා ආකාරයෙන් වෙනසක් ඇති කරයි කියාය,0.008130081300813052,0.09090909090909094,0.9090909090909091,0.0
misc/indo_nlp_eval_summary.csv ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ Subset,CER,WER,BLEU,EM
2
+ Formal (10),0.0631,0.3718,0.6282,0.0000
3
+ Informal (10),0.0422,0.2253,0.7747,0.1000
4
+ Overall (20),0.0526,0.2986,0.7014,0.0500
misc/indo_nlp_results.csv ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ singlish,expected,predicted,subset,cer,wer,bleu,em
2
+ awankawama mata eya mathaka ethi akaraya eyayi namuth eya wikarayaki mama obata ashwaya kerehi wedi elmak nodakwana namuth eya mage wilasithawa nowe,අවංකවම මට එය මතක ඇති ආකාරය එයයි නමුත් එය විකාරයකි මම ඔබට අශ්වයා කෙරෙහි වැඩි ඇල්මක් නොදක්වන නමුත් එය මගේ විලාසිතාව නොවේ,අවංකවාම මට එය මතක ඇති ආකාරය එයයි නමුත් එය විකරයකි මම ඔබටා අශවය කෙරෙහි වැඩි ඇලීමක් නොදක්වාන නමුත් එය මගේ විලාසිතව නොවේ,formal,0.03829787234042559,0.31818181818181823,0.6818181818181818,0
3
+ oba mage aneka yeyi adahas karanne kese ho oba ema wilasithawata andinne mandeyi mama asami,ඔබ මගේ අනෙකා යැයි අදහස් කරන්නේ කෙසේ හෝ ඔබ එම විලාසිතාවට අඳින්නේ මන්දැයි මම අසමි,ඔබ මගේ අණෙක යැයි අදහස් කරන්නේ කෙසේ හෝ ඔබ ඒම විලාසිතවට අඳින්නේ මන්දැයි මම අසමි,formal,0.038461538461538436,0.19999999999999996,0.8,0
4
+ mama kiwa yuthuyi oba wedipura penenne obe mahalu athmayayi oba adahas karanne mage aneka bawayi,මම කිව යුතුයි ඔබ වැඩිපුර පෙනෙන්නේ ඔබේ මහලු ආත්මයයි ඔබ අදහස් කරන්නේ මගේ අනෙකා බවයි,මම කිව යුතුයි ඔබ වැඩිපුරා පෙනෙන්නේ ඔබේ ම ආතේමයයි ඔබ අදහස් කරන්නේ මගේ අනෙකා බවයි,formal,0.03749999999999998,0.19999999999999996,0.8,0
5
+ kese ho oba ese andinne mandeyi mata eseemata ida etha mama shokayen sitina bawa pehedili yeyi mata sithiya yuthuwa thibuni,"කෙසේ හෝ ඔබ එසේ අඳින්නේ මන්දැයි මට ඇසීමට ඉඩ ඇත, මම ශෝකයෙන් සිටින බව පැහැදිලි යැයි මට සිතිය යුතුව තිබුණි",කෙසේ හෝ ඔබ එසේ අඳින්නේ මන්දැයි මට ඇසීමට ඉඩ ඇත මම ශෝකයෙන් සිටින බව පැහැදිලි යැයි මට සිතිය යුතුව තිබුණි,formal,0.0049261083743842304,0.050000000000000044,0.95,0
6
+ mona hari adahas monada,මොනා හරි අදහස් මොනාද,මොන හරි අදහසේ මොනද,formal,0.10526315789473684,0.75,0.25,0
7
+ mta eka prshnyk ahanna puluwn nm awulak ne,මට එක ප්‍රශ්නයක් අහන්න පුළුවන් නම් අවුලක් නෑ,මට එක ප්‍රශ්නයක අහන්න පුළුවන් නම් අවුලක් නෑ,informal,0.011494252873563204,0.125,0.875,0
8
+ hondyi eka modyi wge,"හොඳයි, ඒක මෝඩයි වගේ",හොඳයි ඒක මෝඩයි වගේ,informal,0.027027027027026973,0.25,0.75,0
9
+ kmk nehe modyi wge,කමක් නැහැ මෝඩයි වගේ,කමක් නැහැ මෝදයි වගේ,informal,0.052631578947368474,0.25,0.75,0
10
+ kmk nehe oba eyta kemthi nownu etha,කමක් නැහැ ඔබ එයට කැමති නොවනු ඇත,කමක් නැහැ ඔබ එයට කැමති නොවනු ඇත,informal,0.0,0.0,1.0,1
11
+ oba eyta kemthi nownu etha eya asanna,"ඔබ එයට කැමති නොවනු ඇත, එය අසන්න",ඔබ එයට කැමති නොවනු ඇත එය අසන්න,informal,0.016393442622950838,0.1428571428571429,0.8571428571428571,0
misc/internal_500_results.csv ADDED
The diff for this file is too large to render. See raw diff
 
misc/internal_test_set_500.csv ADDED
@@ -0,0 +1,501 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ id,category,input,code_mixed_reference
2
+ 1,colloquial,api heta gedara yanawa,අපි හෙට ගෙදර යනවා
3
+ 2,colloquial,mama dan inne office eke,මම දැන් ඉන්නේ office එකේ
4
+ 3,code_mixed,mage assignment eka submit kala,මගේ assignment එක submit කළා
5
+ 4,code_mixed,api meeting eka cancel kala,අපි meeting එක cancel කළා
6
+ 5,formal,obage upakarayata apage wishesha sthuthiya.,ඔබගේ උපකාරයට අපගේ විශේෂ ස්තූතිය.
7
+ 6,long_sentence,mema videowe bit rate eka godak wadi nisa buffer wenawa,මෙම වීඩියෝවේ bit rate එක ගොඩක් වැඩි නිසා buffer වෙනවා
8
+ 7,short_phrase,honda naa,හොඳ නෑ
9
+ 8,edge_case,api 3 dena passe yamu,අපි 3 දෙනා පස්සේ යමු
10
+ 9,colloquial,oya dan koheda yanne,ඔයා දැන් කොහේද යන්නේ
11
+ 10,colloquial,mata ada godak wada thiyenawa,මට අද ගොඩක් වැඩ තියෙනවා
12
+ 11,colloquial,heta ude keeyatada enne,හෙට උදේ කීයටද එන්නේ
13
+ 12,colloquial,amma ada monawada kaama haduwe,අම්මා අද මොනවාද කෑම හැදුවේ
14
+ 13,colloquial,mata hariyata ninda giye na,මට හරියට නින්ද ගියේ නෑ
15
+ 14,colloquial,nikan boru kiyanna epa,නිකන් බොරු කියන්න එපා
16
+ 15,colloquial,api passe welawaka katha karamu,අපි පස්සේ වෙලාවක කතා කරමු
17
+ 16,colloquial,eka dakkama mata baya hithuna,ඒක දැක්කම මට බය හිතුණා
18
+ 17,colloquial,mama ada game giya,මම අද ගමේ ගියා
19
+ 18,colloquial,oya thama kewe nadda,ඔයා තාම කෑවේ නැද්ද
20
+ 19,colloquial,api dennath ekka heta yamu,අපි දෙන්නත් එක්ක හෙට යමු
21
+ 20,colloquial,dan nikan inna epa wada karanna,දැන් නිකන් ඉන්න එපා වැඩ කරන්න
22
+ 21,colloquial,thama bus eka awe na,තාම බස් එක ආවේ නෑ
23
+ 22,colloquial,wathura nathiwa inna ba,වතුර නැතිව ඉන්න බෑ
24
+ 23,colloquial,dan hariyata mahansi wage,දැන් හරියට මහන්සි වගේ
25
+ 24,colloquial,ai oya ehema kale,ඇයි ඔයා එහෙම කළේ
26
+ 25,colloquial,mata oya gana tharahak na,මට ඔයා ගැන තරහක් නෑ
27
+ 26,colloquial,oya thawa kaama ganna,ඔයා තව කෑම ගන්න
28
+ 27,colloquial,me pota kiyawala balanna,මේ පොත කියවලා බලන්න
29
+ 28,colloquial,thaththa dan gedara awada,තාත්තා දැන් ගෙදර ආවාද
30
+ 29,colloquial,api moko karanne dan,අපි මොකෝ කරන්නේ දැන්
31
+ 30,colloquial,poddak inna mama enakan,පොඩ්ඩක් ඉන්න මම එනකන්
32
+ 31,colloquial,dan moko hithenne,දැන් මොකෝ හිතෙන්නේ
33
+ 32,colloquial,hama dama ekama kaama,හැමදාම එකම කෑම
34
+ 33,colloquial,malli ada school giya,මල්ලි අද school ගියා
35
+ 34,colloquial,oya dan moko karanne,ඔයා දැන් මොකෝ කරන්නේ
36
+ 35,colloquial,me paara mara rasnei,මේ පාර මාර රස්නෙයි
37
+ 36,colloquial,oya dan mawa rawattuwa,ඔයා දැන් මාව රැවැට්ටුවා
38
+ 37,colloquial,e gana hithanna epa,ඒ ගැන හිතන්න එපා
39
+ 38,colloquial,dan nam godak rathri wela,දැන් නම් ගොඩක් රාත්‍රී වෙලා
40
+ 39,colloquial,heta ude wenakan inna,හෙට උදේ වෙනකන් ඉන්න
41
+ 40,colloquial,oya hariyata katha karanna,ඔයා හරියට කතා කරන්න
42
+ 41,colloquial,mata nam eka epa wuna,මට නම් ඒක එපා වුණා
43
+ 42,colloquial,poddi kiyatada enne,පොඩ්ඩී කීයටද එන්නේ
44
+ 43,colloquial,oya ada gedarada inne,ඔයා අද ගෙදරද ඉන්නේ
45
+ 44,colloquial,meka hariyata karanna balanna,මේක හරියට කරන්න බලන්න
46
+ 45,colloquial,mata nam mara badagini dan,මට නම් මාර බඩගිනියි දැන්
47
+ 46,colloquial,oya kiyana de mata therenne na,ඔයා කියන දේ මට තේරෙන්නේ නෑ
48
+ 47,colloquial,ada ude hariyata wassa,අද උදේ හරියට වැස්සා
49
+ 48,colloquial,mama dan kade yanawa,මම දැන් කඩේ යනවා
50
+ 49,colloquial,api eka parak yamu balanna,අපි එක පාරක් යමු බලන්න
51
+ 50,colloquial,kauruwath awe na thama,කවුරුවත් ආවේ නෑ තාම
52
+ 51,colloquial,hondata kaala nidaganna,හොඳට කාලා නිදාගන්න
53
+ 52,colloquial,dan nam wada wadi,දැන් නම් වැඩ වැඩියි
54
+ 53,colloquial,oya moko kiyanne e gana,ඔයා මොකෝ කියන්නේ ඒ ගැන
55
+ 54,colloquial,dan eliyata yanna epa,ද��න් එළියට යන්න එපා
56
+ 55,colloquial,mata sathutuwen inna one,මට සතුටුවෙන් ඉන්න ඕනේ
57
+ 56,colloquial,moko oya bayawela wage,මොකෝ ඔයා බයවෙලා වගේ
58
+ 57,colloquial,api thawa tikakin katha karamu,අපි තව ටිකකින් කතා කරමු
59
+ 58,colloquial,oya ada kiyatada yanne,ඔයා අද කීයටද යන්නේ
60
+ 59,colloquial,mama loku deyak kale na,මම ලොකු දෙයක් කළේ නෑ
61
+ 60,colloquial,poddak udaw karanna puluwanda,පොඩ්ඩක් උදව් කරන්න පුළුවන්ද
62
+ 61,colloquial,heta ude game yanna one,හෙට උදේ ගමේ යන්න ඕනේ
63
+ 62,colloquial,me dawas wala hariyata rathne,මේ දවස් වල හරියට රත්නේ
64
+ 63,colloquial,mata oya gana mara dukai,මට ඔයා ගැන මාර දුකයි
65
+ 64,colloquial,moko mechchara tharaha gihin,මොකෝ මෙච්චර තරහ ගිහින්
66
+ 65,colloquial,api hita hita inna epa,අපි හිත හිත ඉන්න එපා
67
+ 66,colloquial,oya ada kohedo hitiye,ඔයා අද කොහේද හිටියේ
68
+ 67,colloquial,me de karanna ba kiyanna epa,මේ දේ කරන්න බෑ කියන්න එපා
69
+ 68,colloquial,oya dan hariyata wenas wela,ඔයා දැන් හරියට වෙනස් වෙලා
70
+ 69,colloquial,api heta canteen ekedi hamuwemu,අපි හෙට canteen එකේදී හමුවෙමු
71
+ 70,colloquial,kaama thama lipe thiyenne,කෑම තාම ලිපේ තියෙන්නේ
72
+ 71,colloquial,oya mawa dakke nadda,ඔයා මාව දැක්කේ නැද්ද
73
+ 72,colloquial,me parashne wisadanna balamu,මේ ප්‍රශ්නේ විසඳන්න බලමු
74
+ 73,colloquial,mama heta kiyatath yannam,මම හෙට කීයටත් යන්නම්
75
+ 74,colloquial,mata ada tikak amaru wage,මට අද ටිකක් අමාරු වගේ
76
+ 75,colloquial,dan kauruwath gedara na,දැන් කවුරුවත් ගෙදර නෑ
77
+ 76,colloquial,mama heta ude ennamko,මම හෙට උදේ එන්නම්කෝ
78
+ 77,colloquial,oya kiyana eka boru,ඔයා කියන එක බොරු
79
+ 78,colloquial,mata nikan ninda yanawa dan,මට නිකන් නින්ද යනවා දැන්
80
+ 79,colloquial,thawa deyak kiyanna one,තව දෙයක් කියන්න ඕනේ
81
+ 80,colloquial,moko oya thama awe natthe,මොකෝ ඔයා තාම ආවේ නැත්තේ
82
+ 81,colloquial,mama ada library gihin awa,මම අද library ගිහින් ආවා
83
+ 82,colloquial,poddak methanata enna,පොඩ්ඩක් මෙතනට එන්න
84
+ 83,colloquial,dan oya moko kiyanne,දැන් ඔයා මොකෝ කියන්නේ
85
+ 84,colloquial,mata moko une kiyala therenne na,මට මොකෝ වුණේ කියලා තේරෙන්නේ නෑ
86
+ 85,colloquial,poddak inna kiyala kiyanna,පොඩ්ඩක් ඉන්න කියලා කියන්න
87
+ 86,colloquial,oya mawa amataka kala neda,ඔයා මාව අමතක කළා නේද
88
+ 87,colloquial,kaama kaddi katha karanna epa,කෑම කද්දී කතා කරන්න එපා
89
+ 88,colloquial,mama heta ude call karannam,මම හෙට උදේ call කරන්නම්
90
+ 89,colloquial,moko oya ada lassanata inne,මොකෝ ඔයා අද ලස්සනට ඉන්නේ
91
+ 90,colloquial,mama dan hariyata bayawela inne,මම දැන් හරියට බයවෙලා ඉන්නේ
92
+ 91,colloquial,me parashne nam iwarayak na,මේ ප්‍රශ්නේ නම් ඉවරයක් නෑ
93
+ 92,colloquial,api moko hithanne heta gana,අපි මොකෝ හිතන්නේ හෙට ගැන
94
+ 93,colloquial,mama dan nikan innawa,මම දැන් නිකන් ඉන්නවා
95
+ 94,colloquial,oya moko ada parakku,ඔයා මොකෝ අද පරක්කු
96
+ 95,colloquial,mata ada raama yanawa,මට අද රෑම යනවා
97
+ 96,colloquial,poddak methana indagena inna,පොඩ්ඩක් මෙතන ඉඳගෙන ඉන්න
98
+ 97,colloquial,oya heta yanawada kade,ඔයා හෙට යනවාද කඩේ
99
+ 98,colloquial,mata kisima deyak therenne na,මට කිසිම දෙයක් තේරෙන්නේ නෑ
100
+ 99,colloquial,thawa tika welawakin yamu,තව ටික වෙලාවකින් යමු
101
+ 100,colloquial,oya moko ehema balanne,ඔයා මොකෝ එහෙම බලන්නේ
102
+ 101,colloquial,mata nam epa wela thiyenne,මට නම් එපා වෙලා තියෙන්නේ
103
+ 102,colloquial,oya ada moko karanne,ඔයා අද මොකෝ කරන්නේ
104
+ 103,colloquial,dan yamu nikan inna epa,දැන් යමු නිකන් ඉන්න එපා
105
+ 104,colloquial,thawa tikak welawa ganna,තව ටිකක් වෙලාව ගන්න
106
+ 105,colloquial,mata badagini na dan,මට බඩගිනි නෑ දැන්
107
+ 106,colloquial,moko mechchara wada thiyenne,මොකෝ මෙච්චර වැඩ තියෙන්නේ
108
+ 107,colloquial,api heta udema yamu,අපි හෙට උදේම යමු
109
+ 108,colloquial,mama ada knna giye na,මම අද කන්න ගියේ නෑ
110
+ 109,colloquial,dan mata mara amaruwak thiyenne,දැන් මට මාර අමාරුවක් තියෙන්නේ
111
+ 110,colloquial,oya kiyana de mata therenawa,ඔයා කියන දේ මට තේරෙනවා
112
+ 111,colloquial,api meka karala iwara karamu,අපි මේක කරලා ඉවර කරමු
113
+ 112,colloquial,mama ada nidagatta na thama,මම අද නිදාගත්තා නෑ තාම
114
+ 113,colloquial,poddak inna mama katha karannam,පොඩ්ඩක් ඉන්න මම කතා කරන්නම්
115
+ 114,colloquial,moko mechchara hithanne oya,මොකෝ මෙච්චර හිතන්නේ ඔයා
116
+ 115,colloquial,api heta raata hamuwemu,අපි හෙට රෑට හමුවෙමු
117
+ 116,colloquial,oya mara deyakne karanne,ඔයා මාර දෙයක්නේ කරන්නේ
118
+ 117,colloquial,mata tikak dunnoth hondai,මට ටිකක් දුන්නොත් හොඳයි
119
+ 118,colloquial,oya ada kade giyada,ඔයා අද කඩේ ගියාද
120
+ 119,colloquial,dan mata kisima bayak na,දැන් මට කිසිම බයක් නෑ
121
+ 120,colloquial,oya mawa dakka neda ada,ඔයා මාව දැක්කා නේද අද
122
+ 121,colloquial,poddak inna meka kiyanna,පොඩ්ඩක් ඉන්න මේක කියන්න
123
+ 122,colloquial,mata ada loku prashnayak thiyenawa,මට අද ලොකු ප්‍රශ්නයක් තියෙනවා
124
+ 123,colloquial,moko me tharah gihin inne,මොකෝ මේ තරහ ගිහින් ඉන්නේ
125
+ 124,colloquial,oya heta kiyatada enne,ඔයා හෙට කීයටද එන්නේ
126
+ 125,colloquial,mama ada kaama haduwe na,මම අද කෑම හැදුවේ නෑ
127
+ 126,colloquial,dan katha karala wadak na,දැන් කතා කරලා වැඩක් නෑ
128
+ 127,colloquial,oya mawa amataka karanne epa,ඔයා මාව අමතක කරන්නේ එපා
129
+ 128,colloquial,dan mara widihata wassa,දැන් මාර විදිහට වැස්සා
130
+ 129,colloquial,api heta gedara yanawada,අපි හෙට ගෙදර යනවාද
131
+ 130,colloquial,mama ada dan hitiye na,මම අද දන්න හිටියේ නෑ
132
+ 131,colloquial,poddak inna thawa tikakin ennam,පොඩ්ඩක් ඉන්න තව ටිකකින් එන්නම්
133
+ 132,code_mixed,e class eka cancel una,ඒ class එක cancel වුණා
134
+ 133,code_mixed,mama application eka download kala,මම application එක download කළා
135
+ 134,code_mixed,lecture eka thiyenne kiyatada,lecture එක තියෙන්නේ කීයටද
136
+ 135,code_mixed,oyage computer eka update karanna,ඔයාගේ computer එක update කරන්න
137
+ 136,code_mixed,mata me project eka godak wadagath,මට මේ project එක ගොඩක් වැදගත්
138
+ 137,code_mixed,results kawada eyida danne na,results කවදා එයිද දන්නේ නෑ
139
+ 138,code_mixed,oyage id card eka genna,ඔයාගේ id card එක ගේන්න
140
+ 139,code_mixed,mama internship eka start kala,මම internship එක start කළා
141
+ 140,code_mixed,canteen eka dan wahala athi,canteen එක දැන් වහලා ඇති
142
+ 141,code_mixed,oya presentation eka ready da,ඔයා presentation එක ready ද
143
+ 142,code_mixed,mama ada office giye na,මම අද office ගියේ නෑ
144
+ 143,code_mixed,mema data set eka evaluate karanna,මෙම data set එක evaluate කරන්න
145
+ 144,code_mixed,oya link eka send karanna,ඔයා link එක send කරන්න
146
+ 145,code_mixed,mata internet slow wela ada,මට internet slow වෙලා අද
147
+ 146,code_mixed,exam hall ekata yanna parakku wenawa,exam hall එකට යන්න පරක්කු වෙනවා
148
+ 147,code_mixed,oyage feedback eka ewanna balanna,ඔයාගේ feedback එක එවන්න බලන්න
149
+ 148,code_mixed,mama mage mobile phone eka nathi kala,මම මගේ mobile phone එක නැති කළා
150
+ 149,code_mixed,lecture notes kiyawala balanna one,lecture notes කියවලා බලන්න ඕනේ
151
+ 150,code_mixed,oyage user account eka block wela,ඔයාගේ user account එක block වෙලා
152
+ 151,code_mixed,mama application eka submit kala ada,මම application එක submit කළා අද
153
+ 152,code_mixed,oya project report eka finalize kalaada,ඔයා project report එක finalize කළාද
154
+ 153,code_mixed,oya system eka install karala thiyenne,ඔයා system එක install කරලා තියෙන්නේ
155
+ 154,code_mixed,mata me course eka amaru wage,මට මේ course එක අමාරු වගේ
156
+ 155,code_mixed,oyage account balance eka check karanna,ඔයාගේ account balance එක check කරන්න
157
+ 156,code_mixed,api meka group chat eke katha karamu,අපි මේක group chat එකේ කතා කරමු
158
+ 157,code_mixed,oya registration form eka fill karanna,ඔයා registration form එක fill කරන්න
159
+ 158,code_mixed,mama profile picture eka change kala,මම profile picture එක change කළා
160
+ 159,code_mixed,lecture eka record karanna puluwanda,lecture එක record කරන්න පුළුවන්ද
161
+ 160,code_mixed,mama mage password eka amataka kala,මම මගේ password එක අමතක කළා
162
+ 161,code_mixed,oya video eka watch kalaada,ඔයා video එක watch කළාද
163
+ 162,code_mixed,api next week eke yamu,අපි next week එකේ යමු
164
+ 163,code_mixed,oyage message eka labuna mata,ඔයාගේ message එක ලැබුණා මට
165
+ 164,code_mixed,mama application form eka sign kala,මම application form එක sign කළා
166
+ 165,code_mixed,oya photo eka edit karala ewanna,ඔයා photo එක edit කරලා එවන්න
167
+ 166,code_mixed,mata laptop eka repair karanna one,මට laptop එක repair කරන්න ඕනේ
168
+ 167,code_mixed,oyage results online balanna puluwan,ඔයාගේ results online බලන්න පුළුවන්
169
+ 168,code_mixed,api meka online meet wela karamu,අපි මේක online meet වෙලා කරමු
170
+ 169,code_mixed,oya driver eka update karala thiyenne,ඔයා driver එක update කරලා තියෙන්නේ
171
+ 170,code_mixed,mama browser eka refresh kala dan,මම browser එක refresh කළා දැන්
172
+ 171,code_mixed,oyage payment eka successful wela thiyenne,ඔයාගේ payment එක successful වෙලා තියෙන්නේ
173
+ 172,code_mixed,mama file eka download karala iwarai,මම file එක download කරලා ඉවරයි
174
+ 173,code_mixed,oyage profile eka update karanna balanna,ඔයාගේ profile එක update කරන්න බලන්න
175
+ 174,code_mixed,mama application status eka check kala,මම application status එක check කළා
176
+ 175,code_mixed,oya post eka share karala thiyenne,ඔයා post එක share කරලා තියෙන්නේ
177
+ 176,code_mixed,mama notification eka dakke na thama,මම notification එක දැක්කේ නෑ තාම
178
+ 177,code_mixed,oya meeting invite eka accept kalaada,ඔයා meeting invite එක accept කළාද
179
+ 178,code_mixed,mama mage location eka share karannam,මම මගේ location එක share කරන්නම්
180
+ 179,code_mixed,oyage internet connection eka check karanna,ඔයාගේ internet connection එක check කරන්න
181
+ 180,code_mixed,mama server eka restart kala dan,මම server එක restart කළා දැන්
182
+ 181,code_mixed,oya update eka install karala thiyenne,ඔයා update එක install කරලා තියෙන්නේ
183
+ 182,code_mixed,mama message eka reply kala ada,මම message එක reply කළා අද
184
+ 183,code_mixed,oya file eka upload karala thiyenne,ඔයා file එක upload කරලා තියෙන්නේ
185
+ 184,code_mixed,mama website eka search kala godak,මම website එක search කළා ගොඩක්
186
+ 185,code_mixed,oyage order eka confirm wela thiyenne,ඔයාගේ order එක confirm වෙලා තියෙන්නේ
187
+ 186,code_mixed,mama notification eka clear kala dan,මම notification එක clear කළා දැන්
188
+ 187,code_mixed,oya user id eka check karanna,ඔයා user id එක check කරන්න
189
+ 188,code_mixed,mama backup eka restore kala ada,මම backup එක restore කළා අද
190
+ 189,code_mixed,oya process eka start karala thiyenne,ඔයා process එක start කරලා තියෙන්නේ
191
+ 190,code_mixed,mama account settings change kala tika,මම account settings change කළා ටික
192
+ 191,code_mixed,oya system error eka fix kalaada,ඔයා system error එක fix කළාද
193
+ 192,code_mixed,mama security code eka enter kala,මම security code එක enter කළා
194
+ 193,code_mixed,oya mobile app eka update karanna,ඔයා mobile app එක update කරන්න
195
+ 194,code_mixed,mama login details share kala ada,මම login details share කළා අද
196
+ 195,code_mixed,oya verification email eka check karanna,ඔයා verification email එක check කරන්න
197
+ 196,code_mixed,mama feedback form eka submit kala,මම feedback form එක submit කළා
198
+ 197,code_mixed,oya project goal eka achieve kalaada,ඔයා project goal එක achieve කළාද
199
+ 198,code_mixed,mama link eka copy karala thibba,මම link එක copy කරලා තිබ්බා
200
+ 199,code_mixed,oya task eka complete karala thiyenne,ඔයා task එක complete කරලා තියෙන්නේ
201
+ 200,code_mixed,mama data entry kala iwaraik,මම data entry කළා ඉවරයි
202
+ 201,code_mixed,oya screen share eka enable karanna,ඔයා screen share එක enable කරන්න
203
+ 202,code_mixed,mama call eka disconnect kala dan,මම call එක disconnect කළා දැන්
204
+ 203,code_mixed,oya message eka delete karala thiyenne,ඔයා message එක delete කරලා තියෙන්නේ
205
+ 204,code_mixed,mama audio quality eka check kala,මම audio quality එක check කළා
206
+ 205,code_mixed,oya output eka verify karala thiyenne,ඔයා output එක verify කරලා තියෙන්නේ
207
+ 206,code_mixed,mama input data eka validate kala,මම input data එක validate කළා
208
+ 207,code_mixed,oya code eka review karala thiyenne,ඔයා code එක review කරලා තියෙන්නේ
209
+ 208,code_mixed,mama version control eka check kala,මම version control එක check කළා
210
+ 209,code_mixed,oya merge request eka approve kalaada,ඔයා merge request එක approve කළාද
211
+ 210,code_mixed,mama documentation eka update kala ada,මම documentation එක update කළා අද
212
+ 211,code_mixed,oya bug fix eka test kalaada,ඔයා bug fix එක test කළාද
213
+ 212,code_mixed,mama deployment eka success kala dan,මම deployment එක success කළා දැන්
214
+ 213,code_mixed,oya release note eka kiyawala thiyenne,ඔයා release note එක කියවලා තියෙන්නේ
215
+ 214,code_mixed,mama cloud storage eka use kala,මම cloud storage එක use කළා
216
+ 215,code_mixed,oya password reset eka request kalaada,ඔයා password reset එක request කළාද
217
+ 216,code_mixed,mama profile info eka edit kala,මම profile info එක edit කළා
218
+ 217,code_mixed,oya privacy settings update karala thiyenne,ඔයා privacy settings update කරලා තියෙන්නේ
219
+ 218,code_mixed,mama contact list eka sync kala,මම contact list එක sync කළා
220
+ 219,code_mixed,oya battery level eka check karanna,ඔයා battery level එක check කරන්න
221
+ 220,code_mixed,mama screen brightness eka adu kala,මම screen brightness එක අඩු කළා
222
+ 221,code_mixed,oya storage space eka clear karanna,ඔයා storage space එක clear කරන්න
223
+ 222,code_mixed,mama software update eka download kala,මම software update එක download කළා
224
+ 223,code_mixed,oya network speed eka check kalaada,ඔයා network speed එක check කළාද
225
+ 224,code_mixed,mama wifi connection eka fix kala,මම wifi connection එක fix කළා
226
+ 225,code_mixed,oya signal strength eka check karanna,ඔයා signal strength එක check කරන්න
227
+ 226,code_mixed,mama app permissions change kala ada,මම app permissions change කළා අද
228
+ 227,code_mixed,oya cache memory eka clear karanna,ඔයා cache memory එක clear කරන්න
229
+ 228,code_mixed,mama database eka optimize kala dan,මම database එක optimize කළා දැන්
230
+ 229,code_mixed,oya query eka execute karala thiyenne,ඔයා query එක execute කරලා තියෙන්නේ
231
+ 230,code_mixed,mama search result eka filter kala,මම search result එක filter කළා
232
+ 231,code_mixed,oya sorting order eka change karanna,ඔයා sorting order එක change කරන්න
233
+ 232,code_mixed,mama list eka refresh kala ada,මම list එක refresh කළා අද
234
+ 233,code_mixed,oya item eka select karala thiyenne,ඔයා item එක select කරලා තියෙන්නේ
235
+ 234,code_mixed,mama chart eka generate kala dan,මම chart එක generate කළා දැන්
236
+ 235,code_mixed,oya report eka export karala thiyenne,ඔයා report එක export කරලා තියෙන්නේ
237
+ 236,code_mixed,mama file format eka change kala,මම file format එක change කළා
238
+ 237,code_mixed,oya image resolution eka check karanna,ඔයා image resolution එක check කරන්න
239
+ 238,code_mixed,mama video duration eka adu kala,මම video duration එක අඩු කළා
240
+ 239,code_mixed,oya thumbnail eka create karala thiyenne,ඔයා thumbnail එක create කරලා තියෙන්නේ
241
+ 240,code_mixed,mama subtitle file eka upload kala,මම subtitle file එක upload කළා
242
+ 241,code_mixed,oya audio track eka change karanna,ඔයා audio track එක change කරන්න
243
+ 242,code_mixed,mama volume level eka wadi kala,මම volume level එක වැඩි කළා
244
+ 243,code_mixed,oya mute button eka press karanna,ඔයා mute button එක press කරන්න
245
+ 244,code_mixed,mama playback speed eka change kala,මම playback speed එක change කළා
246
+ 245,code_mixed,oya playlist eka create karala thiyenne,ඔයා playlist එක create කරලා තියෙන්නේ
247
+ 246,code_mixed,mama album art eka change kala,මම album art එක change කළා
248
+ 247,code_mixed,oya artist name eka check karanna,ඔයා artist name එක check කරන්න
249
+ 248,code_mixed,mama song title eka edit kala,මම song title එක edit කළා
250
+ 249,code_mixed,oya lyrics eka search karala thiyenne,ඔයා lyrics එක search කරලා තියෙන්නේ
251
+ 250,code_mixed,mama app store eka check kala,මම app store එක check කළා
252
+ 251,code_mixed,oya download link eka click karanna,ඔයා download link එක click කරන්න
253
+ 252,code_mixed,mama installation process eka follow kala,මම installation process එක follow කළා
254
+ 253,code_mixed,oya setup wizard eka complete karanna,ඔයා setup wizard එක complete කරන්න
255
+ 254,code_mixed,mama activation key eka enter kala,මම activation key එක enter කළා
256
+ 255,code_mixed,oya license agreement eka accept karanna,ඔයා license agreement එක accept කරන්න
257
+ 256,code_mixed,mama terms and conditions kiyewwa,මම terms and conditions කියෙව්වා
258
+ 257,code_mixed,oya user manual eka check karanna,ඔයා user manual එක check කරන්න
259
+ 258,code_mixed,mama help menu eka search kala,මම help menu එක search කළා
260
+ 259,code_mixed,oya customer support eka contact karanna,ඔයා customer support එක contact කරන්න
261
+ 260,code_mixed,mama support ticket eka open kala,මම support ticket එක open කළා
262
+ 261,code_mixed,oya issue report eka submit karanna,ඔයා issue report එක submit කරන්න
263
+ 262,code_mixed,mama status update eka check kala,මම status update එක check කළා
264
+ 263,code_mixed,oya resolution details eka check karanna,ඔයා resolution details එක check කරන්න
265
+ 264,code_mixed,mama case number eka note kala,මම case number එක note කළා
266
+ 265,code_mixed,oya service request eka cancel karanna,ඔයා service request එක cancel කරන්න
267
+ 266,code_mixed,mama feedback score eka check kala,මම feedback score එක check කළා
268
+ 267,code_mixed,oya rating eka review karala thiyenne,ඔයා rating එක review කරලා තියෙන්නේ
269
+ 268,code_mixed,mama comment section eka check kala,මම comment section එක check කළා
270
+ 269,code_mixed,oya forum post eka read karanna,ඔයා forum post එක read කරන්න
271
+ 270,code_mixed,mama community guideline eka follow kala,මම community guideline එක follow කළා
272
+ 271,code_mixed,oya blog post eka publish kalaada,ඔයා blog post එක publish කළාද
273
+ 272,code_mixed,mama article eka edit karala iwarai,මම article එක edit කරලා ඉවරයි
274
+ 273,code_mixed,oya content eka check karala thiyenne,ඔයා content එක check කරලා තියෙන්නේ
275
+ 274,code_mixed,mama keyword eka search kala godak,මම keyword එක search කළා ගොඩක්
276
+ 275,code_mixed,oya tag eka add karala thiyenne,ඔයා tag එක add කරලා තියෙන්නේ
277
+ 276,code_mixed,mama category eka change kala dan,මම category එක change කළා දැන්
278
+ 277,code_mixed,oya author name eka check karanna,ඔයා author name එක check කරන්න
279
+ 278,code_mixed,mama publish date eka check kala,මම publish date එක check කළා
280
+ 279,code_mixed,oya link status eka verify karanna,ඔයා link status එක verify කරන්න
281
+ 280,formal,mema pahasukam siyalu denatama podu we,මෙම පහසුකම් සියලු දෙනාටම පොදු වේ
282
+ 281,formal,karunakarala oba ge namaya sadahan karanna,කරුණාකරලා ඔබගේ නාමය සඳහන් කරන්න
283
+ 282,formal,oba ge upadeshaya apata godak wadagath,ඔබගේ උපදේශය අපට ගොඩක් වැදගත්
284
+ 283,formal,mema nivedanaya avadanayata ganna,මෙම නිවේදනය අවධානයට ගන්න
285
+ 284,formal,adyaapana depaarthamenthuwa mema thiranaya gaththa,අධ්‍යාපන දෙපාර්තමේන්තුව මෙම තීරණය ගත්තා
286
+ 285,formal,mema wadashatahana sadaha obaata aradhana karamu,මෙම වැඩසටහන සඳහා ඔබට ආරාධනා කරමු
287
+ 286,formal,oba ge upakaaraya sadaha sthuthiwantha wemu,ඔබගේ උපකාරය සඳහා ස්තූතිවන්ත වෙමු
288
+ 287,formal,rajaye nivedanaya anuwa kriya karanna,රජයේ නිවේදනය අනුව ක්‍රියා කරන්න
289
+ 288,formal,oba ge arayaachanaya salaka balanu labe,ඔබගේ අයදුම්පත සලකා බලනු ලැබේ
290
+ 289,formal,mema karuna piliyela karana lada deyak,මෙම කරුණ පිළියෙළ කරන ලද දෙයක්
291
+ 290,formal,mema prashne gana pashchath vimarshanaya karanna,මෙම ප්‍රශ්නය ගැන පශ්චාත් විමර්ශනය කරන්න
292
+ 291,formal,oba ge sewaya apata agaya kala hakiya,ඔබගේ සේවය අපට අගය කළ හැකිය
293
+ 292,formal,vishwa vidyaalaye palaveni wasare shishyayan,විශ්ව විද්‍යාලයේ පළවෙනි වසරේ ශිෂ්‍යයන්
294
+ 293,formal,parishlana nivedanaya balanna karunakarala,පරිශීලන නිවේදනය බලන්න කරුණාකරලා
295
+ 294,formal,mema kriyavaliya hariyata kriyathmaka karanna,මෙම ක්‍රියාවලිය හරියට ක්‍රියාත්මක කරන්න
296
+ 295,formal,adala lekana pirihenu labe,අදාළ ලේඛන පිරිනමනු ලැබේ
297
+ 296,formal,oba ge sahayogaya apata athyawashya we,ඔබග��� සහයෝගය අපට අත්‍යවශ්‍ය වේ
298
+ 297,formal,mema sthanaye rakshawa thahawuru karanna,මෙම ස්ථානයේ රක්ෂාව තහවුරු කරන්න
299
+ 298,formal,paurshika thorathuru rakshitha we,පෞද්ගලික තොරතුරු රක්ෂිත වේ
300
+ 299,formal,mema kramaya anugamanaya karanna balanna,මෙම ක්‍රමය අනුගමනය කරන්න බලන්න
301
+ 300,formal,oba ge adahas idiripath karanna,ඔබගේ අදහස් ඉදිරිපත් කරන්න
302
+ 301,formal,mema pahasukama pavichchi karanna puluwan,මෙම පහසුකම පාවිච්චි කරන්න පුළුවන්
303
+ 302,formal,shishya kalyana sangamaya mema wada karai,ශිෂ්‍ය සුබසාධන සංගමය මෙම වැඩ කරයි
304
+ 303,formal,oba ge upatha saha thorathuru sadahan karanna,ඔබගේ උපත සහ තොරතුරු සඳහන් කරන්න
305
+ 304,formal,rajaye upadeshaya anuwa kriya karanna one,රජයේ උපදේශය අනුව ක්‍රියා කරන්න ඕනේ
306
+ 305,formal,adala niladhariyan wetha thorathuru ewanna,අදාළ නිලධාරීන් වෙත තොරතුරු එවන්න
307
+ 306,formal,mema kramaya sadaha anumathiya labuna,මෙම ක්‍රමය සඳහා අනුමතිය ලැබුණා
308
+ 307,formal,oba ge gatalu apata danyapat karanna,ඔබගේ ගැටලු අපට දන්වා එවන්න
309
+ 308,formal,mema parikshana prathipala keti kalayakin labe,මෙම පරීක්ෂණ ප්‍රතිඵල කෙටි කලයකින් ලැබේ
310
+ 309,formal,visheshitha karuna sadaha avadanaya yomu karanna,විශේෂිත කරුණු සඳහා අවධානය යොමු කරන්න
311
+ 310,formal,oba ge sahayogaya apata godak wadagath we,ඔබගේ සහයෝගය අපට ගොඩක් වැදගත් වේ
312
+ 311,formal,mema karyaya sapura iwara kala yuthuya,මෙම කාර්යය සපුරා ඉවර කළ යුතුය
313
+ 312,formal,oba ge lekana keti kalayakin labe,ඔබගේ ලේඛන කෙටි කලයකින් ලැබේ
314
+ 313,formal,mema sewaya sadaha ayabeerak aya nokere,මෙම සේවය සඳහා අය කිරීමක් අය නොකෙරේ
315
+ 314,formal,oba ge upadeshaya anuwa api kriya karamu,ඔබගේ උපදේශය අනුව අපි ක්‍රියා කරමු
316
+ 315,formal,mema thorathuru rahasya lesa thaba ganna,මෙම තොරතුරු රහස්‍ය ලෙස තබා ගන්න
317
+ 316,formal,oba ge parashna apata danyapat karanna balanna,ඔබගේ ප්‍රශ්න අපට දන්වා එවන්න බලන්න
318
+ 317,formal,mema kramavedaya hariyata kriyathmaka karanna,මෙම ක්‍රමවේදය හරියට ක්‍රියාත්මක කරන්න
319
+ 318,formal,oba ge sadaha vishesha sthuthiya pudakaramu,ඔබගේ සඳහා විශේෂ ස්තූතිය පුදකරමු
320
+ 319,formal,mema nivedanaya balapathmaka wanne heta sita,මෙම නිවේදනය බලපෑමක වන්නේ හෙට සිට
321
+ 320,formal,oba ge arayaachanaya thira karala iwarai,ඔබගේ අයදුම්පත තීරණය කරලා ඉවරයි
322
+ 321,formal,mema karyalaya pradhaniya visin anumatha kala,මෙම කාර්යාල ප්‍රධානියා විසින් අනුමත කළා
323
+ 322,formal,oba ge thorathuru rahasyathawa thahawuru karanu labe,ඔබගේ තොරතුරු රහස්‍යභාවය තහවුරු කරනු ලැබේ
324
+ 323,formal,mema wadashatahana udashanna kaledi thiyeyi,මෙම වැඩසටහන උදෑසන කාලයේදී තියෙයි
325
+ 324,formal,oba ge sabaawaya apata loku shakthiyak,ඔබගේ සහභාගීත්වය අපට ලොකු ශක්තියක්
326
+ 325,formal,mema lekanaya keti kalayakin labe,මෙම ලේඛනය කෙටි කලයකින් ලැබේ
327
+ 326,formal,oba ge adahas apata sadarayen piliyanamu,ඔබගේ අදහස් අපට සාදරයෙන් පිළිගනිමු
328
+ 327,formal,mema kriyawaliya sadaha oba ge sahayogaya one,මෙම ක්‍රියාවලිය සඳහා ඔබගේ සහයෝගය ඕනේ
329
+ 328,formal,oba ge karyaya sapura iwara kala yuthuya,ඔබගේ කාර්යය සපුරා ඉවර කළ යුතුය
330
+ 329,formal,mema thorathuru sadahan karanna karunakarala,මෙම තොරතුරු සඳහන් කරන්න කරුණාකරලා
331
+ 330,formal,oba ge sahayogaya apata nithara labuna,ඔබගේ සහයෝගය අපට නිතර ලැබුණා
332
+ 331,formal,mema prashne gana vishesha vimarshanayak karamu,මෙම ප්‍රශ්නය ගැන විශේෂ විමර්ශනයක් කරමු
333
+ 332,formal,oba ge sewaya apata sadahayen agaya karamu,ඔබගේ සේවය අපට සාදරයෙන් අගය කරමු
334
+ 333,formal,mema kramaya sadaha vishesha anumathiyak one,මෙම ක්‍රමය සඳහා විශේෂ අනුමතියක් ඕනේ
335
+ 334,formal,oba ge upakaaraya apata nithara labuna,ඔබගේ උපකාරය අපට නිතර ලැබුණා
336
+ 335,formal,mema karyaya sapura iwara kala hakiya,මෙම කාර්යය සපුරා ඉවර කළ හැකිය
337
+ 336,formal,oba ge thorathuru sadahan karala ewanna,ඔබගේ තොරතුරු සඳහන් කරලා එවන්න
338
+ 337,formal,mema nivedanaya balathmaka wanne ada sita,මෙම නිවේදනය බලපෑමක වන්නේ අද සිට
339
+ 338,formal,oba ge upadeshaya apata godak wadagath we,ඔබගේ උපදේශය අපට ගොඩක් වැදගත් වේ
340
+ 339,formal,mema kramavedaya anugamanaya karanna balanna,මෙම ක්‍රමවේදය අනුගමනය කරන්න බලන්න
341
+ 340,formal,oba ge sahayogaya apata athyawashya we dan,ඔබගේ සහයෝගය අපට අත්‍යවශ්‍ය වේ දැන්
342
+ 341,formal,mema kriyawaliya sadaha vishesha dushyakawaya one,මෙම ක්‍රියාවලිය සඳහා විශේෂ දෘශ්‍යතාවය ඕනේ
343
+ 342,formal,oba ge adahas apata sadarayen piliyanamu dan,ඔබගේ අදහස් අපට සාදරයෙන් පිළිගනිමු දැන්
344
+ 343,formal,mema thorathuru rahasya lesa thaba ganna balanna,මෙම තොරතුරු රහස්‍ය ලෙස තබා ගන්න බලන්න
345
+ 344,formal,oba ge sewaya apata nithara agaya karamu,ඔබගේ සේවය අපට නිතර අගය කරමු
346
+ 345,formal,mema karyaya sapura iwara kala hakiya dan,මෙම කාර්යය සපුරා ඉවර කළ හැකිය දැන්
347
+ 346,formal,oba ge thorathuru sadahan karala ewanna balanna,ඔබගේ තොරතුරු සඳහන් කරලා එවන්න බලන්න
348
+ 347,formal,mema nivedanaya balathmaka wanne heta sita dan,මෙම නිවේදනය බලපෑමක වන්නේ හෙට සිට දැන්
349
+ 348,formal,oba ge upadeshaya apata godak wadagath we ada,ඔබගේ උපදේශය අපට ගොඩක් වැදගත් වේ අද
350
+ 349,formal,mema kramavedaya anugamanaya karanna balanna ada,මෙම ක්‍රමවේදය අනුගමනය කරන්න බලන්න අද
351
+ 350,formal,oba ge sahayogaya apata athyawashya we heta sita,ඔබගේ සහයෝගය අපට අත්‍යවශ්‍ය වේ හෙට සිට
352
+ 351,formal,mema kriyawaliya sadaha vishesha dushyakawaya one ada,මෙම ක්‍රියාවලිය සඳහා විශේෂ දෘශ්‍යතාවය ඕනේ අද
353
+ 352,formal,oba ge adahas apata sadarayen piliyanamu heta sita,ඔබගේ අදහස් අපට සාදරයෙන් පිළිගනිමු හෙට සිට
354
+ 353,formal,mema thorathuru rahasya lesa thaba ganna balanna ada,මෙම තොරතුරු රහස්‍ය ලෙස තබා ගන්න බලන්න අද
355
+ 354,formal,oba ge sewaya apata nithara agaya karamu dan,ඔබගේ සේවය අපට නිතර අගය කරමු දැන්
356
+ 355,formal,mema karyaya sapura iwara kala hakiya heta sita,මෙම කාර්යය සපුරා ඉවර කළ හැකිය හෙට සිට
357
+ 356,formal,oba ge thorathuru sadahan karala ewanna balanna dan,ඔබගේ තොරතුරු සඳහන් කරලා එවන්න බලන්න දැන්
358
+ 357,formal,mema nivedanaya balathmaka wanne ada sita danma,මෙම නිවේදනය බලපෑමක වන්නේ අද සිට දැන්ම
359
+ 358,formal,oba ge upadeshaya apata godak wadagath we heta,ඔබගේ උපදේශය අපට ගොඩක් වැදගත් වේ හෙට
360
+ 359,formal,mema kramavedaya anugamanaya karanna balanna heta sita,මෙම ක්‍රමවේදය අනුගමනය කරන්න බලන්න හෙට සිට
361
+ 360,formal,oba ge sahayogaya apata athyawashya we ada sitama,ඔබගේ සහයෝගය අපට අත්‍යවශ්‍ය වේ අද සිටම
362
+ 361,formal,mema kriyawaliya sadaha vishesha dushyakawaya one heta,මෙම ක්‍රියාවලිය සඳහා විශේෂ දෘශ්‍යතාවය ඕනේ හෙට
363
+ 362,formal,oba ge adahas apata sadarayen piliyanamu ada sitama,ඔබගේ අදහස් අපට සාදරයෙන් පිළිගනිමු අද සිටම
364
+ 363,formal,mema thorathuru rahasya lesa thaba ganna balanna heta,මෙම තොරතුරු රහස්‍ය ලෙස තබා ගන්න බලන්න හෙට
365
+ 364,formal,oba ge sewaya apata nithara agaya karamu ada,ඔබගේ සේවය අපට නිතර අගය කරමු අද
366
+ 365,formal,mema karyaya sapura iwara kala hakiya ada sitama,මෙම කාර්යය සපුරා ඉවර කළ හැකිය අද සිටම
367
+ 366,formal,oba ge thorathuru sadahan karala ewanna balanna heta,ඔබගේ තොරතුරු සඳහන් කරලා එවන්න බලන්න හෙට
368
+ 367,formal,mema nivedanaya balathmaka wanne heta sita danma,මෙම නිවේදනය බලපෑමක වන්නේ හෙට සිට දැන්ම
369
+ 368,formal,oba ge upadeshaya apata godak wadagath we ada sitama,ඔබගේ උපදේශය අපට ගොඩක් වැදගත් වේ අද සිටම
370
+ 369,formal,mema kramavedaya anugamanaya karanna balanna ada sitama,මෙම ක්‍රමවේදය අනුගමනය කරන්න බලන්න අද සිටම
371
+ 370,formal,oba ge sahayogaya apata athyawashya we heta sitama,ඔබගේ සහයෝගය අපට අත්‍යවශ්‍ය වේ හෙට සිටම
372
+ 371,formal,mema kriyawaliya sadaha vishesha dushyakawaya one ada sitama,මෙම ක්‍රියාවලිය සඳහා විශේෂ දෘශ්‍යතාවය ඕනේ අද සිටම
373
+ 372,formal,oba ge adahas apata sadarayen piliyanamu heta sitama,ඔබගේ අදහස් අපට සාදරයෙන් පිළිගනිමු හෙට සිටම
374
+ 373,formal,mema thorathuru rahasya lesa thaba ganna balanna ada sitama,මෙම තොරතුරු රහස්‍ය ලෙස තබා ගන්න බලන්න අද සිටම
375
+ 374,formal,oba ge sewaya apata nithara agaya karamu heta sitama,ඔබගේ සේවය අපට නිතර අගය කරමු හෙට සිටම
376
+ 375,formal,mema karyaya sapura iwara kala hakiya heta sitama,මෙම කාර්යය සපුරා ඉවර කළ හැකිය හෙට සිටම
377
+ 376,formal,oba ge thorathuru sadahan karala ewanna balanna ada sitama,ඔබගේ තොරතුරු සඳහන් කරලා එවන්න බලන්න අද සිටම
378
+ 377,formal,mema nivedanaya balathmaka wanne ada sitama thawa duratath,මෙම නිවේදනය බලපෑමක වන්නේ අද සිටම තවදුරටත්
379
+ 378,formal,oba ge upadeshaya apata godak wadagath we thawa duratath,ඔබගේ උපදේශය අපට ගොඩක් වැදගත් වේ තවදුරටත්
380
+ 379,long_sentence,ada ude gedara indan campus ekata yaddi mara traffic ekak thibba,අද උදේ ගෙදර ඉඳන් campus එකට යද්දී මාර traffic එකක් තිබ්බා
381
+ 380,long_sentence,mama hithanne na ada campus eke lecture eka thiyeyi kiyala,මම හිතන්නේ නෑ අද campus එකේ lecture එක තියෙයි කියලා
382
+ 381,long_sentence,oya heta ude kiyatada train yanna balan inne kiyanna balanna,ඔයා හෙට උදේ කීයටද train යන්න බලන් ඉන්නේ කියන්න බලන්න
383
+ 382,long_sentence,mata ada hawasa library ekata gihin poth tikak ganna one wenawa,මට අද හවස library එකට ගිහින් පොත් ටිකක් ගන්න ඕනේ වෙනවා
384
+ 383,long_sentence,api heta canteen ekedi hamuwela presentation eka gana katha karamu neda,අපි හෙට canteen එකේදී හමුවෙලා presentation එක ගැන කතා කරමු නේද
385
+ 384,long_sentence,oya ada ude kaama haduwe monawada kiyala mata thawa tika welawakin ewanna,ඔයා අද උදේ කෑම හැදුවේ මොනවාද කියලා මට තව ටික වෙලාවකින් එවන්න
386
+ 385,long_sentence,mata ada ude indan mara widihata oluwe kakumak thiyenawa kiyala therenawa,මට අද උදේ ඉඳන් මාර විදිහට ඔළුවේ කැක්කුමක් තියෙනවා කියලා තේරෙනවා
387
+ 386,long_sentence,oya heta kade yaddi mata thawa tika welawakin call ekak ganna puluwanda,ඔයා හෙට කඩේ යද්දී මට තව ටික වෙලාවකින් call එකක් ගන්න පුළුවන්ද
388
+ 387,long_sentence,api heta gihilla ammata ona karana badu tika aran emu neda,අපි හෙට ගිහිල්ලා අම්මට ඕන කරන බඩු ටික අරන් එමු නේද
389
+ 388,long_sentence,mama hithanne ada wasinna puluwan kiyala nikan dakkama nam ehemayi penne,මම හිතන්නේ අද වහින්න පුළුවන් කියලා නිකන් දැක්කම නම් එහෙමයි පේන්නේ
390
+ 389,long_sentence,oya ada kade giye na neda mama hithuwe oya yeyi kiyala,ඔයා අද කඩේ ගියේ නෑ නේද මම හිතුවේ ඔයා යයි කියලා
391
+ 390,long_sentence,mata ada ude indan kisima wada karanna tharam hitha sanasillak na dan,මට අද උදේ ඉඳන් කිසිම වැඩ කරන්න තරම් හිත සැනසිල්ලක් නෑ දැන���
392
+ 391,long_sentence,api heta ude canteen ekedi hamuwela ape project report eka hadamu balanna,අපි හෙට උදේ canteen එකේදී හමුවෙලා අපේ project report එක හදමු බලන්න
393
+ 392,long_sentence,oya ada ude kiyatada campus ekata giye kiyala mata kiyanna puluwanda dan,ඔයා අද උදේ කීයටද campus එකට ගියේ කියලා මට කියන්න පුළුවන්ද දැන්
394
+ 393,long_sentence,mata ada raata kaama hadanna kisima widihakata mahansi wenna hithenne na thama,මට අද රෑට කෑම හදන්න කිසිම විදිහකට මහන්සි වෙන්න හිතෙන්නේ නෑ තාම
395
+ 394,long_sentence,api heta yaddi nangiwa school ekata dammaoth hondai kiyala mama hithanawa,අපි හෙට යද්දී නංගිව school එකට දැම්මොත් හොඳයි කියලා මම හිතනවා
396
+ 395,long_sentence,oya ada kade gihilla mata ona karana badu tika aran awada balanna,ඔයා අද කඩේ ගිහිල්ලා මට ඕන කරන බඩු ටික අරන් ආවාද බලන්න
397
+ 396,long_sentence,mama hithanne me parashne nam wisadanna godak kalayak yayi kiyala thama hithenne,මම හිතන්නේ මේ ප්‍රශ්නය නම් විසඳන්න ගොඩක් කාලයක් යයි කියලා තාම හිතෙන්නේ
398
+ 397,long_sentence,oya ada ude canteen ekedi kauruwath dakke nadda kiyala mata kiyanna puluwanda,ඔයා අද උදේ canteen එකේදී කාවවත් දැක්කේ නැද්ද කියලා මට කියන්න පුළුවන්ද
399
+ 398,long_sentence,api heta presentation eka karanna kalin presentation notes tika kiyawala balanna one neda,අපි හෙට presentation එක කරන්න කලින් presentation notes ටික කියවලා බලන්න ඕනේ නේද
400
+ 399,long_sentence,mata ada ude indan kisima deyak therenne na wage dan hariyata mahansiyi,මට අද උදේ ඉඳන් කිසිම දෙයක් තේරෙන්නේ නෑ වගේ දැන් හරියට මහන්සියි
401
+ 400,long_sentence,oya heta kade yaddi thawa tika welawakin call ekak deela badu tika kiyanna,ඔයා හෙට කඩේ යද්දී තව ටික වෙලාවකින් call එකක් දීලා බඩු ටික කියන්න
402
+ 401,long_sentence,api heta gihilla ammata badu tika aran thawa tika welawakin emu neda,අපි හෙට ගිහිල්ලා අම්මට බඩු ටික අරන් තව ටික වෙලාවකින් එමු නේද
403
+ 402,long_sentence,mama hithanne me para nam results mara widihata parakku wenna puluwan kiyala,මම හිතන්නේ මේ පාර නම් results මාර විදිහට පරක්කු වෙන්න පුළුවන් කියලා
404
+ 403,long_sentence,oya ada kade giyoth mata thawa tika welawakin ewanna puluwanda badu tika dan,ඔයා අද කඩේ ගියොත් මට තව ටික වෙලාවකින් එවන්න පුළුවන්ද බඩු ටික දැන්
405
+ 404,long_sentence,mata ada ude indan kisima wada karanna hitha denne na mara widihata kamaliy,මට අද උදේ ඉඳන් කිසිම වැඩ කරන්න හිත දෙන්නේ නෑ මාර විදිහට කම්මැලියි
406
+ 405,long_sentence,api heta canteen ekedi hamuwela presentation eka thawa tika welawakin ready karamu neda,අපි හෙට canteen එකේදී හමුවෙලා presentation එක තව ටික වෙලාවකින් ready කරමු නේද
407
+ 406,long_sentence,oya ada ude kiyatada campus ekata giye kiyala kiyanna puluwanda mata thawa tika welawakin,ඔයා අද උදේ කීයටද campus එකට ගියේ කියලා කියන්න පුළුවන්ද මට තව ටික වෙලාවකින්
408
+ 407,long_sentence,mata ada raata kaama hadanna hithenne na thawa tika welawakin kade yamu balanna,මට අද රෑට කෑම හදන්න හිතෙන්නේ නෑ තව ටික වෙලාවකින් කඩේ යමු බලන්න
409
+ 408,long_sentence,api heta yaddi nangiwa school ekata dammaoth hondai neda thawa tika welawakin,අපි හෙට යද්දී නංගිව school එකට දැම්මොත් හොඳයි නේද තව ටික වෙලාවකින්
410
+ 409,long_sentence,oya ada kade gihilla mata badu tika aran awada kiyala thawa tika welawakin kiyanna,ඔයා අද කඩේ ගිහිල්ලා මට බඩු ටික අරන් ආවාද කියලා තව ටික වෙලාවකින් කියන්න
411
+ 410,long_sentence,mama hithanne me parashne thawa tika welawakin wisadanna puluwan kiyala thama hithenne mata,මම හිතන්නේ මේ ප්‍ර��්නය තව ටික වෙලාවකින් විසඳන්න පුළුවන් කියලා තාම හිතෙන්නේ මට
412
+ 411,long_sentence,oya ada ude canteen ekedi kauruwath dakke nadda kiyala mata thawa tika welawakin kiyanna,ඔයා අද උදේ canteen එකේදී කාවවත් දැක්කේ නැද්ද කියලා මට තව ටික වෙලාවකින් කියන්න
413
+ 412,long_sentence,api heta presentation notes tika kiyawala thawa tika welawakin presentation eka ready karamu balanna,අපි හෙට presentation notes ටික කියවලා තව ටික වෙලාවකින් presentation එක ready කරමු බලන්න
414
+ 413,long_sentence,mata ada ude indan kisima deyak therenne na dan mara widihata mahansi wela thiyenne,මට අද උදේ ඉඳන් කිසිම දෙයක් තේරෙන්නේ නෑ දැන් මාර විදිහට මහන්සි වෙලා තියෙන්නේ
415
+ 414,long_sentence,oya heta kade yaddi call ekak deela badu tika mata thawa tika welawakin kiyanna,ඔයා හෙට කඩේ යද්දී call එකක් දීලා බඩු ටික මට තව ටික වෙලාවකින් කියන්න
416
+ 415,long_sentence,api heta gihilla badu tika aran thawa tika welawakin emu neda ada raata,අපි හෙට ගිහිල්ලා බඩු ටික අරන් තව ටික වෙලාවකින් එමු නේද අද රෑට
417
+ 416,long_sentence,mama hithanne results thawa tika welawakin online balanna puluwan kiyala thama dan hithenne,මම හිතන්නේ results තව ටික වෙලාවකින් online බලන්න පුළුවන් කියලා තාම දැන් හිතෙන්නේ
418
+ 417,long_sentence,oya ada kade giyoth badu tika mata thawa tika welawakin ewanna puluwanda danma,ඔයා අද කඩේ ගියොත් බඩු ටික මට තව ටික වෙලාවකින් එවන්න පුළුවන්ද දැන්ම
419
+ 418,long_sentence,mata ada ude indan wada karanna hitha denne na mara widihata kamaliy ada nam,මට අද උදේ ඉඳන් වැඩ කරන්න හිත දෙන්නේ නෑ මාර විදිහට කම්මැලියි අද නම්
420
+ 419,long_sentence,api heta canteen ekedi presentation eka thawa tika welawakin ready karamu neda api dennama,අපි හෙට canteen එකේදී presentation එක තව ටික වෙලාවකින් ready කරමු නේද අපි දෙන්නම
421
+ 420,long_sentence,oya ada ude campus ekata giye kiyatada kiyala kiyanna thawa tika welawakin mata balanna,ඔයා අද උදේ campus එකට ගියේ කීයටද කියලා කියන්න තව ටික වෙලාවකින් මට බලන්න
422
+ 421,long_sentence,mata ada raata kaama hadanna hithenne na kade yamu balanna thawa tika welawakin api,මට අද රෑට කෑම හදන්න හිතෙන්නේ නෑ කඩේ යමු බලන්න තව ටික වෙලාවකින් අපි
423
+ 422,long_sentence,api heta yaddi nangiwa school ekata dammaoth hondai kiyala mama hithanawa thawa duratath,අපි හෙට යද්දී නංගිව school එකට දැම්මොත් හොඳයි කියලා මම හිතනවා තවදුරටත්
424
+ 423,long_sentence,oya ada kade gihilla badu tika aran awada kiyala thawa tika welawakin mata kiyanna,ඔයා අද කඩේ ගිහිල්ලා බඩු ටික අරන් ආවාද කියලා තව ටික වෙලාවකින් මට කියන්න
425
+ 424,long_sentence,mama hithanne parashne thawa tika welawakin wisadanna puluwan kiyala thama hithenne mata dan,මම හිතන්නේ ප්‍රශ්නය තව ටික වෙලාවකින් විසඳන්න පුළුවන් කියලා තාම හිතෙන්නේ මට දැන්
426
+ 425,long_sentence,oya ada ude canteen ekedi kauruwath dakke nadda kiyala thawa tika welawakin mata kiyanna,ඔයා අද උදේ canteen එකේදී කාවවත් දැක්කේ නැද්ද කියලා තව ටික වෙලාවකින් මට කියන්න
427
+ 426,long_sentence,api presentation notes tika kiyawala thawa tika welawakin presentation eka ready karamu balanna heta,අපි presentation notes ටික කියවලා තව ටික වෙලාවකින් presentation එක ready කරමු බලන්න හෙට
428
+ 427,long_sentence,mata ada ude indan therenne na mara widihata mahansi wela thiyenne thawa duratath dan,මට අද උදේ ඉඳන් තේරෙන්නේ නෑ මාර විදිහට මහන්සි වෙලා තියෙන්නේ තවදුරටත් දැන්
429
+ 428,long_sentence,oya heta kade yaddi call ekak deela badu tika mata thawa tika welawakin kiyanna balanna,ඔයා හෙට කඩේ යද්දී call එකක් දීලා බඩු ටික මට තව ටික වෙලාවකින් කියන්න බලන්න
430
+ 429,long_sentence,api gihilla badu tika aran thawa tika welawakin emu neda ada raata hamoma,අපි ගිහිල්ලා බඩු ටික අරන් තව ටික වෙලාවකින් එමු නේද අද රෑට හැමෝම
431
+ 430,long_sentence,mama hithanne results thawa tika welawakin online balanna puluwan kiyala thama hithenne mata ada,මම හිතන්නේ results තව ටික වෙලාවකින් online බලන්න පුළුවන් කියලා තාම හිතෙන්නේ මට අද
432
+ 431,long_sentence,oya kade giyoth badu tika mata thawa tika welawakin ewanna puluwanda danma balanna oya,ඔයා කඩේ ගියොත් බඩු ටික මට තව ටික වෙලාවකින් එවන්න පුළුවන්ද දැන්ම බලන්න ඔයා
433
+ 432,long_sentence,mata ude indan wada karanna hitha denne na mara widihata kamaliy ada nam thawa duratath,මට උදේ ඉඳන් වැඩ කරන්න හිත දෙන්නේ නෑ මාර විදිහට කම්මැලියි අද නම් තවදුරටත්
434
+ 433,long_sentence,api canteen ekedi presentation eka thawa tika welawakin ready karamu neda api dennama hamoma,අපි canteen එකේදී presentation එක තව ටික වෙලාවකින් ready කරමු නේද අපි දෙන්නම හැමෝම
435
+ 434,long_sentence,oya campus ekata giye kiyatada kiyala kiyanna thawa tika welawakin mata balanna ada ude,ඔයා campus එකට ගියේ කීයටද කියලා කියන්න තව ටික වෙලාවකින් මට බලන්න අද උදේ
436
+ 435,long_sentence,mata kaama hadanna hithenne na kade yamu balanna thawa tika welawakin api heta udema,මට කෑම හදන්න හිතෙන්නේ නෑ කඩේ යමු බලන්න තව ටික වෙලාවකින් අපි හෙට උදේම
437
+ 436,long_sentence,api yaddi nangiwa school ekata dammaoth hondai kiyala mama hithanawa thawa duratath heta,අපි යද්දී නංගිව school එකට දැම්මොත් හොඳයි කියලා මම හිතනවා තවදුරටත් හෙට
438
+ 437,long_sentence,oya kade gihilla badu tika aran awada kiyala thawa tika welawakin mata kiyanna balanna,ඔයා කඩේ ගිහිල්ලා බඩු ටික අරන් ආවාද කියලා තව ටික වෙලාවකින් මට කියන්න බලන්න
439
+ 438,long_sentence,mama hithanne meka thawa tika welawakin wisadanna puluwan kiyala thama hithenne mata dan meka,මම හිතන්නේ මේක තව ටික වෙලාවකින් විසඳන්න පුළුවන් කියලා තාම හිතෙන්නේ මට දැන් මේක
440
+ 439,long_sentence,oya canteen ekedi kauruwath dakke nadda kiyala thawa tika welawakin mata kiyanna balanna heta,ඔයා canteen එකේදී කාවවත් දැක්කේ නැද්ද කියලා තව ටික වෙලාවකින් මට කියන්න බලන්න හෙට
441
+ 440,long_sentence,api presentation eka ready karamu balanna heta ude canteen ekedi hamuwela api dennama meka,අපි presentation එක ready කරමු බලන්න හෙට උදේ canteen එකේදී හමුවෙලා අපි දෙන්නම මේක
442
+ 441,long_sentence,mata therenne na mara widihata mahansi wela thiyenne thawa duratath dan mata nam meka,මට තේරෙන්නේ නෑ මාර විදිහට මහන්සි වෙලා තියෙන්නේ තවදුරටත් දැන් මට නම් මේක
443
+ 442,long_sentence,oya call ekak deela badu tika mata thawa tika welawakin kiyanna balanna heta kade yaddi,ඔයා call එකක් දීලා බඩු ටික මට තව ටික වෙලාවකින් කියන්න බලන්න හෙට කඩේ යද්දී
444
+ 443,long_sentence,api badu tika aran thawa tika welawakin emu neda ada raata hamoma nuwara gihilla,අපි බඩු ටික අරන් තව ටික වෙලාවකින් එමු නේද අද රෑට හැමෝම නුවර ගිහිල්ලා
445
+ 444,long_sentence,mama hithanne results online balanna puluwan kiyala thama hithenne mata ada thawa tika welawakin,මම හිතන්නේ results online බලන්න පුළුවන් කියලා තාම හිතෙන්නේ මට අද තව ටික වෙලාවකින්
446
+ 445,long_sentence,oya badu tika mata thawa tika welawakin ewanna puluwanda danma balanna kade giyoth oya,ඔයා බඩු ටික මට තව ටික වෙලාවකින් එවන්න පුළුවන්ද දැන්ම බලන්න කඩේ ගියොත් ඔයා
447
+ 446,long_sentence,mata wada karanna hitha denne na mara widihata kamaliy ada nam thawa duratath ude indan,මට වැඩ කරන්න හිත දෙන්නේ නෑ මාර විදිහට කම්මැලියි අද නම් තවදුරටත් උදේ ඉඳන්
448
+ 447,long_sentence,api presentation eka thawa tika welawakin ready karamu neda canteen ekedi hamuwela api dennama ada,අපි presentation එක තව ටික වෙලාවකින් ready කරමු නේද canteen එකේදී හමුවෙලා අපි දෙන්නම අද
449
+ 448,long_sentence,oya kiyatada giye kiyala kiyanna thawa tika welawakin mata balanna ada ude campus ekata,ඔයා කීයටද ගියේ කියලා කියන්න තව ටික වෙලාවකින් මට බලන්න අද උදේ campus එකට
450
+ 449,long_sentence,mata kaama hadanna hithenne na kade yamu balanna thawa tika welawakin api heta raata,මට කෑම හදන්න හිතෙන්නේ නෑ කඩේ යමු බලන්න තව ටික වෙලාවකින් අපි හෙට රෑට
451
+ 450,long_sentence,api nangiwa school ekata dammoth hondai kiyala mama hithanawa,අපි නංගිව school එකට දැම්මොත් හොඳයි කියලා මම හිතනවා
452
+ 451,long_sentence,oya badu tika aran awada kiyala thawa tika welawakin mata kiyanna balanna kade gihilla,ඔයා බඩු ටික අරන් ආවාද කියලා තව ටික වෙලාවකින් මට කියන්න බලන්න කඩේ ගිහිල්ලා
453
+ 452,long_sentence,mama hithanne thawa tika welawakin wisadanna puluwan kiyala thama hithenne mata dan me parashnaya,මම හිතන්නේ තව ටික වෙලාවකින් විසඳන්න පුළුවන් කියලා තාම හිතෙන්නේ මට දැන් මේ ප්‍රශ්නය
454
+ 453,short_phrase,honda naa,හොඳ නෑ
455
+ 454,short_phrase,kohomada oya,කොහොමද ඔයා
456
+ 455,short_phrase,kiyatada enne,කීයටද එන්නේ
457
+ 456,short_phrase,me kohedo,මේ කොහේද
458
+ 457,short_phrase,dan yamu,දැන් යමු
459
+ 458,short_phrase,epa epa,එපා එපා
460
+ 459,short_phrase,poddak inna,පොඩ්ඩක් ඉන්න
461
+ 460,short_phrase,kauda inne,කවුද ඉන්නේ
462
+ 461,short_phrase,moko une,මොකෝ වුණේ
463
+ 462,short_phrase,hari hari,හරි හරි
464
+ 463,short_phrase,kiyanna balanna,කියන්න බලන්න
465
+ 464,short_phrase,thawa tika welawakin,තව ටික වෙලාවකින්
466
+ 465,short_phrase,kohedu giye,කොහේද ගියේ
467
+ 466,short_phrase,kaama kawaada,කෑම කෑවාද
468
+ 467,short_phrase,ninda giye na,නින්ද ගියේ නෑ
469
+ 468,short_phrase,moko karanne,මොකෝ කරන්නේ
470
+ 469,short_phrase,api yamu,අපි යමු
471
+ 470,short_phrase,mata epa,මට එපා
472
+ 471,short_phrase,badagini wela,බඩගිනි වෙලා
473
+ 472,short_phrase,wahinna wage,වහින්න වගේ
474
+ 473,short_phrase,heta ennam,හෙට එන්නම්
475
+ 474,short_phrase,parakku wenawa,පරක්කු වෙනවා
476
+ 475,short_phrase,kohe inne,කොහේ ඉන්නේ
477
+ 476,short_phrase,mokakda e,මොකක්ද ඒ
478
+ 477,short_phrase,dan enna,දැන් එන්න
479
+ 478,short_phrase,kisima deyak na,කිසිම දෙයක් නෑ
480
+ 479,short_phrase,sathutuwen inna,සතුටුවෙන් ඉන්න
481
+ 480,short_phrase,aththada ehemada,ඇත්තද එහෙමද
482
+ 481,short_phrase,kiyanna puluwanda,කියන්න පුළුවන්ද
483
+ 482,edge_case,api 1st floor ekata yamu,අපි 1st floor එකට යමු
484
+ 483,edge_case,oya 5000k denawada mata,ඔයා 5000ක් දෙනවාද මට
485
+ 484,edge_case,wada karanne na???,වැඩ කරන්නේ නෑ???
486
+ 485,edge_case,bye bye heta hamuwemu,bye bye හෙට හමුවෙමු
487
+ 486,edge_case,mama 10.30ta nuwara yanawa,මම 10.30ට නුවර යනවා
488
+ 487,edge_case,oya kiyatada 2nd lecture ekata enne,ඔයා කීයටද 2nd lecture එකට එන්නේ
489
+ 488,edge_case,mama 100%k sure kiyala kiyanna,මම 100%ක් sure කියලා කියන්න
490
+ 489,edge_case,me moko me... moko une,මේ මොකෝ මේ... මොකෝ වුණේ
491
+ 490,edge_case,oya results 1st rank ekatama gaththa,ඔයා results 1st rank එකටම ගත්තා
492
+ 491,edge_case,mata 500/- k denna puluwanda dan,මට 500/- ක් දෙන්න පුළුවන්ද දැන්
493
+ 492,edge_case,oya me wada 2-3 parak kala neda,ඔයා මේ වැඩ 2-3 පාරක් කළා නේද
494
+ 493,edge_case,mama 9.00 a.m. wenakan balan hitiya,මම 9.00 a.m. වෙනකන් බලන් හිටියා
495
+ 494,edge_case,"oya presentation eka ""ready"" neda balanna","ඔයා presentation එක ""ready"" නේද බලන්න"
496
+ 495,edge_case,mama message 10k damma thama awe na,මම message 10ක් දැම්මා තාම ආවේ නෑ
497
+ 496,edge_case,api 3.30 p.m. meeting eka cancel karamu,අපි 3.30 p.m. meeting එක cancel කරමු
498
+ 497,edge_case,oya wada 100%k complete karala iwarada,ඔයා වැඩ 100%ක් complete කරලා ඉවරද
499
+ 498,edge_case,mm 1st attempt ekenma pass una,මම 1st attempt එකෙන්ම pass වුණා
500
+ 499,edge_case,me moko me??? bayawela neda???,මේ මොකෝ මේ??? බයවෙලා නේද???
501
+ 500,edge_case,api 5 dena passe welawaka katha karamu,අපි 5 දෙනා පස්සේ වෙලාවක කතා කරමු
misc/quick_eval.py ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Quick evaluation of ByT5 on Indo NLP test sets - simplified version."""
3
+
4
+ import sys
5
+ from pathlib import Path
6
+
7
+ project_root = Path(__file__).parent.parent
8
+ sys.path.insert(0, str(project_root))
9
+
10
+ import torch
11
+ import pandas as pd
12
+
13
+ from core.decoder import BeamSearchDecoder
14
+
15
+ def load_test_set(filepath, max_samples=None):
16
+ """Load Indo NLP test set (pairs of lines: Singlish, Sinhala)."""
17
+ samples = []
18
+ with open(filepath, 'r', encoding='utf-8') as f:
19
+ lines = [line.strip() for line in f.readlines() if line.strip()]
20
+
21
+ for i in range(0, len(lines), 2):
22
+ if i + 1 < len(lines):
23
+ samples.append({
24
+ 'singlish': lines[i],
25
+ 'expected': lines[i + 1]
26
+ })
27
+ if max_samples and len(samples) >= max_samples:
28
+ break
29
+ return samples
30
+
31
+ def compute_metrics(predicted, expected):
32
+ """Compute CER, WER, BLEU, EM."""
33
+ from difflib import SequenceMatcher
34
+
35
+ # CER (Character Error Rate)
36
+ matcher_char = SequenceMatcher(None, predicted, expected)
37
+ cer = 1.0 - matcher_char.ratio() if expected else (1.0 if predicted else 0.0)
38
+
39
+ # WER (Word Error Rate)
40
+ pred_words = predicted.split()
41
+ exp_words = expected.split()
42
+ matcher_word = SequenceMatcher(None, pred_words, exp_words)
43
+ wer = 1.0 - matcher_word.ratio() if exp_words else (1.0 if pred_words else 0.0)
44
+
45
+ # BLEU (simple unigram overlap)
46
+ if exp_words:
47
+ matches = sum(1 for t in pred_words if t in exp_words)
48
+ bleu = matches / len(exp_words)
49
+ else:
50
+ bleu = 1.0 if not pred_words else 0.0
51
+
52
+ # EM (Exact Match)
53
+ em = 1 if predicted == expected else 0
54
+
55
+ return {'cer': cer, 'wer': wer, 'bleu': bleu, 'em': em}
56
+
57
+ def main():
58
+ device = "cuda" if torch.cuda.is_available() else "cpu"
59
+ print(f"Device: {device}\n")
60
+
61
+ # Parse command line
62
+ max_samples = int(sys.argv[1]) if len(sys.argv) > 1 else 5
63
+
64
+ print(f"Loading BeamSearchDecoder...")
65
+ decoder = BeamSearchDecoder(device=device)
66
+ print(f"Decoder loaded!\n")
67
+
68
+ # Load test sets
69
+ test_dir = Path("IndoNLP-2025-Shared-Task/Test Dataset/Sinhala")
70
+
71
+ print(f"Loading test sets (max {max_samples} samples each)...")
72
+ formal_samples = load_test_set(test_dir / "Sinhala Test set 1.txt", max_samples=max_samples)
73
+ informal_samples = load_test_set(test_dir / "Sinhala Test set 2.txt", max_samples=max_samples)
74
+ print(f"Formal: {len(formal_samples)}, Informal: {len(informal_samples)}\n")
75
+
76
+ all_results = []
77
+
78
+ # Evaluate formal
79
+ print("="*60)
80
+ print(f"FORMAL SUBSET ({len(formal_samples)} samples)")
81
+ print("="*60)
82
+
83
+ formal_results = []
84
+ for idx, sample in enumerate(formal_samples):
85
+ try:
86
+ predicted, _, _ = decoder.decode(sample['singlish'])
87
+ metrics = compute_metrics(predicted, sample['expected'])
88
+ result = {**sample, 'predicted': predicted, 'subset': 'formal', **metrics}
89
+ formal_results.append(result)
90
+ all_results.append(result)
91
+ print(f"{idx+1}/{len(formal_samples)}: EM={metrics['em']} CER={metrics['cer']:.3f} WER={metrics['wer']:.3f}")
92
+ except Exception as e:
93
+ print(f"{idx+1}/{len(formal_samples)}: ERROR - {e}")
94
+ result = {**sample, 'predicted': '[ERROR]', 'subset': 'formal', 'cer': 1.0, 'wer': 1.0, 'bleu': 0.0, 'em': 0}
95
+ formal_results.append(result)
96
+ all_results.append(result)
97
+
98
+ # Evaluate informal
99
+ print("\n" + "="*60)
100
+ print(f"INFORMAL SUBSET ({len(informal_samples)} samples)")
101
+ print("="*60)
102
+
103
+ informal_results = []
104
+ for idx, sample in enumerate(informal_samples):
105
+ try:
106
+ predicted, _, _ = decoder.decode(sample['singlish'])
107
+ metrics = compute_metrics(predicted, sample['expected'])
108
+ result = {**sample, 'predicted': predicted, 'subset': 'informal', **metrics}
109
+ informal_results.append(result)
110
+ all_results.append(result)
111
+ print(f"{idx+1}/{len(informal_samples)}: EM={metrics['em']} CER={metrics['cer']:.3f} WER={metrics['wer']:.3f}")
112
+ except Exception as e:
113
+ print(f"{idx+1}/{len(informal_samples)}: ERROR - {e}")
114
+ result = {**sample, 'predicted': '[ERROR]', 'subset': 'informal', 'cer': 1.0, 'wer': 1.0, 'bleu': 0.0, 'em': 0}
115
+ informal_results.append(result)
116
+ all_results.append(result)
117
+
118
+ # Summary
119
+ print("\n" + "="*60)
120
+ print("SUMMARY")
121
+ print("="*60)
122
+
123
+ formal_df = pd.DataFrame(formal_results)
124
+ informal_df = pd.DataFrame(informal_results)
125
+ all_df = pd.DataFrame(all_results)
126
+
127
+ for name, df in [("Formal", formal_df), ("Informal", informal_df), ("Overall", all_df)]:
128
+ print(f"\n{name} (n={len(df)}):")
129
+ print(f" CER: {df['cer'].mean():.4f} ± {df['cer'].std():.4f}")
130
+ print(f" WER: {df['wer'].mean():.4f} ± {df['wer'].std():.4f}")
131
+ print(f" BLEU: {df['bleu'].mean():.4f} ± {df['bleu'].std():.4f}")
132
+ print(f" EM: {df['em'].mean():.4f} ({int(df['em'].sum())}/{len(df)})")
133
+
134
+ # Save
135
+ all_df.to_csv("misc/quick_eval_results.csv", index=False)
136
+ print(f"\nResults saved to: misc/quick_eval_results.csv")
137
+
138
+ if __name__ == "__main__":
139
+ main()
misc/quick_eval_results.csv ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ singlish,expected,predicted,subset,cer,wer,bleu,em
2
+ awankawama mata eya mathaka ethi akaraya eyayi namuth eya wikarayaki mama obata ashwaya kerehi wedi elmak nodakwana namuth eya mage wilasithawa nowe,අවංකවම මට එය මතක ඇති ආකාරය එයයි නමුත් එය විකාරයකි මම ඔබට අශ්වයා කෙරෙහි වැඩි ඇල්මක් නොදක්වන නමුත් එය මගේ විලාසිතාව නොවේ,අවංකවාම මට එය මතක ඇති ආකාරය එයයි නමුත් එය විකරයකි මම ඔබටා අශවය කෙරෙහි වැඩි ඇලීමක් නොදක්වාන නමුත් එය මගේ විලාසිතව නොවේ,formal,0.03829787234042559,0.31818181818181823,0.6818181818181818,0
3
+ oba mage aneka yeyi adahas karanne kese ho oba ema wilasithawata andinne mandeyi mama asami,ඔබ මගේ අනෙකා යැයි අදහස් කරන්නේ කෙසේ හෝ ඔබ එම විලාසිතාවට අඳින්නේ මන්දැයි මම අසමි,ඔබ මගේ අණෙක යැයි අදහස් කරන්නේ කෙසේ හෝ ඔබ ඒම විලාසිතවට අඳින්නේ මන්දැයි මම අසමි,formal,0.038461538461538436,0.19999999999999996,0.8,0
4
+ mama kiwa yuthuyi oba wedipura penenne obe mahalu athmayayi oba adahas karanne mage aneka bawayi,මම කිව යුතුයි ඔබ වැඩිපුර පෙනෙන්නේ ඔබේ මහලු ආත්මයයි ඔබ අදහස් කරන්නේ මගේ අනෙකා බවයි,මම කිව යුතුයි ඔබ වැඩිපුරා පෙනෙන්නේ ඔබේ ම ආතේමයයි ඔබ අදහස් කරන්නේ මගේ අනෙකා බවයි,formal,0.03749999999999998,0.19999999999999996,0.8,0
5
+ kese ho oba ese andinne mandeyi mata eseemata ida etha mama shokayen sitina bawa pehedili yeyi mata sithiya yuthuwa thibuni,"කෙසේ හෝ ඔබ එසේ අඳින්නේ මන්දැයි මට ඇසීමට ඉඩ ඇත, මම ශෝකයෙන් සිටින බව පැහැදිලි යැයි මට සිතිය යුතුව තිබුණි",කෙසේ හෝ ඔබ එසේ අඳින්නේ මන්දැයි මට ඇසීමට ඉඩ ඇත මම ශෝකයෙන් සිටින බව පැහැදිලි යැයි මට සිතිය යුතුව තිබුණි,formal,0.0049261083743842304,0.050000000000000044,0.95,0
6
+ mona hari adahas monada,මොනා හරි අදහස් මොනාද,මොන හරි අදහසේ මොනද,formal,0.10526315789473684,0.75,0.25,0
7
+ mta eka prshnyk ahanna puluwn nm awulak ne,මට එක ප්‍රශ්නයක් අහන්න පුළුවන් නම් අවුලක් නෑ,මට එක ප්‍රශ්නයක අහන්න පුළුවන් නම් අවුලක් නෑ,informal,0.011494252873563204,0.125,0.875,0
8
+ hondyi eka modyi wge,"හොඳයි, ඒක මෝඩයි වගේ",හොඳයි ඒක මෝඩයි වගේ,informal,0.027027027027026973,0.25,0.75,0
9
+ kmk nehe modyi wge,කමක් නැහැ මෝඩයි වගේ,කමක් නැහැ මෝදයි වගේ,informal,0.052631578947368474,0.25,0.75,0
10
+ kmk nehe oba eyta kemthi nownu etha,කමක් නැහැ ඔබ එයට කැමති නොවනු ඇත,කමක් නැහැ ඔබ එයට කැමති නොවනු ඇත,informal,0.0,0.0,1.0,1
11
+ oba eyta kemthi nownu etha eya asanna,"ඔබ එයට කැමති නොවනු ඇත, එය අසන්න",ඔබ එයට කැමති නොවනු ඇත එය අසන්න,informal,0.016393442622950838,0.1428571428571429,0.8571428571428571,0
requirements.txt CHANGED
@@ -4,3 +4,4 @@ sentencepiece
4
  datasets
5
  streamlit
6
  pandas
 
 
4
  datasets
5
  streamlit
6
  pandas
7
+ requests
seq2seq/finetune_corrections.py CHANGED
@@ -17,9 +17,11 @@ Run from the project root:
17
 
18
  from __future__ import annotations
19
 
 
20
  import random
21
  import sys
22
  from pathlib import Path
 
23
 
24
  ROOT = Path(__file__).parent.parent
25
  if str(ROOT) not in sys.path:
@@ -37,9 +39,11 @@ from transformers import (
37
 
38
  # ── Config ────────────────────────────────────────────────────────────────────
39
 
40
- MODEL_PATH = ROOT / "seq2seq" / "byt5-singlish-sinhala" / "final"
41
  DATA_PATH = ROOT / "seq2seq" / "wsd_pairs.csv"
42
- OUTPUT_DIR = ROOT / "seq2seq" / "byt5-singlish-sinhala" / "final" # overwrite in place
 
 
 
43
 
44
  REPEAT = 500 # how many times each correction pair is repeated
45
  BG_SAMPLES = 50_000 # random background pairs from wsd_pairs.csv to prevent forgetting
@@ -207,17 +211,63 @@ def build_dataset(tokenizer) -> Dataset:
207
  return ds
208
 
209
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
210
  # ── Main ──────────────────────────────────────────────────────────────────────
211
 
212
  def main():
 
 
213
  device = "cuda" if torch.cuda.is_available() else "cpu"
214
  print(f"\nDevice : {device}")
215
- if device == "cpu":
216
- print("WARNING: running on CPU — this will take ~30-60 min.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
217
 
218
- print(f"Loading model from {MODEL_PATH} ...")
219
- tokenizer = AutoTokenizer.from_pretrained(str(MODEL_PATH))
220
- model = AutoModelForSeq2SeqLM.from_pretrained(str(MODEL_PATH))
 
 
 
 
221
 
222
  print("\nBuilding correction dataset ...")
223
  ds = build_dataset(tokenizer)
@@ -230,7 +280,7 @@ def main():
230
  warmup = max(100, len(train_ds) // (BATCH_SIZE * 20))
231
 
232
  args = Seq2SeqTrainingArguments(
233
- output_dir=str(OUTPUT_DIR),
234
  num_train_epochs=EPOCHS,
235
  per_device_train_batch_size=BATCH_SIZE,
236
  per_device_eval_batch_size=BATCH_SIZE,
@@ -260,9 +310,9 @@ def main():
260
  print("\nStarting correction fine-tune ...")
261
  trainer.train()
262
 
263
- print(f"\nSaving corrected model to {OUTPUT_DIR} ...")
264
- model.save_pretrained(str(OUTPUT_DIR))
265
- tokenizer.save_pretrained(str(OUTPUT_DIR))
266
  print("Done.")
267
 
268
 
 
17
 
18
  from __future__ import annotations
19
 
20
+ import argparse
21
  import random
22
  import sys
23
  from pathlib import Path
24
+ from datetime import datetime
25
 
26
  ROOT = Path(__file__).parent.parent
27
  if str(ROOT) not in sys.path:
 
39
 
40
  # ── Config ────────────────────────────────────────────────────────────────────
41
 
 
42
  DATA_PATH = ROOT / "seq2seq" / "wsd_pairs.csv"
43
+ # Clean base model downloaded from HF Hub never fine-tuned directly.
44
+ # Experiments always read from here and write to a timestamped subfolder.
45
+ DEFAULT_MODEL_PATH = ROOT / "seq2seq" / "byt5-base-clean"
46
+ EXPERIMENTS_ROOT = ROOT / "seq2seq" / "experiments" / "byt5-corrections"
47
 
48
  REPEAT = 500 # how many times each correction pair is repeated
49
  BG_SAMPLES = 50_000 # random background pairs from wsd_pairs.csv to prevent forgetting
 
211
  return ds
212
 
213
 
214
+ def parse_args() -> argparse.Namespace:
215
+ parser = argparse.ArgumentParser(
216
+ description="Fine-tune ByT5 corrections on an experiment copy (GPU-only)."
217
+ )
218
+ parser.add_argument(
219
+ "--model-path",
220
+ type=Path,
221
+ default=DEFAULT_MODEL_PATH,
222
+ help="Input model directory (experiment copy recommended).",
223
+ )
224
+ parser.add_argument(
225
+ "--output-dir",
226
+ type=Path,
227
+ default=None,
228
+ help="Output directory for this run. If omitted, a timestamped experiment folder is created.",
229
+ )
230
+ parser.add_argument(
231
+ "--allow-cpu",
232
+ action="store_true",
233
+ help="Allow CPU training (not recommended). By default training requires CUDA.",
234
+ )
235
+ return parser.parse_args()
236
+
237
+
238
  # ── Main ──────────────────────────────────────────────────────────────────────
239
 
240
  def main():
241
+ cli = parse_args()
242
+
243
  device = "cuda" if torch.cuda.is_available() else "cpu"
244
  print(f"\nDevice : {device}")
245
+ if device != "cuda" and not cli.allow_cpu:
246
+ raise RuntimeError(
247
+ "CUDA GPU is required for fine-tuning. "
248
+ "No GPU was detected, so the run was stopped to avoid CPU slowdown. "
249
+ "If you really need CPU mode, run with --allow-cpu."
250
+ )
251
+
252
+ model_path = cli.model_path
253
+ if not model_path.exists():
254
+ raise FileNotFoundError(f"Model path not found: {model_path}")
255
+
256
+ if cli.output_dir is None:
257
+ run_name = datetime.now().strftime("run-%Y%m%d-%H%M%S")
258
+ output_dir = EXPERIMENTS_ROOT / run_name
259
+ else:
260
+ output_dir = cli.output_dir
261
+
262
+ output_dir.mkdir(parents=True, exist_ok=True)
263
 
264
+ print(f"Loading model from {model_path} ...")
265
+ tokenizer = AutoTokenizer.from_pretrained(str(model_path))
266
+ model = AutoModelForSeq2SeqLM.from_pretrained(str(model_path))
267
+
268
+ # Explicitly move model to GPU
269
+ model = model.to(device)
270
+ print(f"Model moved to: {device}")
271
 
272
  print("\nBuilding correction dataset ...")
273
  ds = build_dataset(tokenizer)
 
280
  warmup = max(100, len(train_ds) // (BATCH_SIZE * 20))
281
 
282
  args = Seq2SeqTrainingArguments(
283
+ output_dir=str(output_dir),
284
  num_train_epochs=EPOCHS,
285
  per_device_train_batch_size=BATCH_SIZE,
286
  per_device_eval_batch_size=BATCH_SIZE,
 
310
  print("\nStarting correction fine-tune ...")
311
  trainer.train()
312
 
313
+ print(f"\nSaving corrected model to {output_dir} ...")
314
+ model.save_pretrained(str(output_dir))
315
+ tokenizer.save_pretrained(str(output_dir))
316
  print("Done.")
317
 
318
 
seq2seq/prepare_experiment_model.py ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Prepare local clean model snapshots and experiment copies.
3
+
4
+ Workflow:
5
+ 1) Download/save a clean Hugging Face model to a stable local path once.
6
+ 2) Create a copy of that clean local model for each experiment run.
7
+
8
+ This prevents accidental overwrites of your base model and keeps
9
+ fine-tuning runs isolated.
10
+
11
+ Examples:
12
+ python seq2seq/prepare_experiment_model.py --model-id Kalana001/mbart50-large-singlish-sinhala
13
+ python seq2seq/prepare_experiment_model.py --model-id Kalana001/mbart50-large-singlish-sinhala --run-name exp-lr5e5
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ import argparse
19
+ import shutil
20
+ import sys
21
+ from datetime import datetime
22
+ from pathlib import Path
23
+
24
+ import torch
25
+ from transformers import AutoModelForSeq2SeqLM, AutoTokenizer
26
+
27
+ ROOT = Path(__file__).parent.parent
28
+ if str(ROOT) not in sys.path:
29
+ sys.path.insert(0, str(ROOT))
30
+
31
+ from core.constants import DEFAULT_MBART_MODEL
32
+
33
+ CLEAN_ROOT = ROOT / "seq2seq" / "clean_models"
34
+ EXPERIMENT_ROOT = ROOT / "seq2seq" / "experiments"
35
+
36
+
37
+ def parse_args() -> argparse.Namespace:
38
+ parser = argparse.ArgumentParser(
39
+ description="Download a clean model once and create an isolated experiment copy (GPU required)."
40
+ )
41
+ parser.add_argument(
42
+ "--model-id",
43
+ default=DEFAULT_MBART_MODEL,
44
+ help="Hugging Face model ID to prepare.",
45
+ )
46
+ parser.add_argument(
47
+ "--clean-dir",
48
+ type=Path,
49
+ default=None,
50
+ help="Optional custom clean-model directory.",
51
+ )
52
+ parser.add_argument(
53
+ "--run-name",
54
+ default=None,
55
+ help="Optional experiment run folder name. Defaults to timestamp.",
56
+ )
57
+ parser.add_argument(
58
+ "--force-refresh-clean",
59
+ action="store_true",
60
+ help="Re-download and overwrite the local clean model snapshot.",
61
+ )
62
+ parser.add_argument(
63
+ "--allow-cpu",
64
+ action="store_true",
65
+ help="Allow running without CUDA. Default is GPU-only to avoid workstation slowdown.",
66
+ )
67
+ return parser.parse_args()
68
+
69
+
70
+ def safe_name(model_id: str) -> str:
71
+ return model_id.replace("/", "--")
72
+
73
+
74
+ def main() -> None:
75
+ args = parse_args()
76
+
77
+ if not torch.cuda.is_available() and not args.allow_cpu:
78
+ raise RuntimeError(
79
+ "CUDA GPU is required by default. "
80
+ "No GPU detected. Use --allow-cpu only if you intentionally want CPU mode."
81
+ )
82
+
83
+ model_slug = safe_name(args.model_id)
84
+ clean_dir = args.clean_dir or (CLEAN_ROOT / model_slug)
85
+
86
+ if clean_dir.exists() and args.force_refresh_clean:
87
+ print(f"Removing existing clean model at: {clean_dir}")
88
+ shutil.rmtree(clean_dir)
89
+
90
+ if not clean_dir.exists():
91
+ print(f"Downloading clean model: {args.model_id}")
92
+ tokenizer = AutoTokenizer.from_pretrained(args.model_id)
93
+ model = AutoModelForSeq2SeqLM.from_pretrained(args.model_id)
94
+
95
+ clean_dir.mkdir(parents=True, exist_ok=True)
96
+ tokenizer.save_pretrained(clean_dir)
97
+ model.save_pretrained(clean_dir)
98
+ print(f"Saved clean model to: {clean_dir}")
99
+ else:
100
+ print(f"Using existing clean model: {clean_dir}")
101
+
102
+ run_name = args.run_name or datetime.now().strftime("run-%Y%m%d-%H%M%S")
103
+ exp_dir = EXPERIMENT_ROOT / model_slug / run_name
104
+ exp_model_dir = exp_dir / "model"
105
+
106
+ if exp_model_dir.exists():
107
+ raise FileExistsError(
108
+ f"Experiment model directory already exists: {exp_model_dir}. "
109
+ "Use a different --run-name."
110
+ )
111
+
112
+ exp_dir.mkdir(parents=True, exist_ok=True)
113
+ shutil.copytree(clean_dir, exp_model_dir)
114
+
115
+ print("\nExperiment ready")
116
+ print(f" clean_model : {clean_dir}")
117
+ print(f" experiment : {exp_dir}")
118
+ print(f" model_copy : {exp_model_dir}")
119
+
120
+
121
+ if __name__ == "__main__":
122
+ main()
seq2seq/train.py CHANGED
@@ -76,11 +76,14 @@ def main():
76
 
77
  device = "cuda" if torch.cuda.is_available() else "cpu"
78
  print(f" Device : {device}")
79
- if device == "cuda":
80
- print(f" GPU : {torch.cuda.get_device_name(0)}")
81
- print(f" VRAM : {torch.cuda.get_device_properties(0).total_memory / 1e9:.1f} GB")
82
- else:
83
- print(" WARNING: No GPU detected — training will be very slow!")
 
 
 
84
 
85
  tokenizer = AutoTokenizer.from_pretrained(BASE_MODEL)
86
  model = AutoModelForSeq2SeqLM.from_pretrained(BASE_MODEL)
 
76
 
77
  device = "cuda" if torch.cuda.is_available() else "cpu"
78
  print(f" Device : {device}")
79
+ if device != "cuda":
80
+ raise RuntimeError(
81
+ "CUDA GPU is required for training. "
82
+ "No GPU was detected, so training was stopped to avoid CPU slowdown."
83
+ )
84
+
85
+ print(f" GPU : {torch.cuda.get_device_name(0)}")
86
+ print(f" VRAM : {torch.cuda.get_device_properties(0).total_memory / 1e9:.1f} GB")
87
 
88
  tokenizer = AutoTokenizer.from_pretrained(BASE_MODEL)
89
  model = AutoModelForSeq2SeqLM.from_pretrained(BASE_MODEL)
sincode_model.py CHANGED
@@ -4,7 +4,7 @@ SinCode v3 — public API entry point.
4
  Usage:
5
  from sincode_model import BeamSearchDecoder
6
  decoder = BeamSearchDecoder()
7
- result, logs = decoder.decode("mema videowe bit rate eka godak wadi nisa buffer wenawa")
8
  """
9
 
10
  from core.decoder import BeamSearchDecoder, ScoredCandidate # noqa: F401
 
4
  Usage:
5
  from sincode_model import BeamSearchDecoder
6
  decoder = BeamSearchDecoder()
7
+ result, logs, word_candidates = decoder.decode("mema videowe bit rate eka godak wadi nisa buffer wenawa")
8
  """
9
 
10
  from core.decoder import BeamSearchDecoder, ScoredCandidate # noqa: F401