Set Up Python for Finetuning

Set up a Python environment for finetuning with this hands-on LLM Finetuning tutorial. Learn the essentials, avoid common pitfalls, and get ready for the next lesson.

Focus: set up a python environment for finetuning

Sponsored

You’ve got a great model in mind and a dataset ready to go — but the moment you try to install that training library, you hit a wall. Dependency conflicts, CUDA mismatches, and a pip install that silently breaks your system Python have brought countless finetuning experiments to a screeching halt. This lesson is your escape hatch: learn how to set up a Python environment for finetuning so that your LLM training runs are reproducible, isolated, and pain-free from the very first command.

The problem this lesson solves

Finetuning an LLM is not a simple pip install transformers. It pulls in a deep stack: PyTorch or TensorFlow, tokenizers, datasets, peft, bitsandbytes, and GPU drivers. Each of these has its own version constraints. A single wrong version can cause obscure runtime errors or, worse, silent numerical inconsistencies that degrade your model.

The classic mistake is installing everything into the global Python environment. Over time, packages accumulate, versions clash, and one upgrade breaks another. You end up in dependency hell — a place where pip freeze output looks like a horror novel and your system scripts start failing for reasons you can’t trace.

Even if you’re only following tutorials, a clean, reproducible environment is the backbone of successful finetuning. It lets you:

  • Isolate conflicting dependencies (e.g., one project needs torch==2.1, another needs 2.2).
  • Replicate your setup on a new machine or a colleague’s workstation in minutes.
  • Avoid polluting your base Python installation, which might be critical for system tools.

More importantly, the setup you build here becomes the launchpad for every subsequent step in this track: preparing data, choosing a base model, running a LoRA finetune, and evaluating the results. Get the environment right once, and the rest becomes far smoother.

Core concept / mental model

Think of a Python environment as a workbench with its own set of tools. Your base Python is the warehouse floor — shared, cluttered, and risky for delicate work. A virtual environment (venv) gives you a clean, dedicated bench where every tool (library) is exactly the version you need, and you can pack it up and move it anywhere without touching the warehouse.

For LLM finetuning, the environment is more than just pip — it’s the GPU stack. This includes:

  • Python — the interpreter itself (3.10+ recommended).
  • Package manager — pip or conda, which fetches and installs libraries.
  • Deep learning framework — PyTorch or TensorFlow, the engine that runs your model.
  • CUDA toolkit and drivers — the bridge between PyTorch and your NVIDIA GPU.
  • Hugging Face ecosystemtransformers, datasets, peft, accelerate, bitsandbytes.

Here’s a simple mental diagram of the stack:

Your finetuning script
        |
    transformers / peft
        |
       torch
        |
      CUDA / CUDNN
        |
      GPU drivers

Each layer depends on the one below it. If the bottom is misconfigured, everything above suffers.

A virtual environment isolates the Python-level packages. But it does not isolate the GPU driver or CUDA version — those are system-level. That’s why tools like Docker exist to containerize the entire stack. For this lesson, we focus on the virtual environment layer, which is the most common and practical starting point.

How it works step by step

Setting up a Python environment for finetuning follows a logical sequence. Let’s break it down.

1. Choose your package manager

You have two main options: pip + venv (the standard Python approach) or conda (a more heavyweight package manager that also handles non-Python dependencies). For most finetuning work, pip + venv is sufficient and more aligned with modern Python best practices. Conda shines when you need to manage Python versions or install non-Python binaries like CUDA libraries — but it can introduce its own complexities.

2. Create a virtual environment

The venv module (built into Python 3.3+) creates a lightweight, isolated directory containing its own Python executable and pip. Activating it changes your shell’s PATH so python and pip point to the environment’s versions.

3. Install core dependencies

First, install the deep learning framework. For NVIDIA GPUs, you need a version of PyTorch that matches your CUDA version. The official PyTorch website provides a quick-start command. Then install the Hugging Face ecosystem packages.

