Discord

Checklist OAI 2024 Stage II – Implementation Contest · Task 1

Machine Translation

Polish title: Tłumaczenia maszynowe

Implement and train the attention-based encoder–decoder of Bahdanau et al. ("Neural Machine Translation by Jointly Learning to Align and Translate") for German–English translation on Multi30k.

  • NLP
  • Paper reproduction (sequence-to-sequence translation with attention)
  • Polish original · English translation

The task

The contestant implements the method described in the paper "Neural machine translation by jointly learning to align and translate" (supplied as paper.pdf) and simplifies its reproduction. Points are awarded for implementing and training the model, computing appropriate metrics, and carrying out additional experiments and visualisations; code clarity, readability and the appearance of plots are also assessed, and the implementation is judged for fidelity to the paper.

The model is trained on a parallel corpus of English and German sentences (the bentrevett/multi30k dataset loaded with the datasets library); data loaders, spaCy tokenisers and vocabularies are prepared in the starter code, with German as the source and English as the target language.

Subtasks: (1) implement the model exactly as in the paper — Encoder, Attention, Decoder and Seq2Seq (7 points); (2) train it, monitor and plot training and validation loss, evaluate on the test split with suitable metrics (for example those used in the paper) and show correct and incorrect translations (3 points); (3) visualise learned attention maps for interesting sentences (1 point); (4) additional experiments such as model modifications or ablations (2 points).

Abridged and translated by SOTA from the official Polish materials. The official statement has the exact rules, and it wins wherever this summary differs.

In English

This task was published in Polish. SOTA translated it into English on 16 September 2026. Only the words changed in the notebooks: markdown, code comments, messages and printed output. The code, file names and paths are the original's, so a translated notebook runs with the original data.

Read the task notebook in English 425 words and 19 code cells

Machine translation

In today's contest, your task will be to implement the method described in the paper "Neural machine translation by jointly learning to align and translate". You will receive points for implementing and training the model, computing the appropriate metrics, and carrying out additional experiments and visualisations. While working, you should take care of the clarity and readability of your code, as well as the aesthetics of the plots you present. Your implementation will be assessed for its fidelity to the publication.

Contest rules

You must observe the following rules:

  • You may not use the Internet. The exceptions are the OpenAI API, the PyTorch documentation and the Olympiad's Google Classroom.
  • You may not use Copilot or any other models that help write code, other than models from the GPT3.5 family.
  • You may not use your own notes: neither handwritten notes nor files on your computer (including, in particular, code downloaded to your computer).
  • You may not connect to computing resources other than Google Colab with a T4 GPU.

Task and scoring

You will train the models on a dataset containing pairs of sentences in English and German (parallel corpus). Remember good coding practices and correct formatting; they will affect your score. On the basis of the attached paper, complete the following subtasks.

Subtask 1: Model implementation (7 pts)

In this section we ask you to implement the method from the paper very precisely.

Subtask 2: Model training (3 pts)

Train the model on the provided dataset (the dataloaders are already implemented in the starter code). During training, make sure to monitor both the training loss and the validation loss. Then plot these losses as a function of the iteration. Evaluate the trained model on the test subset of the provided dataset using appropriate metrics. You may use the metrics used in the paper. Present examples of both correct and incorrect translations.

Subtask 3: Attention visualisation (1 pt)

Present visualisations of the learned attention maps on examples of interesting sentences. You may model them on the plots in the paper.

Subtask 4: Additional experiments (2 pts)

If you have ideas for additional interesting experiments, you can receive extra points for them. You may consider modifications of the model, ablations and other things.

Remarks

  • You may change the signatures of functions and classes, as well as the code structure we propose below. Remember good practices, however.

Starter code

! pip install datasets
! pip install evaluate
! pip install torchtext

# Download the embedding models
! python -m spacy download en_core_web_sm 
! python -m spacy download de_core_news_sm
import random

import datasets
import evaluate
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import numpy as np
import spacy
import torch
import torch.nn as nn

import torchtext; torchtext.disable_torchtext_deprecation_warning()
import torchtext.vocab; torchtext.disable_torchtext_deprecation_warning()

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
######################### DO NOT CHANGE THIS CELL ##########################
seed = 1234

random.seed(seed)
np.random.seed(seed)
torch.manual_seed(seed)
torch.cuda.manual_seed(seed)
torch.backends.cudnn.deterministic = True

Datasets

We have prepared dataloaders and tokenizers for you.

######################### DO NOT CHANGE THIS CELL ##########################
dataset = datasets.load_dataset("bentrevett/multi30k")

en_nlp = spacy.load("en_core_web_sm")
de_nlp = spacy.load("de_core_news_sm")

sos_token = "<sos>"
eos_token = "<eos>"


def tokenize_example(example, max_length=1000):
    en_tokens = [token.text.lower() for token in en_nlp.tokenizer(example["en"])][:max_length]
    de_tokens = [token.text.lower() for token in de_nlp.tokenizer(example["de"])][:max_length]

    en_tokens = [sos_token] + en_tokens + [eos_token]
    de_tokens = [sos_token] + de_tokens + [eos_token]
    return {"en_tokens": en_tokens, "de_tokens": de_tokens}


train_data = dataset["train"].map(tokenize_example)
valid_data = dataset["validation"].map(tokenize_example)
test_data = dataset["test"].map(tokenize_example)
######################### DO NOT CHANGE THIS CELL ##########################
min_freq = 2
unk_token = "<unk>"
pad_token = "<pad>"

special_tokens = [unk_token, pad_token, sos_token, eos_token]

en_vocab = torchtext.vocab.build_vocab_from_iterator(
    train_data["en_tokens"],
    min_freq=min_freq,
    specials=special_tokens,
)

