|
import torch |
|
import gradio as gr |
|
import json |
|
import time |
|
import random |
|
from transformers import pipeline |
|
import pycountry |
|
from datetime import datetime |
|
from pydantic import BaseModel, PydanticUserError, ConfigDict |
|
from pydantic import BaseModel, ConfigDict |
|
import json |
|
|
|
class MyModel(BaseModel): |
|
request: 'starlette.requests.Request' |
|
model_config = ConfigDict(arbitrary_types_allowed=True) |
|
from pydantic_core import core_schema |
|
from starlette.requests import Request |
|
|
|
def get_pydantic_core_schema(request_type, handler): |
|
return core_schema.any_schema() |
|
|
|
Request.__get_pydantic_core_schema__ = get_pydantic_core_schema |
|
|
|
try: |
|
lang_detector = pipeline("text-classification", model="papluca/xlm-roberta-base-language-detection") |
|
|
|
text_translator = pipeline("translation", model="facebook/nllb-200-distilled-600M") |
|
|
|
print("๐ AI Translation Hub initialized successfully!") |
|
except Exception as e: |
|
print(f"โ ๏ธ Error initializing models: {e}") |
|
|
|
|
|
LANGUAGES = { |
|
'English': '๐บ๐ธ', |
|
'Spanish': '๐ช๐ธ', |
|
'French': '๐ซ๐ท', |
|
'German': '๐ฉ๐ช', |
|
'Italian': '๐ฎ๐น', |
|
'Portuguese': '๐ต๐น', |
|
'Russian': '๐ท๐บ', |
|
'Chinese (Simplified)': '๐จ๐ณ', |
|
'Japanese': '๐ฏ๐ต', |
|
'Korean': '๐ฐ๐ท', |
|
'Arabic': '๐ธ๐ฆ', |
|
'Hindi': '๐ฎ๐ณ', |
|
'Dutch': '๐ณ๐ฑ', |
|
'Swedish': '๐ธ๐ช', |
|
'Norwegian': '๐ณ๐ด' |
|
} |
|
|
|
|
|
try: |
|
with open('language.json', 'r') as file: |
|
language_data = json.load(file) |
|
except FileNotFoundError: |
|
print("โ ๏ธ Language data file not found. Using basic mapping.") |
|
language_data = {'languages': []} |
|
|
|
|
|
translation_stats = { |
|
'total_translations': 0, |
|
'languages_detected': set(), |
|
'session_start': datetime.now() |
|
} |
|
|
|
def get_FLORES_code_from_language(language): |
|
"""Enhanced FLORES code lookup with fallback mapping""" |
|
|
|
import re |
|
|
|
clean_language = re.sub(r'[๐ฆ-๐ฟ]{2}\s*', '', language).strip() |
|
|
|
for entry in language_data.get('languages', []): |
|
if entry['Language'].lower() == clean_language.lower(): |
|
return entry['FLORES-200 code'] |
|
|
|
|
|
fallback_mapping = { |
|
'english': 'eng_Latn', |
|
'spanish': 'spa_Latn', |
|
'french': 'fra_Latn', |
|
'german': 'deu_Latn', |
|
'chinese (simplified)': 'zho_Hans', |
|
'italian': 'ita_Latn', |
|
'portuguese': 'por_Latn', |
|
'russian': 'rus_Cyrl', |
|
'japanese': 'jpn_Jpan', |
|
'korean': 'kor_Hang', |
|
'arabic': 'arb_Arab', |
|
'hindi': 'hin_Deva', |
|
'dutch': 'nld_Latn', |
|
'swedish': 'swe_Latn', |
|
'norwegian': 'nor_Latn' |
|
} |
|
|
|
return fallback_mapping.get(clean_language.lower()) |
|
|
|
def detect_language_confidence(text): |
|
"""Get language detection with confidence score""" |
|
if not text.strip(): |
|
return "Unknown", 0.0 |
|
|
|
try: |
|
result = lang_detector(text)[0] |
|
return result['label'], result['score'] |
|
except: |
|
return "Unknown", 0.0 |
|
|
|
def translate_with_analytics(text, destination_language, show_confidence=True): |
|
"""Enhanced translation with analytics and progress tracking""" |
|
|
|
if not text.strip(): |
|
return "โ ๏ธ Please enter some text to translate", "", "" |
|
|
|
|
|
translation_stats['total_translations'] += 1 |
|
|
|
|
|
yield "๐ Analyzing text...", "", "" |
|
time.sleep(0.5) |
|
|
|
|
|
detected_lang, confidence = detect_language_confidence(text) |
|
translation_stats['languages_detected'].add(detected_lang) |
|
|
|
yield f"๐ง Detected language: {detected_lang.upper()} ({confidence:.1%} confidence)", "", "" |
|
time.sleep(0.3) |
|
|
|
|
|
try: |
|
lang = pycountry.languages.get(alpha_2=detected_lang) |
|
src_code = f"{lang.alpha_3}_Latn" if lang else "eng_Latn" |
|
except: |
|
src_code = "eng_Latn" |
|
|
|
dest_code = get_FLORES_code_from_language(destination_language) |
|
if not dest_code: |
|
yield f"โ Unsupported target language: {destination_language}", "", "" |
|
return |
|
|
|
yield f"โก Translating to {destination_language.split(' ', 1)[-1] if ' ' in destination_language else destination_language}...", "", "" |
|
time.sleep(0.5) |
|
|
|
|
|
if src_code == dest_code: |
|
analytics = f""" |
|
๐ **Translation Analytics** |
|
- Source: {detected_lang.upper()} ({confidence:.1%} confidence) |
|
- Target: Same language detected |
|
- Action: No translation needed |
|
- Processing time: <1s |
|
""" |
|
yield "โ
Translation complete!", text, analytics.strip() |
|
return |
|
|
|
|
|
try: |
|
start_time = time.time() |
|
|
|
|
|
input_length = len(text) |
|
|
|
max_length = max(512, min(2048, int(input_length * 1.5))) |
|
|
|
translation = text_translator( |
|
text, |
|
src_lang=src_code, |
|
tgt_lang=dest_code, |
|
max_length=max_length, |
|
do_sample=False, |
|
num_beams=4 |
|
) |
|
processing_time = time.time() - start_time |
|
|
|
result = translation[0]['translation_text'] |
|
|
|
|
|
import re |
|
clean_dest_lang = re.sub(r'[๐ฆ-๐ฟ]{2}\s*', '', destination_language).strip() |
|
|
|
analytics = f""" |
|
๐ **Translation Analytics** |
|
- **Source Language**: {detected_lang.upper()} ({confidence:.1%} confidence) |
|
- **Target Language**: {clean_dest_lang} |
|
- **Characters Processed**: {len(text):,} |
|
- **Max Length Used**: {max_length} |
|
- **Processing Time**: {processing_time:.2f}s |
|
- **Session Translations**: {translation_stats['total_translations']} |
|
- **Languages Detected**: {len(translation_stats['languages_detected'])} |
|
""" |
|
|
|
yield "โ
Translation complete!", result, analytics.strip() |
|
|
|
except Exception as e: |
|
yield f"โ Translation failed: {str(e)}", "", "" |
|
|
|
def clear_all(): |
|
"""Reset all fields""" |
|
return "", "", "", "" |
|
|
|
|
|
custom_css = """ |
|
.gradio-container { |
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; |
|
} |
|
|
|
.gr-button { |
|
background: linear-gradient(45deg, #FF6B6B, #4ECDC4); |
|
border: none; |
|
border-radius: 25px; |
|
color: white; |
|
font-weight: bold; |
|
transition: all 0.3s ease; |
|
box-shadow: 0 4px 15px rgba(0,0,0,0.2); |
|
} |
|
|
|
.gr-button:hover { |
|
transform: translateY(-2px); |
|
box-shadow: 0 6px 20px rgba(0,0,0,0.3); |
|
} |
|
|
|
.gr-textbox { |
|
border-radius: 15px; |
|
border: 2px solid #e0e0e0; |
|
transition: all 0.3s ease; |
|
} |
|
|
|
.gr-textbox:focus { |
|
border-color: #667eea; |
|
box-shadow: 0 0 15px rgba(102, 126, 234, 0.3); |
|
} |
|
|
|
.gr-dropdown { |
|
border-radius: 15px; |
|
border: 2px solid #e0e0e0; |
|
} |
|
|
|
.gr-panel { |
|
background: rgba(255,255,255,0.95); |
|
border-radius: 20px; |
|
backdrop-filter: blur(10px); |
|
box-shadow: 0 8px 32px rgba(0,0,0,0.1); |
|
} |
|
|
|
.gr-form { |
|
background: transparent; |
|
} |
|
|
|
.gr-box { |
|
border-radius: 15px; |
|
background: rgba(255,255,255,0.9); |
|
} |
|
""" |
|
|
|
|
|
with gr.Blocks(css=custom_css, title="๐ KS Translation Hub") as demo: |
|
gr.HTML(""" |
|
<div style="text-align: center; padding: 20px; background: linear-gradient(45deg, #FF6B6B, #4ECDC4); border-radius: 20px; margin-bottom: 20px;"> |
|
<h1 style="color: white; font-size: 3em; margin: 0; text-shadow: 2px 2px 4px rgba(0,0,0,0.3);"> |
|
๐ KS Translation Hub |
|
</h1> |
|
<p style="color: white; font-size: 1.2em; margin: 10px 0 0 0; opacity: 0.9;"> |
|
Powered by Advanced Neural Networks โข Real-time Language Detection โข 15+ Languages |
|
</p> |
|
</div> |
|
""") |
|
|
|
with gr.Row(): |
|
with gr.Column(scale=1): |
|
gr.HTML("<h3 style='text-align: center; color: #333;'>๐ Input</h3>") |
|
input_text = gr.Textbox( |
|
label="Enter text to translate", |
|
placeholder="Type or paste your text here... ๐๏ธ", |
|
lines=8, |
|
show_label=False |
|
) |
|
|
|
with gr.Row(): |
|
target_lang = gr.Dropdown( |
|
choices=[f"{flag} {lang}" for lang, flag in LANGUAGES.items()], |
|
label="๐ฏ Target Language", |
|
value="๐ช๐ธ Spanish", |
|
show_label=True |
|
) |
|
|
|
with gr.Column(scale=1): |
|
gr.HTML("<h3 style='text-align: center; color: #333;'>โจ Output</h3>") |
|
output_text = gr.Textbox( |
|
label="Translation", |
|
lines=8, |
|
show_label=False, |
|
interactive=False |
|
) |
|
|
|
with gr.Row(): |
|
with gr.Column(scale=1): |
|
status_text = gr.Textbox( |
|
label="๐ Status", |
|
value="Ready to translate...", |
|
interactive=False, |
|
show_label=True |
|
) |
|
|
|
with gr.Column(scale=1): |
|
analytics_text = gr.Textbox( |
|
label="๐ Analytics", |
|
value="Translation analytics will appear here...", |
|
interactive=False, |
|
show_label=True, |
|
lines=6 |
|
) |
|
|
|
with gr.Row(): |
|
translate_btn = gr.Button("๐ Translate", variant="primary", size="lg") |
|
clear_btn = gr.Button("๐๏ธ Clear All", variant="secondary", size="lg") |
|
|
|
|
|
translate_btn.click( |
|
fn=translate_with_analytics, |
|
inputs=[input_text, target_lang], |
|
outputs=[status_text, output_text, analytics_text] |
|
) |
|
|
|
clear_btn.click( |
|
fn=clear_all, |
|
outputs=[input_text, output_text, status_text, analytics_text] |
|
) |
|
|
|
|
|
input_text.submit( |
|
fn=translate_with_analytics, |
|
inputs=[input_text, target_lang], |
|
outputs=[status_text, output_text, analytics_text] |
|
) |
|
|
|
gr.HTML(""" |
|
<div style="text-align: center; padding: 20px; margin-top: 20px; background: rgba(255,255,255,0.8); border-radius: 15px;"> |
|
<p style="color: #666; font-size: 0.9em;"> |
|
๐ค Powered by Transformers โข ๐ Privacy-First โข โก Real-time Processing |
|
</p> |
|
</div> |
|
""") |
|
|
|
|
|
if __name__ == "__main__": |
|
demo.launch() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|