A Copier template for machine learning research projects using PyTorch Lightning + Hydra + W&B
- PyTorch Lightning 2.x: High-level training framework
- Hydra 1.3+: Powerful configuration management
- W&B/TensorBoard/MLflow: Experiment tracking
- PyTorch Geometric: Graph Neural Networks (optional)
- uv: 10-100x faster Python package manager than pip
- pixi: Conda alternative with isolated CUDA environment (no host interference)
- Unified pyproject.toml: Single configuration file for both package managers
- ruff: Fast linter & formatter
- ty: Fast type checker (by Astral)
- pytest: Testing framework
| PyTorch | CUDA Versions |
|---|---|
| 2.9.0 | 12.6, 13.0 |
| 2.8.0 | 12.6, 12.8 |
| 2.7.1 | 11.8, 12.6 |
| 2.6.0 | 12.4 |
| 2.5.1 | 12.1 |
| 2.4.1 | 11.8 |
# Install uv
curl -LsSf https://astral.sh/uv/install.sh | sh
# Or install pixi
curl -fsSL https://pixi.sh/install.sh | bash# From GitHub (recommended)
uvx copier copy --trust gh:nishide-dev/ml-research-template my-project
# From local clone
git clone https://github.com/nishide-dev/ml-research-template.git
uvx copier copy --trust ./ml-research-template my-project
# Navigate to your project
cd my-project
# Start training
uv run python src/my_project/train.py # if using uv
pixi run train # if using pixiTip: Auto-fill author information from Git config:
uvx copier copy --trust gh:nishide-dev/ml-research-template my-project \
--data author_name="$(git config user.name)" \
--data author_email="$(git config user.email)"Interactive prompts will ask for:
Project Basics:
- Project name, package name, description
- Author name, email
- Python version (3.10, 3.11, 3.12, 3.13)
Package Manager:
uv: Fast, pip-compatible, PyTorch with bundled CUDApixi: Conda-based, isolated CUDA environment (.pixi/envs/)
PyTorch/CUDA Configuration:
- 9 presets (PyTorch 2.4-2.9, CUDA 11.8-13.0)
- Custom configuration available
- Optional torchvision / torchaudio
ML Frameworks:
- PyTorch Lightning (2.2, 2.3, 2.4)
- Hydra (1.2, 1.3)
- PyTorch Geometric (for GNNs)
Experiment Tracking:
- TensorBoard (simple)
- Weights & Biases (feature-rich)
- MLflow (on-premise)
- Both (TensorBoard + W&B)
- None
Development Tools:
- ruff (linter/formatter)
- ty (type checker)
- pytest (testing)
my-project/
βββ src/
β βββ my_project/
β βββ __init__.py
β βββ train.py # Main training script (Hydra)
β βββ models/
β β βββ __init__.py
β β βββ base_model.py # LightningModule
β βββ data/
β β βββ __init__.py
β β βββ datamodule.py # LightningDataModule
β βββ utils/
β βββ __init__.py
βββ tests/
β βββ __init__.py
β βββ test_my_project.py
βββ configs/ # Hydra configuration
β βββ config.yaml # Main config
β βββ model/
β β βββ default.yaml
β βββ data/
β β βββ default.yaml
β βββ trainer/
β β βββ default.yaml
β βββ logger/
β β βββ tensorboard.yaml
β β βββ wandb.yaml
β β βββ mlflow.yaml
β βββ experiment/
β βββ baseline.yaml
βββ pyproject.toml # Unified config (uv + pixi)
βββ ruff.toml # ruff config
βββ .gitignore
βββ .python-version
βββ README.md
# Train with default config
uv run python src/my_project/train.py
# Override parameters
uv run python src/my_project/train.py trainer.max_epochs=50 data.batch_size=64
# Use specific experiment config
uv run python src/my_project/train.py experiment=baseline# Override multiple parameters
uv run python src/my_project/train.py \
trainer.max_epochs=100 \
data.batch_size=128 \
model.learning_rate=0.001 \
logger.name=my_experiment
# Multi-run sweep (hyperparameter search)
uv run python src/my_project/train.py -m \
data.batch_size=32,64,128 \
model.learning_rate=0.0001,0.001,0.01# TensorBoard
tensorboard --logdir logs/
# Weights & Biases (login required)
wandb login
uv run python src/my_project/train.py
# MLflow
mlflow ui --backend-store-uri file:./mlruns# Format and lint
uv run ruff format .
uv run ruff check . --fix
# Type check
uv run ty check src/
# Run tests
uv run pytest tests/ -v
# Run tests with coverage
uv run pytest --cov=src --cov-report=html# Test with defaults
uvx copier copy --trust --defaults . /tmp/test-project
# Test with custom config
uvx copier copy --trust \
--data project_name="test-ml" \
--data python_version="3.12" \
--data package_manager="uv" \
--data pytorch_cuda_preset="pytorch-2.8.0-cuda-12.6" \
--data use_lightning=true \
--data use_hydra=true \
--data logger_choice="tensorboard" \
. /tmp/test-project
# Verify the generated project
cd /tmp/test-project
uv sync
uv run pytest tests/
uv run ruff check .# Update existing project with latest template
uvx copier update /path/to/my-projectBoth uv and pixi package managers use a single pyproject.toml file:
- UV users: Uses
[tool.uv]sections with PyTorch wheel indexes (bundled CUDA) - Pixi users: Uses
[tool.pixi.*]sections with conda CUDA toolkit (isolated in.pixi/envs/)
Pixi projects provide complete CUDA isolation from the host system:
[tool.pixi.activation]
env = { PYTHONNOUSERSITE = "1" } # Isolate from ~/.local
[tool.pixi.dependencies]
cuda = { version = "12.6.*", channel = "nvidia" } # Isolated CUDABenefits:
- No interference with host CUDA installations
- Reproducible GPU environments across machines
- Multiple CUDA versions on same machine (different projects)
Verification:
pixi run python -c "import torch; print(torch.__file__)"
# Output: /path/to/project/.pixi/envs/default/lib/python3.11/site-packages/torch/- uv: Fast Python package manager
- pixi: Fast Conda alternative
- PyTorch Lightning: PyTorch training framework
- Hydra: Configuration management framework
Contributions are welcome! See CONTRIBUTING.md for details.
MIT License - see LICENSE for details.
- Issues: GitHub Issues
- Discussions: GitHub Discussions
Made with β€οΈ for ML researchers