The pivot point — from training models to adapting foundation models. Tokenization, data quality, and the GPT/BERT/T5 map
6 hours · 2 modules · PyTorch, NLTK, spaCy, Hugging Face tokenizers
The pivot point of the certificate. Courses 1–6 were about training models. From here on you are an AI Engineer: you take enormous pretrained models and adapt them. This course sets the vocabulary for everything that follows.
new data from it.
That's the whole distinction, and it's the first quiz question.
RNN / LSTM — sequential, hidden state carries memory. Superseded for language, still used for small time-series work. Weakness: no parallelism, weak long-range memory.
Transformer — self-attention, fully parallel, long-range. The architecture behind every current LLM.
VAE (Variational Autoencoder) — encoder produces a distribution (μ, σ) over a latent space; sample it and decode to generate. Loss = reconstruction + KL divergence. Smooth, interpolatable latent space; outputs tend to be blurry.
GAN — generator vs discriminator, adversarial. Sharp outputs, one-shot generation, unstable training, mode collapse.
Diffusion — learn to reverse a gradual noising process. Currently dominant for images (Stable Diffusion, DALL·E, Midjourney). Stable training, excellent quality, slow generation because it's iterative.
| Best at | Weakness | |
|---|---|---|
| RNN/LSTM | short sequences, streaming | slow, forgets long range |
| Transformer | text, anything sequential | O(n²) attention cost |
| VAE | smooth latent space, interpolation | blurry samples |
| GAN | sharp images, fast generation | unstable, mode collapse |
| Diffusion | highest-fidelity images | slow, many sampling steps |
| Model | Architecture | Pretraining objective | Good at |
|---|---|---|---|
| GPT | decoder-only | next-token prediction (causal LM) | generation, chat, completion |
| BERT | encoder-only | masked LM + next-sentence prediction | classification, NER, understanding |
| BART | encoder–decoder | denoising (corrupt then reconstruct) | summarisation, generation |
| T5 | encoder–decoder | span corruption, everything as text-to-text | translation, summarisation, QA |
The mental model:
Ask "does this task need to read, write, or translate?" and the family follows.
Tasks the videos enumerate: text generation, summarisation, translation, question answering, sentiment analysis, code generation, chatbots/dialogue, named entity recognition.
The shift the course is arguing for: previously each task needed a task-specific model trained on task-specific labelled data. Now one foundation model handles all of them via prompting, with fine-tuning only where you need domain adaptation.
An LLM produces fluent, confident, false output. Not a bug you can patch — a consequence of the objective. The model is trained to predict plausible next tokens, and plausible is not the same as true. It has no internal fact-checking mechanism and no representation of its own uncertainty.
Causes: gaps in training data, outdated training data, ambiguous prompts, over-confident decoding, and the model's tendency to complete a pattern rather than decline.
Mitigations, in rough order of effectiveness:
Why it matters here: this is why the last third of the certificate is about RAG. The architecture answer to hallucination is don't ask the model to recall — give it the document.
IBM's product for AI governance: model lifecycle tracking, bias/drift monitoring, explainability, and regulatory compliance documentation. It appears because it's IBM's course. Know the concept — AI governance = monitoring, documentation, risk and compliance for deployed models — and that it's a real interview topic under the EU AI Act.
pipeline(), TrainerThe fastest possible LLM call, which the lab has you run:
from transformers import pipeline
gen = pipeline('text-generation', model='gpt2')
print(gen("The future of AI is", max_length=50, num_return_sequences=1))
clf = pipeline('sentiment-analysis')
print(clf("This course is dense but useful."))
pipeline() handles tokenisation, model loading, inference and decoding in one call. Good for demos; you'll drop to the lower-level API when you need control.
Splitting text into the units a model actually processes. Everything downstream depends on it.
Word-based — split on whitespace/punctuation.
<UNK>; "run/running/ran" are unrelatedentries.
Character-based — tiny vocabulary (~100), no OOV ever.
Subword — the compromise every modern LLM uses. Frequent words stay whole; rare words break into meaningful pieces. unhappiness → un + happi + ness. Fixed vocabulary, no OOV, morphology partly captured.
Subword algorithms:
adjacent pair. Used by GPT-2, RoBERTa.
BERT. Marks continuations with ##.
so it needs no pre-tokenisation and handles languages without spaces. Used by T5, XLNet, ALBERT.
import nltk
nltk.word_tokenize("Don't split this wrongly.")
# ['Do', "n't", 'split', 'this', 'wrongly', '.']
import spacy
nlp = spacy.load('en_core_web_sm')
[t.text for t in nlp("Apple is looking at buying a U.K. startup.")]
from transformers import BertTokenizer, XLNetTokenizer
bt = BertTokenizer.from_pretrained('bert-base-uncased')
bt.tokenize("Tokenization is unbelievably important")
# ['token', '##ization', 'is', 'unbelievable', '##ly', 'important'] ← ## = continuation
xt = XLNetTokenizer.from_pretrained('xlnet-base-cased')
xt.tokenize("Tokenization is important")
# ['▁Token', 'ization', '▁is', '▁important'] ← ▁ = word start
Two conventions to keep straight: BERT/WordPiece marks continuation with ##; XLNet and SentencePiece mark word start with ▁.
| Token | Purpose |
|---|---|
[CLS] / <s> | start of sequence; its final embedding represents the whole sequence |
[SEP] / </s> | separator / end of sequence |
[PAD] | padding to equal length within a batch |
[UNK] | unknown token |
[MASK] | the position BERT must predict during masked-LM pretraining |
enc = tokenizer("Hello world", padding=True, truncation=True,
max_length=128, return_tensors='pt')
enc['input_ids'] # token IDs
enc['attention_mask'] # 1 = real token, 0 = padding
attention_mask is not optional. It tells the model to ignore padding positions. Without it, padding tokens participate in attention and corrupt the representation — silently.
Three steps, always in this order: tokenize → numericalize → pad.
Text samples have different lengths, so batching needs a collate_fn:
from torch.nn.utils.rnn import pad_sequence
from torch.utils.data import DataLoader
def collate_fn(batch):
texts, labels = zip(*batch)
ids = [torch.tensor(tokenizer.encode(t)) for t in texts]
ids = pad_sequence(ids, batch_first=True, padding_value=tokenizer.pad_token_id)
return ids, torch.tensor(labels)
loader = DataLoader(dataset, batch_size=32, shuffle=True, collate_fn=collate_fn)
collate_fn runs after __getitem__ gathers a batch and before it's handed to your loop — it's where padding belongs. Pad per batch, not to a global maximum: padding everything to the longest document in the dataset wastes enormous compute.
For torchtext-style pipelines the course also shows build_vocab_from_iterator, vocab objects, and <unk> default index handling.
The section with the highest real-world value in this course.
Quality dimensions:
Why it dominates model quality: at fixed compute, data quality beats data quantity. Deduplication alone measurably improves models — duplicated passages get memorised and crowd out learning. Recent small-model results (training on curated/textbook-quality corpora) beat much larger models trained on raw scrapes.
Bias in → bias out. A model trained on internet text reproduces the internet's demographic skews, stereotypes and coverage gaps. There is no debiasing step downstream that fully repairs a skewed corpus — which is exactly why data curation is a job, and why it connects directly to the Human Data Lead work.
The preprocessing pipeline:
produces garbage — the ID→token mapping is different. No error, just nonsense output.
max_length. Know your model's limit (BERT 512tokens; modern LLMs far more) and chunk deliberately rather than letting it clip.
text run much higher. This is what you're billed on with commercial APIs.
attention_mask do and what breaks without it?## = WordPiece continuation, ▁ = SentencePiece word start[CLS] [SEP] [PAD] [UNK] [MASK]collate_fn; always send attention_mask