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.
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
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_smandde_core_news_smtokenisers, andpaper.pdfin 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.