de_vocab = torchtext.vocab.build_vocab_from_iterator(
    train_data["de_tokens"],
    min_freq=min_freq,
    specials=special_tokens,
)

assert en_vocab[unk_token] == de_vocab[unk_token]
assert en_vocab[pad_token] == de_vocab[pad_token]

unk_index = en_vocab[unk_token]
pad_index = en_vocab[pad_token]

en_vocab.set_default_index(unk_index)
de_vocab.set_default_index(unk_index)
######################### DO NOT CHANGE THIS CELL ##########################
def numericalize_example(example):
    en_ids = en_vocab.lookup_indices(example["en_tokens"])
    de_ids = de_vocab.lookup_indices(example["de_tokens"])
    return {"en_ids": en_ids, "de_ids": de_ids}

train_data = train_data.map(numericalize_example)
valid_data = valid_data.map(numericalize_example)
test_data = test_data.map(numericalize_example)
######################### DO NOT CHANGE THIS CELL ##########################
format_columns = ["en_ids", "de_ids"]

train_data = train_data.with_format(
    type="torch", columns=format_columns, output_all_columns=True
)

valid_data = valid_data.with_format(
    type="torch",
    columns=format_columns,
    output_all_columns=True,
)

test_data = test_data.with_format(
    type="torch",
    columns=format_columns,
    output_all_columns=True,
)
######################### DO NOT CHANGE THIS CELL ##########################
BATCH_SIZE = 128

def get_data_loader(dataset, batch_size, pad_index, shuffle=False):
    def collate_fn(batch):
        batch_en_ids = [example["en_ids"] for example in batch]
        batch_de_ids = [example["de_ids"] for example in batch]
        batch_en_ids = nn.utils.rnn.pad_sequence(batch_en_ids, padding_value=pad_index)
        batch_de_ids = nn.utils.rnn.pad_sequence(batch_de_ids, padding_value=pad_index)
        batch = {
            "en_ids": batch_en_ids,
            "de_ids": batch_de_ids,
        }
        return batch

    data_loader = torch.utils.data.DataLoader(
        dataset=dataset,
        batch_size=batch_size,
        collate_fn=collate_fn,
        shuffle=shuffle,
    )
    return data_loader

train_data_loader = get_data_loader(train_data, BATCH_SIZE, pad_index, shuffle=True)
valid_data_loader = get_data_loader(valid_data, BATCH_SIZE, pad_index)
test_data_loader = get_data_loader(test_data, BATCH_SIZE, pad_index)

Subtask 1: Model implementation

class Encoder(nn.Module):
    def __init__(self, input_dim, embedding_dim, encoder_hidden_dim, decoder_hidden_dim, dropout):
        super().__init__()
        # TODO

    def forward(self, src):
        # TODO
        return outputs, hidden
class Attention(nn.Module):
    def __init__(self, encoder_hidden_dim, decoder_hidden_dim):
        super().__init__()
        # TODO

    def forward(self, hidden, encoder_outputs):
        # TODO
        return result
class Decoder(nn.Module):
    def __init__(
        self,
        output_dim,
        embedding_dim,
        encoder_hidden_dim,
        decoder_hidden_dim,
        dropout,
        attention,
    ):
        super().__init__()
        # TODO

    def forward(self, input, hidden, encoder_outputs):
        # TODO
        return prediction, hidden, attention
class Seq2Seq(nn.Module):
    def __init__(self, encoder, decoder):
        super().__init__()
        # TODO

    def forward(self, src, trg):
        # TODO
        return outputs
input_dim = len(de_vocab)
output_dim = len(en_vocab)
encoder_embedding_dim = 256
decoder_embedding_dim = 256
encoder_hidden_dim = 512
decoder_hidden_dim = 512
encoder_dropout = 0.5
decoder_dropout = 0.5

attention = ...  # TODO
encoder = ...  # TODO
decoder = ...  # TODO
model = ...  # TODO

Subtask 2: Model training

# TODO: Write the training loop. Remember to collect training and validation statistics.

# TODO: Train the model on the provided dataset
# TODO: Plot the loss function
# TODO: Evaluate the model on the test set
def translate_sentence(sentence, model):
    # TODO
    return en_tokens, de_tokens, attention


# TODO: Translation examples

Subtask 3: Attention visualisation

def plot_attention(sentence, translation, attention):
    # TODO


# TODO: Attention visualisation

Subtask 4: Additional experiments

# TODO

Translated by SOTA. The Polish original is the official version and wins wherever the two differ. An open-ended implementation task graded by hand: students reimplement Bahdanau et al., "Neural machine translation by jointly learning to align and translate". The notebook refers to the paper as attached but does not link it. If you organise this olympiad and would like the translation removed, email [email protected] and we will take it down.

At a glance

You get
The bentrevett/multi30k dataset (Hugging Face), spaCy en_core_web_sm and de_core_news_sm tokenisers, and paper.pdf in the task folder.
You submit
The completed notebook with implementation, training, evaluation, attention visualisations and experiments.
Scoring
Manual assessment: up to 7 points for the implementation, 3 for training and evaluation, 1 for attention visualisation and 2 for additional experiments (13 in total), taking code quality and fidelity to the paper into account.
Rules
  • No Internet access, except the OpenAI API, the PyTorch documentation and the Olympiad's Google Classroom.
  • No Copilot or other code-assistant models, except models from the GPT-3.5 family.
  • No personal notes, handwritten or on the computer (including downloaded code).
  • Only Google Colab with a T4 GPU may be used as a compute resource.
Format
Implementation contest held during the Stage II final camp in Krzyżowa, 15–21 June 2024; the site reports two participants distinguished in this contest.

Details

Year
2024, Krzyżowa, Poland
Round
Stage II – Implementation Contest · Task 1
Language
Polish; English translation by SOTA
License
Not stated by the source