""" Cuneiform Translator Built for the Build Small Hackathon 2026. Translate between English and the oldest writing systems on Earth. 4,000 years ago someone pressed a reed into wet clay to record a beer recipe. Now you can read it. """ import gradio as gr from transformers import AutoTokenizer, AutoModelForSeq2SeqLM import re # --- Models --- MODELS = { "thalesian": { "repo": "Thalesian/cuneiformBase-400m", "name": "cuneiformBase-400m", }, "praeclarum": { "repo": "praeclarum/cuneiform", "name": "cuneiform-T5", }, } # Load primary model print("Loading Thalesian/cuneiformBase-400m...") try: tokenizer = AutoTokenizer.from_pretrained(MODELS["thalesian"]["repo"], use_fast=False) model = AutoModelForSeq2SeqLM.from_pretrained(MODELS["thalesian"]["repo"]) MODEL_LOADED = True print("Model loaded.") except Exception as e: print(f"Model failed: {e}") MODEL_LOADED = False tokenizer = None model = None # Unicode cuneiform lookup CUNEIFORM_MAP = { "an": "𒀭", "ki": "𒆠", "en": "𒂗", "me": "𒈨", "nam": "𒉆", "lu": "𒇻", "mu": "𒈬", "du": "𒆕", "ga": "𒂵", "ma": "𒈠", "ni": "𒉌", "pa": "𒉺", "ra": "𒊏", "sa": "𒊓", "ta": "𒋫", "ti": "𒋾", "zu": "𒍪", "ba": "𒁀", "bi": "𒁉", "da": "𒁕", "di": "𒁲", "e": "𒂊", "gi": "𒄀", "gu": "𒄖", "ha": "𒄩", "hu": "𒄷", "li": "𒇷", "kal": "𒅗", "im": "𒅎", "ab": "𒀊", "ug": "𒌑", "lugal": "𒈗", "nin": "𒊩", "dam": "𒁮", "dumu": "𒌉", "ama": "𒂼", "dingir": "𒀭", "nanna": "𒀭𒂗𒍪", "inanna": "𒀭𒈹", "enlil": "𒀭𒂗𒍪", "enki": "𒀭𒂗𒆠", "utu": "𒀭𒌓", "ag": "𒀝", "nam-ti": "𒉆𒋾", "nam-lu": "𒉆𒇻", "ki-ag": "𒆠𒀝", "me-en": "𒈨𒂗", "za": "𒍝", "nun": "𒉣", "ur": "𒌨", "ub": "𒌒", "su": "𒍪", "szu": "𒋗", "ig": "𒅅", "ib": "𒅁", "a": "𒀀", "u": "𒌋", "i": "𒄿", "la": "𒆷", "na": "𒈾", "nu": "𒉡", "si": "𒋛", "ka": "𒅗", "gal": "𒃲", "tur": "𒌉", "nig": "𒐊", "sag": "𒊕", "kur": "𒆳", "e2": "𒂍", "ud": "𒌓", } REVERSE_MAP = {v: k for k, v in CUNEIFORM_MAP.items() if len(v) == 1} def to_cuneiform_script(transliteration): """Convert transliteration to Unicode cuneiform signs.""" text = transliteration.lower().strip() chunks = re.split(r'[\s\-]+', text) result = [] for chunk in chunks: if not chunk: continue matched = False for k in sorted(CUNEIFORM_MAP.keys(), key=len, reverse=True): if chunk == k: result.append(CUNEIFORM_MAP[k]) matched = True break if not matched: for k in sorted(CUNEIFORM_MAP.keys(), key=len, reverse=True): if chunk.startswith(k): result.append(CUNEIFORM_MAP[k]) matched = True break if not matched: result.append(f"[{chunk}]") return " ".join(result) DIRECTIONS = [ "Translate English to Akkadian cuneiform:", "Translate English to Sumerian cuneiform:", "Translate Akkadian cuneiform to English:", "Translate Sumerian cuneiform to English:", "Translate Hittite cuneiform to English:", "Translate Linear B to English:", "Transliterate Akkadian cuneiform to plain:", "Transliterate Sumerian cuneiform to plain:", "Convert Akkadian transliteration to cuneiform:", "Convert Sumerian transliteration to cuneiform:", ] def translate(text, direction): """Run translation through the model.""" if not text.strip(): return "", "", "" if not MODEL_LOADED: return "Model not available.", "", "" prompt = f"{direction} {text}" try: inputs = tokenizer(prompt, return_tensors="pt", max_length=512, truncation=True) outputs = model.generate( **inputs, max_length=256, num_beams=4, early_stopping=True, ) result = tokenizer.decode(outputs[0], skip_special_tokens=True) # Generate cuneiform script if output looks like transliteration cuneiform_script = "" if direction.startswith("Translate English") or direction.startswith("Convert"): cuneiform_script = to_cuneiform_script(result) elif direction.startswith("Transliterate"): cuneiform_script = to_cuneiform_script(result) # Show what went in info = f"Direction: {direction}\nInput tokens: {len(inputs['input_ids'][0])}\nOutput tokens: {len(outputs[0])}" return result, cuneiform_script, info except Exception as e: return f"Error: {str(e)}", "", "" EXAMPLES = [ ["The king built a great temple", "Translate English to Akkadian cuneiform:"], ["The king built a great temple", "Translate English to Sumerian cuneiform:"], ["szar-ru ra-bu-u2 e2-gal ib-ni", "Translate Akkadian cuneiform to English:"], ["lugal e2 gal mu-un-du3", "Translate Sumerian cuneiform to English:"], ["lugal kur gal-e", "Convert Sumerian transliteration to cuneiform:"], ] CUSTOM_CSS = """ @import url('https://fonts.googleapis.com/css2?family=Quicksand:wght@400;600;700&display=swap'); .cuneiform-output { font-size: 2.2em; line-height: 1.8; letter-spacing: 0.15em; padding: 20px; text-align: center; color: #8B6914; background: #FAF8F0; border-radius: 12px; border: 1px solid #E8E0C8; min-height: 60px; } .gradio-container { background: #F5F4F0 !important; max-width: 800px !important; margin: 0 auto !important; } .gr-button-primary { background: #8B6914 !important; border: none !important; font-family: 'Quicksand', sans-serif !important; padding: 12px 36px !important; border-radius: 12px !important; } .gr-button-primary:hover { background: #7A5B10 !important; } footer { display: none !important; } """ with gr.Blocks(css=CUSTOM_CSS, title="Cuneiform Translator", theme=gr.themes.Soft()) as app: gr.HTML("""
Translate between English and the oldest writing systems on Earth. Akkadian, Sumerian, Hittite, and Linear B.