--- id: python-dev-environment title: Python Dev Environment for AI code: PD subtitle: Install uv, make one venv per project, pin with lockfiles, check the route, set up VS Code and avoid silent Python bugs. hue: 210 sources: phases/00-setup-and-tooling/01-dev-environment, phases/00-setup-and-tooling/06-python-environments, phases/00-setup-and-tooling/08-editor-setup, phases/00-setup-and-tooling/13-python-for-ai-engineering source_hash: c1902990e64b40be --- ## The four-layer stack type: architecture from: phases/00-setup-and-tooling/01-dev-environment/docs/en.md ```arch node | sys | 1,1 | 1. System Foundation | OS, shell, git, editor, GPU drivers | process node | pkg | 2,1 | 2. Package Managers | uv, pnpm, cargo, juliaup | store node | run | 3,1 | 3. Language Runtimes | Python 3.11+, Node 20+, Rust, Julia | process node | lib | 4,1 | 4. AI/ML Libraries | PyTorch, JAX, transformers | model edge | sys | pkg | install first edge | pkg | run | edge | run | lib | ``` ## Install the toolchain type: command-table from: phases/00-setup-and-tooling/01-dev-environment/docs/en.md span: 2 | Command | What it does | |---|---| | `xcode-select --install` | macOS build tools and git | | `sudo apt install -y build-essential git curl wget unzip` | Ubuntu or Debian base tools | | `wsl --install -d Ubuntu-24.04` | Windows: use WSL2 | | `curl -LsSf https://astral.sh/uv/install.sh \| sh` | Install uv | | `uv python install 3.12` | Install Python 3.12 | | `fnm install 22` then `fnm use 22` | Node.js 22 for TypeScript lessons | | `npm install -g pnpm` | Install pnpm | ## Make an environment type: task-table from: phases/00-setup-and-tooling/06-python-environments/docs/en.md span: 2 | Task | Code | |---|---| | uv venv (recommended) | `uv venv` then `source .venv/bin/activate` | | New project with pyproject.toml | `uv init my-ai-project` then `uv add torch numpy matplotlib` | | Built-in venv | `python3 -m venv .venv` | | Activate on Windows | `.venv\Scripts\activate` | | Conda env | `conda create -n myproject python=3.12` then `conda activate myproject` | | Install an extra group | `uv pip install -e ".[torch,llm]"` | | Make a lockfile | `uv pip compile pyproject.toml -o requirements.lock` | | Install from the lockfile | `uv pip install -r requirements.lock` | ## pyproject.toml with extras type: annotated-code lang: toml from: phases/00-setup-and-tooling/06-python-environments/docs/en.md ```toml [project] name = "ai-engineering-from-scratch" version = "0.1.0" requires-python = ">=3.11" # course minimum dependencies = [ "numpy>=1.26", "matplotlib>=3.8", "jupyter>=1.0", "scikit-learn>=1.4", ] [project.optional-dependencies] torch = ["torch>=2.3", "torchvision>=0.18"] # uv pip install -e ".[torch]" llm = ["anthropic>=0.39", "openai>=1.50"] # uv pip install -e ".[llm]" ``` ## Check the route type: command-table from: phases/00-setup-and-tooling/01-dev-environment/docs/en.md, phases/00-setup-and-tooling/01-dev-environment/code/verify.py, phases/00-setup-and-tooling/06-python-environments/docs/en.md, phases/00-setup-and-tooling/06-python-environments/code/env_setup.sh | Command | What it does | |---|---| | `verify.py --route beginner` | Default route. Requires python and git | | `--route ml-foundations` | Also requires numpy | | `--route agent-skills` | Requires python, git, node and npx | | `--route llm-engineering`, `agents`, `mcp`, `certification` | Require python and git | | `--show-later` | Also checks optional and later tools | | `[PASS]`, `[FAIL]`, `[LATER]` | Status of each probe. Exit code 1 on a FAIL | | `bash .../code/env_setup.sh` | Makes `.venv` at the repo root and verifies it | ## Install PyTorch and check the GPU type: annotated-code lang: bash from: phases/00-setup-and-tooling/01-dev-environment/docs/en.md, phases/00-setup-and-tooling/06-python-environments/docs/en.md ```bash nvidia-smi # driver CUDA version uv pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124 uv pip install torch torchvision torchaudio # macOS: plain build with MPS python -c "import torch; print(torch.version.cuda)" # PyTorch CUDA version python -c "import torch; print(torch.__version__)" # install worked which python # must show .venv/bin/python ``` ## VS Code settings type: defaults from: phases/00-setup-and-tooling/08-editor-setup/docs/en.md, phases/00-setup-and-tooling/08-editor-setup/code/vscode/settings.json | Setting | Default | Note | |---|---|---| | `python.analysis.typeCheckingMode` | `"basic"` | Catches wrong argument types before a run | | `editor.formatOnSave` | `true` | Black formats each save | | `black-formatter.args` | `["--line-length", "88"]` | Black wraps at 88 | | `editor.rulers` | `[88, 120]` | 120 marks long docstrings | | `notebook.output.scrolling` | `true` | Long training output stays small | | `files.autoSave` | `"afterDelay"` | `files.autoSaveDelay` is 1000 | | `terminal.integrated.scrollback` | 10000 | Lines kept in the terminal | | `ruff.lint.run` | `"onSave"` | Ruff lints each save | ## Troubleshooting type: troubleshooting from: phases/00-setup-and-tooling/01-dev-environment/docs/en.md, phases/00-setup-and-tooling/06-python-environments/docs/en.md, phases/00-setup-and-tooling/08-editor-setup/docs/en.md | Symptom | Cause | Fix | |---|---|---| | Packages missing at run | Venv not active | `source .venv/bin/activate` | | `which python` shows `/usr/bin/python` | Global install | Activate, then install again | | Conda env breaks | `pip install` mixed into conda | Conda first, pip packages last | | GPU not used | PyTorch CUDA above driver CUDA | PyTorch CUDA must be <= driver CUDA | | Torch install fails on a Mac | `--index-url .../cuXXX` wheels | Install the plain build | | `Not installing fnm due to missing dependencies.` | No `unzip` | `sudo apt install -y unzip` | | `Cannot install under Rosetta 2` | Terminal runs as `i386` | `arch -arm64 brew install fnm` | | `code` not found on macOS | Shell command not in PATH | "Install 'code' command in PATH" | ## Silent Python bugs type: annotated-code lang: python from: phases/00-setup-and-tooling/13-python-for-ai-engineering/docs/en.md, phases/00-setup-and-tooling/13-python-for-ai-engineering/code/main.py ```python independent = list(weights) # assignment does not copy grid = [[0] * 3 for _ in range(2)] # not [[0] * 3] * 2 def add_good(item, bucket=None): ... # never bucket=[] hidden: list[int] = field(default_factory=lambda: [64, 32]) random.Random(seed).shuffle(order) # private generator sum(x * y for x, y in zip(a, b, strict=True)) # ValueError on a length mismatch for epoch in range(2): sizes = [len(b) for b in batches(range(10), 4)] # new generator each epoch raise ValueError(f"label must be an integer, got {text!r}") from None if __name__ == "__main__": # tests import without the demo ``` ## Questions type: qa from: phases/00-setup-and-tooling/06-python-environments/docs/en.md, phases/00-setup-and-tooling/13-python-for-ai-engineering/docs/en.md, phases/00-setup-and-tooling/01-dev-environment/docs/en.md - **One env for the whole course?** No. Phases need conflicting dependencies. Use a per-phase strategy. - **When conda?** For a CUDA toolkit without a system install, or on a shared cluster. - **Commit `.venv`?** No. Add `.venv/` to `.gitignore`. Commit `pyproject.toml` and the lockfile. - **No CUDA on a Mac?** That is expected. MPS is the Apple GPU backend. - **Why does `(3, 2)` with `(3,)` fail?** The trailing 2 and 3 differ. Use `keepdims=True`. ## Tips type: tips from: phases/00-setup-and-tooling/01-dev-environment/docs/en.md, phases/00-setup-and-tooling/06-python-environments/docs/en.md, phases/00-setup-and-tooling/13-python-for-ai-engineering/docs/en.md - Run every lesson command from the repository root. - Fix the first failed preflight line before you read the next one. - Install later tools when a lesson asks for them. - Give `encoding="utf-8"` to each file open. Open CSV files with `newline=""`. - Split the data before standardization. Fit statistics on the train split only. ## Editor and SSH commands type: command-table from: phases/00-setup-and-tooling/08-editor-setup/docs/en.md | Command | What it does | |---|---| | `code --install-extension ` | Install one extension by ID | | `code --list-extensions` | List installed extension IDs | | `ssh-keygen -t ed25519 -C ""` | Make an SSH key | | `ssh-copy-id user@your-gpu-box-ip` | Passwordless login to the GPU box | | `Remote-SSH: Connect to Host` | Open the remote folder as local | | `watch -n 1 nvidia-smi` | Watch the GPU in a split terminal |