MAMMOTH Sharing Schemes¶
MAMMOTH is designed as a flexible modular system, allowing users to configure, train, and test various sharing schemes. This tutorial walks through setting up and experimenting with different sharing schemes, including:
fully shared
fully unshared
encoder shared
decoder shared
modular (partially shared) stacks
The scheme is controlled entirely by the YAML config, so switching between schemes never requires a code change.
The commands below follow the ready-to-use setups in csc_env/ for the CSC supercomputers (LUMI with AMD MI250X, and Roihu with NVIDIA GH200). The same configs work on any SLURM cluster, or on a single workstation GPU, once you adapt the paths.
Data and Tokenizers¶
Each translation task needs:
Parallel training data — one source file and one target file per task (plain text or
.gz, one sentence per line, line-aligned).Validation data (Optional) — a source/target pair per task (the
csc_envconfigs use FLORES-200dev).One HuggingFace tokenizer per language (
tokenizer.json). MAMMOTH uses separate source and target vocabularies:src_vocabtokenizes the input,tgt_vocabtokenizes the output. HuggingFace tokenizer is suggested while SentencePiece model is also supported as a legacy option.
Language codes are arbitrary strings (such as eng, spa, fin); they are used as keys in src_vocab/tgt_vocab and inside the sharing groups.
Example Configuration¶
A complete single-task config (csc_env/lumi/single_node.yaml; csc_env/roihu/single_node.yaml is identical apart from the paths). Adapt the paths to your machine:
tasks:
eng-spa:
src_tgt: "eng-spa"
weight: 1 # relative sampling weight of this task
introduce_at_training_step: 0 # step at which the task starts being sampled
node_gpu: "0:0" # "node:gpu" this task is placed on
enc_sharing_group: ["eng"]
dec_sharing_group: ["spa"]
transforms: [filtertoolong]
path_src: /path/to/train.eng.gz
path_tgt: /path/to/train.spa.gz
path_valid_src: /path/to/flores200/dev/eng_Latn.dev
path_valid_tgt: /path/to/flores200/dev/spa_Latn.dev
src_vocab:
eng: /path/to/tokenizer/eng/32000/tokenizer.json
tgt_vocab:
spa: /path/to/tokenizer/spa/32000/tokenizer.json
# Model architecture
enc_layers: [6]
dec_layers: [6]
model_dim: 1024
model_dtype: bf16
add_language_tokens: false
# Native PyTorch transformer options
heads: 16 # model_dim must be divisible by heads
rotary_pos_emb: true # RoPE (currently the only option)
post_emb_norm: true # RMSNorm after the token embedding
attn_dropout: 0.1
ff_dropout: 0.1
ff_activation: swiglu # "swiglu" (default) or "gelu"
# Sequence lengths
src_seq_length_min: 1
tgt_seq_length_min: 1
src_seq_length_max: 512
tgt_seq_length_max: 512
max_length: 512
# Training
train_steps: 100000
early_stopping: 5
accum_count: [4]
lookahead_minibatches: 8
batch_size: 23000
batch_type: tokens
normalization: tokens
queue_size: 120
# Optimizer and LR schedule
optim: adamw
learning_rate: 0.0003
adam_beta1: 0.9
adam_beta2: 0.95
weight_decay: 0.01
max_grad_norm: 1.0
label_smoothing: 0.1
warmup_steps: 1000
decay_method: linear_warmup
learning_rate_decay: 0.5
start_decay_steps: 10000
# Distributed setup
world_size: 1 # total number of GPUs across all nodes
gpu_ranks: [0] # GPU ids used on each node
node_rank: 0
n_nodes: 1
task_distribution_strategy: weighted_sampling
seed: 42
# Validation decoding
valid_batch_size: 16
valid_steps: 1500
valid_metrics: [bleu, chrf]
beam_size: 1
# Checkpointing
save_model: /path/to/output/model/
save_strategy: best_and_last
save_checkpoint_steps: 2500
keep_checkpoint: 1
The example configs also enable a BART-style denoising objective (denoising_objective: bart, mask_ratio, mask_length, poisson_lambda, replace_length); remove those keys if you only want plain translation training.
For multi-GPU / multi-node runs, add one entry to tasks per language pair and place each on a GPU with node_gpu: "<node>:<gpu>". Set n_nodes, gpu_ranks (GPU ids per node) and world_size (total GPU count) to match. See csc_env/roihu/multi_nodes.yaml for a 2-node × 4-GPU example with eight tasks.
Notes:¶
To test a different scheme, change only the
enc_sharing_group/dec_sharing_groupentries (andnode_gpuif you add tasks), retrain, and pointtask_idat the task you want to decode.