anlp-a2

Model checkpoints and result files for Tasks 1 and 2 of Assignment 2 (Advanced NLP, Monsoon 2026). Every model here was trained from scratch with PyTorch on one RTX 5060 Ti (16 GB). Task 3 (decoding strategies) uses the pretrained EleutherAI/pythia-160m, so it has no checkpoints in this repository. The code is in the course repository on code.iiit.ac.in.

Layout

task1/                      Mixture-of-Experts translation models (Vietnamese/Japanese -> English)
  model.py                  model definition (needed to load the checkpoints)
  tokenizer.json            shared byte-level BPE tokenizer
  test_metrics.csv/.png     test perplexity and BLEU of the five variants
  val_loss.png              validation loss vs. training tokens
  v1/ ... v5/               one folder per FFN variant
task2/                      one dense model trained with four optimizers
  model.py, optimizers.py   model definition and the four optimizer implementations
  tokenizer.json            English byte-level BPE tokenizer
  final_metrics.json        final metrics of all runs
  training_dynamics.png     validation loss and test BLEU vs. fraction of the dataset seen
  adamw/ nadamw/ lion/ muon/

Every final.pt is {"config": <TransformerConfig fields>, "model": <state_dict>}. It holds the weights only, with no optimizer state.

import torch
from model import Transformer, TransformerConfig      # model.py from the task folder

ckpt = torch.load("v2/final.pt", map_location="cpu")  # e.g. task1/v2/final.pt
model = Transformer(TransformerConfig(**ckpt["config"]))
model.load_state_dict(ckpt["model"])
model.eval()
logits, aux_loss, expert_counts = model(input_ids, attention_mask, "cpu")   # input_ids, attention_mask: (B, N)

Task 1: Mixture of Experts

Decoder-only transformer (d_model 512, 8 heads, 6 layers, RMSNorm, sinusoidal positions, tied input/output embeddings, vocabulary 16,384). Attention, embeddings, data and training are identical across the five models; only the feed-forward block differs:

variant FFN params total / active per token
v1 dense 2-layer MLP (hidden 2048) 27.30M / 27.30M
v2 4 experts, top-1 27.32M / 17.86M
v3 4 experts, top-2 27.32M / 21.02M
v4 1 shared expert + 3 routed experts, top-1 routed 27.32M / 21.01M
v5 4 experts (twice the width), top-2, active parameters matched to v1 39.91M / 27.31M

Data and tokenizer. belumind/en-vi-ja-curated-500k-triplets: 446,252 training rows, each used twice (vi->en and ja->en), giving 892,504 samples; 24,792 validation and 24,792 test rows. Each sample is <BOS> source <SEP> English <EOS> (no language tags) and the loss covers only the English tokens. The tokenizer is a byte-level BPE (16,384 tokens, NFC normalisation) trained on the three language columns of the training split. Special ids: <PAD>=0, <BOS>=1, <EOS>=2, <SEP>=3.

Training. One epoch (13,946 steps, 64 sequences per step, about 39.1M tokens), AdamW (betas 0.9 / 0.95, weight decay 0.1), constant learning rate 3e-4, bf16 autocast, gradient clipping at 1.0, seed 0 (identical data order for every variant). The MoE variants add a Switch-style load-balancing loss with weight 0.01. Notes: v3 crashed with a CUDA out-of-memory error at step 4692 and was resumed from its step-4000 checkpoint. Batches above 12,288 padded tokens are split into chunks with gradient accumulation; this was used by v3 from step 4001 on and by v4 and v5, but not by v1 and v2 (the cross-entropy is unchanged by the split; only the load-balancing term is computed per chunk).

Results (test set, 24,792 sentences per direction; perplexity is exp of the mean cross-entropy on the English target tokens given the source; BLEU is sacreBLEU corpus BLEU of greedy decodes, "overall" pools both directions):

variant final val loss ppl vi->en ppl ja->en ppl overall BLEU vi->en BLEU ja->en BLEU overall
v1 3.174 17.96 33.37 24.48 18.60 10.77 14.70
v2 2.866 13.59 24.52 18.26 22.53 13.51 18.00
v3 2.961 14.69 26.96 19.90 20.71 12.09 16.35
v4 2.928 14.27 25.70 19.15 21.52 12.32 16.84
v5 2.860 13.23 24.36 17.95 22.62 13.56 18.11

Files in each task1/vN/: final.pt, history.json (validation loss vs. tokens seen), test_metrics.json, samples.json (50 test translations per source language). For the MoE variants (v2 to v5) also expert_heatmap.png (expert usage per layer and source language, all tokens), expert_heatmap_source.png (source tokens only) and expert_counts.json / expert_counts_source.json (the raw routing counts behind the heatmaps).


Task 2: Optimizers

The dense architecture of Task 1 variant v1 (27.30M parameters, context 256, vocabulary 16,384), trained from scratch for next-token prediction on browndw/human-ai-parallel-corpus (66,320 texts). The texts are split 90 / 5 / 5 into train / validation / test by source document, so no version of a document appears in two splits (39,068,808 / 2,167,168 / 2,162,705 tokens). The English byte-level BPE tokenizer (16,384 tokens, <PAD>=0, <BOS>=1, <EOS>=2) is trained on the training split; documents are concatenated with <EOS> and cut into 256-token blocks.

Optimizers (optimizers.py, each subclasses torch.optim.Optimizer directly):

run category settings
adamw baseline betas (0.9, 0.95), eps 1e-8
nadamw variance-reduced AdamW variants Nesterov momentum, same settings as AdamW
lion memory-efficient betas (0.9, 0.99)
muon matrix-based momentum 0.95 (Nesterov), 5 Newton-Schulz steps, update scaled by sqrt(max(1, rows/cols)); used for the hidden 2-D weight matrices, while the embedding, norm gains and biases use an AdamW update

Training (identical for all four). One epoch (39.07M tokens), 16 sequences of 256 tokens per step, learning rate 3e-4 for every optimizer (Muon: 3e-4 for the matrices and 3e-4 for its AdamW path; no per-optimizer tuning), weight decay 0.1, linear warmup over the first 2% of steps and then linear decay to 10% of the peak, gradient clipping at 1.0, bf16 autocast, seed 0. Validation loss and test BLEU are recorded every 0.1x of the dataset.

Test BLEU is defined as follows: 500 fixed test documents; the model gets the first 128 tokens and greedily generates the next 64, which are scored with sacreBLEU against the true tokens 129 to 192.

Final results:

run val loss test loss test BLEU
adamw 5.245 5.230 1.05
nadamw 5.084 5.068 1.17
lion 6.433 6.429 0.14
muon 4.675 4.653 1.95

Files in each task2/<run>/: final.pt, history.json (validation loss and test BLEU at each 0.1x of the epoch), final_metrics.json, bleu_examples.json (generated and reference continuations).

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. ๐Ÿ™‹ Ask for provider support