Tooling: Git, GPUs, experiments and the Hugging Face Hub
Making your work reproducible, shareable and affordable
The difference between a learner who finishes projects and one who does not is rarely talent; it is whether yesterday's experiment can be found, rerun and compared today. Git, a reproducible environment, seeds, an experiment tracker and the Hugging Face Hub are the infrastructure for that. This lesson also tells you where to get free GPUs and how not to burn money on cloud ones — knowledge you will need from 4.9 PyTorch II: real training pipelines onward and for every API-based project in 9.11 Project: a cited RAG assistant over your own documents, with evals and 10.12 Project: build a research agent with tools, an MCP server and an eval harness.
You'll be able to
- Use the core Git workflow (branch, commit, push, pull request) and know what never belongs in a repository
- Pick a compute option — Colab, Kaggle, a cloud GPU or your own hardware — based on VRAM, quotas and price
- Make a training run reproducible with seeds, pinned environments and logged configs, and know its limits
- Track experiments with Weights & Biases or MLflow and compare runs honestly
- Download models and datasets from the Hugging Face Hub, and publish your own model card and Space
Key ideas
- Git's daily subset is status/diff/add/commit/switch/push/pull; never commit secrets, large files or notebook outputs.
- Use free GPUs (Colab, Kaggle) through Phase 7; rent cloud GPUs only with budget alerts and checkpointing, and shut them down.
- VRAM is the binding constraint: weights × bytes + optimizer states + activations; a 7B model in fp16 is ~14 GB of weights alone.
Show 5 more key ideas
- Reproducibility has layers: pinned environment, seeds for random/NumPy/PyTorch, logged config + commit hash, determinism flags.
- Bit-exact reproduction across hardware is not guaranteed; report results over several seeds and treat differences within the spread as noise.
- Experiment trackers (W&B, MLflow) record config, metrics and artifacts per run; compare on held-out metrics, not training loss.
- The Hugging Face Hub provides datasets, pretrained models, model cards and Spaces for demos; datasets is Arrow-backed and lazy.
- A src/ + configs/ + README skeleton with a one-command reproduction is the backbone of a portfolio project.
Suggested path through this lesson
Git: a time machine for your code
Git records snapshots (commits) of a directory and lets you branch, merge and travel between them; GitHub hosts those repositories and adds pull requests, issues and a public portfolio. The subset you need daily:
# shell commands, shown here for reference
# git init start tracking a folder
# git status / git diff what changed since the last commit
# git add -A && git commit -m "Add baseline logistic regression"
# git switch -c feature/knn create and switch to a branch
# git push -u origin feature/knn publish the branch; open a pull request on GitHub
# git pull bring in others' commits
# git log --oneline --graph read the history
Commit small and often with messages that say why. Three things must never be committed: secrets (API keys — use a .env file listed in .gitignore and read it with os.environ), large data or model weights (use the Hugging Face Hub, DVC or cloud storage; Git chokes above ~100 MB), and notebook output cells full of images (strip outputs with nbstripout or clear them before committing, otherwise every diff is unreadable). A repository with a README, a pinned environment and a src/ folder is already more professional than most.
Where to get a GPU
Deep learning needs a GPU for anything beyond toy models because matrix multiplication parallelizes across thousands of cores (4.12 Compute, hardware and scale basics). The question is which one, and the honest answer for a learner is: free ones first.
| option | what you get | good for | catch |
|---|---|---|---|
| Google Colab (free) | a T4 (16 GB) for a few hours at a time | Phases 2–7 notebooks, fine-tuning small models | session resets, usage limits; Pro tiers add better GPUs |
| Kaggle Notebooks | ~30 GPU-hours/week on T4/P100, 2×T4 option | the same, plus datasets already attached | 12-hour session cap |
| Cloud GPU rentals (Lambda, RunPod, Vast.ai, and the big clouds) | an A100/H100 by the hour | multi-hour training, LLM fine-tuning | real money: tens of dollars per hour for a top GPU; forgotten instances are the #1 learner mistake |
| Your own GPU | a consumer card with 8–24 GB VRAM | everything small, always available | VRAM is the limit: a 7B-parameter model in fp16 needs ~14 GB just for weights (4.12 Compute, hardware and scale basics) |
| Apple silicon (MPS) | unified memory | small models, inference | slower than CUDA; some ops unsupported |
VRAM is the quantity to reason about: weights × bytes per parameter + optimizer states + activations (4.12 Compute, hardware and scale basics does the arithmetic). When renting, set a budget alert, use spot/preemptible instances with checkpointing, and shut down in the same session you started. For API-based work (8.4 Prompting as programming, 9.6 Generation side: context assembly, citations, structured outputs and tool calling) the same discipline applies: set a monthly hard cap in the provider dashboard, cache responses during development, and prefer smaller models while iterating.
Reproducibility: seeds and their limits
A result you cannot reproduce is an anecdote. Four layers of reproducibility, from cheapest to most complete:
- Pin the environment —
uv.lockorrequirements.txtwith exact versions (2.1 Python for ML, fast). - Seed every source of randomness — Python's
random, NumPy, and PyTorch (CPU and CUDA). Data shuffling, weight initialization and dropout all draw from these. - Log the configuration — every hyperparameter, the data version and the Git commit hash, saved next to the results.
- Determinism flags —
torch.use_deterministic_algorithms(True)andcudnn.benchmark=Falsemake GPU kernels pick deterministic (sometimes slower) implementations.
import random, numpy as np, torch
def seed_everything(seed=42):
random.seed(seed); np.random.seed(seed); torch.manual_seed(seed)
torch.cuda.manual_seed_all(seed)
Even with all four, bit-for-bit identical results across different GPUs or library versions are not guaranteed — floating-point addition is not associative, so parallel reductions can differ in the last bits and the differences compound over training. The practical standard is therefore statistical reproducibility: run with 3–5 seeds and report the mean and spread (1.8 Statistics essentials). A difference between two methods smaller than the seed-to-seed spread is noise, not a finding — an idea you will meet again in evaluating LLMs (8.7 Evaluating LLMs).
Experiment tracking
After ten runs you will not remember which learning rate produced which curve. Trackers solve this: Weights & Biases (hosted, free for individuals) and MLflow (open source, runs locally) both record configs, metrics over time, system stats and artifacts, and give you a dashboard to compare runs. The pattern is three calls: init(config=asdict(cfg)) at the start, log({"loss": loss.item(), "lr": lr}, step=step) inside the loop, and finish() at the end. Log everything cheap (loss, metrics, learning rate, gradient norm, throughput) and the hardware you used; log rarely the expensive things (sample predictions, images). Name runs descriptively and tag them. Compare runs by the metric that matters on held-out data, never by training loss alone (3.5 Evaluating models: metrics, validation and the bias–variance trade-off).
The Hugging Face Hub
The Hub is the GitHub of machine learning: 1M+ models, hundreds of thousands of datasets, and Spaces for hosting demos, all versioned with Git under the hood. You will use it in three ways. Consume: from datasets import load_dataset; ds = load_dataset("imdb") streams a benchmark dataset with splits and features already defined, and AutoModel.from_pretrained("...") downloads pretrained weights (7.5 Encoder-only: BERT and friends (and sentence embeddings)). Publish: huggingface-cli login once, then model.push_to_hub("you/my-model") uploads weights plus a model card — a README describing the data, training procedure, intended use, limitations and evaluation. Writing a model card forces the questions that 8.12 Safety, risks and responsible AI formalizes. Demo: a Space with a app.py built on Gradio turns a model into a web app in twenty lines, which is how the projects in 5.10 Project: train and deploy an image classifier and 8.13 Project: fine-tune a small LLM with LoRA and ship a chat app get shipped.
The datasets library deserves a note of its own: it is Arrow-backed, so datasets larger than RAM load lazily and map transforms are cached; ds.to_pandas() and Dataset.from_pandas connect it to 2.3 pandas, data wrangling and plotting.
A project skeleton
# learnai-lab/
# pyproject.toml, uv.lock, .gitignore, .env (never committed), README.md
# data/ raw/ and processed/ (git-ignored; documented in README)
# notebooks/ exploration only; numbered 01_eda.ipynb, 02_baseline.ipynb
# src/lab/ data.py, model.py, train.py, evaluate.py (importable code)
# configs/ yaml or dataclass configs per experiment
# runs/ checkpoints and logs (git-ignored; tracker has the metadata)
# tests/ small tests for data shapes and a one-batch training smoke test
Move code from notebooks into src/ as soon as you run it twice. A README that states what the project does, how to set it up (uv sync) and how to reproduce the main result (uv run python -m lab.train --config configs/base.yaml) is the single most valuable artifact for your portfolio (11.3 Portfolio project ladder).
Where this shows up later
- Every project lesson assumes this skeleton and a tracker — 3.14 Project: end-to-end tabular ML with scikit-learn, 5.10 Project: train and deploy an image classifier, 8.13 Project: fine-tune a small LLM with LoRA and ship a chat app, 9.11 Project: a cited RAG assistant over your own documents, with evals, 10.12 Project: build a research agent with tools, an MCP server and an eval harness.
- VRAM and FLOP arithmetic get their full treatment in 4.12 Compute, hardware and scale basics and 7.10 Efficient inference: KV cache, GQA, FlashAttention, speculative decoding, quantization; cost control for APIs returns in 9.9 Production: latency, cost, caching, guardrails, security and privacy.
- Seeds, variance and error bars underpin honest evaluation — 3.5 Evaluating models: metrics, validation and the bias–variance trade-off, 8.7 Evaluating LLMs, 10.9 Evaluating agents.
- Model cards and dataset documentation are part of responsible AI — 3.13 Feature engineering, data quality and data-centric ML, 8.12 Safety, risks and responsible AI.
Common pitfalls (5)
- Committing an API key to a public repository; keys get scraped within minutes — use .env and .gitignore.
- Leaving a rented GPU instance running overnight; set alerts and stop instances in the same session.
- Declaring a method better after one seed; seed-to-seed variance often exceeds the claimed gain.
- Comparing experiments by training loss; only held-out metrics reflect generalization.
- Keeping all logic in notebooks, so nothing can be imported, tested or rerun from the command line.
Recap: all 8 key points
- Git's daily subset is status/diff/add/commit/switch/push/pull; never commit secrets, large files or notebook outputs.
- Use free GPUs (Colab, Kaggle) through Phase 7; rent cloud GPUs only with budget alerts and checkpointing, and shut them down.
- VRAM is the binding constraint: weights × bytes + optimizer states + activations; a 7B model in fp16 is ~14 GB of weights alone.
- Reproducibility has layers: pinned environment, seeds for random/NumPy/PyTorch, logged config + commit hash, determinism flags.
- Bit-exact reproduction across hardware is not guaranteed; report results over several seeds and treat differences within the spread as noise.
- Experiment trackers (W&B, MLflow) record config, metrics and artifacts per run; compare on held-out metrics, not training loss.
- The Hugging Face Hub provides datasets, pretrained models, model cards and Spaces for demos; datasets is Arrow-backed and lazy.
- A src/ + configs/ + README skeleton with a one-command reproduction is the backbone of a portfolio project.
Watch
Shows the notebook-on-Kaggle workflow and deploying a model as a Hugging Face Space in one sitting.
Read
Exercises
- Your first ML repository
Create a GitHub repository with the skeleton above, a
.gitignorefor Python/data/.env, and a README. Move the logistic-regression script from 2.4 PyTorch I: tensors, autograd and the training loop intosrc/, make three meaningful commits on a branch, open a pull request to main and merge it. Expected:uv sync && uv run python -m lab.trainworks from a fresh clone. - Seeds and variance
Train the 2.4 PyTorch I: tensors, autograd and the training loop MLP on MNIST (via
torchvisionorload_dataset("mnist")) for one epoch with five different seeds, logging test accuracy to W&B or MLflow. Expected: a spread of a few tenths of a percent; write down the mean ± standard deviation and compare two learning rates against that spread. - Publish a model and a demo
Push the trained MLP's weights to the Hugging Face Hub with a model card (data, training details, limitations). Then create a Gradio Space that lets a user draw a digit and shows the prediction. Expected: a public URL you can put in your portfolio.
- Cost sanity check
Using a cloud provider's price list, estimate the cost of training the 7.8 Build GPT from scratch (nanoGPT walkthrough) 124M-parameter GPT-2 for 10 hours on one A100, and the cost of 1,000 API calls to a frontier model with 2,000 input and 500 output tokens each (use the provider's current per-token prices). Expected: two numbers you can defend, plus the budget alert you set in the dashboard.
Quiz
Flashcards
These cards are now in your spaced-repetition queue. Review all due cards →