{"metadata":{"kernelspec":{"name":"python3","display_name":"Python 3","language":"python"},"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":"none","dataSources":[{"sourceType":"datasetVersion","sourceId":15270172,"datasetId":9768159,"databundleVersionId":16170089},{"sourceType":"datasetVersion","sourceId":15257466,"datasetId":9760662,"databundleVersionId":16156147}],"dockerImageVersionId":31286,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# # Deep Past Challenge - Translate Akkadian to English\n# This baseline notebook sets up the data processing, trains a hugging face sequence-to-sequence model and outputs the submission file over the Old Assyrian Cuneiform translation dataset.\n","metadata":{}},{"cell_type":"code","source":"# Cell 1: Check environment and locate files\nimport os\nimport pandas as pd\nimport re\n\nprint(\"=\" * 50)\nprint(\"ENVIRONMENT CHECK\")\nprint(\"=\" * 50)\n\n# Check current directory\ncurrent_dir = os.getcwd()\nprint(f\"Current directory: {current_dir}\")\n\n# Set the correct path for your dataset\nDATA_DIR = '/kaggle/input/datasets/abdullaharain786/deeppast'\nprint(f\"\\nLooking for dataset in: {DATA_DIR}\")\n\n# Check if directory exists\nif os.path.exists(DATA_DIR):\n    print(f\"✅ Dataset directory found!\")\n    \n    # List all files in the dataset directory\n    print(\"\\nFiles in dataset directory:\")\n    all_files = os.listdir(DATA_DIR)\n    for f in all_files:\n        print(f\"  - {f}\")\n        \n    # Look for CSV files\n    csv_files = [f for f in all_files if f.endswith('.csv')]\n    print(f\"\\n📊 CSV files found: {csv_files}\")\n    \n    # Try to find train and test files\n    train_file = None\n    test_file = None\n    \n    for f in csv_files:\n        if 'train' in f.lower():\n            train_file = f\n        elif 'test' in f.lower():\n            test_file = f\n    \n    if train_file and test_file:\n        print(f\"\\n✅ Found train file: {train_file}\")\n        print(f\"✅ Found test file: {test_file}\")\n        \n        TRAIN_PATH = os.path.join(DATA_DIR, train_file)\n        TEST_PATH = os.path.join(DATA_DIR, test_file)\n        \n        # Load the data\n        print(\"\\n\" + \"=\" * 50)\n        print(\"LOADING DATA\")\n        print(\"=\" * 50)\n        \n        try:\n            train_df = pd.read_csv(TRAIN_PATH)\n            test_df = pd.read_csv(TEST_PATH)\n            \n            print(f\"✅ Successfully loaded:\")\n            print(f\"   Train samples: {len(train_df)}\")\n            print(f\"   Test samples: {len(test_df)}\")\n            print(f\"\\nTrain columns: {list(train_df.columns)}\")\n            print(f\"Test columns: {list(test_df.columns)}\")\n            \n            # Show data preview\n            print(\"\\n\" + \"=\" * 50)\n            print(\"DATA PREVIEW\")\n            print(\"=\" * 50)\n            print(\"\\nFirst 3 rows of training data:\")\n            print(train_df.head(3))\n            \n            print(\"\\nFirst 3 rows of test data:\")\n            print(test_df.head(3))\n            \n            # Define preprocessing function\n            def preprocess_text(text):\n                if pd.isna(text):\n                    return ''\n                text = str(text)\n                text = text.replace('[x]', '<gap>')\n                text = text.replace('…', '<big_gap>')\n                text = text.replace('[… …]', '<big_gap>')\n                text = text.replace('Ḫ', 'H').replace('ḫ', 'h')\n                text = text.replace('<gap>', '__GAP__')\n                text = text.replace('<big_gap>', '__BIG_GAP__')\n                for c in ['!', '?', '/', ':', '.', '<', '>', '˹', '˺', '[', ']']:\n                    text = text.replace(c, '')\n                text = text.replace('__GAP__', '<gap>')\n                text = text.replace('__BIG_GAP__', '<big_gap>')\n                text = re.sub(r'\\s+', ' ', text).strip()\n                return text\n            \n            # Apply preprocessing\n            print(\"\\n\" + \"=\" * 50)\n            print(\"PREPROCESSING DATA\")\n            print(\"=\" * 50)\n            \n            # Check if columns exist\n            if 'transliteration' in train_df.columns and 'translation' in train_df.columns:\n                train_df['clean_transliteration'] = train_df['transliteration'].apply(preprocess_text)\n                train_df['clean_translation'] = train_df['translation'].apply(preprocess_text)\n                test_df['clean_transliteration'] = test_df['transliteration'].apply(preprocess_text)\n                \n                print(\"✅ Preprocessing complete!\")\n                print(\"\\nSample preprocessed text:\")\n                print(f\"Original: {train_df['transliteration'].iloc[0][:100]}...\")\n                print(f\"Cleaned: {train_df['clean_transliteration'].iloc[0][:100]}...\")\n                \n                print(\"\\n\" + \"=\" * 50)\n                print(\"✅ READY TO PROCEED - DATA LOADED SUCCESSFULLY!\")\n                print(\"=\" * 50)\n            else:\n                print(\"❌ Required columns not found!\")\n                print(f\"Available columns: {list(train_df.columns)}\")\n                \n        except Exception as e:\n            print(f\"❌ Error loading files: {e}\")\n    else:\n        print(\"\\n❌ Could not identify train/test files!\")\n        print(f\"Available files: {csv_files}\")\n        \n        # Manual input if needed\n        print(\"\\nPlease enter the filenames manually:\")\n        train_file = input(\"Train filename: \").strip()\n        test_file = input(\"Test filename: \").strip()\n        \n        if train_file and test_file:\n            TRAIN_PATH = os.path.join(DATA_DIR, train_file)\n            TEST_PATH = os.path.join(DATA_DIR, test_file)\n            # ... (rest of loading code)\nelse:\n    print(f\"❌ Dataset directory not found: {DATA_DIR}\")\n    print(\"\\nAvailable directories in /kaggle/input/:\")\n    try:\n        input_dirs = os.listdir('/kaggle/input/')\n        for d in input_dirs:\n            print(f\"  - {d}\")\n    except:\n        print(\"  Could not list directory\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-20T07:10:39.345359Z","iopub.execute_input":"2026-03-20T07:10:39.345640Z","iopub.status.idle":"2026-03-20T07:10:40.855158Z","shell.execute_reply.started":"2026-03-20T07:10:39.345611Z","shell.execute_reply":"2026-03-20T07:10:40.854140Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Cell 2: Install required packages (run once)\n!pip install datasets transformers accelerate sentencepiece","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-20T07:10:40.857247Z","iopub.execute_input":"2026-03-20T07:10:40.857533Z","iopub.status.idle":"2026-03-20T07:10:46.225348Z","shell.execute_reply.started":"2026-03-20T07:10:40.857505Z","shell.execute_reply":"2026-03-20T07:10:46.223975Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Cell 3: Import additional libraries\nfrom datasets import Dataset\nfrom transformers import (\n    AutoTokenizer, \n    AutoModelForSeq2SeqLM, \n    Seq2SeqTrainingArguments, \n    Seq2SeqTrainer, \n    DataCollatorForSeq2Seq\n)\nimport torch\nimport numpy as np\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-20T07:10:46.230305Z","iopub.execute_input":"2026-03-20T07:10:46.230725Z","iopub.status.idle":"2026-03-20T07:11:09.304546Z","shell.execute_reply.started":"2026-03-20T07:10:46.230677Z","shell.execute_reply":"2026-03-20T07:11:09.303714Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Preprocess Data\nCleaning text by applying the rules such as replacing `<gap>` markings, swapping out characters and removing unused bracketed items.","metadata":{}},{"cell_type":"code","source":"# Cell 4: Create Hugging Face datasets\nprint(\"Creating datasets...\")\n\n# Rename columns for Hugging Face\ntrain_dataset = Dataset.from_pandas(\n    train_df[['clean_transliteration', 'clean_translation']].rename(\n        columns={\n            'clean_transliteration': 'input_text', \n            'clean_translation': 'target_text'\n        }\n    )\n)\n\ntest_dataset = Dataset.from_pandas(\n    test_df[['id', 'clean_transliteration']].rename(\n        columns={\n            'clean_transliteration': 'input_text'\n        }\n    )\n)\n\n# Split training data into train and validation\ntrain_val_split = train_dataset.train_test_split(test_size=0.1, seed=42)\nprint(f\"Train size: {len(train_val_split['train'])}\")\nprint(f\"Validation size: {len(train_val_split['test'])}\")\nprint(f\"Test size: {len(test_dataset)}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-20T07:11:09.305679Z","iopub.execute_input":"2026-03-20T07:11:09.306285Z","iopub.status.idle":"2026-03-20T07:11:09.377658Z","shell.execute_reply.started":"2026-03-20T07:11:09.306250Z","shell.execute_reply":"2026-03-20T07:11:09.376711Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Cell 5: Load model and tokenizer using Kaggle's cached models or create from scratch\nimport os\nimport torch\nfrom transformers import AutoTokenizer, AutoModelForSeq2SeqLM, T5Config, T5ForConditionalGeneration\n\nprint(\"Checking available models...\")\n\nmodel_loaded = False\nmodel = None\ntokenizer = None\nmodel_name = None\n\n# First, try to use a pre-trained model from cache\ntry:\n    print(\"Attempting to use cached model...\")\n    # Try to load from transformers cache with local_files_only\n    tokenizer = AutoTokenizer.from_pretrained('t5-small', local_files_only=True)\n    model = AutoModelForSeq2SeqLM.from_pretrained('t5-small', local_files_only=True)\n    model_name = 't5-small'\n    model_loaded = True\n    print(\"✅ Loaded t5-small from cache!\")\nexcept:\n    print(\"No cached model found, creating custom model...\")\n\n# If no cached model, create from scratch\nif not model_loaded:\n    print(\"\\nCreating custom T5 model from scratch...\")\n    \n    # Install sentencepiece if needed\n    import subprocess\n    try:\n        import sentencepiece\n        print(\"✅ sentencepiece already installed\")\n    except:\n        print(\"Installing sentencepiece...\")\n        subprocess.run(['pip', 'install', 'sentencepiece'], capture_output=True)\n        import sentencepiece\n        print(\"✅ sentencepiece installed\")\n    \n    # Create T5 config\n    config = T5Config(\n        vocab_size=32128,\n        d_model=256,\n        d_kv=64,\n        d_ff=512,\n        num_layers=2,\n        num_heads=4,\n        relative_attention_num_buckets=32,\n        dropout_rate=0.1,\n        decoder_start_token_id=0,\n        pad_token_id=0,\n        eos_token_id=1,\n    )\n    \n    # Create model\n    model = T5ForConditionalGeneration(config)\n    model_name = 'custom-t5-mini'\n    \n    # Create tokenizer using sentencepiece or simple tokenizer\n    try:\n        # Try to create a simple tokenizer\n        from transformers import AutoTokenizer\n        \n        # Use a simple character-level tokenizer\n        from transformers import PreTrainedTokenizerFast\n        \n        # Define vocabulary\n        vocab = [\"<pad>\", \"</s>\", \"<unk>\", \"<s>\", \"<mask>\", \"<gap>\", \"<big_gap>\"]\n        \n        # Add common characters\n        chars = \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 .,;:!?()[]{}\"\n        vocab.extend(list(chars))\n        \n        # Add common Akkadian characters\n        akkadian_chars = \"āēīūšḫṣṭ\"\n        vocab.extend(list(akkadian_chars))\n        \n        # Create vocabulary dictionary\n        vocab_dict = {word: i for i, word in enumerate(vocab)}\n        \n        # Create tokenizer from vocabulary\n        tokenizer = PreTrainedTokenizerFast(\n            tokenizer_object=None,\n            vocab=vocab_dict,\n            unk_token=\"<unk>\",\n            pad_token=\"<pad>\",\n            eos_token=\"</s>\",\n            bos_token=\"<s>\",\n            mask_token=\"<mask>\",\n        )\n        \n        print(f\"✅ Created tokenizer with vocabulary size: {len(tokenizer)}\")\n        \n    except Exception as e:\n        print(f\"Error creating tokenizer: {e}\")\n        # Last resort: use a simple tokenizer\n        class SimpleTokenizer:\n            def __init__(self):\n                self.pad_token = \"<pad>\"\n                self.eos_token = \"</s>\"\n                self.unk_token = \"<unk>\"\n                self.pad_token_id = 0\n                self.eos_token_id = 1\n                self.unk_token_id = 2\n                self.vocab = {self.pad_token: 0, self.eos_token: 1, self.unk_token: 2}\n                self.inv_vocab = {0: self.pad_token, 1: self.eos_token, 2: self.unk_token}\n                self.vocab_size = 3\n                \n            def __call__(self, text, padding=False, truncation=False, max_length=None, return_tensors=None):\n                # Simple character-level tokenization\n                tokens = list(str(text))\n                input_ids = [self.vocab.get(t, self.unk_token_id) for t in tokens]\n                \n                # Truncate if needed\n                if truncation and max_length:\n                    input_ids = input_ids[:max_length]\n                \n                # Pad if needed\n                if padding and max_length:\n                    input_ids = input_ids + [self.pad_token_id] * (max_length - len(input_ids))\n                \n                result = {'input_ids': torch.tensor([input_ids])}\n                if return_tensors == 'pt':\n                    result['attention_mask'] = torch.ones_like(result['input_ids'])\n                return result\n                \n            def batch_decode(self, sequences, skip_special_tokens=True):\n                texts = []\n                for seq in sequences:\n                    tokens = [self.inv_vocab.get(id.item(), self.unk_token) for id in seq]\n                    texts.append(''.join(tokens).replace(self.pad_token, ''))\n                return texts\n                \n            def save_pretrained(self, path):\n                pass\n        \n        tokenizer = SimpleTokenizer()\n        print(\"✅ Created simple character-level tokenizer\")\n    \n    model_loaded = True\n    print(\"✅ Custom model created successfully!\")\n\n# Add special tokens if tokenizer supports it\nif hasattr(tokenizer, 'add_special_tokens'):\n    try:\n        special_tokens = ['<gap>', '<big_gap>']\n        tokenizer.add_special_tokens({'additional_special_tokens': special_tokens})\n        if hasattr(model, 'resize_token_embeddings'):\n            model.resize_token_embeddings(len(tokenizer))\n        print(f\"✅ Added special tokens: {special_tokens}\")\n    except Exception as e:\n        print(f\"⚠️ Could not add special tokens: {e}\")\n\nprint(f\"\\n\" + \"=\"*50)\nprint(\"MODEL SUMMARY\")\nprint(\"=\"*50)\nprint(f\"Model: {model_name}\")\nprint(f\"Model type: {type(model).__name__}\")\nprint(f\"Tokenizer type: {type(tokenizer).__name__}\")\nprint(f\"Vocabulary size: {len(tokenizer)}\")\nprint(f\"Device: {'cuda' if torch.cuda.is_available() else 'cpu'}\")\n\n# Count parameters\nif hasattr(model, 'parameters'):\n    params = sum(p.numel() for p in model.parameters())\n    print(f\"Parameters: {params/1e6:.2f}M\")\n\n# Test if model works\nprint(\"\\nTesting model...\")\ntry:\n    test_text = \"test\"\n    test_input = tokenizer(test_text, return_tensors=\"pt\", padding=True, truncation=True, max_length=10)\n    # Move to device\n    test_input = {k: v.to(model.device) for k, v in test_input.items()}\n    \n    with torch.no_grad():\n        test_output = model.generate(**test_input, max_length=5)\n    print(\"✅ Model test passed!\")\nexcept Exception as e:\n    print(f\"⚠️ Model test warning: {e}\")\n\nprint(\"\\n✅ Model ready for training!\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-20T07:36:37.729694Z","iopub.execute_input":"2026-03-20T07:36:37.730136Z","iopub.status.idle":"2026-03-20T07:36:38.224931Z","shell.execute_reply.started":"2026-03-20T07:36:37.730101Z","shell.execute_reply":"2026-03-20T07:36:38.224106Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Cell 6: Tokenization function\ndef tokenize_function(examples):\n    # Tokenize inputs\n    model_inputs = tokenizer(\n        examples['input_text'], \n        max_length=128, \n        truncation=True,\n        padding=False\n    )\n    \n    # Tokenize targets (for training data)\n    if 'target_text' in examples:\n        labels = tokenizer(\n            examples['target_text'], \n            max_length=128, \n            truncation=True,\n            padding=False\n        )\n        model_inputs['labels'] = labels['input_ids']\n    \n    return model_inputs\n\n# Apply tokenization\nprint(\"Tokenizing datasets...\")\ntokenized_train = train_val_split['train'].map(\n    tokenize_function, \n    batched=True,\n    remove_columns=train_val_split['train'].column_names\n)\n\ntokenized_val = train_val_split['test'].map(\n    tokenize_function, \n    batched=True,\n    remove_columns=train_val_split['test'].column_names\n)\n\n# Create data collator\ndata_collator = DataCollatorForSeq2Seq(\n    tokenizer=tokenizer,\n    model=model,\n    padding=True\n)\n\nprint(\"Tokenization complete!\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-20T07:36:44.989416Z","iopub.execute_input":"2026-03-20T07:36:44.990221Z","iopub.status.idle":"2026-03-20T07:36:45.595960Z","shell.execute_reply.started":"2026-03-20T07:36:44.990188Z","shell.execute_reply":"2026-03-20T07:36:45.595057Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# ### Modeling\n# Load `mt5-small` model and tokenize text ensuring custom gap tokens are preserved.","metadata":{}},{"cell_type":"code","source":"# Cell 7: Set up training arguments with compatibility fixes\nimport transformers\nfrom packaging import version\n\n# Check if CUDA is available\ndevice = \"cuda\" if torch.cuda.is_available() else \"cpu\"\nprint(f\"Using device: {device}\")\nprint(f\"Transformers version: {transformers.__version__}\")\n\n# Base arguments that work in all versions\ntraining_args_dict = {\n    'output_dir': './results',\n    'num_train_epochs': 3,\n    'per_device_train_batch_size': 8,\n    'per_device_eval_batch_size': 8,\n    'learning_rate': 3e-4,\n    'weight_decay': 0.01,\n    'logging_dir': './logs',\n    'logging_steps': 100,\n    'save_total_limit': 2,\n    'predict_with_generate': True,\n    'fp16': torch.cuda.is_available(),\n    'remove_unused_columns': False,\n}\n\n# Check which parameters are supported\ntransformers_version = transformers.__version__\nis_new_version = version.parse(transformers_version) >= version.parse(\"4.4.0\")\n\nif is_new_version:\n    print(\"Using new transformers version with evaluation_strategy\")\n    training_args_dict['evaluation_strategy'] = 'epoch'\n    training_args_dict['save_strategy'] = 'epoch'\n    training_args_dict['load_best_model_at_end'] = True\n    training_args_dict['metric_for_best_model'] = 'loss'\n    training_args_dict['greater_is_better'] = False\n    training_args_dict['report_to'] = 'none'\nelse:\n    print(\"Using older transformers version with eval_steps\")\n    # Calculate steps per epoch (approximate)\n    steps_per_epoch = len(tokenized_train) // 8  # batch size\n    training_args_dict['eval_steps'] = steps_per_epoch\n    training_args_dict['save_steps'] = steps_per_epoch\n    \n    # For very old versions\n    if version.parse(transformers_version) < version.parse(\"4.0.0\"):\n        training_args_dict['evaluate_during_training'] = True\n\n# Filter out None values\ntraining_args_dict = {k: v for k, v in training_args_dict.items() if v is not None}\n\n# Create training arguments with error handling\ntry:\n    training_args = Seq2SeqTrainingArguments(**training_args_dict)\n    print(\"Training arguments configured successfully!\")\nexcept TypeError as e:\n    print(f\"Error with arguments: {e}\")\n    print(\"Trying with minimal arguments...\")\n    \n    # Minimal fallback arguments\n    minimal_args = {\n        'output_dir': './results',\n        'num_train_epochs': 3,\n        'per_device_train_batch_size': 8,\n        'per_device_eval_batch_size': 8,\n        'learning_rate': 3e-4,\n        'logging_dir': './logs',\n        'remove_unused_columns': False,\n    }\n    training_args = Seq2SeqTrainingArguments(**minimal_args)\n    print(\"Minimal arguments configured successfully!\")\n\nprint(\"\\nFinal training arguments:\")\nfor key, value in training_args.to_dict().items():\n    if key in ['output_dir', 'num_train_epochs', 'per_device_train_batch_size', \n               'learning_rate', 'evaluation_strategy', 'eval_steps']:\n        print(f\"  {key}: {value}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-20T07:36:50.071494Z","iopub.execute_input":"2026-03-20T07:36:50.071885Z","iopub.status.idle":"2026-03-20T07:36:50.086674Z","shell.execute_reply.started":"2026-03-20T07:36:50.071854Z","shell.execute_reply":"2026-03-20T07:36:50.085901Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Cell 8: Create trainer\nfrom transformers import Seq2SeqTrainer\n\n# Check if tokenizer parameter is supported\nimport inspect\n\n# Get the signature of Seq2SeqTrainer.__init__\nsig = inspect.signature(Seq2SeqTrainer.__init__)\nprint(f\"Supported parameters: {list(sig.parameters.keys())}\")\n\n# Create trainer based on supported parameters\nif 'tokenizer' in sig.parameters:\n    # Newer versions support tokenizer parameter\n    trainer = Seq2SeqTrainer(\n        model=model,\n        args=training_args,\n        train_dataset=tokenized_train,\n        eval_dataset=tokenized_val,\n        tokenizer=tokenizer,\n        data_collator=data_collator\n    )\n    print(\"Created trainer with tokenizer parameter\")\nelse:\n    # Older versions don't support tokenizer parameter\n    trainer = Seq2SeqTrainer(\n        model=model,\n        args=training_args,\n        train_dataset=tokenized_train,\n        eval_dataset=tokenized_val,\n        data_collator=data_collator\n    )\n    print(\"Created trainer without tokenizer parameter\")\n    \n    # Set tokenizer separately if needed\n    if hasattr(trainer, 'tokenizer'):\n        trainer.tokenizer = tokenizer\n\nprint(\"Trainer created successfully!\")\nprint(f\"Trainer type: {type(trainer)}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-20T07:37:00.014001Z","iopub.execute_input":"2026-03-20T07:37:00.014348Z","iopub.status.idle":"2026-03-20T07:37:00.029908Z","shell.execute_reply.started":"2026-03-20T07:37:00.014312Z","shell.execute_reply":"2026-03-20T07:37:00.028826Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Cell 9: Train the model\nprint(\"=\" * 50)\nprint(\"STARTING TRAINING\")\nprint(\"=\" * 50)\n\ntrainer.train()\n\nprint(\"=\" * 50)\nprint(\"TRAINING COMPLETE!\")\nprint(\"=\" * 50)\n\n# Save the model\nmodel_save_path = './final_model'\ntrainer.save_model(model_save_path)\ntokenizer.save_pretrained(model_save_path)\nprint(f\"Model saved to {model_save_path}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-20T07:37:05.187773Z","iopub.execute_input":"2026-03-20T07:37:05.188134Z","iopub.status.idle":"2026-03-20T07:39:58.257727Z","shell.execute_reply.started":"2026-03-20T07:37:05.188102Z","shell.execute_reply":"2026-03-20T07:39:58.256816Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Cell 10: Inference function\ndef generate_translation(batch):\n    # Tokenize inputs\n    inputs = tokenizer(\n        batch['input_text'], \n        padding=True, \n        truncation=True, \n        max_length=128,\n        return_tensors='pt'\n    )\n    \n    # Move to same device as model\n    inputs = {k: v.to(model.device) for k, v in inputs.items()}\n    \n    # Generate translations\n    with torch.no_grad():\n        outputs = model.generate(\n            **inputs,\n            max_length=128,\n            num_beams=4,  # Beam search for better quality\n            early_stopping=True,\n            no_repeat_ngram_size=3\n        )\n    \n    # Decode predictions\n    batch['predicted_translation'] = tokenizer.batch_decode(\n        outputs, \n        skip_special_tokens=True\n    )\n    return batch\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-20T07:41:00.288995Z","iopub.execute_input":"2026-03-20T07:41:00.289402Z","iopub.status.idle":"2026-03-20T07:41:00.296714Z","shell.execute_reply.started":"2026-03-20T07:41:00.289358Z","shell.execute_reply":"2026-03-20T07:41:00.295647Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Cell 11: Run inference on test set\nprint(\"Generating translations for test set...\")\nresults = test_dataset.map(\n    generate_translation, \n    batched=True, \n    batch_size=8\n)\n\nprint(f\"Generated {len(results)} translations\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-20T07:41:06.001475Z","iopub.execute_input":"2026-03-20T07:41:06.001936Z","iopub.status.idle":"2026-03-20T07:41:07.735667Z","shell.execute_reply.started":"2026-03-20T07:41:06.001903Z","shell.execute_reply":"2026-03-20T07:41:07.734929Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Cell 12: Create submission file\nsubmission = pd.DataFrame({\n    'id': results['id'],\n    'translation': results['predicted_translation']\n})\n\n# Fill any missing translations\nsubmission['translation'] = submission['translation'].fillna('No translation available.')\n\n# Save submission\nsubmission_path = './submission.csv'\nsubmission.to_csv(submission_path, index=False)\nprint(f\"Submission file saved to {submission_path}\")\n\n# Show sample predictions\nprint(\"\\n\" + \"=\" * 50)\nprint(\"SAMPLE PREDICTIONS\")\nprint(\"=\" * 50)\nprint(submission.head(10))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-20T07:41:11.540399Z","iopub.execute_input":"2026-03-20T07:41:11.541280Z","iopub.status.idle":"2026-03-20T07:41:11.559438Z","shell.execute_reply.started":"2026-03-20T07:41:11.541247Z","shell.execute_reply":"2026-03-20T07:41:11.558375Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Cell 13: Optional - Validate on training data\nprint(\"\\n\" + \"=\" * 50)\nprint(\"VALIDATION SAMPLES\")\nprint(\"=\" * 50)\n\ndef validate_sample(batch):\n    inputs = tokenizer(\n        batch['input_text'], \n        padding=True, \n        truncation=True, \n        max_length=128,\n        return_tensors='pt'\n    ).to(model.device)\n    \n    with torch.no_grad():\n        outputs = model.generate(\n            **inputs,\n            max_length=128,\n            num_beams=4,\n            early_stopping=True\n        )\n    \n    batch['predicted'] = tokenizer.batch_decode(outputs, skip_special_tokens=True)\n    return batch\n\n# Get validation predictions\nval_results = train_val_split['test'].select(range(10)).map(\n    validate_sample,\n    batched=True,\n    batch_size=8\n)\n\n# Show comparison\nfor i in range(len(val_results)):\n    print(f\"\\nInput: {val_results[i]['input_text']}\")\n    print(f\"Actual: {val_results[i]['target_text']}\")\n    print(f\"Predicted: {val_results[i]['predicted']}\")\n    print(\"-\" * 50)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-20T07:41:16.561479Z","iopub.execute_input":"2026-03-20T07:41:16.561853Z","iopub.status.idle":"2026-03-20T07:41:19.666998Z","shell.execute_reply.started":"2026-03-20T07:41:16.561821Z","shell.execute_reply":"2026-03-20T07:41:19.666191Z"}},"outputs":[],"execution_count":null}]}