KalanaPabasara commited on
Commit ·
1fed70a
1
Parent(s): f6f45d5
SinCode v3 — seq2seq pipeline, evaluation scripts, IndoNLP benchmark data
Browse files- .gitignore +5 -0
- IndoNLP-2025-Shared-Task/Images/sample.png +0 -0
- IndoNLP-2025-Shared-Task/Readme.md +53 -0
- IndoNLP-2025-Shared-Task/Test Dataset/Bengali/Bengali Test Set 1.txt +0 -0
- IndoNLP-2025-Shared-Task/Test Dataset/Bengali/Bengali Test Set 2.txt +0 -0
- IndoNLP-2025-Shared-Task/Test Dataset/Gujarati/Gujarati Test 1.txt +0 -0
- IndoNLP-2025-Shared-Task/Test Dataset/Gujarati/Gujarati Test 2.txt +0 -0
- IndoNLP-2025-Shared-Task/Test Dataset/Hindi/Hindi Test Set 1.txt +0 -0
- IndoNLP-2025-Shared-Task/Test Dataset/Hindi/Hindi Test Set 2.txt +0 -0
- IndoNLP-2025-Shared-Task/Test Dataset/Malayalam/Malayalam Test Set 1.txt +0 -0
- IndoNLP-2025-Shared-Task/Test Dataset/Malayalam/Malayalam Test Set 2.txt +0 -0
- IndoNLP-2025-Shared-Task/Test Dataset/Sinhala/Sinhala Test set 1.txt +0 -0
- IndoNLP-2025-Shared-Task/Test Dataset/Sinhala/Sinhala Test set 2.txt +0 -0
- app.py +172 -18
- core/constants.py +5 -0
- core/decoder.py +111 -19
- feedback_schema.sql +19 -0
- feedback_store.py +101 -0
- misc/eval_indo.py +160 -0
- misc/eval_internal_500.py +167 -0
- misc/evaluate_indo_nlp.py +241 -0
- misc/indo_nlp_eval_results.csv +21 -0
- misc/indo_nlp_eval_summary.csv +4 -0
- misc/indo_nlp_results.csv +11 -0
- misc/internal_500_results.csv +0 -0
- misc/internal_test_set_500.csv +501 -0
- misc/quick_eval.py +139 -0
- misc/quick_eval_results.csv +11 -0
- requirements.txt +1 -0
- seq2seq/finetune_corrections.py +61 -11
- seq2seq/prepare_experiment_model.py +122 -0
- seq2seq/train.py +8 -5
- sincode_model.py +1 -1
.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 |
+

|
| 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 |
-
|
| 9 |
-
|
| 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.
|
| 18 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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
|
| 37 |
"(e.g. *buffer*, *bit rate*). "
|
| 38 |
"**Full Sinhala**: transliterates every word to Sinhala script "
|
| 39 |
-
"(e.g. *business*
|
| 40 |
),
|
| 41 |
)
|
| 42 |
|
| 43 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
-
|
| 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 |
-
|
| 186 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
-
|
| 237 |
-
|
| 238 |
-
|
| 239 |
-
|
| 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 |
-
|
|
|
|
|
|
|
|
|
|
| 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 =
|
| 216 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 217 |
|
| 218 |
-
print(f"Loading model from {
|
| 219 |
-
tokenizer = AutoTokenizer.from_pretrained(str(
|
| 220 |
-
model = AutoModelForSeq2SeqLM.from_pretrained(str(
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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(
|
| 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 {
|
| 264 |
-
model.save_pretrained(str(
|
| 265 |
-
tokenizer.save_pretrained(str(
|
| 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 =
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
|
|
|
|
|
|
|
|
|
| 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
|