| 3 min read

Python Virtual Environments for AI Project Isolation

Python virtual environments venv dependency management AI development

Why Isolation Matters for AI Projects

AI projects have notoriously complex dependency trees. PyTorch 2.x needs one version of numpy. An older project uses TensorFlow which pins a different version. Whisper needs a specific ffmpeg-python version. Without isolation, installing dependencies for one project breaks another.

I learned this the hard way when a pip install for a new project silently upgraded numpy and broke three existing projects on my server. Since then, every project gets its own virtual environment, no exceptions.

The Basics: venv

Python's built-in venv module is all you need. No need for conda, pipenv, or poetry for most AI projects (though they have their place):

# Create a virtual environment
python3 -m venv /home/user/projects/my-ai-project/venv

# Activate it
source /home/user/projects/my-ai-project/venv/bin/activate

# Install dependencies
pip install -r requirements.txt

# Deactivate when done
deactivate

Once activated, python and pip point to the virtual environment's copies. Anything you install goes into the venv directory, not the system Python.

My Project Structure

I follow a consistent structure for every AI project:

my-ai-project/
  venv/              # Virtual environment (git-ignored)
  src/               # Source code
  data/              # Data files (git-ignored)
  models/            # Model files (git-ignored)
  requirements.txt   # Pinned dependencies
  requirements-dev.txt  # Development dependencies
  .env               # Environment variables (git-ignored)
  .gitignore

The .gitignore always excludes the venv directory. Never commit virtual environments to version control.

Managing Dependencies Properly

Pinning Versions

Always pin exact versions in requirements.txt for production projects:

# Good: pinned versions
openai==1.12.0
whisper==1.1.10
httpx==0.27.0
numpy==1.26.4

# Bad: unpinned versions
openai
whisper
httpx
numpy

Generate a pinned requirements file from your current working environment:

pip freeze > requirements.txt

This captures every installed package with exact versions, ensuring reproducible installations.

Separating Dev Dependencies

Keep development tools separate from production dependencies:

# requirements-dev.txt
-r requirements.txt  # Include production deps
pytest==8.0.0
black==24.1.0
ruff==0.2.0
ipython==8.21.0

On your development machine, install with pip install -r requirements-dev.txt. On the production server, use just requirements.txt.

Working with Multiple Projects

On my production server, I run nine different AI services. Each has its own venv. Here is how I manage them:

Activation Aliases

I add shell aliases for frequently used projects:

# In ~/.bashrc
alias activate-video="source /home/user/video-pipeline/venv/bin/activate"
alias activate-blog="source /home/user/blog-generator/venv/bin/activate"
alias activate-api="source /home/user/api-server/venv/bin/activate"

PM2 with Virtual Environments

When using PM2 to manage Python services, specify the venv Python path directly:

// ecosystem.config.js
module.exports = {
  apps: [{
    name: 'video-pipeline',
    script: '/home/user/video-pipeline/venv/bin/python',
    args: '/home/user/video-pipeline/src/main.py',
    cwd: '/home/user/video-pipeline'
  }]
}

This avoids activation scripts entirely. PM2 just calls the venv's Python binary directly, which is cleaner for process management.

Common Pitfalls

  • System packages leaking in: Some system Python packages are visible inside venvs by default. Create venvs with --system-site-packages only when you deliberately need this.
  • Python version mismatches: If you create a venv with Python 3.11 and later upgrade your system to Python 3.12, the venv breaks. Recreate it with the new Python version.
  • Large venvs: AI projects with PyTorch can create multi-gigabyte venvs. Monitor disk space and clean unused venvs regularly.
  • Forgetting to activate: Running pip install without activating the venv installs to the system Python. I have done this more times than I care to admit.

When to Use Conda Instead

For projects that need specific CUDA versions, system-level C libraries, or non-Python dependencies, conda is a better choice. It manages both Python packages and system dependencies. But for pure-Python AI projects that use pip-installable packages, venv is simpler and lighter.

The Discipline

Virtual environments are not exciting. They are housekeeping. But the 30 seconds it takes to create a venv for a new project saves hours of dependency debugging later. Make it a habit: new project, new venv, no exceptions.