{"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":[{"sourceId":121150,"databundleVersionId":15061024,"isSourceIdPinned":false,"sourceType":"competition"},{"sourceId":723801,"sourceType":"modelInstanceVersion","isSourceIdPinned":false,"modelInstanceId":550779,"modelId":563404},{"sourceId":721543,"sourceType":"modelInstanceVersion","isSourceIdPinned":false,"modelInstanceId":543118,"modelId":556282}],"dockerImageVersionId":31260,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# ============================================================================\n# BULLETPROOF INFERENCE SCRIPT\n# ============================================================================\nimport sys\nimport os\nimport glob\nimport torch\nimport pandas as pd\nimport numpy as np\nfrom tqdm.auto import tqdm\nfrom transformers import AutoTokenizer, AutoModelForSeq2SeqLM\nimport gc\n\n# --- 1. CONFIGURATION (CRITICAL: UPDATE PATHS) ---\nclass Config:\n    # 🔴 UPDATE THIS: Path to the ByT5 Model you added (Check Input sidebar!)\n    BYT5_MODEL_PATH = \"/kaggle/input/byt5-small/transformers/default/1\" \n    \n    # 🔴 UPDATE THIS: Path to your FLAN-T5 Model\n    FLANT5_MODEL_PATH = \"/kaggle/input/flan-t5-small-kf-cleaned/pytorch/default/2\"\n    \n    TEST_CSV = \"/kaggle/input/deep-past-initiative-machine-translation/test.csv\"\n    OUTPUT_FILE = \"/kaggle/working/submission.csv\"\n\n# --- 2. OFFLINE LIBS ---\nwheel_files = glob.glob('/kaggle/input/**/*.whl', recursive=True)\nif wheel_files:\n    for whl in wheel_files:\n        !pip install \"{whl}\" --no-deps --quiet\n\n# --- 3. MODEL LOADING (WITH FAIL-SAFE) ---\nprint(\"⚙️ Loading Models...\")\nmodels_loaded = False\n\ntry:\n    # Load ByT5\n    print(f\"  -> Loading ByT5: {Config.BYT5_MODEL_PATH}\")\n    if not os.path.exists(Config.BYT5_MODEL_PATH):\n        raise FileNotFoundError(f\"Path not found: {Config.BYT5_MODEL_PATH}\")\n    \n    tokenizer_byt5 = AutoTokenizer.from_pretrained(Config.BYT5_MODEL_PATH)\n    model_byt5 = AutoModelForSeq2SeqLM.from_pretrained(Config.BYT5_MODEL_PATH).to(\"cuda\")\n    model_byt5.eval()\n\n    # Load FLAN-T5\n    print(f\"  -> Loading FLAN-T5: {Config.FLANT5_MODEL_PATH}\")\n    if not os.path.exists(Config.FLANT5_MODEL_PATH):\n        raise FileNotFoundError(f\"Path not found: {Config.FLANT5_MODEL_PATH}\")\n        \n    tokenizer_flan = AutoTokenizer.from_pretrained(Config.FLANT5_MODEL_PATH)\n    model_flan = AutoModelForSeq2SeqLM.from_pretrained(Config.FLANT5_MODEL_PATH).to(\"cuda\")\n    model_flan.eval()\n    \n    models_loaded = True\n    print(\"✓ Models loaded successfully.\")\n\nexcept Exception as e:\n    print(f\"\\n❌ CRITICAL ERROR LOADING MODELS: {e}\")\n    print(\"⚠️ GENERATING DUMMY SUBMISSION TO ALLOW DEBUGGING.\")\n    models_loaded = False\n\n# --- 4. PREDICTION LOOP ---\ntest_df = pd.read_csv(Config.TEST_CSV)\nsrc_col = [c for c in test_df.columns if 'transliteration' in c.lower() or 'source' in c.lower()][0]\ntest_df[src_col] = test_df[src_col].fillna(\"\")\n\npredictions = []\n\nif models_loaded:\n    print(f\"🚀 Generating predictions for {len(test_df)} rows...\")\n    for text in tqdm(test_df[src_col]):\n        try:\n            # 1. ByT5\n            in_b = tokenizer_byt5(str(text), return_tensors=\"pt\", max_length=1024, truncation=True).to(\"cuda\")\n            out_b = model_byt5.generate(**in_b, max_length=1024, num_beams=5, repetition_penalty=1.2, no_repeat_ngram_size=3)\n            pred_b = tokenizer_byt5.decode(out_b[0], skip_special_tokens=True)\n            \n            # 2. FLAN-T5\n            in_f = tokenizer_flan(\"Translate to English: \" + str(text), return_tensors=\"pt\", max_length=512, truncation=True).to(\"cuda\")\n            out_f = model_flan.generate(**in_f, max_length=200, num_beams=5, repetition_penalty=1.2, no_repeat_ngram_size=3)\n            pred_f = tokenizer_flan.decode(out_f[0], skip_special_tokens=True)\n            \n            # 3. Ensemble Decision\n            # If ByT5 is too short or empty, use Flan. Else ByT5.\n            if len(pred_b) < len(pred_f) * 0.5 or not pred_b.strip():\n                predictions.append(pred_f)\n            else:\n                predictions.append(pred_b)\n                \n        except Exception as e:\n            predictions.append(\"\") # Fallback for bad row\nelse:\n    # FAIL-SAFE: Generate Dummy Data if models failed\n    print(\"⚠️ Filling with dummy data so 'submission.csv' is created.\")\n    predictions = [\"Error_Check_Logs\"] * len(test_df)\n\n# --- 5. SAVE SUBMISSION (ALWAYS RUNS) ---\nif 'id' in test_df.columns:\n    submission = pd.DataFrame({'id': test_df['id'], 'translation': predictions})\nelse:\n    submission = pd.DataFrame({'id': range(len(predictions)), 'translation': predictions})\n\nsubmission.to_csv(Config.OUTPUT_FILE, index=False)\nprint(f\"✅ Saved: {Config.OUTPUT_FILE} (Rows: {len(submission)})\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-22T18:16:17.139298Z","iopub.execute_input":"2026-01-22T18:16:17.139500Z","iopub.status.idle":"2026-01-22T18:17:17.481820Z","shell.execute_reply.started":"2026-01-22T18:16:17.139478Z","shell.execute_reply":"2026-01-22T18:17:17.481160Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}