4. Verify everything works

A quick sanity check that imports torch and checks CUDA availability confirms the GPU stack is functioning. You don’t want to discover a missing driver mid-training.

5. Document your environment

Save the exact package versions to a requirements.txt file (or use pip freeze) so you can reproduce the setup later.

Hands-on walkthrough

Let’s put this into practice. I’ll assume you have Python 3.10+ and a terminal open. First, check your Python version:

python --version

If you don’t have Python 3.10+, install it via your system package manager or from python.org. Now, create and activate a virtual environment:

# Create a project directory (if you haven't already)
mkdir llm-finetuning
cd llm-finetuning

# Create a virtual environment named 'venv'
python -m venv venv

# Activate it (Linux/macOS)
source venv/bin/activate

# On Windows use:
# venv\Scripts\activate

Your prompt should now show (venv) at the beginning. To confirm, run which python and you should see the path inside your project directory.

Now install the core packages. Start with PyTorch. The installation command depends on your GPU and CUDA version. For CUDA 12.1 (a common version), use:

pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121

If you don’t have an NVIDIA GPU, install the CPU version:

pip install torch torchvision torchaudio

Next, install the Hugging Face libraries:

pip install transformers datasets peft accelerate bitsandbytes

Pro tip: Always use pip inside the active virtual environment. You can check this by running pip -V — if it shows the venv path, you’re good.

Now, verify the installation with a quick script. Create check_env.py:

import torch
import transformers
import datasets

print("PyTorch version:", torch.__version__)
print("CUDA available:", torch.cuda.is_available())
if torch.cuda.is_available():
    print("GPU name:", torch.cuda.get_device_name(0))

print("Transformers version:", transformers.__version__)
print("Datasets version:", datasets.__version__)

Run it:

python check_env.py

Expected output (your versions may differ):

PyTorch version: 2.3.0+cu121
CUDA available: True
GPU name: NVIDIA GeForce RTX 4080
Transformers version: 4.40.0
Datasets version: 2.19.0

If CUDA is not available, your GPU drivers or CUDA installation need attention — we’ll cover that in troubleshooting.

Finally, document your environment:

pip freeze > requirements.txt

This file lets you recreate the exact environment with pip install -r requirements.txt on another machine.

Compare options / when to choose what

Here’s a comparison of the most common environment management approaches for finetuning:

Approach Pros Cons Best for
pip + venv Lightweight, built into Python, simple No control over Python version; can’t install non-Python binaries Standard projects, most finetuning tasks
conda Manages Python versions, can install CUDA toolkit Slower, heavier, sometimes conflicts with pip Complex environments needing exact Python or CUDA
Docker Isolates entire OS, perfect reproducibility Steeper learning curve, resource overhead Production deployments, team collaboration

For most developers starting out, pip + venv is the sweet spot. It’s simple, transparent, and sufficient for running finetuning scripts with PyTorch and Hugging Face. If you later need to move to a GPU cluster or share your setup with a team, you can wrap the same requirements.txt in a Dockerfile.

Troubleshooting & edge cases

Even with a clean setup, things go wrong. Here are the most common issues and their fixes.

"CUDA is not available" after installing PyTorch

Symptom: torch.cuda.is_available() returns False.

Causes:

  • NVIDIA GPU drivers aren’t installed or too old. Run nvidia-smi — if it fails, install drivers.
  • PyTorch was installed for CPU only. Reinstall with the correct --index-url for your CUDA version.
  • CUDA version mismatch. Check your driver’s CUDA version with nvidia-smi and match it (e.g., cu121 for CUDA 12.1).

pip shows a system path instead of your venv

Symptom: pip -V points to /usr/bin/pip.

Fix: Deactivate and reactivate the venv. Sometimes the activation command fails silently if your shell isn’t Bash/Zsh or you’re in a subshell. Use source venv/bin/activate again, or use venv/bin/pip directly.

