PyTorch, Transformers, Datasets and the Hugging Face Ecosystem
By the end of this lesson you will be able to name every library a training recipe in this course is built from, say in one sentence what each is responsible for, and know which one’s documentation to open when a run fails. You will also know how the Hub sits underneath all of them: what a repository, a revision and a gated model are, and where the token that reaches them lives.
This is a map rather than a tutorial. Nothing here is installed until the next lesson and nothing is trained until the lab. The point is that when a stack trace goes twelve frames deep, you can tell which of six projects it is actually complaining about.
Six libraries, one job each
Section titled “Six libraries, one job each”A fine-tuning script is a short piece of code sitting on a tall stack. Read it from the bottom.
What a training script stands on
- Accelerator and driverCUDA on Tracks S and N, ROCm on Track X, Metal on Track M. Part 5 covers what each one is and how to check it.
- PyTorchTensors, automatic differentiation, optimisers, devices, mixed precision. Everything above is a convenience over this.
- transformersModel architectures, tokenisers, the Hub loading code, generation, and the Trainer loop.
- datasetsLoading, streaming, mapping and splitting the examples, backed by memory-mapped Arrow files.
- peft and trlpeft attaches adapters such as LoRA; trl wraps the Trainer into named post-training methods, starting with supervised fine-tuning.
- acceleratePlaces tensors on devices and launches the run, on one accelerator or several. Used through the Trainer rather than directly in this course.
- Your training scriptA configuration, a dataset, a trainer, and a line that saves the result. Fifty lines in the lab.
Every training recipe you will meet, in this course and outside it, is some arrangement of those layers. Unsloth, Axolotl and LLaMA-Factory, which Part 13 covers, replace the top layer with a configuration file and change some of the middle for speed; they do not replace the stack.
PyTorch: tensors, gradients and devices
Section titled “PyTorch: tensors, gradients and devices”Part 1 introduced tensors and the training loop. Three things about PyTorch matter for the rest of Level 3.
Autograd is a graph that is rebuilt every iteration. The autograd documentation describes a
directed acyclic graph whose leaves are the input tensors and whose roots are the outputs, recorded
as the forward pass executes, and states plainly that “the graph is recreated from scratch at every
iteration”. An operation is recorded only if at least one of its inputs requires gradients, and
after backward() only leaf tensors with requires_grad=True have gradients accumulated into
their .grad fields. That single sentence explains the whole of LoRA’s memory advantage, which
this part’s third lesson works through: freeze the base model’s parameters and the graph stops
holding what it would have needed to differentiate them.
Gradients can be switched off, and this is not the same as evaluation mode. The same page describes no-grad mode and inference mode as two ways of excluding operations from the backward graph. The evaluation passes in the lab use them; so does every engine in Level 2, which is why inference memory in Part 4 has no gradient term at all.
A device is a choice you make and print. torch.cuda.is_available(), and
torch.backends.mps.is_available() on a Mac, decide where tensors live. Part 1’s script picks
between them and prints the answer, and every script in this part does the same. On Track X the
ROCm build reports AMD GPUs through the cuda device name, which is a naming artefact and not a
mistake.
Mixed precision also lives here. The torch.amp documentation describes torch.autocast as a
context manager that runs regions of a script in mixed precision, in torch.float16 or
torch.bfloat16, and pairs it with torch.amp.GradScaler when the dtype is float16, because small
gradients underflow in that format. With bfloat16 the scaler is not part of the recipe. This is why
the course’s training runs ask for BF16 wherever the hardware reports support for it, and fall back
to float32 rather than to float16.
transformers: architectures, tokenisers and the Trainer
Section titled “transformers: architectures, tokenisers and the Trainer”The transformers library, pinned here at transformers 5.16.1 · verified 2026-09-08, is three things at
once.
It is a collection of architectures: the Python that turns a config.json into a model with
the right number of layers, heads and dimensions. AutoModelForCausalLM.from_pretrained reads the
config, builds the class it names, and loads the weights.
It is a collection of tokenisers, reached through AutoTokenizer.from_pretrained, which
carries the vocabulary, the special tokens and the chat template. The next-but-one lesson is
entirely about getting that part right.
It is a training loop. The Trainer class is documented as “a simple but feature-complete
training and eval loop for PyTorch”, configured by a TrainingArguments object and taking model,
args, train_dataset, eval_dataset and processing_class. Its train() method accepts
resume_from_checkpoint, evaluate() returns a dictionary containing the evaluation loss, and
save_model() writes something from_pretrained() can read back. You will not call Trainer
directly in this course, because TRL’s trainers wrap it, but every argument you set is one of its
arguments and every log line you read is one of its log lines.
datasets: getting examples in and out
Section titled “datasets: getting examples in and out”The datasets library loads examples from the Hub or from local files and hands them to the
trainer. Three of its behaviours matter.
It loads local JSON Lines directly. The loading guide gives load_dataset("json", data_files="my_file.json") and states that the most efficient format is multiple JSON objects,
one per line. That is the shape the lab’s dataset ships in, and it is why the course’s training data
is JSON Lines rather than CSV.
It maps, filters and splits without loading everything. map() applies a function to every
example, optionally in batches with batched=True and in parallel with num_proc;
train_test_split(test_size=...) produces splits and shuffles them by default; shuffle(seed=...)
takes a seed. Every one of those is a place where a run becomes irreproducible if the seed is left
out, which is the fifth lesson’s subject.
It streams when the data is too large to keep. streaming=True returns an iterable dataset
that reads as it goes. You will not need it for a two-hundred-example lab; you will need it in
Part 12, where the pretraining corpus is far larger than the machine.
peft and trl: adapters and named methods
Section titled “peft and trl: adapters and named methods”peft, pinned at PEFT 0.20.0 · verified 2026-09-08, attaches parameter-efficient adapters to a frozen
model. Its conceptual guide describes LoRA as representing “the weight updates with two smaller
matrices (called update matrices) through low-rank decomposition”, with the original weight matrix
frozen. LoraConfig carries r, the rank; lora_alpha, the scaling; lora_dropout;
target_modules, the names of the layers to adapt; and task_type. get_peft_model wraps a
model and print_trainable_parameters() reports how much of it is now trainable; the developer
guide’s own example prints under one per cent. Part 13 teaches the knobs properly. Here, the point
is which project owns them.
trl, pinned at TRL 1.12.0 · verified 2026-09-08, wraps the Trainer into named post-training methods.
Its SFTTrainer is the one this part uses, and its quick start is genuinely four lines: a model
id, a dataset, and trainer.train(). SFTConfig is a subclass of TrainingArguments with SFT’s
own settings added and some defaults changed, and it takes a peft_config argument, which is how a
LoRA fine-tune becomes a one-line change from a full one. TRL’s release notes for the pinned
version list SFT, DPO, KTO, GRPO, RLOO, Reward and Distillation trainers as stable; Parts 14 and 15
use several of the others.
accelerate: where the tensors go
Section titled “accelerate: where the tensors go”accelerate is the layer that places tensors on devices and launches a run across however many
accelerators are present. Its documentation describes adding four lines to a plain PyTorch loop, an
Accelerator object and a prepare() call, after which the same code runs on any configuration,
and launching through accelerate launch {my_script.py}. It also states that it provides “automatic
support for mixed-precision training”.
In this course you almost never call it directly, because the Trainer is built on it. It becomes
visible in two places: when a single-machine run needs a launch configuration, and in Part 18,
where multiple accelerators stop being an implementation detail.
The Hub underneath all of it
Section titled “The Hub underneath all of it”Every one of those libraries reaches the same place for weights and data.
What from_pretrained actually does
- Resolve the repositoryAn id such as Qwen/Qwen3-0.6B, or a local path. Organisation and name, exactly as on the Hub.
- Pick a revisionA branch, tag or commit hash. The default is the head of the main branch, which can move between two of your runs.
- Authenticate if requiredA user access token, for private repositories and for gated ones you have been granted.
- Download into the cacheThen load from there. A second run reads the cache and needs no network at all.
Repositories and revisions. A repository is model files plus a card; a revision is a point in
its history. The Datasets loading guide documents a revision parameter taking “tag name, or
branch name, or commit hash”, and the hf command-line tool, from huggingface-hub pinned at
Hugging Face CLI 1.30.0 · verified 2026-09-08, takes --revision on hf download for the same purpose.
Pinning a revision is the difference between a run you can repeat and a run whose base model
quietly changed underneath it.
Tokens. The Hub documentation calls these User Access Tokens and describes three roles:
fine-grained, scoped to specific resources; read, for downloading private repositories; and
write, for pushing. Its own advice is to create one token per application and to prefer
fine-grained tokens in production, so that a leak can be contained. hf auth login stores a token
on the machine; the HF_TOKEN environment variable is the non-interactive alternative, and the
documentation notes that hf auth logout will not log you out if that variable is what is
authenticating you.
Gated models. The Hub lets an author require an access request before the files can be
downloaded. The documentation is explicit that requesting access “can only be done from your
browser”, that approval may be automatic or manual, and that “to download files from a gated model
you’ll need to be authenticated”. Several models this course names are gated; when one is, its page
says so, and the step is a browser visit followed by hf auth login on the machine that will do
the downloading.
Debug at the boundary between libraries
Section titled “Debug at the boundary between libraries”When a run fails, identify the last representation that was correct. Start with a raw dataset row, then the rendered conversation, token IDs, loss mask, batch tensor shapes, model outputs and optimiser step. Each boundary has an owner: a dataset loader cannot repair an incompatible attention kernel, and an accelerator launcher cannot correct mislabeled examples.
Keep one tiny batch available for inspection. Decode its non-padding tokens and annotate which positions contribute to loss. Confirm that a forward pass returns a finite scalar loss, a backward pass creates gradients for the intended parameters, and an optimiser step changes at least one trainable parameter. Frozen base parameters should remain frozen in an adapter run.
Save the package versions together, because compatibility belongs to the combination. When upgrading, run this small boundary check before a full experiment. If the miniature example works and the full dataset fails, inspect data-dependent shapes, lengths and masks. If it fails before reading data, investigate imports, binary extensions and device support. This is more efficient than changing several libraries and hyperparameters simultaneously.
A training script stands on six layers: PyTorch for tensors, gradients and devices; transformers
for architectures, tokenisers and the training loop; datasets for loading, mapping and splitting;
peft for adapters; trl for named post-training methods; accelerate for device placement and
launching. Autograd rebuilds its graph every iteration and only records what requires gradients,
which is the mechanism behind every memory saving in the next lessons. Mixed precision is
torch.autocast, with a gradient scaler needed for float16 and not for bfloat16. Underneath all of
it is the Hub, where a repository plus a revision identifies exactly what you loaded, a user access
token authorises private and gated repositories, and trust_remote_code is a decision about
running someone else’s Python rather than a convenience flag.
Check your understanding
Sources for this lesson
13 verified · checked 2026-09-09
- 01PyTorch documentation — Autograd mechanics§ How autograd encodes the history; Setting requires_grad; Locally disabling gradient computationdocs.pytorch.org/docs/2.14/notes/autograd.html2026-09-09
- 02PyTorch documentation — Automatic Mixed Precision package, torch.amp§ Autocasting; Gradient Scalingdocs.pytorch.org/docs/2.14/amp.html2026-09-09
- 03Transformers documentation — Trainer§ Trainer; train; evaluate; save_modelhuggingface.co/docs/transformers/main/en/main_classes/trainer2026-09-09
- 04Transformers documentation — Customizing models§ Uploadhuggingface.co/docs/transformers/main/en/custom_models2026-09-09
- 05Datasets documentation — Load§ Hugging Face Hub; Local and remote files; JSONhuggingface.co/docs/datasets/main/en/loading2026-09-09
- 06Datasets documentation — Process§ Map; Split; Shufflehuggingface.co/docs/datasets/main/en/process2026-09-09
- 07PEFT documentation — LoRA (conceptual guide)huggingface.co/docs/peft/main/en/conceptual_guides/lora2026-09-09
- 08PEFT documentation — LoRA developer guide§ LoraConfig; merge_and_unloadhuggingface.co/docs/peft/main/en/developer_guides/lora2026-09-09
- 09TRL documentation — SFT Trainer§ Quick start; Expected dataset type and format; Train adapters with PEFThuggingface.co/docs/trl/main/en/sft_trainer2026-09-09
- 10Accelerate documentation — indexhuggingface.co/docs/accelerate/main/en/index2026-09-09
- 11Hugging Face Hub documentation — User access tokens§ What are User Access Tokens; Best practiceshuggingface.co/docs/hub/security-tokens2026-09-09
- 12Hugging Face Hub documentation — Gated models§ Access gated models as a user; Download fileshuggingface.co/docs/hub/models-gated2026-09-09
- 13Hugging Face Hub documentation — Command Line Interface (CLI)§ hf auth login; hf download; Download a specific revisionhuggingface.co/docs/huggingface_hub/main/en/guides/cli2026-09-09
Every technical claim on this page was checked against the official documentation of the tool, vendor or model publisher on the date shown, at the version pinned for the course. Where the course disagrees with folklore, the source is how you can tell which one to trust.