{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceType":"competition","sourceId":121150,"databundleVersionId":15745837},{"sourceType":"datasetVersion","sourceId":14557053,"datasetId":9297841,"databundleVersionId":15388499,"isSourceIdPinned":true},{"sourceType":"modelInstanceVersion","sourceId":363134,"databundleVersionId":12066720,"modelInstanceId":301514,"modelId":322000},{"sourceType":"modelInstanceVersion","sourceId":764730,"databundleVersionId":15820131,"modelInstanceId":584307,"modelId":595873}],"dockerImageVersionId":31260,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# !pip install vllm --find-links /kaggle/input/vllm-bitsandbytes-install --no-index\n# !uv pip install --system vllm-tpu --find-links /kaggle/input/vllm-bitsandbytes-install/vllm --no-index","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-24T02:38:50.416464Z","iopub.execute_input":"2026-02-24T02:38:50.417115Z","iopub.status.idle":"2026-02-24T02:38:50.421217Z","shell.execute_reply.started":"2026-02-24T02:38:50.417083Z","shell.execute_reply":"2026-02-24T02:38:50.420396Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nos.environ[\"HF_HUB_OFFLINE\"]=\"1\"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-24T02:38:50.422735Z","iopub.execute_input":"2026-02-24T02:38:50.423251Z","iopub.status.idle":"2026-02-24T02:38:52.233808Z","shell.execute_reply.started":"2026-02-24T02:38:50.423218Z","shell.execute_reply":"2026-02-24T02:38:52.23274Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nfrom transformers import AutoModelForCausalLM, AutoProcessor\nfrom peft import PeftModel\n\n# Define your paths\nbase_model_path = \"/kaggle/input/models/qwen-lm/qwen-3/transformers/4b/1\"\nadapter_path = \"/kaggle/input/models/rejk11/qwen-lora-20260224/transformers/v2/1\"\noutput_path = \"/tmp/model\"\n\nprint(\"1. Loading base model and tokenizer...\")\nprocessor = AutoProcessor.from_pretrained(base_model_path)\nbase_model = AutoModelForCausalLM.from_pretrained(\n    base_model_path,\n    torch_dtype=torch.bfloat16, # Using bfloat16 or float16 is recommended to save RAM\n    device_map=\"auto\" \n)\n\nprint(\"2. Loading LoRA adapter...\")\nmodel = PeftModel.from_pretrained(base_model, adapter_path)\n\nprint(\"3. Merging adapter weights with base model...\")\n# merge_and_unload combines the LoRA weights with the base model weights\nmerged_model = model.merge_and_unload()\n\nprint(f\"4. Saving merged model to {output_path}...\")\nmerged_model.save_pretrained(output_path)\nprocessor.save_pretrained(output_path)\n\nprint(\"Merge complete!\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-24T02:38:52.235383Z","iopub.execute_input":"2026-02-24T02:38:52.235754Z","iopub.status.idle":"2026-02-24T02:38:53.00504Z","shell.execute_reply.started":"2026-02-24T02:38:52.235718Z","shell.execute_reply":"2026-02-24T02:38:53.003973Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!ls /tmp/model","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-24T02:43:26.238019Z","iopub.execute_input":"2026-02-24T02:43:26.23834Z","iopub.status.idle":"2026-02-24T02:43:26.391498Z","shell.execute_reply.started":"2026-02-24T02:43:26.238314Z","shell.execute_reply":"2026-02-24T02:43:26.390672Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!ln -sf /usr/local/nvidia/lib64/libcuda.so /usr/lib/x86_64-linux-gnu/libcuda.so\n!ln -sf /usr/local/nvidia/lib64/libcuda.so.1 /usr/lib/x86_64-linux-gnu/libcuda.so.1","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-24T02:38:54.429729Z","iopub.execute_input":"2026-02-24T02:38:54.429995Z","iopub.status.idle":"2026-02-24T02:38:55.442798Z","shell.execute_reply.started":"2026-02-24T02:38:54.429965Z","shell.execute_reply":"2026-02-24T02:38:55.441766Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"%%writefile /kaggle/working/transliteration_normalization.py\nimport re\nimport pandas as pd\n# ASCII to diacritics mapping based on common Akkadian conventions\nASCII_TO_DIACRITICS = {\n    # Common substitutions\n    'sz': 'š',   'SZ': 'Š',\n    'ts': 'ṣ',   'TS': 'Ṣ', \n    'tt': 'ṭ',   'TT': 'Ṭ',\n    'hh': 'ḫ',   'HH': 'Ḫ',\n    \n    # Vowel diacritics\n    'u2': 'ú',   'u3': 'ù',   'u4': 'û',\n    'a2': 'á',   'a3': 'à',   'a4': 'â', \n    'e2': 'é',   'e3': 'è',   'e4': 'ê',\n    'i2': 'í',   'i3': 'ì',   'i4': 'î',\n    'o2': 'ó',   'o3': 'ò',   'o4': 'ô',\n    \n    # Complex patterns from competition examples (order matters - longest first)\n    'Si2': 'Ṣí',  'pi3': 'pì',\n    'KU3': 'KÙ',  'KISZIB': 'KIŠIB',\n    \n    # Additional patterns\n    'kà': 'kà',  'šà': 'šà',  'lá': 'lá',  'mà': 'mà',\n    'ḫa': 'ḫa',  'ša': 'ša',  'ṣa': 'ṣa',  'ṭa': 'ṭa',\n}\n\ndef ascii_to_diacritics(text):\n    \"\"\"\n    Convert ASCII substitutes to proper diacritics.\n    \n    Args:\n        text (str): Input text with potential ASCII substitutes\n        \n    Returns:\n        str: Text with ASCII substitutes converted to diacritics\n        \n    Examples:\n        >>> ascii_to_diacritics(\"i-Si2-ba-at\")\n        'i-Ṣí-ba-at'\n        >>> ascii_to_diacritics(\"KU3-pi3-a\") \n        'KÙ-pì-a'\n    \"\"\"\n    if not isinstance(text, str):\n        return str(text) if text else \"\"\n    \n    # Apply conversions from longest to shortest to avoid partial matches\n    # This ensures 'Si2' is processed before 'i2', etc.\n    for ascii_form, diacritic_form in sorted(ASCII_TO_DIACRITICS.items(), \n                                           key=lambda x: len(x[0]), reverse=True):\n        text = text.replace(ascii_form, diacritic_form)\n    \n    return text\n\ndef normalize_gaps_for_alignment(text):\n    \"\"\"\n    Normalize gap markers for parallel alignment between transliteration and translation.\n    \n    Key rules:\n    - Single x → <gap>\n    - Multiple consecutive x → <big_gap> \n    - Collapse gap combinations for better sentence alignment\n    - Preserve gaps attached to words (e.g., <gap>-A-šùr)\n    \n    Args:\n        text (str): Input text with gap markers\n        \n    Returns:\n        str: Text with normalized gap markers\n    \"\"\"\n    if not isinstance(text, str):\n        return str(text) if text else \"\"\n    \n    # Multi-dot patterns → <big_gap>\n    text = re.sub(r'\\.{3}(?:\\s+\\.{3})+', ' <big_gap> ', text)\n    text = re.sub(r'\\.{6,}', ' <big_gap> ', text)\n    text = re.sub(r'\\.\\.\\.', ' <big_gap> ', text)\n    text = re.sub(r'……', ' <big_gap> ', text)\n    text = re.sub(r'…', ' <big_gap> ', text)\n    \n    # x patterns - handle word boundaries carefully\n    # Multiple x's → <big_gap>\n    text = re.sub(r'\\bx\\s+x\\s+x\\s+x\\b', ' <big_gap> ', text)  # x x x x\n    text = re.sub(r'\\bx\\s+x\\s+x\\b', ' <big_gap> ', text)      # x x x  \n    text = re.sub(r'\\bx\\s+x\\b', ' <big_gap> ', text)          # x x\n    text = re.sub(r'\\bx{2,}\\b', ' <big_gap> ', text)          # xx, xxx, etc.\n    \n    # Single x → <gap> (but preserve attached gaps like <gap>-word)\n    text = re.sub(r'\\bx\\b', ' <gap> ', text)\n    \n    # Collapse gap combinations for parallel alignment\n    # This is crucial for preventing model misalignment\n    text = re.sub(r'<gap>\\s*<big_gap>', ' <big_gap> ', text)\n    text = re.sub(r'<big_gap>\\s*<gap>', ' <big_gap> ', text) \n    text = re.sub(r'<gap>\\s*<gap>', ' <big_gap> ', text)\n    text = re.sub(r'<big_gap>\\s*<big_gap>', ' <big_gap> ', text)\n    \n    return text\n\ndef normalize_transliteration(text):\n    \"\"\"\n    Complete transliteration normalization pipeline.\n    \n    This applies the full recommended strategy:\n    1. Convert ASCII substitutes to diacritics\n    2. Normalize gaps for parallel alignment  \n    3. Clean up whitespace\n    \n    Args:\n        text (str): Raw transliteration text\n        \n    Returns:\n        str: Normalized transliteration text\n        \n    Examples:\n        >>> normalize_transliteration(\"i-Si2-ba-at x x KU3-pi3-a\")\n        'i-Ṣí-ba-at <big_gap> KÙ-pì-a'\n    \"\"\"\n    if pd.isna(text):\n        return \"\"\n        \n    text = str(text)\n    \n    # Step 1: Convert ASCII substitutes to diacritics (KEEP diacritics)\n    text = ascii_to_diacritics(text)\n    \n    # Step 2: Normalize gaps for parallel alignment\n    text = normalize_gaps_for_alignment(text)\n    \n    # Step 3: Clean up whitespace\n    text = re.sub(r'\\s+', ' ', text)\n    text = text.strip()\n    \n    return text\n\ndef validate_normalization(text):\n    \"\"\"\n    Validate that text follows the expected format.\n    \n    Returns warnings for potential issues:\n    - ASCII substitutes that should be diacritics\n    - Inconsistent gap patterns\n    \"\"\"\n    issues = []\n    \n    if 'sz' in text or 'SZ' in text:\n        issues.append(\"Contains 'sz' - should be 'š'\")\n    if 'u2' in text or 'u3' in text:\n        issues.append(\"Contains 'u2/u3' - should use diacritics\")\n    if re.search(r'\\bx\\s+x\\b', text):\n        issues.append(\"Contains 'x x' pattern - should be '<big_gap>'\")\n    if '<gap><big_gap>' in text or '<big_gap><gap>' in text:\n        issues.append(\"Contains mixed gap pattern - should be collapsed\")\n        \n    return issues\n\n# Convenience function for batch processing\ndef normalize_dataframe_column(df, column_name, validate=False):\n    \"\"\"\n    Apply transliteration normalization to a DataFrame column.\n    \n    Args:\n        df (pd.DataFrame): DataFrame containing transliteration data\n        column_name (str): Name of column to normalize\n        validate (bool): If True, report validation issues\n        \n    Returns:\n        pd.DataFrame: DataFrame with normalized column\n    \"\"\"\n    df = df.copy()\n    df[column_name] = df[column_name].apply(normalize_transliteration)\n    \n    if validate:\n        # Report validation issues\n        for idx, text in df[column_name].items():\n            issues = validate_normalization(text)\n            if issues:\n                print(f\"Row {idx}: {'; '.join(issues)}\")\n    \n    return df\n\nif __name__ == \"__main__\":\n    # Test examples from the competition guidance\n    test_cases = [\n        \"i-Si2-ba-at x x\",\n        \"KU3-pi3-a sz\",  \n        \"KISZIB tt uu3\",\n        \"i-Si2-ba-at x x x x test\",\n        \"<gap> test <big_gap>\",\n    ]\n    \n    print(\"Transliteration Normalization Test Results:\")\n    print(\"=\" * 50)\n    \n    for test in test_cases:\n        normalized = normalize_transliteration(test)\n        issues = validate_normalization(test)\n        \n        print(f\"Input:      {test}\")\n        print(f\"Normalized: {normalized}\")\n        if issues:\n            print(f\"Issues:     {'; '.join(issues)}\")\n        print(\"-\" * 30)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-24T02:38:55.444343Z","iopub.execute_input":"2026-02-24T02:38:55.444571Z","iopub.status.idle":"2026-02-24T02:38:56.023864Z","shell.execute_reply.started":"2026-02-24T02:38:55.444545Z","shell.execute_reply":"2026-02-24T02:38:56.022288Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport pandas as pd\nimport torch\nimport shutil\nimport urllib.request\nimport re\nfrom tqdm import tqdm\nfrom transformers import AutoModelForCausalLM, AutoTokenizer,AutoProcessor\nfrom transliteration_normalization import normalize_transliteration\n\n# --- Configuration ---\nMODEL_DIR = \"/tmp/model\"\nTEST_CSV = \"/kaggle/input/deep-past-initiative-machine-translation/test.csv\"\nOUTPUT_CSV = \"/kaggle/working/submission.csv\"\nBATCH_SIZE = 8  # Adjust based on your GPU VRAM (8-16 is usually safe for 7B/9B models)\n\n\ndef preprocess_input(text):\n    return normalize_transliteration(text)\n\n\ndef postprocess_output(text):\n    \"\"\"\n    Post-processing optimizations:\n    1. ḫ→h conversion\n    2. Subscript number normalization\n    3. Gap normalization\n    4. Character denoising\n    \"\"\"\n    if not isinstance(text, str):\n        return str(text) if text else \"broken text\"\n    \n    if not text.strip():\n        return \"broken text\"\n    \n    # ḫ/Ḫ → h/H conversion\n    text = text.replace('ḫ', 'h')\n    text = text.replace('Ḫ', 'H')\n    \n    # Subscript number normalization\n    subscript_map = {\n        '₀': '0', '₁': '1', '₂': '2', '₃': '3', '₄': '4',\n        '₅': '5', '₆': '6', '₇': '7', '₈': '8', '₉': '9',\n    }\n    for sub, normal in subscript_map.items():\n        text = text.replace(sub, normal)\n    \n    # Convert gap patterns in output to proper tags\n    text = re.sub(r'\\[x\\]', '<gap>', text, flags=re.IGNORECASE)\n    text = re.sub(r'\\(x\\)', '<gap>', text, flags=re.IGNORECASE)\n    text = re.sub(r'\\bx\\b', '<gap>', text)\n    text = re.sub(r'\\.\\.\\.+', '<big_gap>', text)\n    text = re.sub(r'…', '<big_gap>', text)\n    text = re.sub(r'\\[\\.+\\]', '<big_gap>', text)\n    \n    # Gap consolidation (same-type only!)\n    text = re.sub(r'<gap>\\s*<gap>', '<big_gap>', text)\n    text = re.sub(r'<big_gap>\\s*<big_gap>', '<big_gap>', text)\n    \n    # Remove scribal annotations\n    scribal_patterns = [\n        r'\\(fem\\.\\s*plur\\.\\)', r'\\(fem\\.\\)', r'\\(plur\\.\\)', \n        r'\\(pl\\.\\)', r'\\(sing\\.\\)', r'\\(singular\\)', r'\\(plural\\)',\n        r'\\(\\?\\)', r'\\(!\\)',\n    ]\n    for pattern in scribal_patterns:\n        text = re.sub(pattern, '', text, flags=re.IGNORECASE)\n    \n    # Character denoising\n    text = text.replace('<gap>', '\\x00GAP\\x00')\n    text = text.replace('<big_gap>', '\\x00BIGGAP\\x00')\n    \n    forbidden_chars = [\n        '!', '?', '(', ')', '\"', '\"', '\"', ';', '—', '–',\n        '<', '>', '⌈', '⌊', '⌋', '[', ']', '+', 'ʾ', '/',\n    ]\n    for char in forbidden_chars:\n        text = text.replace(char, '')\n    \n    text = text.replace('\\x00GAP\\x00', '<gap>')\n    text = text.replace('\\x00BIGGAP\\x00', '<big_gap>')\n    \n    # Fraction normalization\n    text = re.sub(r'(\\d+)\\.5\\b', r'\\1 ½', text)\n    text = re.sub(r'(\\d+)\\.33+\\d*\\b', r'\\1 ⅓', text)\n    text = re.sub(r'(\\d+)\\.66+\\d*\\b', r'\\1 ⅔', text)\n    text = re.sub(r'(\\d+)\\.25\\b', r'\\1 ¼', text)\n    text = re.sub(r'(\\d+)\\.75\\b', r'\\1 ¾', text)\n    \n    text = re.sub(r'\\b0\\.5\\b', '½', text)\n    text = re.sub(r'\\b0\\.33+\\d*\\b', '⅓', text)\n    text = re.sub(r'\\b0\\.66+\\d*\\b', '⅔', text)\n    text = re.sub(r'\\b0\\.25\\b', '¼', text)\n    text = re.sub(r'\\b0\\.75\\b', '¾', text)\n    \n    # After / removal, \"1/2\" becomes \"1 2\"\n    text = text.replace(' 1 2', ' ½')\n    text = text.replace(' 1 3', ' ⅓')\n    text = text.replace(' 2 3', ' ⅔')\n    text = text.replace(' 1 4', ' ¼')\n    text = text.replace(' 3 4', ' ¾')\n    \n    # Final cleanup\n    text = re.sub(r'\\s+', ' ', text)\n    text = text.strip()\n    text = re.sub(r'^-\\s*', '', text)\n    text = re.sub(r'\\s*-$', '', text)\n    \n    return text if text else \"broken text\"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-24T02:44:43.335489Z","iopub.execute_input":"2026-02-24T02:44:43.33631Z","iopub.status.idle":"2026-02-24T02:44:43.355721Z","shell.execute_reply.started":"2026-02-24T02:44:43.336271Z","shell.execute_reply":"2026-02-24T02:44:43.354904Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# --- 1. Load Data ---\nprint(\"--- Loading Test Data ---\")\ntest_df = pd.read_csv(TEST_CSV)\n\n# --- 2. Initialize Transformers Model ---\nprint(\"--- Initializing Transformers ---\")\n\n# Load Processor (handles both tokenizer and any multimodal inputs)\nprocessor = AutoProcessor.from_pretrained(MODEL_DIR, trust_remote_code=True)\ntry:\n    tokenizer = processor.tokenizer\nexcept:\n    tokenizer=processor\n# Ensure padding side is left for generation to work correctly with batching\ntokenizer.padding_side = \"left\"\nif tokenizer.pad_token is None:\n    tokenizer.pad_token = tokenizer.eos_token\n\n# Get the end_of_turn token ID for proper stopping\nend_of_turn_id = tokenizer.convert_tokens_to_ids(\"<end_of_turn>\")\nprint(f\"EOS token ID: {tokenizer.eos_token_id}, End of turn token ID: {end_of_turn_id}\")\n\n# Prepare messages in proper Gemma 3 format (matching training format)\nmessages_list = [\n    [\n        {\n            \"role\": \"user\",\n            \"content\": f\"/no_think Translate Akkadian to English: {preprocess_input(text)}\"\n        }\n    ]\n    for text in test_df['transliteration']\n]\n\n# Format with processor's chat template\nraw_prompts = [\n    processor.apply_chat_template(\n        messages,\n        tokenize=False,\n        add_generation_prompt=True  # Add generation prompt for inference\n    )\n    for messages in messages_list\n]\n\n# Load Model\n# device_map=\"auto\" handles multi-GPU distribution automatically\n# torch_dtype=torch.float16 is standard for inference (saves memory vs float32)\nmodel = AutoModelForCausalLM.from_pretrained(\n    MODEL_DIR,\n    device_map=\"auto\",\n    torch_dtype=torch.float32, \n    trust_remote_code=True,\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-24T02:49:33.019087Z","iopub.execute_input":"2026-02-24T02:49:33.019835Z","iopub.status.idle":"2026-02-24T02:49:45.826593Z","shell.execute_reply.started":"2026-02-24T02:49:33.019802Z","shell.execute_reply":"2026-02-24T02:49:45.825849Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# --- 1. Fix the Token IDs (Before the loop) ---\n# Qwen doesn't have <end_of_turn>. \n# It uses <|im_end|> for chat or just the standard EOS.\neos_id = tokenizer.eos_token_id\n\n# If you specifically want to catch the chat end token:\nim_end_id = tokenizer.convert_tokens_to_ids(\"<|im_end|>\")\n\n# Build a valid stop list (filter out None values)\nstop_ids = [eos_id]\nif im_end_id is not None:\n    stop_ids.append(im_end_id)\n\nprint(f\"Stopping on token IDs: {stop_ids}\")\n\n# --- 2. Corrected Inference Loop ---\npredictions = []\n\nfor i in tqdm(range(0, len(raw_prompts), BATCH_SIZE)):\n    batch_prompts = raw_prompts[i : i + BATCH_SIZE]\n    \n    inputs = tokenizer(\n        batch_prompts,\n        return_tensors=\"pt\", \n        padding=True, \n        truncation=True,\n        max_length=1024\n    ).to(model.device)\n\n    with torch.no_grad():\n        outputs = model.generate(\n            **inputs,\n            max_new_tokens=512,\n            do_sample=True,\n            temperature=0.9,\n            top_p=0.95,\n            top_k=20,\n            repetition_penalty=1.05,\n            pad_token_id=tokenizer.pad_token_id,\n            # Use the cleaned list of IDs here\n            eos_token_id=stop_ids, \n        )\n    \n    input_len = inputs.input_ids.shape[1]\n    generated_tokens = outputs[:, input_len:]\n    decoded_batch = tokenizer.batch_decode(generated_tokens, skip_special_tokens=True)\n    predictions.extend(decoded_batch)\nfinal_predictions = []\nfor text in predictions:\n    # Strip reasoning traces if present (DeepSeek/R1 style)\n    if \"</think>\" in text:\n        text = text.partition(\"</think>\")[2]\n    # Apply postprocessing normalization\n    print(text)\n    text = postprocess_output(text.strip().replace(r\"\\n\",\" \"))\n    print([text])\n    print(\"=\"*20)\n    final_predictions.append(text)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-24T02:51:57.564291Z","iopub.execute_input":"2026-02-24T02:51:57.565013Z","iopub.status.idle":"2026-02-24T02:52:07.490913Z","shell.execute_reply.started":"2026-02-24T02:51:57.564973Z","shell.execute_reply":"2026-02-24T02:52:07.490133Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission_df = pd.DataFrame(\n    {\"id\": test_df[\"id\"], \"translation\": final_predictions}\n)\n\nsubmission_df.to_csv(OUTPUT_CSV, index=False)\nprint(f\"Submission saved to {OUTPUT_CSV}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-24T02:52:11.70969Z","iopub.execute_input":"2026-02-24T02:52:11.71Z","iopub.status.idle":"2026-02-24T02:52:11.726027Z","shell.execute_reply.started":"2026-02-24T02:52:11.709975Z","shell.execute_reply":"2026-02-24T02:52:11.725265Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# !cat /kaggle/input/deep-past-initiative-machine-translation/test.csv","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-24T02:38:58.467332Z","iopub.status.idle":"2026-02-24T02:38:58.467774Z","shell.execute_reply.started":"2026-02-24T02:38:58.467606Z","shell.execute_reply":"2026-02-24T02:38:58.467649Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# !cat submission.csv","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-24T02:52:28.522306Z","iopub.execute_input":"2026-02-24T02:52:28.523079Z","iopub.status.idle":"2026-02-24T02:52:28.721304Z","shell.execute_reply.started":"2026-02-24T02:52:28.523038Z","shell.execute_reply":"2026-02-24T02:52:28.720408Z"}},"outputs":[],"execution_count":null}]}