Memory errors during package installation

Symptom: Killed or MemoryError when installing large packages like torch.

Fix: Reduce pip’s cache usage: pip install --no-cache-dir <package>. Or install with --no-deps and then add dependencies manually.

Version conflicts between transformers and torch

Symptom: Import errors like cannot import name X from transformers.

Fix: Upgrade all packages together: pip install --upgrade transformers datasets peft accelerate. If it persists, create a fresh venv and reinstall from requirements.txt.

Forgetting to activate the venv

Symptom: Your script runs but uses the global Python, missing packages.

Fix: Always check your prompt. If you don't see (venv), activate it. For automation, you can prefix commands with venv/bin/python to be explicit.

What you learned & what's next

You now know how to set up a Python environment for finetuning — the core concept of isolation, the step-by-step creation of a venv, installing the GPU stack, and verifying your setup. You can also troubleshoot common pitfalls like CUDA availability and dependency conflicts. This foundation is crucial for everything that follows.

Next lesson: you’ll move from the environment to the data preparation phase. You’ll learn how to load, clean, and format your dataset for finetuning, building on the clean workspace you’ve just created. Your environment is the canvas; data is the paint — get ready to create your masterpiece.

Practice recap

Create a new virtual environment named test-env, install only torch and transformers, and run a short script that prints the versions and checks CUDA. Then delete the environment with deactivate and rm -rf test-env to confirm the isolation works. This drills the core setup process you need for the next lesson.

Common mistakes

  • Installing packages into the global Python instead of a venv — leads to dependency conflicts and a broken system Python. Always activate the environment first.
  • Checking torch.cuda.is_available() returns False — this usually means you installed the CPU-only PyTorch version or your GPU drivers are outdated. Use the correct --index-url for your CUDA version.
  • Ignoring the CUDA version — your PyTorch must match the CUDA version supported by your GPU driver. Running nvidia-smi tells you the driver’s CUDA version; install PyTorch accordingly.
  • Forgetting to save requirements.txt — you can't reproduce the environment without it. Always pip freeze > requirements.txt after a successful setup.
  • Activating the venv in the wrong shell (e.g., using source venv/bin/activate in Windows CMD) — use the correct activation command per your OS and shell.

Variations

  1. Instead of pip + venv, you can use conda: conda create -n llm-finetune python=3.10 then conda activate llm-finetune. This manages Python versions more flexibly.
  2. For fully reproducible GPUs, use Docker with a PyTorch base image. This isolates the entire OS stack, not just Python packages.
  3. Some practitioners use virtualenv instead of venv; it's similar but allows you to choose a specific Python version (e.g., virtualenv -p python3.11 myenv).

Real-world use cases

  • Data scientist sets up a reproducible environment to train a custom NER model with LoRA on a shared GPU server.
  • ML engineer uses a Docker-based setup to deploy a finetuning pipeline to a cloud VM, ensuring identical dependencies across stages.
  • Research team reproduces a paper's finetuning results by sharing a requirements.txt with exact package versions.

Key takeaways

  • A Python virtual environment isolates your finetuning dependencies and prevents system-wide conflicts.
  • The GPU stack — Python, PyTorch, CUDA, and drivers — must be version-matched; verify with nvidia-smi and torch.cuda.is_available().
  • Install PyTorch with the correct --index-url for your CUDA version to ensure GPU acceleration.
  • Document your environment with pip freeze > requirements.txt for reproducibility.
  • For complex or production scenarios, consider conda or Docker instead of a bare venv.
  • Troubleshooting common issues like CUDA unavailability or version conflicts is a skill that saves hours.

Sponsored

Sponsored

Discussion

Questions, corrections, and tips help everyone reading this page.

0 comments

Add a comment

Shown publicly with your comment.

Be constructive · max 4,000 characters

No comments yet — start the thread.

Related tutorials, quizzes, and articles for this topic.