diff --git a/.gitignore b/.gitignore index be6b700a..711f6022 100644 --- a/.gitignore +++ b/.gitignore @@ -20,7 +20,6 @@ parts/ sdist/ var/ wheels/ -share/python-wheels/ *.egg-info/ .installed.cfg *.egg @@ -39,17 +38,14 @@ pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ -.nox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover -*.py,cover .hypothesis/ .pytest_cache/ -cover/ # Translations *.mo @@ -59,7 +55,6 @@ cover/ *.log local_settings.py db.sqlite3 -db.sqlite3-journal # Flask stuff: instance/ @@ -70,51 +65,19 @@ instance/ # Sphinx documentation docs/_build/ +_docs/ # PyBuilder -.pybuilder/ target/ # Jupyter Notebook .ipynb_checkpoints -# IPython -profile_default/ -ipython_config.py - # pyenv -# For a library or package, you might want to ignore these files since the code is -# intended to run in multiple environments; otherwise, check them in: -# .python-version +.python-version -# pipenv -# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. -# However, in case of collaboration, if having platform-specific dependencies or dependencies -# having no cross-platform support, pipenv may install dependencies that don't work, or not -# install all needed dependencies. -#Pipfile.lock - -# poetry -# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. -# This is especially recommended for binary packages to ensure reproducibility, and is more -# commonly ignored for libraries. -# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control -#poetry.lock - -# pdm -# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. -#pdm.lock -# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it -# in version control. -# https://pdm.fming.dev/#use-with-ide -.pdm.toml - -# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm -__pypackages__/ - -# Celery stuff +# celery beat schedule file celerybeat-schedule -celerybeat.pid # SageMath parsed files *.sage.py @@ -127,23 +90,29 @@ venv/ ENV/ env.bak/ venv.bak/ +tinytorch-env/ -# TinyTorch specific -.venv/ -*.log -logs/ -checkpoints/ -runs/ -wandb/ +# Spyder project settings +.spyderproject +.spyproject -# IDE files +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ + +# IDE .vscode/ .idea/ *.swp *.swo *~ -# OS generated files +# OS .DS_Store .DS_Store? ._* @@ -152,6 +121,40 @@ wandb/ ehthumbs.db Thumbs.db +# Logs +*.log +logs/ + +# TinyTorch specific +checkpoints/ +experiments/ +runs/ +wandb/ + +# nbdev specific - we keep notebooks and exported Python code +# Everything else is auto-generated and shouldn't be tracked + +# OLD STRUCTURE - Remove these when migrating +modules/ +# We now use notebooks/ and let nbdev handle exports + +# Training artifacts +*.pth +*.pt +*.ckpt +model_*.json +training_*.json + +# Data (too large for git) +data/ +datasets/ +*.csv +*.npz +*.npy +*.pickle +*.pkl + # Temporary files -*.tmp -*.temp \ No newline at end of file +tmp/ +temp/ +*.tmp \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..2f04311c --- /dev/null +++ b/Makefile @@ -0,0 +1,96 @@ +# TinyTorch - Notebook-first ML Systems Course +# Makefile for convenience commands + +.PHONY: help install sync test clean docs jupyter lab setup + +# Default target +help: + @echo "TinyTorch - Build ML Systems from Scratch" + @echo "==========================================" + @echo "" + @echo "Available commands:" + @echo "" + @echo " install Install dependencies and setup environment" + @echo " sync Export notebook code to Python package" + @echo " test Run all tests" + @echo " test-setup Run setup module tests" + @echo " clean Clean notebook outputs and cache" + @echo " docs Build documentation" + @echo " jupyter Start Jupyter Lab" + @echo " info Show system information" + @echo " doctor Run environment diagnosis" + @echo "" + @echo "Development workflow:" + @echo " 1. make jupyter # Work in notebooks/" + @echo " 2. make sync # Export to Python" + @echo " 3. make test # Run tests" + @echo " 4. make docs # Build docs (optional)" + +# Install dependencies +install: + @echo "πŸ”§ Installing TinyTorch dependencies..." + pip install -r requirements.txt + pip install nbdev jupyter + @echo "βœ… Installation complete!" + +# Export notebooks to Python package +sync: + @echo "πŸ”„ Exporting notebooks to Python package..." + python bin/tito.py sync + +# Run all tests +test: + @echo "πŸ§ͺ Running all tests..." + python bin/tito.py test --all + +# Run setup module tests specifically +test-setup: + @echo "πŸ§ͺ Running setup module tests..." + python bin/tito.py test --module setup + +# Clean notebook outputs and Python cache +clean: + @echo "🧹 Cleaning notebook outputs and cache..." + python bin/tito.py nbdev --clean + find . -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true + find . -type f -name "*.pyc" -delete 2>/dev/null || true + @echo "βœ… Cleanup complete!" + +# Build documentation +docs: + @echo "πŸ“š Building documentation..." + python bin/tito.py nbdev --build-docs + +# Start Jupyter Lab +jupyter: + @echo "πŸš€ Starting Jupyter Lab..." + python bin/tito.py jupyter --lab + +# Alias for jupyter +lab: jupyter + +# Show system information +info: + @echo "ℹ️ System information..." + python bin/tito.py info + +# Run environment diagnosis +doctor: + @echo "πŸ”¬ Running environment diagnosis..." + python bin/tito.py doctor + +# Setup new environment (for first-time users) +setup: + @echo "πŸš€ Setting up TinyTorch development environment..." + @echo "1. Creating virtual environment..." + python -m venv .venv + @echo "2. Installing dependencies..." + .venv/bin/pip install -r requirements.txt + .venv/bin/pip install nbdev jupyter + @echo "" + @echo "βœ… Setup complete!" + @echo "" + @echo "Next steps:" + @echo " 1. Activate the environment: source .venv/bin/activate" + @echo " 2. Start coding: make jupyter" + @echo " 3. Test your code: make sync && make test" \ No newline at end of file diff --git a/QUICKSTART.md b/QUICKSTART.md new file mode 100644 index 00000000..c7ae2773 --- /dev/null +++ b/QUICKSTART.md @@ -0,0 +1,301 @@ +# πŸš€ TinyTorch Quick Start Guide + +Get up and running with TinyTorch in 10 minutes! This guide will walk you through setting up your environment and implementing your first ML component. + +## πŸ“‹ Prerequisites + +- **Python 3.8+** (check with `python --version`) +- **Git** for cloning the repository +- **Basic Python knowledge** (functions, classes, imports) +- **Jupyter** familiarity (we'll install it for you) + +## ⚑ 5-Minute Setup + +### Step 1: Clone and Navigate +```bash +git clone https://github.com/tinytorch/TinyTorch.git +cd TinyTorch +``` + +### Step 2: Create Virtual Environment +```bash +# Create isolated environment +python -m venv .venv + +# Activate it +source .venv/bin/activate # Linux/Mac +# OR: .venv\Scripts\activate # Windows +``` + +### Step 3: Install Dependencies +```bash +# Install all required packages +pip install -r requirements.txt + +# This installs: numpy, matplotlib, jupyter, nbdev, pytest, and more +``` + +### Step 4: Verify Installation +```bash +# Check TinyTorch CLI +python bin/tito.py --version + +# Check environment +python bin/tito.py info +``` + +**βœ… If you see system information, you're ready to go!** + +## 🎯 Your First Module: Setup + +Let's implement your first TinyTorch component to understand the workflow. + +### Step 1: Navigate to Setup Module +```bash +cd modules/setup/ +``` + +### Step 2: Read the Module Overview +```bash +# This explains what you'll build +cat README.md +``` + +### Step 3: Open the Development Notebook +```bash +# Start Jupyter Lab +jupyter lab setup.ipynb + +# The notebook will open in your browser at http://localhost:8888 +``` + +### Step 4: Follow the Notebook +The notebook guides you through: +1. **Environment check** - Verify everything works +2. **Hello function** - Implement `hello_tinytorch()` +3. **Export process** - Learn the `#| export` directive +4. **Testing** - Run interactive tests + +### Step 5: Export Your Code +```bash +# Back in terminal (new tab/window): +cd /path/to/TinyTorch # Navigate back to root + +# Export notebook code to Python package +python bin/tito.py sync +``` + +This creates `tinytorch/core/utils.py` with your function! + +### Step 6: Test Your Implementation +```bash +# Run automated tests +python bin/tito.py test --module setup + +# Should show: βœ… All tests passed! +``` + +### Step 7: Verify Integration +```bash +# Test that your function is importable +python -c "from tinytorch.core.utils import hello_tinytorch; print(hello_tinytorch())" +``` + +**πŸŽ‰ Congratulations! You've completed your first module!** + +## πŸ”„ The TinyTorch Development Workflow + +Now you understand the core workflow that you'll use for every module: + +```mermaid +graph LR + A[Read README] --> B[Open Notebook] + B --> C[Implement Code] + C --> D[Mark #|export] + D --> E[Test in Notebook] + E --> F[Export with tito sync] + F --> G[Run Tests] + G --> H{Tests Pass?} + H -->|No| C + H -->|Yes| I[Next Module] +``` + +### Key Commands Reference + +| Command | Purpose | When to Use | +|---------|---------|-------------| +| `cat README.md` | Read module overview | Start of each module | +| `jupyter lab [module].ipynb` | Open development environment | Implement code | +| `python bin/tito.py sync` | Export notebooks to package | After coding in notebook | +| `python bin/tito.py test --module [name]` | Test your implementation | Verify correctness | +| `python bin/tito.py info` | Check system status | Anytime | + +## πŸ§— Next Steps: Building Your First Tensor + +Ready for the real challenge? Let's build the foundation of TinyTorch! + +### Step 1: Move to Tensor Module +```bash +cd modules/tensor/ +``` + +### Step 2: Read the Overview +```bash +cat README.md +``` + +### Step 3: Start Building +```bash +jupyter lab tensor.ipynb +``` + +In this module, you'll implement: +- **Tensor class** - Multi-dimensional arrays +- **Arithmetic operations** - Addition, multiplication +- **Utility methods** - Reshape, transpose, sum +- **Error handling** - Robust edge cases + +### Expected Timeline +- **Setup module**: 15-30 minutes +- **Tensor module**: 2-4 hours +- **Complete course**: 40-80 hours (over several weeks) + +## πŸ› οΈ Development Environment Tips + +### Jupyter Lab Shortcuts +- **Shift + Enter**: Run cell and move to next +- **Ctrl + Enter**: Run cell and stay +- **A**: Insert cell above +- **B**: Insert cell below +- **DD**: Delete cell + +### TinyTorch Best Practices +1. **Read module READMEs first** - Understand objectives +2. **Test frequently** - Don't implement everything at once +3. **Use `#| export` correctly** - Only mark code for the package +4. **Write docstrings** - Document your functions +5. **Check tests** - They show exactly what's expected + +### Common Issues and Solutions + +#### "ModuleNotFoundError" +```bash +# Make sure you've activated your environment +source .venv/bin/activate + +# And exported your notebooks +python bin/tito.py sync +``` + +#### "Command 'tito' not found" +```bash +# Use the full path +python bin/tito.py [command] + +# Make sure you're in the TinyTorch root directory +pwd # Should end with /TinyTorch +``` + +#### "Tests failing" +```bash +# Run with verbose output to see details +python bin/tito.py test --module setup -v + +# Check the specific error messages +# Fix in the notebook, then re-export and test +``` + +#### "Jupyter not starting" +```bash +# Make sure it's installed +pip install jupyter jupyterlab + +# Try classic notebook instead +jupyter notebook modules/setup/setup.ipynb +``` + +## πŸ“š Learning Path + +### Beginner Track (Start Here) +1. **Setup** (30 min) - Learn the workflow +2. **Tensor** (4 hours) - Core data structures +3. **MLP** (6 hours) - Basic neural networks + +### Intermediate Track +4. **Autograd** (8 hours) - Automatic differentiation +5. **CNN** (6 hours) - Convolutional networks +6. **Training** (4 hours) - Training loops and optimizers + +### Advanced Track +7. **Data** (3 hours) - Efficient data loading +8. **Kernels** (10 hours) - Custom GPU operations +9. **Compression** (6 hours) - Model optimization + +### Expert Track +10. **Profiling** (4 hours) - Performance analysis +11. **Benchmarking** (4 hours) - Systematic evaluation +12. **Config** (2 hours) - Configuration management +13. **MLOps** (8 hours) - Production systems + +## 🎯 Success Metrics + +You'll know you're succeeding when: + +### After Each Module +- βœ… All tests pass: `python bin/tito.py test --module [name]` +- βœ… Code is importable: `from tinytorch.core.X import Y` +- βœ… You understand what you built +- βœ… Ready for the next module + +### After Major Milestones +- **Tensor complete**: Can create and manipulate multi-dimensional arrays +- **MLP complete**: Can build and train simple neural networks +- **CNN complete**: Can implement convolutional architectures +- **Course complete**: You've built a complete ML framework! + +## πŸ’‘ Getting Help + +### Self-Help Resources +1. **Module READMEs** - Detailed explanations and tips +2. **Test files** - Show exactly what's expected +3. **Notebook examples** - See reference implementations +4. **Error messages** - Often contain helpful guidance + +### Debugging Workflow +1. **Read the error** - Understand what failed +2. **Check the test** - See what was expected +3. **Review the notebook** - Look for implementation issues +4. **Test incrementally** - Don't implement everything at once +5. **Use print statements** - Debug your logic + +### Community Support +- **GitHub Issues** - Report bugs or ask questions +- **Discussions** - Share tips and solutions +- **Study Groups** - Find fellow learners + +## πŸš€ Ready to Build? + +You now have everything you need to start building ML systems from scratch! + +```bash +# Quick reminder of the workflow: +cd modules/setup/ # Navigate to module +cat README.md # Read overview +jupyter lab setup.ipynb # Start implementing +# [work in notebook] +python bin/tito.py sync # Export to package +python bin/tito.py test --module setup # Test implementation +``` + +**Welcome to TinyTorch! Let's build something amazing! πŸ”₯** + +--- + +## πŸ“– What's Next? + +After completing the QUICKSTART: +- **Dive deeper**: Read `COURSE_GUIDE.md` for the complete curriculum +- **Understand the structure**: Review `STRUCTURE_PROPOSAL.md` for architecture details +- **Stay updated**: Check `README.md` for the latest information + +Happy coding! πŸŽ‰ \ No newline at end of file diff --git a/README.md b/README.md index 1aade59e..eb3a3c9c 100644 --- a/README.md +++ b/README.md @@ -1,450 +1,236 @@ -# TinyπŸ”₯Torch: Build a Machine Learning System from Scratch +# πŸ”₯ TinyTorch: Build ML Systems from Scratch -TinyTorch is a pedagogical project designed to accompany the [*Machine Learning Systems*](https://mlsysbook.ai) textbook. Inspired by OS and compiler courses where students build entire systems from first principles, TinyTorch guides you through building a complete ML training and inference runtime β€” from autograd to data pipelines, optimizers to profilers β€” **entirely from scratch**. +> A hands-on systems course where you implement every component of a modern ML system -This is not a PyTorch tutorial. In TinyTorch, you'll **write the components that frameworks like PyTorch are built on.** +[![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/) +[![License](https://img.shields.io/badge/license-Apache%202.0-green.svg)](LICENSE) +[![nbdev](https://img.shields.io/badge/built%20with-nbdev-orange.svg)](https://nbdev.fast.ai/) ---- +TinyTorch is a comprehensive machine learning systems course where you'll build everything from tensors to production monitoring systems. Using a **module-first** approach, students work in self-contained modules while building a complete ML framework. ## 🎯 What You'll Build -By the end of this project, you'll have implemented a fully functional ML system capable of: +By the end of this course, you will have implemented: -- **Training neural networks** (MLPs, CNNs) on real datasets 10) -- **Automatic differentiation** with a custom autograd engine -- **Memory-efficient data loading** with custom DataLoader implementations -- **Multiple optimization algorithms** (SGD, Adam, RMSprop) -- **Performance profiling** and bottleneck identification -- **Model compression** through pruning and quantization -- **Custom compute kernels** for matrix operations -- **Production monitoring** with MLOps infrastructure -- **Reproducible experiments** with checkpointing and logging +- βœ… **Core tensor operations** with automatic differentiation +- βœ… **Neural network layers** (Linear, CNN, RNN, Transformer) +- βœ… **Training algorithms** (SGD, Adam, distributed training) +- βœ… **Data pipelines** with efficient loading and preprocessing +- βœ… **Model compression** (pruning, quantization, distillation) +- βœ… **Performance optimization** (profiling, kernel fusion) +- βœ… **Production systems** (deployment, monitoring, MLOps) -**End Goal**: Train a CNN on CIFAR-10 achieving >85% accuracy using only your implementation. +## πŸš€ Quick Start ---- +### 1. Setup Environment -## 🧠 Project Goals & Learning Objectives - -### Core Learning Objectives -- **Systems Understanding**: Learn how modern ML systems are constructed, not just how to use them -- **Full-Stack ML Infrastructure**: Build core components from tensor operations to training orchestration -- **Performance Engineering**: Understand computational and memory bottlenecks in ML workloads -- **Software Architecture**: Design modular, extensible systems with clean abstractions -- **Infrastructure Thinking**: Make design decisions that impact performance, reproducibility, and maintainability - -### Technical Skills Gained -- **Low-level ML Implementation**: Tensor operations, gradient computation, optimization algorithms -- **Memory Management**: Efficient data structures, gradient accumulation, batch processing -- **Performance Optimization**: Profiling, kernel optimization, memory access patterns -- **System Design**: Modular architecture, clean APIs, extensible frameworks -- **Testing & Validation**: Numerical stability, gradient checking, performance regression testing - ---- - -## πŸ—οΈ System Architecture - -### Core Components Overview - -``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ TinyTorch System β”‚ -β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ -β”‚ CLI Interface (bin/tito.py) β”‚ -β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ -β”‚ Training Orchestration (trainer.py) β”‚ -β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ -β”‚ Model Definition β”‚ Data Pipeline β”‚ Optimization β”‚ -β”‚ (modules.py) β”‚ (dataloader.py) β”‚ (optimizer.py) β”‚ -β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ -β”‚ Automatic Differentiation Engine (autograd) β”‚ -β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ -β”‚ Tensor Operations & Storage (tensor.py) β”‚ -β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ -β”‚ Profiling & MLOps (profiler.py, mlops.py) β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -``` - -### Design Principles -1. **Modularity**: Each component has a single responsibility and clean interfaces -2. **Composability**: Components can be mixed and matched for different use cases -3. **Performance**: Designed for efficiency without sacrificing readability -4. **Extensibility**: Easy to add new layers, optimizers, and functionality -5. **Debuggability**: Built-in profiling and logging for understanding system behavior - ---- - -## πŸ“š Curriculum Integration & Roadmap - -TinyTorch aligns with **Chapters 1–13** of the [*Machine Learning Systems*](https://mlsysbook.ai) textbook. Each project builds progressively toward a complete ML infrastructure. - -### πŸ“š Course Details & Learning Objectives - -Each project is inspired by key themes from the [*Machine Learning Systems*](https://mlsysbook.ai) textbook: - -### πŸ“– Part I: The Essentials (Chapters 1-4) -*Core principles, components, and architectures* - -| Project | Chapter | Core Learning | Key Deliverable | -|---------|---------|---------------|-----------------| -| Setup | 1 (Introduction) | Environment setup, tool familiarity | Working dev environment + CLI | -| Tensor | 2 (ML Systems) | Basic tensor operations, NumPy-style | Simple Tensor class with math ops | -| MLP | 3 (DL Primer) | Forward pass, manual backprop | Train MLP on MNIST (manual gradients) | -| CNN | 4 (DNN Architectures) | Convolution concepts, architectures | Basic conv implementation | - -### πŸ—οΈ Part II: Engineering Principles (Chapters 5-13) -*Workflows, data engineering, optimization strategies, and operational challenges* - -| Project | Chapter | Core Learning | Key Deliverable | -|---------|---------|---------------|-----------------| -| Data | 6 (Data Engineering) | Efficient data loading, batching | Custom DataLoader with transformations | -| Training | 8 (AI Training) | **Autograd engine**, optimization algorithms | Complete training system with autodiff | -| Profiling | 9 (Efficient AI) | Performance measurement, debugging | Memory/compute profiler with visualizations | -| Compression | 10 (Model Optimizations) | Pruning, quantization techniques | Compress model while maintaining accuracy | -| Kernels | 11 (AI Acceleration) | Low-level optimization, vectorization | Optimized matrix multiplication kernels | -| Benchmarking | 12 (Benchmarking AI) | Performance testing, comparison | Comprehensive benchmarking suite | -| MLOps | 13 (ML Operations) | Production monitoring, deployment | MLOps pipeline with drift detection | - -**Note**: Chapters 5 (AI Workflow) and 7 (AI Frameworks) provide conceptual frameworks that inform the systems projects. Part III (AI Best Practice, Chapters 14-18) and Part IV (Closing Perspectives, Chapters 19-20) focus on deployment considerations and emerging trends covered through readings and discussions. - -### Milestone Targets - -- **Week 1**: Environment setup (`setup`) and basic command familiarity -- **Week 3**: Basic tensor operations (`tensor`) working -- **Week 5**: Train MLP on MNIST (`mlp`) with manual backprop achieving >90% accuracy -- **Week 7**: Train CNN on CIFAR-10 (`cnn`) basic implementation achieving >70% accuracy -- **Week 9**: Data pipeline (`data`) operational with efficient loading -- **Week 11**: Complete autograd engine and training framework (`training`) working -- **Week 13**: Optimized system with profiling tools (`profiling`) -- **Final**: Complete production system with MLOps monitoring (`mlops`) - ---- - -## πŸ“¦ Course Repository Structure - -``` -TinyTorch/ -β”œβ”€β”€ bin/ # Command-line interfaces -β”‚ └── tito.py # Main TinyTorch CLI (tito) -β”œβ”€β”€ tinytorch/ # Core ML system package -β”‚ β”œβ”€β”€ core/ # Core ML components -β”‚ β”‚ β”œβ”€β”€ __init__.py -β”‚ β”‚ β”œβ”€β”€ tensor.py # Tensor class with autograd support -β”‚ β”‚ β”œβ”€β”€ autograd.py # Automatic differentiation engine -β”‚ β”‚ β”œβ”€β”€ modules.py # Neural network layers and models -β”‚ β”‚ β”œβ”€β”€ functional.py # Core operations (conv2d, relu, etc.) -β”‚ β”‚ β”œβ”€β”€ dataloader.py # Data loading and preprocessing -β”‚ β”‚ β”œβ”€β”€ optimizer.py # Optimization algorithms -β”‚ β”‚ β”œβ”€β”€ trainer.py # Training loop orchestration -β”‚ β”‚ β”œβ”€β”€ profiler.py # Performance measurement tools -β”‚ β”‚ β”œβ”€β”€ benchmark.py # Benchmarking and evaluation -β”‚ β”‚ β”œβ”€β”€ mlops.py # MLOps and production monitoring -β”‚ β”‚ └── utils.py # Utility functions -β”‚ β”œβ”€β”€ configs/ # Configuration files -β”‚ β”‚ β”œβ”€β”€ default.yaml # Default training configuration -β”‚ β”‚ β”œβ”€β”€ models/ # Model-specific configs -β”‚ β”‚ └── datasets/ # Dataset-specific configs -β”‚ └── datasets/ # Dataset implementations -β”‚ β”œβ”€β”€ __init__.py -β”‚ β”œβ”€β”€ mnist.py -β”‚ β”œβ”€β”€ cifar10.py -β”‚ └── transforms.py -β”œβ”€β”€ modules/ # 🧩 System Modules -β”‚ β”œβ”€β”€ 01_setup/ # Environment setup & onboarding -β”‚ β”œβ”€β”€ 02_tensor/ # Basic tensor implementation -β”‚ β”œβ”€β”€ 03_mlp/ # Multi-layer perceptron (manual backprop) -β”‚ β”œβ”€β”€ 04_cnn/ # Convolutional neural networks (basic) -β”‚ β”œβ”€β”€ 05_data/ # Data pipeline & loading -β”‚ β”œβ”€β”€ 06_training/ # Autograd engine & training optimization -β”‚ β”œβ”€β”€ 07_profiling/ # Performance profiling tools -β”‚ β”œβ”€β”€ 08_compression/ # Model compression techniques -β”‚ β”œβ”€β”€ 09_kernels/ # Custom compute kernels -β”‚ β”œβ”€β”€ 10_benchmarking/ # Performance benchmarking -β”‚ └── 11_mlops/ # MLOps & production monitoring -β”œβ”€β”€ docs/ # Course documentation -β”‚ β”œβ”€β”€ tutorials/ # Step-by-step tutorials -β”‚ β”œβ”€β”€ api/ # API documentation -β”‚ └── lectures/ # Lecture materials -β”œβ”€β”€ notebooks/ # Jupyter tutorials and demos -β”œβ”€β”€ examples/ # Working examples and demos -β”‚ β”œβ”€β”€ train_mnist_mlp.py -β”‚ β”œβ”€β”€ train_cifar_cnn.py -β”‚ └── benchmark_ops.py -β”œβ”€β”€ tests/ # Comprehensive test suite -β”‚ β”œβ”€β”€ test_tensor.py -β”‚ β”œβ”€β”€ test_autograd.py -β”‚ β”œβ”€β”€ test_modules.py -β”‚ └── test_training.py -β”œβ”€β”€ grading/ # Course grading materials -β”‚ β”œβ”€β”€ rubrics/ # Assignment rubrics -β”‚ β”œβ”€β”€ autograders/ # Automated grading scripts -β”‚ └── solutions/ # Reference solutions -β”œβ”€β”€ resources/ # Course resources -β”‚ β”œβ”€β”€ datasets/ # Course datasets -β”‚ β”œβ”€β”€ pretrained/ # Pre-trained models -β”‚ └── references/ # Reference materials -β”œβ”€β”€ logs/ # Training logs and artifacts -β”‚ └── runs/ -β”œβ”€β”€ checkpoints/ # Model checkpoints -β”œβ”€β”€ requirements.txt # Python dependencies -└── README.md # This file -``` - ---- - -## 🎯 Course Navigation & Getting Started - -**New to TinyTorch?** Start here: [`modules/01_setup/README.md`](modules/01_setup/README.md) - -### πŸ“‹ Module Sequence -Each module builds on the previous ones. Click the links to jump to specific instructions: - -| Order | Module | Status | Description | Instructions | -|-------|--------|--------|-------------|--------------| -| 0 | **Setup** | πŸš€ **START HERE** | Environment & CLI setup | [`modules/01_setup/README.md`](modules/01_setup/README.md) | -| 1 | **Tensor** | ⏳ Coming Next | Basic tensor operations | [`modules/02_tensor/README.md`](modules/02_tensor/README.md) | -| 2 | **MLP** | ⏳ Future | Multi-layer perceptron (manual backprop) | [`modules/03_mlp/README.md`](modules/03_mlp/README.md) | -| 3 | **CNN** | ⏳ Future | Convolutional networks (basic) | [`modules/04_cnn/README.md`](modules/04_cnn/README.md) | -| 4 | **Data** | ⏳ Future | Data loading pipeline | [`modules/05_data/README.md`](modules/05_data/README.md) | -| 5 | **Training** | ⏳ Future | Autograd engine & optimization | [`modules/06_training/README.md`](modules/06_training/README.md) | -| 6 | **Profiling** | ⏳ Future | Performance profiling | [`modules/07_profiling/README.md`](modules/07_profiling/README.md) | -| 7 | **Compression** | ⏳ Future | Model compression | [`modules/08_compression/README.md`](modules/08_compression/README.md) | -| 8 | **Kernels** | ⏳ Future | Custom compute kernels | [`modules/09_kernels/README.md`](modules/09_kernels/README.md) | -| 9 | **Benchmarking** | ⏳ Future | Performance benchmarking | [`modules/10_benchmarking/README.md`](modules/10_benchmarking/README.md) | -| 10 | **MLOps** | ⏳ Future | Production monitoring | [`modules/11_mlops/README.md`](modules/11_mlops/README.md) | - -### πŸš€ Quick Start Guide -**First time?** Follow this exact sequence: - -1. **πŸ“– Read the overview** (you're here!) -2. **🎯 Detailed guidance**: [`COURSE_GUIDE.md`](COURSE_GUIDE.md) (comprehensive walkthrough) -3. **πŸš€ One-command setup**: `python3 bin/tito.py setup` (sets up everything!) -4. **βœ… Run activation**: Follow the command it gives you (usually `bin/activate-tinytorch.sh`) -5. **πŸ“– Start building**: [`projects/setup/README.md`](projects/setup/README.md) - -### Prerequisites -- **Python 3.8+** (type hints and modern features required) -- **NumPy** (numerical computations) -- **Optional**: Numba (JIT compilation for performance) -- **Development**: pytest, black, mypy (for testing and code quality) - -### Environment Setup ```bash -# Clone and setup environment -git clone +# Clone the repository +git clone https://github.com/tinytorch/TinyTorch.git cd TinyTorch -# ONE SMART COMMAND - shows clear commands to copy -python3 bin/tito.py setup -# ↳ First time: Creates environment, installs dependencies, shows activation command -# ↳ Already exists: Shows activation command to copy -# ↳ Already active: Can show deactivation command - -# Copy and run the highlighted command, then: -tito info # Check system status -``` - -### For Instructors -```bash -# Set up the complete course environment +# Setup development environment +python -m venv .venv +source .venv/bin/activate # or `.venv\Scripts\activate` on Windows pip install -r requirements.txt - -# Generate course materials -python3 bin/tito.py generate-projects -python3 bin/tito.py setup-autograders - -# View course progress -python3 bin/tito.py course-status ``` -### For Students +### 2. Start with Setup Module + ```bash -# ONE SMART COMMAND - handles everything (IMPORTANT!) -python3 bin/tito.py setup -# ↳ Shows clear commands to copy and paste! +# Navigate to the setup module +cd modules/setup/ -# Start with Project 0: Setup -cd projects/setup/ -cat README.md # Read instructions -python3 -m pytest test_setup.py -v # Run tests +# Read the module overview +cat README.md -# Then move through the sequence (Part I: The Essentials) -cd ../tensor/ # Project 1: Basic tensors -cd ../mlp/ # Project 2: Multi-layer perceptron (manual backprop) -cd ../cnn/ # Project 3: Convolutional networks (basic) - -# Part II: Engineering Principles -cd ../data/ # Project 4: Data pipeline -cd ../training/ # Project 5: Autograd engine & training - -# Always run tests before submitting -python3 -m pytest projects/tensor/test_tensor.py -v -python3 bin/tito.py submit --project tensor - -python3 -m pytest projects/mlp/test_mlp.py -v -python3 bin/tito.py submit --project mlp +# Open the development notebook +jupyter lab setup.ipynb ``` ---- +### 3. Development Workflow -## 🎯 Implementation Guidelines +1. **Work in module notebooks** (`modules/[module]/[module].ipynb`) +2. **Mark code for export** with `#| export` directives +3. **Export to package** with `python bin/tito.py sync` +4. **Test your code** with `python bin/tito.py test --module [module]` +5. **Move to next module** when tests pass -### Code Quality Standards -- **Type Hints**: All public APIs must have complete type annotations -- **Documentation**: Docstrings for all classes and public methods -- **Testing**: >90% code coverage with unit and integration tests -- **Performance**: Profile-guided optimization with benchmarking -- **Style**: Black code formatting, consistent naming conventions +## πŸ“š Course Structure -### API Design Principles -- **Familiar Interface**: Similar to PyTorch where it makes sense (for learning transfer) -- **Explicit Over Implicit**: Clear parameter names and behavior -- **Composable**: Small, focused components that work together -- **Debuggable**: Rich error messages and debugging hooks +TinyTorch follows a progressive module structure. Each module builds on the previous ones: -### Performance Targets -- **MNIST MLP**: <5 seconds per epoch on modern laptop -- **CIFAR-10 CNN**: <30 seconds per epoch on modern laptop -- **Memory Usage**: <2GB RAM for standard training runs -- **Numerical Stability**: Gradient checking passes for all operations +| Module | Location | Topic | Exports To | +|--------|----------|-------|-----------| +| setup | `modules/setup/` | Environment & Hello World | `tinytorch.core.utils` | +| tensor | `modules/tensor/` | Core Tensor Implementation | `tinytorch.core.tensor` | +| autograd | `modules/autograd/` | Automatic Differentiation | `tinytorch.core.autograd` | +| mlp | `modules/mlp/` | Neural Network Layers | `tinytorch.core.modules` | +| cnn | `modules/cnn/` | Convolutional Networks | `tinytorch.models.cnn` | +| training | `modules/training/` | Training Loops | `tinytorch.training` | +| data | `modules/data/` | Data Loading Pipeline | `tinytorch.data` | +| kernels | `modules/kernels/` | Custom CUDA Kernels | `tinytorch.kernels` | +| compression | `modules/compression/` | Model Compression | `tinytorch.compression` | +| profiling | `modules/profiling/` | Performance Profiling | `tinytorch.profiling` | +| benchmarking | `modules/benchmarking/` | Performance Benchmarks | `tinytorch.benchmarking` | +| config | `modules/config/` | Configuration Management | `tinytorch.config` | +| mlops | `modules/mlops/` | Production Monitoring | `tinytorch.mlops` | ---- +## πŸ”§ Key Commands -## πŸ§ͺ Testing & Validation Strategy +| Command | Purpose | Example | +|---------|---------|---------| +| `python bin/tito.py sync` | Export notebook code to package | Export all modules | +| `python bin/tito.py test --module [name]` | Test specific module | Test tensor module | +| `python bin/tito.py test --all` | Run all tests | Test everything | +| `python bin/tito.py info` | Check implementation status | Show progress | +| `jupyter lab [module].ipynb` | Start module development | Open tensor notebook | -### Test Categories -1. **Unit Tests**: Individual component functionality -2. **Integration Tests**: Component interaction and data flow -3. **Numerical Tests**: Gradient checking and mathematical correctness -4. **Performance Tests**: Regression testing for speed and memory -5. **End-to-End Tests**: Complete training runs with known results +## πŸ“¦ Package Structure -### Validation Methodology -- **Gradient Checking**: Numerical verification of all autodiff operations -- **Reference Comparisons**: Output validation against NumPy/PyTorch (where applicable) -- **Convergence Testing**: Training curves must match expected behavior -- **Ablation Studies**: Systematic testing of individual components +The final TinyTorch package structure (auto-generated from modules): ---- +``` +tinytorch/ # Auto-generated from modules/ +β”œβ”€β”€ __init__.py # Main package +β”œβ”€β”€ core/ # Core ML components +β”‚ β”œβ”€β”€ tensor.py # From modules/tensor/ +β”‚ β”œβ”€β”€ autograd.py # From modules/autograd/ +β”‚ β”œβ”€β”€ modules.py # From modules/mlp/ +β”‚ └── utils.py # From modules/setup/ +β”œβ”€β”€ data/ # From modules/data/ +β”œβ”€β”€ training/ # From modules/training/ +β”œβ”€β”€ models/ # Model architectures +β”‚ └── cnn.py # From modules/cnn/ +β”œβ”€β”€ kernels/ # From modules/kernels/ +β”œβ”€β”€ compression/ # From modules/compression/ +β”œβ”€β”€ profiling/ # From modules/profiling/ +β”œβ”€β”€ benchmarking/ # From modules/benchmarking/ +β”œβ”€β”€ config/ # From modules/config/ +└── mlops/ # From modules/mlops/ +``` -## πŸ’‘ Educational Philosophy +## πŸŽ“ Learning Approach -> "You don't really understand a system until you've built it." +### Module-First Development -### Learning Through Building -TinyTorch emphasizes **active construction** over passive consumption. Students don't just learn about autogradβ€”they implement it. They don't just use optimizersβ€”they write them from scratch. +TinyTorch uses a **module-first** approach where each module is self-contained: -### Systems Thinking -By building a complete system, students understand: -- **Abstraction Boundaries**: What belongs where in the system hierarchy -- **Performance Trade-offs**: How design decisions impact speed and memory -- **Debugging Strategies**: How to trace problems through complex systems -- **Integration Challenges**: How components interact and depend on each other +- βœ… **Self-contained**: Each module has its own notebook, tests, and documentation +- βœ… **Progressive**: Modules build on each other in a logical sequence +- βœ… **Interactive**: Work in Jupyter notebooks with immediate feedback +- βœ… **Tested**: Comprehensive tests verify your implementation +- βœ… **Integrated**: nbdev automatically exports to the main package -### Real-World Relevance -Every component in TinyTorch has a direct analog in production ML systems. The skills learned here transfer directly to understanding and contributing to frameworks like PyTorch, TensorFlow, and JAX. +### Development Workflow per Module ---- +```bash +# 1. Navigate to module +cd modules/[module-name]/ -## πŸ”§ Advanced Features & Extensions +# 2. Read the overview +cat README.md -### Chapter 13: MLOps Deep Dive +# 3. Open development notebook +jupyter lab [module-name].ipynb -**Core MLOps Components** (Chapter 13 will implement): -- **Data Drift Detection**: Statistical tests for distribution shifts in input features -- **Model Performance Monitoring**: Track accuracy, latency, and throughput in production -- **Automatic Retraining Triggers**: When to retrain based on performance degradation -- **A/B Testing Framework**: Compare model versions safely in production -- **Model Registry**: Version control and metadata tracking for deployed models -- **Alert Systems**: Notifications for model failures or performance drops -- **Rollback Mechanisms**: Safe deployment and quick rollback strategies +# 4. Implement functions with #| export +# 5. Test interactively in notebook -**Production Integration**: -- **REST API Serving**: Deploy models as web services -- **Batch Inference Pipelines**: Large-scale offline predictions -- **Feature Store Integration**: Consistent feature engineering across training/serving -- **Monitoring Dashboards**: Real-time system health visualization +# 6. Export to package +python bin/tito.py sync -### Optional Advanced Components -- **Mixed Precision Training**: FP16/FP32 mixed precision implementation -- **Distributed Training**: Multi-GPU and multi-node training support -- **Dynamic Graphs**: Support for variable computation graphs -- **Custom Operators**: Framework for implementing new operations -- **JIT Compilation**: Integration with Numba or custom compilation +# 7. Run automated tests +python bin/tito.py test --module [module-name] -### Research Extensions -- **Novel Optimizers**: Implement cutting-edge optimization algorithms -- **Architecture Search**: Automated neural architecture search -- **Compression Techniques**: Advanced pruning and quantization methods -- **Hardware Acceleration**: GPU kernels and specialized hardware support +# 8. Move to next module when tests pass +``` ---- +### Progressive Complexity -## πŸ“Š Success Metrics +1. **Foundation** (setup, tensor): Basic building blocks +2. **Core ML** (autograd, mlp): Neural network fundamentals +3. **Advanced Architectures** (cnn): Specialized network types +4. **Training Systems** (training, data): Complete learning pipelines +5. **Optimization** (kernels, compression, profiling): Performance +6. **Production** (benchmarking, config, mlops): Real-world deployment -### Technical Milestones -- [ ] Train MLP on MNIST achieving >95% accuracy -- [ ] Implement working autograd engine with gradient checking -- [ ] Train CNN on CIFAR-10 achieving >85% accuracy -- [ ] Profile and optimize for 2x performance improvement -- [ ] Complete all core project implementations +## πŸ› οΈ Module Structure -### Learning Outcomes Assessment -- **Code Reviews**: Peer and instructor evaluation of implementations -- **Design Document**: Architecture decisions and trade-off analysis -- **Performance Analysis**: Profiling report and optimization strategy -- **Presentation**: Explain system design and key insights learned +Each module follows a consistent structure: ---- +``` +modules/[module-name]/ +β”œβ”€β”€ README.md # πŸ“– Module overview and instructions +β”œβ”€β”€ [module-name].ipynb # πŸ““ Main development notebook +β”œβ”€β”€ test_[module].py # πŸ§ͺ Automated tests +└── check_[module].py # βœ… Manual verification (optional) +``` -## 🀝 Course Management +### Module Development Process + +1. **Read README.md** - Understand learning objectives and requirements +2. **Open notebook** - Work through guided implementation +3. **Mark exports** - Use `#| export` for package code +4. **Test locally** - Verify functionality in notebook +5. **Export code** - Run `tito sync` to update package +6. **Run tests** - Ensure implementation meets requirements +7. **Iterate** - Fix issues and repeat until tests pass + +## πŸ“‹ Requirements + +- **Python 3.8+** +- **Jupyter Lab/Notebook** +- **nbdev** (for notebook development) +- **pytest** (for testing) +- **NumPy, Matplotlib** (for ML operations) + +See `requirements.txt` for complete dependency list. + +## 🎯 Goals & Philosophy + +### Educational Goals + +- **Deep Understanding**: Implement every component from first principles +- **Systems Thinking**: Understand how components interact +- **Performance Awareness**: Learn to optimize real systems +- **Production Skills**: Build systems that work in practice + +### Design Philosophy + +- **Module-First**: Self-contained learning units +- **Notebook-Driven**: Interactive development with immediate feedback +- **Test-Driven**: Comprehensive testing for reliability +- **Incremental**: Build understanding step by step +- **Real-World**: Techniques used in production systems + +## πŸš€ Getting Started + +### For New Students + +1. **Setup Environment**: `pip install -r requirements.txt` +2. **Start with Setup**: `cd modules/setup/ && cat README.md` +3. **Follow the sequence**: Complete modules in order +4. **Test frequently**: Use `tito test` to verify progress +5. **Build incrementally**: Each module prepares for the next ### For Instructors -**Project Management**: -- Each chapter has structured projects in `projects/XX-name/` -- Rubrics and grading criteria in `grading/rubrics/` -- Automated testing and grading in `grading/autograders/` -- Reference solutions in `grading/solutions/` +- **Add modules**: Copy existing module structure +- **Update tests**: Add to `modules/[name]/test_[name].py` +- **Document well**: Clear READMEs and notebook explanations +- **Test integration**: Ensure modules work together -**Progress Tracking**: -- Student progress dashboards -- Automated testing and feedback -- Performance benchmarking -- Code quality metrics +## 🀝 Contributing -### For Students +We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details. -**Development Process**: -1. **Start Each Project**: Read project description in `projects/XX-name/README.md` -2. **Implement Features**: Follow step-by-step guided implementation -3. **Run Tests**: Use automated tests to validate implementation -4. **Submit Work**: Automated submission and grading system -5. **Get Feedback**: Detailed feedback on implementation and performance +## πŸ“„ License -### Getting Help -- **Documentation**: Comprehensive docs in `docs/` -- **Tutorials**: Step-by-step tutorials in `notebooks/` -- **Office Hours**: Regular sessions for questions and debugging -- **Peer Discussion**: Collaborative learning encouraged -- **Issue Tracking**: GitHub issues for bugs and feature requests +This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details. ---- +## πŸ™ Acknowledgments -## πŸ“¬ License and Attribution - -TinyTorch is part of the *Machine Learning Systems* course and textbook by Vijay Janapa Reddi et al. Inspired by systems-style pedagogical projects like xv6 (OS), PintOS (OS), and cs231n assignments (ML). - -**License**: MIT -**Citation**: Please cite the Machine Learning Systems textbook when using this educational material. - ---- - -## πŸ”— Additional Resources - -- **Textbook**: [*Machine Learning Systems*](https://mlsysbook.ai) (Chapters 1-13) | [PDF](https://mlsysbook.ai/Machine-Learning-Systems.pdf) -- **Course Website**: Coming soon -- **Video Lectures**: Coming soon -- **External Reading**: Coming soon -- **Community Forum**: [GitHub Discussions](../../discussions) -- **Office Hours**: Coming soon +- Inspired by [PyTorch](https://pytorch.org/), [fastai](https://fast.ai/), and [Karpathy's micrograd](https://github.com/karpathy/micrograd) +- Built with [nbdev](https://nbdev.fast.ai/) for seamless notebook development +- Course structure inspired by modern ML systems courses diff --git a/bin/tito.py b/bin/tito.py index 8d61e193..d370743f 100755 --- a/bin/tito.py +++ b/bin/tito.py @@ -352,7 +352,7 @@ def cmd_test(args): failed_modules = [] # Count existing test files - existing_tests = [p for p in valid_modules if Path(f"modules/{p}/test_{p}.py").exists()] + existing_tests = [p for p in valid_modules if Path(f"tests/test_{p}.py").exists()] console.print(Panel(f"πŸ§ͺ Running tests for {len(existing_tests)} modules", title="Test Suite", border_style="bright_cyan")) @@ -370,7 +370,7 @@ def cmd_test(args): for module in existing_tests: progress.update(task, description=f"Testing {module}...") - test_file = f"modules/{module}/test_{module}.py" + test_file = f"tests/test_{module}.py" result = subprocess.run([sys.executable, "-m", "pytest", test_file, "-v"], capture_output=True, text=True) @@ -395,7 +395,7 @@ def cmd_test(args): elif args.module in valid_modules: # Run specific module tests import subprocess - test_file = f"modules/{args.module}/test_{args.module}.py" + test_file = f"tests/test_{args.module}.py" console.print(Panel(f"πŸ§ͺ Running tests for module: [bold cyan]{args.module}[/bold cyan]", title="Single Module Test", border_style="bright_cyan")) @@ -433,7 +433,7 @@ def cmd_submit(args): submit_text.append(f"πŸ“€ Submitting module: {args.module}\n\n", style="bold cyan") submit_text.append("🚧 Submission system not yet implemented.\n\n", style="yellow") submit_text.append("For now, make sure all tests pass with:\n", style="dim") - submit_text.append(f" python -m pytest modules/{args.module}/test_*.py -v", style="bold white") + submit_text.append(f" python -m pytest tests/test_{args.module}.py -v", style="bold white") console.print(Panel(submit_text, title="Module Submission", border_style="bright_yellow")) @@ -554,6 +554,63 @@ def cmd_jupyter(args): return 0 +def cmd_sync(args): + """Export notebook code to Python package using nbdev.""" + import subprocess + + console.print(Panel("πŸ”„ Synchronizing Notebooks to Package", + title="nbdev Export", border_style="bright_cyan")) + + console.print("πŸ”„ Exporting notebook code to tinytorch package...") + + try: + result = subprocess.run(["nbdev_export"], capture_output=True, text=True, cwd=Path.cwd()) + + if result.returncode == 0: + console.print(Panel("[green]βœ… Successfully exported notebook code to tinytorch package![/green]", + title="Export Success", border_style="green")) + + # Show what was exported + exports_text = Text() + exports_text.append("πŸ“¦ Exported modules:\n", style="bold cyan") + + # Check for exported files + tinytorch_path = Path("tinytorch") + if tinytorch_path.exists(): + for py_file in tinytorch_path.rglob("*.py"): + if py_file.name != "__init__.py" and py_file.stat().st_size > 100: # Non-empty files + rel_path = py_file.relative_to(tinytorch_path) + exports_text.append(f" βœ… tinytorch/{rel_path}\n", style="green") + + exports_text.append("\nπŸ’‘ Next steps:\n", style="bold yellow") + exports_text.append(" β€’ Run: tito test --module setup\n", style="white") + exports_text.append(" β€’ Or: tito test --all\n", style="white") + + console.print(Panel(exports_text, title="Export Summary", border_style="bright_green")) + + else: + error_msg = result.stderr.strip() if result.stderr else "Unknown error" + console.print(Panel(f"[red]❌ Export failed:\n{error_msg}[/red]", + title="Export Error", border_style="red")) + + # Helpful error guidance + help_text = Text() + help_text.append("πŸ’‘ Common issues:\n", style="bold yellow") + help_text.append(" β€’ Missing #| default_exp directive in notebook\n", style="white") + help_text.append(" β€’ Syntax errors in exported code\n", style="white") + help_text.append(" β€’ Missing settings.ini configuration\n", style="white") + help_text.append("\nπŸ”§ Run 'tito doctor' for detailed diagnosis", style="cyan") + + console.print(Panel(help_text, title="Troubleshooting", border_style="yellow")) + + return result.returncode + + except FileNotFoundError: + console.print(Panel("[red]❌ nbdev not found. Install with: pip install nbdev[/red]", + title="Missing Dependency", border_style="red")) + return 1 + + def cmd_nbdev(args): """Run nbdev commands for notebook development.""" import subprocess @@ -561,20 +618,12 @@ def cmd_nbdev(args): console.print(Panel("πŸ““ nbdev Notebook Development", title="Notebook Tools", border_style="bright_cyan")) - if args.build_lib: - console.print("πŸ”¨ Building library from notebooks...") - result = subprocess.run(["nbdev_build_lib"], capture_output=True, text=True) - if result.returncode == 0: - console.print(Panel("[green]βœ… Library built successfully![/green]", - title="Build Success", border_style="green")) - else: - console.print(Panel(f"[red]❌ Build failed: {result.stderr}[/red]", - title="Build Error", border_style="red")) - return result.returncode + if args.export: + return cmd_sync(args) # Use the same logic as sync command elif args.build_docs: console.print("πŸ“š Building documentation from notebooks...") - result = subprocess.run(["nbdev_build_docs"], capture_output=True, text=True) + result = subprocess.run(["nbdev_docs"], capture_output=True, text=True) if result.returncode == 0: console.print(Panel("[green]βœ… Documentation built successfully![/green]", title="Docs Success", border_style="green")) @@ -595,8 +644,8 @@ def cmd_nbdev(args): return result.returncode elif args.clean: - console.print("🧹 Cleaning notebook build artifacts...") - result = subprocess.run(["nbdev_clean_nbs"], capture_output=True, text=True) + console.print("🧹 Cleaning notebook outputs...") + result = subprocess.run(["nbdev_clean"], capture_output=True, text=True) if result.returncode == 0: console.print(Panel("[green]βœ… Cleaned successfully![/green]", title="Clean Success", border_style="green")) @@ -608,15 +657,16 @@ def cmd_nbdev(args): else: help_text = Text() help_text.append("πŸ““ nbdev Commands:\n\n", style="bold cyan") - help_text.append(" tito nbdev --build-lib - Build library from notebooks\n", style="white") + help_text.append(" tito sync - Export notebooks to Python package\n", style="white") + help_text.append(" tito nbdev --export - Same as sync\n", style="white") help_text.append(" tito nbdev --build-docs - Build documentation\n", style="white") help_text.append(" tito nbdev --test - Run notebook tests\n", style="white") - help_text.append(" tito nbdev --clean - Clean build artifacts\n\n", style="white") + help_text.append(" tito nbdev --clean - Clean notebook outputs\n\n", style="white") help_text.append("πŸ’‘ Development workflow:\n", style="bold yellow") - help_text.append(" 1. Work in modules/*/notebook/*_dev.ipynb\n", style="dim") - help_text.append(" 2. Test interactively\n", style="dim") - help_text.append(" 3. Run: tito nbdev --build-lib\n", style="dim") - help_text.append(" 4. Test compiled package\n", style="dim") + help_text.append(" 1. Work in notebooks/*.ipynb\n", style="dim") + help_text.append(" 2. Test interactively in notebook\n", style="dim") + help_text.append(" 3. Run: tito sync\n", style="dim") + help_text.append(" 4. Run: tito test\n", style="dim") console.print(Panel(help_text, title="nbdev Help", border_style="bright_cyan")) return 0 @@ -654,12 +704,15 @@ def main(): # Doctor command doctor_parser = subparsers.add_parser("doctor", help="Run environment diagnosis") + # Sync command (primary nbdev export) + sync_parser = subparsers.add_parser("sync", help="Export notebook code to Python package") + # nbdev commands nbdev_parser = subparsers.add_parser("nbdev", help="nbdev notebook development commands") - nbdev_parser.add_argument("--build-lib", action="store_true", help="Build library from notebooks") + nbdev_parser.add_argument("--export", action="store_true", help="Export notebooks to Python package") nbdev_parser.add_argument("--build-docs", action="store_true", help="Build documentation from notebooks") nbdev_parser.add_argument("--test", action="store_true", help="Run notebook tests") - nbdev_parser.add_argument("--clean", action="store_true", help="Clean notebook build artifacts") + nbdev_parser.add_argument("--clean", action="store_true", help="Clean notebook outputs") # Jupyter command jupyter_parser = subparsers.add_parser("jupyter", help="Start Jupyter notebook server") @@ -698,6 +751,8 @@ def main(): cmd_status(args) elif args.command == "doctor": cmd_doctor(args) + elif args.command == "sync": + return cmd_sync(args) elif args.command == "nbdev": return cmd_nbdev(args) elif args.command == "jupyter": diff --git a/modules/setup/QUICKSTART.md b/modules/setup/QUICKSTART.md deleted file mode 100644 index f16c8e23..00000000 --- a/modules/setup/QUICKSTART.md +++ /dev/null @@ -1,100 +0,0 @@ -# TinyTorch Quick Start Guide - -Get your TinyTorch environment set up in 5 minutes! - -## πŸš€ Option 1: Automated Setup (Recommended) - -**Step 1**: Clone and navigate -```bash -git clone -cd TinyTorch -``` - -**Step 2**: Run the automated setup -```bash -python3 projects/setup/create_env.py -``` - -**Step 3**: Activate environment and verify -```bash -source .venv/bin/activate # macOS/Linux -# OR: .venv\Scripts\activate # Windows - -python3 projects/setup/check_setup.py -``` - -**Done!** If you see all βœ… checkmarks, you're ready to code. - ---- - -## πŸ”§ Option 2: Manual Setup - -**Step 1**: Create virtual environment -```bash -python3 -m venv .venv -source .venv/bin/activate -``` - -**Step 2**: Install dependencies -```bash -pip install --upgrade pip -pip install -r requirements.txt -``` - -**Step 3**: Verify setup -```bash -python3 projects/setup/check_setup.py -``` - ---- - -## 🎯 Every Day Workflow - -**Start working** (run this every time): -```bash -cd TinyTorch -source .venv/bin/activate # Always activate first! -``` - -**Check status**: -```bash -python3 bin/tito.py info -``` - -**Run tests**: -```bash -python3 -m pytest projects/setup/test_setup.py -v -``` - ---- - -## ❗ Common Issues - -**"ModuleNotFoundError"**: You forgot to activate your virtual environment -```bash -source .venv/bin/activate -``` - -**"Command not found"**: Make sure you're in the TinyTorch directory -```bash -cd TinyTorch -ls # Should see bin/, projects/, requirements.txt -``` - -**Dependencies missing**: Reinstall in the virtual environment -```bash -source .venv/bin/activate -pip install -r requirements.txt -``` - ---- - -## πŸ“ What's in Your Environment - -After setup, you'll have: -- βœ… Python 3.8+ with exact dependency versions -- βœ… pytest for running tests -- βœ… All TinyTorch course materials -- βœ… Isolated environment (no conflicts with other projects) - -**Next**: Read `projects/setup/README.md` for detailed instructions! \ No newline at end of file diff --git a/modules/setup/README.md b/modules/setup/README.md index ec3a1f16..0519ecba 100644 --- a/modules/setup/README.md +++ b/modules/setup/README.md @@ -1,223 +1 @@ -# πŸ”₯ Module 01: Setup & Environment - -Welcome to your first TinyTorch module! This setup project gets your development environment ready and introduces you to the workflow you'll use throughout the course. - -## 🎯 Learning Objectives - -By the end of this module, you will: -- βœ… Have a fully working development environment -- βœ… Understand the `tito` CLI workflow -- βœ… Know how to check system status and run tests -- βœ… Have implemented your first TinyTorch component -- βœ… Be ready to build the entire ML system - -## πŸ“‹ Module Structure - -``` -modules/setup/ -β”œβ”€β”€ README.md # πŸ“– This file - Module overview -β”œβ”€β”€ notebook/ # πŸ““ Interactive development -β”‚ └── setup_dev.ipynb # Main development notebook -β”œβ”€β”€ tutorials/ # πŸŽ“ Step-by-step learning guides -β”‚ └── 01_setup_basics.ipynb # Setup fundamentals tutorial -β”œβ”€β”€ test_setup.py # πŸ§ͺ Automated tests -β”œβ”€β”€ check_setup.py # βœ… Manual verification -β”œβ”€β”€ create_env.py # πŸ”§ Environment creation -β”œβ”€β”€ QUICKSTART.md # ⚑ Quick start guide -└── solutions/ # πŸ”‘ Reference solutions (instructors) - └── solution_setup.py -``` - -## πŸš€ Getting Started - -### Step 1: Environment Setup -```bash -# The only command you need! -source bin/activate-tinytorch.sh -``` - -This smart script handles everything: -- πŸ†• **First time**: Creates environment, installs dependencies, activates it -- πŸ’€ **Already exists**: Just activates the existing environment -- βœ… **Already active**: Already good to go! - -**Important**: Use `source` (not `./`) to activate in your current shell! - -### Step 2: System Verification -```bash -# Check that everything is working -tito --version -tito info -tito info --show-architecture -``` - -### Step 3: Read the Tutorial (Recommended) -```bash -# Start Jupyter -tito jupyter --lab - -# Then open this tutorial: -# tutorials/01_setup_basics.ipynb - Learn the workflow -``` - -### Step 4: Implement Your First Function -```bash -# Open the main development notebook -# Navigate to: notebook/setup_dev.ipynb - -# Work through the implementation step by step: -# 1. Environment check -# 2. Import verification -# 3. Function implementation -# 4. Testing and validation -``` - -### Step 5: Test Your Implementation -```bash -# Run automated tests -tito test --module setup - -# Run manual verification -python check_setup.py - -# Test integration -python -c "from tinytorch.core.utils import hello_tinytorch; print(hello_tinytorch())" -``` - -### Step 6: Submit Your Work -```bash -# Submit when ready -tito submit --module setup - -# Move to next module -cd ../tensor/ -cat README.md -``` - -## πŸ“š What You'll Implement - -### Hello World Function -Your task is to implement a `hello_tinytorch()` function in `tinytorch/core/utils.py`: - -```python -def hello_tinytorch() -> str: - """ - Return a greeting message for new TinyTorch users. - - Returns: - A welcoming message string - """ - return "πŸ”₯ Welcome to TinyTorch! Ready to build ML systems from scratch! πŸ”₯" -``` - -### Requirements -1. **Function signature**: Must be named `hello_tinytorch()` with return type `-> str` -2. **Return value**: Must return a non-empty string -3. **Content**: Must contain welcoming content (welcome, hello, tinytorch, ready) -4. **Branding**: Must include the πŸ”₯ emoji (TinyTorch branding) -5. **Documentation**: Must have proper docstring explaining the function - -## πŸ§ͺ Testing Your Implementation - -### Automated Tests -```bash -tito test --module setup -``` -This runs comprehensive tests for: -- βœ… Function exists and can be imported -- βœ… Returns correct type (string) -- βœ… Returns non-empty content -- βœ… Contains welcoming content -- βœ… Contains πŸ”₯ emoji -- βœ… Has proper documentation - -### Manual Verification -```bash -python check_setup.py -``` -This provides human-readable feedback on: -- πŸ“Š Environment status -- πŸ” Function implementation -- πŸ’‘ Specific error messages -- πŸ“‹ Next steps guidance - -### Direct Testing -```python -from tinytorch.core.utils import hello_tinytorch -result = hello_tinytorch() -print(result) -``` - -## 🎯 Success Criteria - -Your implementation is complete when: - -1. **All automated tests pass**: `tito test --module setup` shows βœ… -2. **Manual verification passes**: `python check_setup.py` shows all tests passed -3. **Function works correctly**: Returns proper greeting with πŸ”₯ emoji -4. **Environment is ready**: All CLI commands work properly - -## πŸ“– Learning Resources - -### Tutorial Notebooks -- **01_setup_basics.ipynb**: Introduction to TinyTorch workflow and development process - -### Key Concepts to Understand -- **Project structure**: How modules are organized -- **Development workflow**: Using notebooks, tests, and CLI -- **Testing process**: Automated vs manual verification -- **Environment management**: Virtual environments and dependencies - -## πŸ”§ Implementation Tips - -### Start Simple -1. **Read the tutorial**: Understand the workflow first -2. **Check the environment**: Make sure everything is working -3. **Implement the function**: Add it to the correct file -4. **Test frequently**: Run tests after each change - -### Common Patterns -- **File location**: Always add functions to the correct module file -- **Import testing**: Test imports before implementing -- **Error messages**: Read error messages carefully for guidance -- **Documentation**: Always add proper docstrings - -### Common Pitfalls -- **Wrong file**: Make sure you're editing `tinytorch/core/utils.py` -- **Syntax errors**: Check your Python syntax carefully -- **Missing requirements**: Ensure your function meets all requirements -- **Import issues**: Make sure your function can be imported - -## πŸš€ Next Steps - -Once you complete this module: - -1. **Move to Tensor module**: `cd ../tensor/` -2. **Build core tensors**: Implement the fundamental data structure -3. **Learn operations**: Add arithmetic and utility methods -4. **Test thoroughly**: Use the comprehensive testing framework - -## πŸ’‘ Need Help? - -### Common Issues -- **Environment not working**: Run `bin/activate-tinytorch.sh` -- **Import errors**: Check file paths and syntax -- **Test failures**: Read error messages for specific guidance -- **CLI not working**: Make sure environment is activated - -### Getting Support -- **Check tutorials**: The tutorial notebook has detailed explanations -- **Run verification**: `python check_setup.py` provides specific feedback -- **Review tests**: The test files show exactly what's expected - -## πŸŽ‰ You're Starting Something Amazing! - -This setup module introduces you to the TinyTorch development workflow: -- **Environment management**: Virtual environments and dependencies -- **Testing framework**: Automated and manual verification -- **CLI workflow**: Using `tito` commands for development -- **Project structure**: Understanding how modules are organized - -This foundation will support everything you build in the coming modules! - -Good luck, and happy coding! πŸ”₯ \ No newline at end of file + \ No newline at end of file diff --git a/modules/setup/check_setup.py b/modules/setup/check_setup.py deleted file mode 100644 index 18d3e4e7..00000000 --- a/modules/setup/check_setup.py +++ /dev/null @@ -1,211 +0,0 @@ -#!/usr/bin/env python3 -""" -TinyTorch Setup Verification Script - -This script performs comprehensive checks to ensure the student's -environment is properly configured for the TinyTorch course. - -Usage: python projects/setup/check_setup.py -""" - -import sys -import os -import subprocess -import importlib.util - -def print_header(): - """Print the verification header.""" - print("πŸ”₯ TinyTorch Setup Verification πŸ”₯") - print("=" * 50) - print() - -def check_python_version(): - """Verify Python version is 3.8+.""" - print("🐍 Checking Python version...") - version = sys.version_info - - if version.major == 3 and version.minor >= 8: - print(f"βœ… Python version: {version.major}.{version.minor}.{version.micro} (compatible)") - return True - else: - print(f"❌ Python version: {version.major}.{version.minor}.{version.micro} (need 3.8+)") - return False - -def check_virtual_environment(): - """Check if running in a virtual environment.""" - print("\n🐍 Checking virtual environment...") - - # Check if in virtual environment - in_venv = (hasattr(sys, 'real_prefix') or - (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix)) - - if in_venv: - print("βœ… Virtual environment: Active") - print(f" Environment: {sys.prefix}") - return True - else: - print("⚠️ Virtual environment: Not detected") - print(" Recommendation: Use 'source .venv/bin/activate'") - print(" (This is strongly recommended for consistency)") - return True # Don't fail, just warn - -def check_dependencies(): - """Check that all required dependencies are installed.""" - print("\nπŸ“¦ Checking dependencies...") - - required_packages = { - 'numpy': 'numpy', - 'matplotlib': 'matplotlib', - 'yaml': 'PyYAML', - 'pytest': 'pytest' - } - all_good = True - - for import_name, package_name in required_packages.items(): - try: - if import_name == 'yaml': - import yaml as module - else: - module = __import__(import_name) - - # Get version if available - version = getattr(module, '__version__', 'unknown') - print(f"βœ… {package_name}: {version}") - except ImportError: - print(f"❌ {package_name}: missing") - all_good = False - - if all_good: - print("βœ… Dependencies: All installed correctly") - else: - print("❌ Dependencies: Some packages missing") - print(" Solution: Activate venv and run 'pip install -r requirements.txt'") - - return all_good - -def check_cli_commands(): - """Test that tito CLI commands work.""" - print("\nπŸ”§ Checking CLI commands...") - - try: - # Test --version - result = subprocess.run([sys.executable, 'bin/tito.py', '--version'], - capture_output=True, text=True, timeout=10) - if result.returncode == 0 and 'TinyπŸ”₯Torch' in result.stdout: - print("βœ… tito --version: Working") - else: - print("❌ tito --version: Failed") - return False - - # Test info command - result = subprocess.run([sys.executable, 'bin/tito.py', 'info'], - capture_output=True, text=True, timeout=10) - if result.returncode == 0 and 'Implementation Status' in result.stdout: - print("βœ… tito info: Working") - else: - print("❌ tito info: Failed") - return False - - print("βœ… CLI commands: Working properly") - return True - - except Exception as e: - print(f"❌ CLI commands: Error - {e}") - return False - -def check_hello_implementation(): - """Check the student's hello_tinytorch implementation.""" - print("\nπŸ‘‹ Checking hello_tinytorch() implementation...") - - try: - # Add project root to path - project_root = os.path.join(os.path.dirname(__file__), '../..') - sys.path.insert(0, project_root) - - from tinytorch.core.utils import hello_tinytorch - - # Test the function - result = hello_tinytorch() - - if not isinstance(result, str): - print(f"❌ hello_tinytorch(): Should return string, got {type(result)}") - return False - - if len(result.strip()) == 0: - print("❌ hello_tinytorch(): Should return non-empty string") - return False - - if 'πŸ”₯' not in result: - print("❌ hello_tinytorch(): Should contain πŸ”₯ emoji") - return False - - print(f"βœ… hello_tinytorch(): Implemented correctly") - print(f" Message: {result}") - return True - - except ImportError as e: - print(f"❌ hello_tinytorch(): Function not found - {e}") - print(" Make sure you've added the function to tinytorch/core/utils.py") - return False - except Exception as e: - print(f"❌ hello_tinytorch(): Error - {e}") - return False - -def run_test_suite(): - """Run the pytest test suite for setup.""" - print("\nπŸ§ͺ Running test suite...") - - try: - test_file = os.path.join(os.path.dirname(__file__), 'test_setup.py') - result = subprocess.run([sys.executable, '-m', 'pytest', test_file, '-v'], - capture_output=True, text=True, timeout=30) - - if result.returncode == 0: - print("βœ… Test suite: All tests passing") - return True - else: - print("❌ Test suite: Some tests failing") - print(" Test output:") - print(result.stdout) - if result.stderr: - print(result.stderr) - return False - - except Exception as e: - print(f"❌ Test suite: Error running tests - {e}") - return False - -def print_summary(all_checks): - """Print final summary.""" - print("\n" + "=" * 50) - - if all(all_checks): - print("πŸŽ‰ Setup complete! You're ready to build an ML system from scratch.") - print("\nNext steps:") - print(" cd ../tensor/") - print(" cat README.md") - print("\nYou can now submit this project:") - print(" python bin/tito.py submit --project setup") - else: - print("❌ Setup incomplete. Please fix the issues above before continuing.") - print("\nNeed help? Check the README.md or ask in office hours.") - -def main(): - """Run all setup verification checks.""" - print_header() - - checks = [ - check_python_version(), - check_virtual_environment(), - check_dependencies(), - check_cli_commands(), - check_hello_implementation(), - run_test_suite() - ] - - print_summary(checks) - return all(checks) - -if __name__ == "__main__": - success = main() - sys.exit(0 if success else 1) \ No newline at end of file diff --git a/modules/setup/create_env.py b/modules/setup/create_env.py deleted file mode 100644 index 2caf4ada..00000000 --- a/modules/setup/create_env.py +++ /dev/null @@ -1,205 +0,0 @@ -#!/usr/bin/env python3 -""" -TinyTorch Environment Setup Script - -This script automatically creates a virtual environment and installs -all required dependencies for the TinyTorch course. - -Usage: python projects/setup/create_env.py -""" - -import sys -import subprocess -import os -from pathlib import Path - -def print_step(step, message): - """Print a formatted step message.""" - print(f"\nπŸ”₯ Step {step}: {message}") - print("-" * 50) - -def run_command(cmd, check=True): - """Run a command and handle errors gracefully.""" - print(f"Running: {' '.join(cmd)}") - try: - result = subprocess.run(cmd, check=check, capture_output=True, text=True) - if result.stdout: - print(result.stdout) - return result - except subprocess.CalledProcessError as e: - print(f"❌ Error: {e}") - if e.stderr: - print(f"Error details: {e.stderr}") - return None - -def check_python_version(): - """Check if Python version is compatible.""" - version = sys.version_info - if version.major != 3 or version.minor < 8: - print(f"❌ Python {version.major}.{version.minor} detected. Need Python 3.8+") - print("Please install Python 3.8+ and try again.") - return False - - print(f"βœ… Python {version.major}.{version.minor}.{version.micro} detected (compatible)") - return True - -def create_virtual_environment(): - """Create the TinyTorch virtual environment.""" - env_path = Path(".venv") - - if env_path.exists(): - print(f"⚠️ Virtual environment already exists at {env_path}") - response = input("Remove and recreate? [y/N]: ").lower().strip() - if response == 'y': - import shutil - shutil.rmtree(env_path) - else: - print("Using existing environment...") - return True - - # Create virtual environment - result = run_command([sys.executable, "-m", "venv", ".venv"]) - if result is None: - print("❌ Failed to create virtual environment") - return False - - print("βœ… Virtual environment created") - return True - -def get_venv_python(): - """Get the path to Python in the virtual environment.""" - if sys.platform == "win32": - return Path(".venv/Scripts/python.exe") - else: - return Path(".venv/bin/python") - -def install_dependencies(): - """Install required dependencies in the virtual environment.""" - venv_python = get_venv_python() - - if not venv_python.exists(): - print(f"❌ Virtual environment Python not found at {venv_python}") - return False - - # Upgrade pip first - print("Upgrading pip...") - result = run_command([str(venv_python), "-m", "pip", "install", "--upgrade", "pip"]) - if result is None: - return False - - # Install build tools first (required for Python 3.13+) - print("Installing build tools...") - result = run_command([str(venv_python), "-m", "pip", "install", "--upgrade", "setuptools", "wheel"]) - if result is None: - return False - - # Try installing dependencies - first with requirements file - print("Installing TinyTorch dependencies...") - result = run_command([str(venv_python), "-m", "pip", "install", "-r", "requirements.txt"]) - - # If that fails, try installing core packages individually (fallback for Python 3.13) - if result is None: - print("⚠️ Requirements file failed, trying individual packages...") - core_packages = [ - "numpy>=1.21.0", - "matplotlib>=3.5.0", - "PyYAML>=6.0", - "pytest>=7.0.0", - "pytest-cov>=4.0.0" - ] - - for package in core_packages: - print(f"Installing {package}...") - result = run_command([str(venv_python), "-m", "pip", "install", package]) - if result is None: - print(f"❌ Failed to install {package}") - return False - - print("βœ… Dependencies installed") - return True - -def verify_installation(): - """Verify that everything is installed correctly.""" - venv_python = get_venv_python() - - # Test core imports - test_script = ''' -import sys -try: - import numpy - import matplotlib - import yaml - import pytest - print("βœ… All core dependencies imported successfully") - print(f"Python: {sys.version}") - print(f"NumPy: {numpy.__version__}") - print(f"Matplotlib: {matplotlib.__version__}") - print(f"PyYAML: {yaml.__version__}") - print(f"Pytest: {pytest.__version__}") -except ImportError as e: - print(f"❌ Import error: {e}") - sys.exit(1) -''' - - result = run_command([str(venv_python), "-c", test_script]) - return result is not None - -def print_next_steps(): - """Print instructions for next steps.""" - print("\n" + "=" * 60) - print("πŸŽ‰ Environment setup complete!") - print("=" * 60) - - if sys.platform == "win32": - activate_cmd = ".venv\\Scripts\\activate" - else: - activate_cmd = "source .venv/bin/activate" - - print(f""" -Next steps: - -1. Activate your environment (do this every time you work): - {activate_cmd} - -2. Verify the setup: - python3 projects/setup/check_setup.py - -3. Start the first project: - cd projects/setup/ - cat README.md - -πŸ“ Remember: Always activate your virtual environment before working! -""") - -def main(): - """Run the complete environment setup.""" - print("πŸ”₯ TinyTorch Environment Setup πŸ”₯") - print("=" * 60) - - # Step 1: Check Python version - print_step(1, "Checking Python version") - if not check_python_version(): - return False - - # Step 2: Create virtual environment - print_step(2, "Creating virtual environment") - if not create_virtual_environment(): - return False - - # Step 3: Install dependencies - print_step(3, "Installing dependencies") - if not install_dependencies(): - return False - - # Step 4: Verify installation - print_step(4, "Verifying installation") - if not verify_installation(): - return False - - # Print next steps - print_next_steps() - return True - -if __name__ == "__main__": - success = main() - sys.exit(0 if success else 1) \ No newline at end of file diff --git a/modules/setup/notebook/01_setup_basics.ipynb b/modules/setup/notebook/01_setup_basics.ipynb deleted file mode 100644 index 56fb2ccc..00000000 --- a/modules/setup/notebook/01_setup_basics.ipynb +++ /dev/null @@ -1,287 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# πŸ”₯ Tutorial 01: Setup Basics\n", - "\n", - "Welcome to your first TinyTorch tutorial! This notebook will teach you the fundamentals of the TinyTorch development workflow.\n", - "\n", - "## 🎯 What You'll Learn\n", - "\n", - "In this tutorial, you'll learn:\n", - "- βœ… How the TinyTorch project is organized\n", - "- βœ… The development workflow you'll use throughout the course\n", - "- βœ… How to implement and test your first function\n", - "- βœ… Best practices for TinyTorch development\n", - "\n", - "## πŸ“‹ TinyTorch Project Structure\n", - "\n", - "TinyTorch is organized into **modules** that build upon each other:\n", - "\n", - "```\n", - "modules/\n", - "β”œβ”€β”€ setup/ # πŸ”₯ You are here! (Module 01)\n", - "β”œβ”€β”€ tensor/ # Module 02 - Core tensor implementation\n", - "β”œβ”€β”€ mlp/ # Module 03 - Neural network layers\n", - "β”œβ”€β”€ autograd/ # Module 04 - Automatic differentiation\n", - "β”œβ”€β”€ optimizer/ # Module 05 - Training optimizers\n", - "β”œβ”€β”€ training/ # Module 06 - Training loops\n", - "β”œβ”€β”€ data/ # Module 07 - Data loading\n", - "β”œβ”€β”€ cnn/ # Module 08 - Convolutional networks\n", - "β”œβ”€β”€ compression/ # Module 09 - Model compression\n", - "β”œβ”€β”€ benchmarking/ # Module 10 - Performance testing\n", - "β”œβ”€β”€ profiling/ # Module 11 - Code profiling\n", - "β”œβ”€β”€ config/ # Module 12 - Configuration management\n", - "└── mlops/ # Module 13 - Production deployment\n", - "```\n", - "\n", - "Each module has the same structure:\n", - "- `README.md` - Overview and instructions\n", - "- `notebook/` - Interactive development\n", - "- `tutorials/` - Learning guides (this file!)\n", - "- `test_*.py` - Automated tests\n", - "- `check_*.py` - Manual verification\n", - "- `solutions/` - Reference implementations" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## πŸš€ Development Workflow\n", - "\n", - "Every module follows this workflow:\n", - "\n", - "### 1. **Read the Overview**\n", - "```bash\n", - "cat README.md # Understand what you're building\n", - "```\n", - "\n", - "### 2. **Study the Tutorials**\n", - "```bash\n", - "tito jupyter --lab # Start Jupyter\n", - "# Then open tutorials/01_*.ipynb, 02_*.ipynb, etc.\n", - "```\n", - "\n", - "### 3. **Implement in Notebook**\n", - "```bash\n", - "# Open notebook/*_dev.ipynb for interactive development\n", - "```\n", - "\n", - "### 4. **Test Your Work**\n", - "```bash\n", - "tito test --module setup # Run automated tests\n", - "python check_setup.py # Manual verification\n", - "```\n", - "\n", - "### 5. **Submit When Ready**\n", - "```bash\n", - "tito submit --module setup # Submit your work\n", - "```\n", - "\n", - "### 6. **Move to Next Module**\n", - "```bash\n", - "cd ../tensor/\n", - "cat README.md\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## πŸ”§ CLI Commands You'll Use\n", - "\n", - "The `tito` command is your main interface:\n", - "\n", - "```bash\n", - "# Check system status\n", - "tito info\n", - "\n", - "# Run tests for a specific module\n", - "tito test --module setup\n", - "tito test --module tensor\n", - "\n", - "# Start Jupyter for development\n", - "tito jupyter --lab\n", - "\n", - "# Submit your work\n", - "tito submit --module setup\n", - "\n", - "# Get help\n", - "tito --help\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## πŸ“ Where You Write Code\n", - "\n", - "Your implementations go in the `tinytorch/core/` directory:\n", - "\n", - "```\n", - "tinytorch/core/\n", - "β”œβ”€β”€ utils.py # πŸ”₯ Setup module (you're here!)\n", - "β”œβ”€β”€ tensor.py # Tensor module\n", - "β”œβ”€β”€ modules.py # MLP module\n", - "β”œβ”€β”€ autograd.py # Autograd module\n", - "β”œβ”€β”€ optimizer.py # Optimizer module\n", - "β”œβ”€β”€ trainer.py # Training module\n", - "β”œβ”€β”€ dataloader.py # Data module\n", - "└── ...\n", - "```\n", - "\n", - "**For this setup module**, you'll add to `tinytorch/core/utils.py`." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 🎯 Your First Task\n", - "\n", - "In this setup module, you'll implement a simple greeting function:\n", - "\n", - "```python\n", - "def hello_tinytorch() -> str:\n", - " \"\"\"\n", - " Return a greeting message for new TinyTorch users.\n", - " \n", - " Returns:\n", - " A welcoming message string\n", - " \"\"\"\n", - " return \"πŸ”₯ Welcome to TinyTorch! Ready to build ML systems from scratch! πŸ”₯\"\n", - "```\n", - "\n", - "**Requirements**:\n", - "- βœ… Function must return a string\n", - "- βœ… Must contain welcoming content\n", - "- βœ… Must include the πŸ”₯ emoji (TinyTorch branding)\n", - "- βœ… Must have proper docstring and type hints" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## πŸ§ͺ Testing Your Work\n", - "\n", - "You have multiple ways to test your implementation:\n", - "\n", - "### 1. **Automated Tests**\n", - "```bash\n", - "tito test --module setup\n", - "```\n", - "\n", - "### 2. **Manual Verification**\n", - "```bash\n", - "python modules/setup/check_setup.py\n", - "```\n", - "\n", - "### 3. **Direct Testing**\n", - "```python\n", - "from tinytorch.core.utils import hello_tinytorch\n", - "result = hello_tinytorch()\n", - "print(result)\n", - "```\n", - "\n", - "### 4. **Pytest**\n", - "```bash\n", - "python -m pytest modules/setup/test_setup.py -v\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## πŸ’‘ Best Practices\n", - "\n", - "### **Code Style**\n", - "- Use clear, descriptive function names\n", - "- Add proper docstrings explaining what your function does\n", - "- Include type hints for better code clarity\n", - "- Follow PEP 8 style guidelines\n", - "\n", - "### **Testing**\n", - "- Test frequently as you develop\n", - "- Run both automated and manual tests\n", - "- Check edge cases and error conditions\n", - "\n", - "### **Documentation**\n", - "- Write clear docstrings\n", - "- Explain complex logic with comments\n", - "- Keep your code self-documenting\n", - "\n", - "### **Debugging**\n", - "- Use print statements for quick debugging\n", - "- Use the notebook for interactive development\n", - "- Check error messages carefully" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## πŸ” Understanding Error Messages\n", - "\n", - "When tests fail, you'll see messages like:\n", - "\n", - "```\n", - "❌ hello_tinytorch(): Function not found\n", - " Make sure you've added the function to tinytorch/core/utils.py\n", - "```\n", - "\n", - "**How to fix**:\n", - "1. **Function not found**: Add the function to the correct file\n", - "2. **Import error**: Check your file path and syntax\n", - "3. **Type error**: Make sure you're returning the right type\n", - "4. **Content error**: Check that your output matches requirements" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## πŸš€ Ready to Start?\n", - "\n", - "Now you understand the basics! Here's what to do next:\n", - "\n", - "1. **Open the development notebook**: `notebook/setup_dev.ipynb`\n", - "2. **Follow the step-by-step instructions**\n", - "3. **Implement your `hello_tinytorch()` function**\n", - "4. **Test your implementation**\n", - "5. **Submit when ready**\n", - "\n", - "**Remember**: This is just the beginning! You're building the foundation for an entire ML system from scratch. Each module builds on the previous ones, so take your time and make sure you understand what you're doing.\n", - "\n", - "**Good luck, and happy coding! πŸ”₯**" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8.0" - } - }, - "nbformat": 4, - "nbformat_minor": 4 - } \ No newline at end of file diff --git a/modules/setup/notebook/setup_dev.ipynb b/modules/setup/notebook/setup_dev.ipynb deleted file mode 100644 index 231f206f..00000000 --- a/modules/setup/notebook/setup_dev.ipynb +++ /dev/null @@ -1,345 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# πŸ”₯ Setup Module Development Notebook\n", - "\n", - "Welcome to your first TinyTorch implementation! This notebook will guide you through implementing the `hello_tinytorch()` function.\n", - "\n", - "## 🎯 Learning Objectives\n", - "\n", - "By the end of this notebook, you will:\n", - "- βœ… Understand the TinyTorch development workflow\n", - "- βœ… Implement your first function in the system\n", - "- βœ… Test your implementation\n", - "- βœ… Be ready for the next module\n", - "\n", - "## πŸ“‹ What You'll Implement\n", - "\n", - "You'll add a simple greeting function to `tinytorch/core/utils.py`:\n", - "\n", - "```python\n", - "def hello_tinytorch() -> str:\n", - " \"\"\"\n", - " Return a greeting message for new TinyTorch users.\n", - " \n", - " Returns:\n", - " A welcoming message string\n", - " \"\"\"\n", - " return \"πŸ”₯ Welcome to TinyTorch! Ready to build ML systems from scratch! πŸ”₯\"\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## πŸš€ Step 1: Environment Check\n", - "\n", - "First, let's make sure your environment is working correctly." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Check Python version\n", - "import sys\n", - "print(f\"Python version: {sys.version}\")\n", - "print(f\"Python executable: {sys.executable}\")\n", - "\n", - "# Check if we're in a virtual environment\n", - "in_venv = (hasattr(sys, 'real_prefix') or \n", - " (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix))\n", - "print(f\"Virtual environment: {'Active' if in_venv else 'Not detected'}\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## πŸ“¦ Step 2: Import Check\n", - "\n", - "Let's verify we can import from the TinyTorch system." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Add the project root to Python path\n", - "import os\n", - "import sys\n", - "project_root = os.path.join(os.getcwd(), '..', '..')\n", - "sys.path.insert(0, project_root)\n", - "\n", - "# Try to import from tinytorch\n", - "try:\n", - " from tinytorch.core import utils\n", - " print(\"βœ… Successfully imported tinytorch.core.utils\")\n", - "except ImportError as e:\n", - " print(f\"❌ Failed to import: {e}\")\n", - " print(\"Make sure you're running this from the modules/setup/notebook/ directory\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## πŸ” Step 3: Examine Current Utils\n", - "\n", - "Let's look at what's currently in the utils module." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Check what's currently in utils\n", - "import inspect\n", - "from tinytorch.core import utils\n", - "\n", - "print(\"Current functions in utils:\")\n", - "for name, obj in inspect.getmembers(utils):\n", - " if inspect.isfunction(obj):\n", - " print(f\" - {name}()\")\n", - "\n", - "print(\"\\nLet's look at the current utils.py file:\")\n", - "with open(os.path.join(project_root, 'tinytorch', 'core', 'utils.py'), 'r') as f:\n", - " print(f.read())" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## ✏️ Step 4: Implement Your Function\n", - "\n", - "Now it's time to implement the `hello_tinytorch()` function. You'll need to edit the `tinytorch/core/utils.py` file.\n", - "\n", - "**Your Task**: Add the `hello_tinytorch()` function to the utils module.\n", - "\n", - "**Requirements**:\n", - "- Function should return a string\n", - "- Should contain welcoming content\n", - "- Should include the πŸ”₯ emoji (TinyTorch branding)\n", - "- Should have proper docstring and type hints" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# TODO: Edit tinytorch/core/utils.py and add your hello_tinytorch() function\n", - "# \n", - "# Here's what you need to add:\n", - "# \n", - "# def hello_tinytorch() -> str:\n", - "# \"\"\"\n", - "# Return a greeting message for new TinyTorch users.\n", - "# \n", - "# Returns:\n", - "# A welcoming message string\n", - "# \"\"\"\n", - "# return \"πŸ”₯ Welcome to TinyTorch! Ready to build ML systems from scratch! πŸ”₯\"\n", - "#\n", - "# After you've added the function, run the cell below to test it.\n", - "\n", - "print(\"πŸ“ Please edit tinytorch/core/utils.py and add your hello_tinytorch() function\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## πŸ§ͺ Step 5: Test Your Implementation\n", - "\n", - "Once you've added the function, let's test it!" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Reload the utils module to get your changes\n", - "import importlib\n", - "importlib.reload(utils)\n", - "\n", - "# Try to import your function\n", - "try:\n", - " from tinytorch.core.utils import hello_tinytorch\n", - " print(\"βœ… hello_tinytorch() function found!\")\n", - " \n", - " # Test the function\n", - " result = hello_tinytorch()\n", - " print(f\"πŸ“€ Function returned: {result}\")\n", - " \n", - " # Check requirements\n", - " checks = []\n", - " checks.append(isinstance(result, str))\n", - " checks.append(len(result.strip()) > 0)\n", - " checks.append('πŸ”₯' in result)\n", - " checks.append(any(word in result.lower() for word in ['welcome', 'hello', 'tinytorch', 'ready']))\n", - " \n", - " print(\"\\nπŸ“‹ Requirements Check:\")\n", - " print(f\" βœ… Returns string: {checks[0]}\")\n", - " print(f\" βœ… Non-empty: {checks[1]}\")\n", - " print(f\" βœ… Contains πŸ”₯: {checks[2]}\")\n", - " print(f\" βœ… Welcoming content: {checks[3]}\")\n", - " \n", - " if all(checks):\n", - " print(\"\\nπŸŽ‰ All tests passed! Your implementation is complete!\")\n", - " else:\n", - " print(\"\\n❌ Some tests failed. Please check your implementation.\")\n", - " \n", - "except ImportError as e:\n", - " print(f\"❌ Function not found: {e}\")\n", - " print(\"Make sure you've added the hello_tinytorch() function to tinytorch/core/utils.py\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## πŸ§ͺ Step 6: Run Full Test Suite\n", - "\n", - "Let's run the complete test suite to make sure everything works." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Run the pytest test suite\n", - "import subprocess\n", - "import sys\n", - "\n", - "test_file = os.path.join(project_root, 'modules', 'setup', 'test_setup.py')\n", - "print(f\"Running tests from: {test_file}\")\n", - "\n", - "try:\n", - " result = subprocess.run([sys.executable, '-m', 'pytest', test_file, '-v'], \n", - " capture_output=True, text=True, timeout=30)\n", - " \n", - " if result.returncode == 0:\n", - " print(\"βœ… All tests passed!\")\n", - " print(\"\\nTest output:\")\n", - " print(result.stdout)\n", - " else:\n", - " print(\"❌ Some tests failed.\")\n", - " print(\"\\nTest output:\")\n", - " print(result.stdout)\n", - " if result.stderr:\n", - " print(\"\\nError output:\")\n", - " print(result.stderr)\n", - " \n", - "except Exception as e:\n", - " print(f\"❌ Error running tests: {e}\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## βœ… Step 7: Manual Verification\n", - "\n", - "Let's run the manual verification script for detailed feedback." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Run the manual verification script\n", - "check_script = os.path.join(project_root, 'modules', 'setup', 'check_setup.py')\n", - "print(f\"Running verification script: {check_script}\")\n", - "\n", - "try:\n", - " result = subprocess.run([sys.executable, check_script], \n", - " capture_output=True, text=True, timeout=30)\n", - " \n", - " print(\"\\n\" + \"=\"*50)\n", - " print(\"VERIFICATION RESULTS\")\n", - " print(\"=\"*50)\n", - " print(result.stdout)\n", - " \n", - " if result.stderr:\n", - " print(\"\\nErrors:\")\n", - " print(result.stderr)\n", - " \n", - "except Exception as e:\n", - " print(f\"❌ Error running verification: {e}\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## πŸŽ‰ Congratulations!\n", - "\n", - "If all tests passed, you've successfully completed the Setup module! You've:\n", - "\n", - "βœ… **Set up your development environment**\n", - "βœ… **Implemented your first TinyTorch function**\n", - "βœ… **Learned the testing workflow**\n", - "βœ… **Verified your implementation**\n", - "\n", - "## πŸš€ Next Steps\n", - "\n", - "You're now ready to move to the next module:\n", - "\n", - "```bash\n", - "# Navigate to the tensor module\n", - "cd ../tensor/\n", - "\n", - "# Read the overview\n", - "cat README.md\n", - "\n", - "# Start the development notebook\n", - "tito jupyter --lab\n", - "```\n", - "\n", - "In the tensor module, you'll build the core Tensor class that will be the foundation for everything else in TinyTorch!\n", - "\n", - "**Good luck, and happy coding! πŸ”₯**" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8.0" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/modules/setup/solutions/solution_setup.py b/modules/setup/solutions/solution_setup.py deleted file mode 100644 index 04080a68..00000000 --- a/modules/setup/solutions/solution_setup.py +++ /dev/null @@ -1,48 +0,0 @@ -""" -Setup Module Reference Solution - -This file contains the reference implementation for the setup module. -Instructors can use this to verify student work or provide hints. - -Student Task: Implement hello_tinytorch() function in tinytorch/core/utils.py -""" - -def hello_tinytorch() -> str: - """ - Return a greeting message for new TinyTorch users. - - This function serves as the "hello world" for the TinyTorch system. - It introduces students to the development workflow and testing process. - - Returns: - A welcoming message string that includes: - - Welcoming content - - TinyTorch branding (πŸ”₯ emoji) - - Encouraging message about building ML systems - """ - return "πŸ”₯ Welcome to TinyTorch! Ready to build ML systems from scratch! πŸ”₯" - - -# Example usage and testing -if __name__ == "__main__": - # Test the function - result = hello_tinytorch() - print(f"Function result: {result}") - - # Verify requirements - checks = [] - checks.append(isinstance(result, str)) - checks.append(len(result.strip()) > 0) - checks.append('πŸ”₯' in result) - checks.append(any(word in result.lower() for word in ['welcome', 'hello', 'tinytorch', 'ready'])) - - print("\nRequirements check:") - print(f" βœ… Returns string: {checks[0]}") - print(f" βœ… Non-empty: {checks[1]}") - print(f" βœ… Contains πŸ”₯: {checks[2]}") - print(f" βœ… Welcoming content: {checks[3]}") - - if all(checks): - print("\nπŸŽ‰ All requirements met!") - else: - print("\n❌ Some requirements not met.") \ No newline at end of file diff --git a/modules/setup/test_setup.py b/modules/setup/test_setup.py deleted file mode 100644 index 8914e8cb..00000000 --- a/modules/setup/test_setup.py +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env python3 -""" -Setup Project Tests - -This file tests the student's implementation of the hello_tinytorch() function. -Students can run: python -m pytest projects/setup/test_setup.py -""" - -import sys -import os -import pytest - -# Add the project root to Python path so we can import tinytorch -sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../..')) - -def test_hello_tinytorch_exists(): - """Test that the hello_tinytorch function exists and can be imported.""" - try: - from tinytorch.core.utils import hello_tinytorch - except ImportError: - pytest.fail("Could not import hello_tinytorch from tinytorch.core.utils. " - "Make sure you've implemented the function!") - -def test_hello_tinytorch_returns_string(): - """Test that hello_tinytorch returns a string.""" - from tinytorch.core.utils import hello_tinytorch - - result = hello_tinytorch() - assert isinstance(result, str), f"hello_tinytorch() should return a string, got {type(result)}" - -def test_hello_tinytorch_not_empty(): - """Test that hello_tinytorch returns a non-empty string.""" - from tinytorch.core.utils import hello_tinytorch - - result = hello_tinytorch() - assert len(result.strip()) > 0, "hello_tinytorch() should return a non-empty string" - -def test_hello_tinytorch_contains_welcome(): - """Test that the greeting contains welcoming content.""" - from tinytorch.core.utils import hello_tinytorch - - result = hello_tinytorch().lower() - # Should contain some welcoming words - welcome_words = ['welcome', 'hello', 'tinytorch', 'ready'] - - assert any(word in result for word in welcome_words), \ - f"hello_tinytorch() should contain welcoming content. Got: {hello_tinytorch()}" - -def test_hello_tinytorch_has_fire_emoji(): - """Test that the greeting contains the fire emoji (matching brand).""" - from tinytorch.core.utils import hello_tinytorch - - result = hello_tinytorch() - assert 'πŸ”₯' in result, \ - f"hello_tinytorch() should contain the πŸ”₯ emoji to match TinyTorch branding. Got: {result}" - -def test_hello_tinytorch_proper_format(): - """Test that the function has proper docstring and type hints.""" - from tinytorch.core.utils import hello_tinytorch - import inspect - - # Check that function has a docstring - assert hello_tinytorch.__doc__ is not None, \ - "hello_tinytorch() should have a docstring explaining what it does" - - # Check type annotations - sig = inspect.signature(hello_tinytorch) - assert sig.return_annotation == str, \ - "hello_tinytorch() should have return type annotation -> str" - -if __name__ == "__main__": - # Allow running this file directly for testing - pytest.main([__file__, "-v"]) \ No newline at end of file diff --git a/modules/setup/tutorials/01_setup_basics.ipynb b/modules/setup/tutorials/01_setup_basics.ipynb deleted file mode 100644 index 0519ecba..00000000 --- a/modules/setup/tutorials/01_setup_basics.ipynb +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/modules/tensor/README.md b/modules/tensor/README.md index 8160799c..fbb51fd3 100644 --- a/modules/tensor/README.md +++ b/modules/tensor/README.md @@ -1,201 +1,202 @@ -# πŸ”₯ Module 02: Tensor Implementation +# πŸ”₯ Module: Tensor -Welcome to the Tensor module! This is where you'll build the foundation of TinyTorch by implementing the core Tensor class. +Build the foundation of TinyTorch! This module implements the core Tensor class - the fundamental data structure that powers all neural networks and machine learning operations. ## 🎯 Learning Objectives By the end of this module, you will: -- βœ… Understand what tensors are and why they're fundamental to ML -- βœ… Implement a basic Tensor class with core operations -- βœ… Handle tensor shapes, data types, and basic arithmetic -- βœ… Test your implementation with automated tests -- βœ… Be ready to build neural networks in the next module +- βœ… Understand what tensors are and why they're essential for ML +- βœ… Implement a complete Tensor class with core operations +- βœ… Handle tensor shapes, data types, and memory management +- βœ… Implement element-wise operations and reductions +- βœ… Have a solid foundation for building neural networks ## πŸ“‹ Module Structure ``` modules/tensor/ -β”œβ”€β”€ README.md # πŸ“– This file - Module overview -β”œβ”€β”€ notebook/ # πŸ““ Interactive development -β”‚ └── tensor_dev.ipynb # Main development notebook -β”œβ”€β”€ tutorials/ # πŸŽ“ Step-by-step learning guides -β”‚ β”œβ”€β”€ 01_tensor_basics.ipynb # Introduction to tensors -β”‚ └── 02_tensor_ops.ipynb # Tensor operations tutorial -β”œβ”€β”€ test_tensor.py # πŸ§ͺ Automated tests -β”œβ”€β”€ check_tensor.py # βœ… Manual verification -└── solutions/ # πŸ”‘ Reference solutions (instructors) - └── solution_tensor.py +β”œβ”€β”€ README.md # πŸ“– This file - Module overview +β”œβ”€β”€ tensor.ipynb # πŸ““ Main development notebook +β”œβ”€β”€ test_tensor.py # πŸ§ͺ Automated tests +└── check_tensor.py # βœ… Manual verification (coming soon) ``` ## πŸš€ Getting Started -### Step 1: Environment Setup +### Step 1: Complete Prerequisites +Make sure you've completed the setup module: ```bash -# Make sure your environment is activated -source .venv/bin/activate +python bin/tito.py test --module setup # Should pass +``` -# Navigate to the tensor module +### Step 2: Open the Tensor Notebook +```bash +# Start from the tensor module directory cd modules/tensor/ + +# Open the development notebook +jupyter lab tensor.ipynb ``` -### Step 2: Read the Tutorials (Recommended) +### Step 3: Work Through the Implementation +The notebook guides you through building: +1. **Basic Tensor class** - Constructor and properties +2. **Shape management** - Understanding tensor dimensions +3. **Arithmetic operations** - Addition, multiplication, etc. +4. **Utility methods** - Reshape, transpose, sum, mean +5. **Error handling** - Robust edge case management + +### Step 4: Export and Test ```bash -# Start Jupyter -tito jupyter --lab +# Export your tensor implementation +python bin/tito.py sync -# Then open these notebooks in order: -# 1. tutorials/01_tensor_basics.ipynb - Learn about tensors -# 2. tutorials/02_tensor_ops.ipynb - Learn about operations -``` - -### Step 3: Implement Your Tensor Class -```bash -# Open the main development notebook -# Navigate to: notebook/tensor_dev.ipynb - -# Work through the implementation step by step: -# 1. Basic Tensor class with constructor -# 2. Properties (shape, size, dtype) -# 3. Arithmetic operations (add, subtract, multiply, divide) -# 4. Utility methods (reshape, transpose, sum, mean, etc.) -``` - -### Step 4: Test Your Implementation -```bash -# Run automated tests -tito test --module tensor - -# Run manual verification -python check_tensor.py - -# Test integration -python -c "from tinytorch.core.tensor import Tensor; print('Success!')" -``` - -### Step 5: Submit Your Work -```bash -# Submit when ready -tito submit --module tensor - -# Move to next module -cd ../mlp/ -cat README.md +# Test your implementation +python bin/tito.py test --module tensor ``` ## πŸ“š What You'll Implement ### Core Tensor Class -Your Tensor class should support: +You'll build a complete `Tensor` class that supports: -1. **Constructor**: Initialize with data and optional dtype -2. **Properties**: shape, size, dtype -3. **Arithmetic**: +, -, *, / with tensors and scalars -4. **Utilities**: reshape, transpose, sum, mean, max, min, flatten -5. **Error Handling**: Proper exceptions for invalid operations - -### Example Usage +#### 1. Construction and Properties ```python -# Create tensors -a = Tensor([1, 2, 3]) -b = Tensor([[1, 2], [3, 4]]) +# Creating tensors +a = Tensor([1, 2, 3]) # 1D tensor +b = Tensor([[1, 2], [3, 4]]) # 2D tensor +c = Tensor(5.0) # Scalar tensor -# Basic operations -c = a + 5 # Scalar addition -d = a * b # Element-wise multiplication -e = b.reshape(1, 4) # Reshape -f = b.sum(axis=0) # Sum along axis +# Properties +print(a.shape) # (3,) +print(b.size) # 4 +print(c.dtype) # float32 ``` +#### 2. Arithmetic Operations +```python +# Element-wise operations +result = a + b # Addition +result = a * 2 # Scalar multiplication +result = a @ b # Matrix multiplication (bonus) +``` + +#### 3. Utility Methods +```python +# Shape manipulation +reshaped = b.reshape(1, 4) # Change shape +transposed = b.transpose() # Swap dimensions + +# Reductions +total = a.sum() # Sum all elements +mean_val = a.mean() # Average value +max_val = a.max() # Maximum value +``` + +### Technical Requirements +Your Tensor class must: +- Handle multiple data types (int, float) +- Support N-dimensional arrays +- Implement proper error checking +- Work with NumPy arrays internally +- Export to `tinytorch.core.tensor` + ## πŸ§ͺ Testing Your Implementation ### Automated Tests ```bash -tito test --module tensor +python bin/tito.py test --module tensor ``` -This runs comprehensive tests for: -- βœ… Tensor creation (scalar, list, matrix) -- βœ… Arithmetic operations (add, subtract, multiply, divide) -- βœ… Utility methods (reshape, transpose, sum, mean, etc.) -- βœ… Error handling (invalid inputs, operations) -### Manual Verification -```bash -python check_tensor.py +Tests verify: +- βœ… Tensor creation (scalars, vectors, matrices) +- βœ… Property access (shape, size, dtype) +- βœ… Arithmetic operations (all combinations) +- βœ… Utility methods (reshape, transpose, reductions) +- βœ… Error handling (invalid operations) + +### Interactive Testing +```python +# Test in the notebook or Python REPL +from tinytorch.core.tensor import Tensor + +# Create and test tensors +a = Tensor([1, 2, 3]) +b = Tensor([[1, 2], [3, 4]]) +print(a + 5) # Should work +print(a.sum()) # Should return scalar ``` -This provides human-readable feedback on: -- πŸ“Š Progress tracking -- πŸ” Specific test results -- πŸ’‘ Helpful error messages -- πŸ“‹ Next steps guidance ## 🎯 Success Criteria -Your implementation is complete when: +Your tensor module is complete when: -1. **All automated tests pass**: `tito test --module tensor` shows βœ… -2. **Manual verification passes**: `python check_tensor.py` shows all tests passed -3. **Integration works**: Can import and use Tensor from tinytorch.core.tensor -4. **Error handling works**: Invalid operations raise appropriate exceptions +1. **All tests pass**: `python bin/tito.py test --module tensor` +2. **Tensor imports correctly**: `from tinytorch.core.tensor import Tensor` +3. **Basic operations work**: Can create tensors and do arithmetic +4. **Properties work**: Shape, size, dtype return correct values +5. **Utilities work**: Reshape, transpose, reductions function properly -## πŸ“– Learning Resources +## πŸ’‘ Implementation Tips -### Tutorial Notebooks -- **01_tensor_basics.ipynb**: Introduction to tensor concepts -- **02_tensor_ops.ipynb**: Deep dive into tensor operations +### Start with the Basics +1. **Simple constructor** - Handle lists and NumPy arrays +2. **Basic properties** - Shape, size, dtype +3. **One operation** - Start with addition +4. **Test frequently** - Verify each feature works -### Key Concepts to Understand -- **Tensors as multi-dimensional arrays** -- **Shape and size properties** -- **Element-wise operations** -- **Broadcasting rules** -- **Reduction operations (sum, mean, etc.)** +### Design Patterns +```python +class Tensor: + def __init__(self, data, dtype=None): + # Convert input to numpy array + # Store shape, size, dtype + + def __add__(self, other): + # Handle tensor + tensor + # Handle tensor + scalar + # Return new Tensor + + def sum(self, axis=None): + # Reduce along specified axis + # Return scalar or tensor +``` -## πŸ”§ Implementation Tips +### Common Challenges +- **Shape compatibility** - Check dimensions for operations +- **Data type handling** - Convert inputs consistently +- **Memory efficiency** - Don't create unnecessary copies +- **Error messages** - Provide helpful debugging info -### Start Simple -1. **Basic constructor** that handles lists and numpy arrays -2. **Properties** (shape, size, dtype) that return correct values -3. **Simple arithmetic** (add, multiply) with tensors and scalars -4. **Basic utilities** (reshape, sum) that work correctly +## πŸ”§ Advanced Features (Optional) -### Test Frequently -- Run tests after each major feature -- Use the manual verification for detailed feedback -- Test edge cases (empty tensors, different dtypes) - -### Common Pitfalls -- **Shape handling**: Make sure 0D tensors are handled correctly -- **Data types**: Ensure dtype parameter works properly -- **Error messages**: Provide clear, helpful error messages -- **Memory efficiency**: Avoid unnecessary copies +If you finish early, try implementing: +- **Broadcasting** - Operations on different-shaped tensors +- **Slicing** - `tensor[1:3, :]` syntax +- **In-place operations** - `tensor += other` +- **Matrix multiplication** - `tensor @ other` ## πŸš€ Next Steps -Once you complete this module: +Once you complete the tensor module: -1. **Move to MLP module**: `cd ../mlp/` -2. **Build neural networks**: Use your tensors to create layers -3. **Add autograd**: Implement automatic differentiation -4. **Train models**: Put it all together with training loops +1. **Move to Autograd**: `cd modules/autograd/` +2. **Build automatic differentiation**: Enable gradient computation +3. **Combine with tensors**: Make tensors differentiable +4. **Prepare for neural networks**: Ready for the MLP module -## πŸ’‘ Need Help? +## πŸ”— Why Tensors Matter -### Common Issues -- **Import errors**: Make sure your Tensor class is in `tinytorch/core/tensor.py` -- **Test failures**: Check the specific error messages for guidance -- **Shape mismatches**: Verify your shape calculations are correct +Tensors are the foundation of all ML systems: +- **Neural networks** store weights and activations as tensors +- **Training** computes gradients on tensors +- **Data processing** represents batches as tensors +- **GPU acceleration** operates on tensor primitives -### Getting Support -- **Check tutorials**: The tutorial notebooks have detailed explanations -- **Run verification**: `python check_tensor.py` provides specific feedback -- **Review tests**: The test files show exactly what's expected +Your tensor implementation will power everything else in TinyTorch! -## πŸŽ‰ You're Building Something Amazing! +## πŸŽ‰ Ready to Build? -This Tensor implementation will be the foundation for everything else in TinyTorch: -- **Neural networks** will use your tensors for weights and activations -- **Optimizers** will update your tensors during training -- **Data loading** will convert datasets into your tensors -- **And much more!** +The tensor module is where TinyTorch really begins. You're about to create the fundamental building block that will power neural networks, training loops, and production ML systems. -Good luck, and happy coding! πŸ”₯ \ No newline at end of file +Take your time, test thoroughly, and enjoy building something that really works! πŸ”₯ \ No newline at end of file diff --git a/modules/tensor/check_tensor.py b/modules/tensor/check_tensor.py deleted file mode 100644 index 3102ef79..00000000 --- a/modules/tensor/check_tensor.py +++ /dev/null @@ -1,327 +0,0 @@ -#!/usr/bin/env python3 -""" -Manual verification script for the Tensor module. - -This script provides human-readable feedback on the student's -tensor implementation progress and helps identify what needs to be done. -""" - -import sys -import os -import numpy as np - -# Add the parent directory to the path so we can import from tinytorch -sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..')) - -def print_header(): - """Print the verification header.""" - print("πŸ”₯ TinyTorch Tensor Verification πŸ”₯") - print("=" * 50) - print() - -def check_tensor_import(): - """Check if the Tensor class can be imported.""" - print("πŸ“¦ Checking Tensor Implementation...") - - try: - from tinytorch.core.tensor import Tensor - print("βœ… Tensor class found and imported successfully!") - return True, Tensor - except ImportError as e: - print("❌ Tensor class not found!") - print(f" Error: {e}") - print("πŸ’‘ Make sure to implement the Tensor class in tinytorch/core/tensor.py") - return False, None - -def check_basic_functionality(Tensor): - """Check basic tensor functionality.""" - print("\nπŸ”§ Testing Basic Functionality...") - - tests_passed = 0 - total_tests = 0 - - # Test 1: Scalar creation - total_tests += 1 - try: - t = Tensor(5) - if hasattr(t, 'shape') and hasattr(t, 'size') and hasattr(t, 'data'): - print("βœ… Scalar tensor creation: PASSED") - tests_passed += 1 - else: - print("❌ Scalar tensor creation: FAILED (missing properties)") - except Exception as e: - print(f"❌ Scalar tensor creation: FAILED ({e})") - - # Test 2: List creation - total_tests += 1 - try: - t = Tensor([1, 2, 3, 4]) - if t.shape == (4,) and t.size == 4: - print("βœ… List tensor creation: PASSED") - tests_passed += 1 - else: - print("❌ List tensor creation: FAILED (incorrect shape/size)") - except Exception as e: - print(f"❌ List tensor creation: FAILED ({e})") - - # Test 3: Matrix creation - total_tests += 1 - try: - t = Tensor([[1, 2], [3, 4]]) - if t.shape == (2, 2) and t.size == 4: - print("βœ… Matrix tensor creation: PASSED") - tests_passed += 1 - else: - print("❌ Matrix tensor creation: FAILED (incorrect shape/size)") - except Exception as e: - print(f"❌ Matrix tensor creation: FAILED ({e})") - - # Test 4: Data type handling - total_tests += 1 - try: - t = Tensor([1, 2, 3], dtype=np.float32) - if t.dtype == np.float32: - print("βœ… Data type handling: PASSED") - tests_passed += 1 - else: - print("❌ Data type handling: FAILED (incorrect dtype)") - except Exception as e: - print(f"❌ Data type handling: FAILED ({e})") - - return tests_passed, total_tests - -def check_arithmetic_operations(Tensor): - """Check arithmetic operations.""" - print("\nπŸ”’ Testing Arithmetic Operations...") - - tests_passed = 0 - total_tests = 0 - - # Test 1: Addition - total_tests += 1 - try: - a = Tensor([1, 2, 3]) - b = Tensor([4, 5, 6]) - c = a + b - expected = np.array([5, 7, 9]) - if np.array_equal(c.data, expected): - print("βœ… Tensor addition: PASSED") - tests_passed += 1 - else: - print("❌ Tensor addition: FAILED (incorrect result)") - except Exception as e: - print(f"❌ Tensor addition: FAILED ({e})") - - # Test 2: Scalar addition - total_tests += 1 - try: - a = Tensor([1, 2, 3]) - c = a + 5 - expected = np.array([6, 7, 8]) - if np.array_equal(c.data, expected): - print("βœ… Scalar addition: PASSED") - tests_passed += 1 - else: - print("❌ Scalar addition: FAILED (incorrect result)") - except Exception as e: - print(f"❌ Scalar addition: FAILED ({e})") - - # Test 3: Multiplication - total_tests += 1 - try: - a = Tensor([1, 2, 3]) - b = Tensor([4, 5, 6]) - c = a * b - expected = np.array([4, 10, 18]) - if np.array_equal(c.data, expected): - print("βœ… Tensor multiplication: PASSED") - tests_passed += 1 - else: - print("❌ Tensor multiplication: FAILED (incorrect result)") - except Exception as e: - print(f"❌ Tensor multiplication: FAILED ({e})") - - # Test 4: Scalar multiplication - total_tests += 1 - try: - a = Tensor([1, 2, 3]) - c = a * 3 - expected = np.array([3, 6, 9]) - if np.array_equal(c.data, expected): - print("βœ… Scalar multiplication: PASSED") - tests_passed += 1 - else: - print("❌ Scalar multiplication: FAILED (incorrect result)") - except Exception as e: - print(f"❌ Scalar multiplication: FAILED ({e})") - - return tests_passed, total_tests - -def check_utility_methods(Tensor): - """Check utility methods.""" - print("\nπŸ› οΈ Testing Utility Methods...") - - tests_passed = 0 - total_tests = 0 - - # Test 1: Reshape - total_tests += 1 - try: - t = Tensor([[1, 2, 3], [4, 5, 6]]) - reshaped = t.reshape(3, 2) - expected = np.array([[1, 2], [3, 4], [5, 6]]) - if np.array_equal(reshaped.data, expected) and reshaped.shape == (3, 2): - print("βœ… Reshape method: PASSED") - tests_passed += 1 - else: - print("❌ Reshape method: FAILED (incorrect result)") - except Exception as e: - print(f"❌ Reshape method: FAILED ({e})") - - # Test 2: Transpose - total_tests += 1 - try: - t = Tensor([[1, 2, 3], [4, 5, 6]]) - transposed = t.transpose() - expected = np.array([[1, 4], [2, 5], [3, 6]]) - if np.array_equal(transposed.data, expected) and transposed.shape == (3, 2): - print("βœ… Transpose method: PASSED") - tests_passed += 1 - else: - print("❌ Transpose method: FAILED (incorrect result)") - except Exception as e: - print(f"❌ Transpose method: FAILED ({e})") - - # Test 3: Sum - total_tests += 1 - try: - t = Tensor([[1, 2, 3], [4, 5, 6]]) - result = t.sum() - expected = np.array(21) - if np.array_equal(result.data, expected): - print("βœ… Sum method: PASSED") - tests_passed += 1 - else: - print("❌ Sum method: FAILED (incorrect result)") - except Exception as e: - print(f"❌ Sum method: FAILED ({e})") - - # Test 4: Mean - total_tests += 1 - try: - t = Tensor([[1, 2, 3], [4, 5, 6]]) - result = t.mean() - expected = np.array(3.5) - if np.allclose(result.data, expected): - print("βœ… Mean method: PASSED") - tests_passed += 1 - else: - print("❌ Mean method: FAILED (incorrect result)") - except Exception as e: - print(f"❌ Mean method: FAILED ({e})") - - # Test 5: Flatten - total_tests += 1 - try: - t = Tensor([[1, 2, 3], [4, 5, 6]]) - flattened = t.flatten() - expected = np.array([1, 2, 3, 4, 5, 6]) - if np.array_equal(flattened.data, expected) and flattened.shape == (6,): - print("βœ… Flatten method: PASSED") - tests_passed += 1 - else: - print("❌ Flatten method: FAILED (incorrect result)") - except Exception as e: - print(f"❌ Flatten method: FAILED ({e})") - - return tests_passed, total_tests - -def check_error_handling(Tensor): - """Check error handling.""" - print("\n🚨 Testing Error Handling...") - - tests_passed = 0 - total_tests = 0 - - # Test 1: Invalid data type - total_tests += 1 - try: - Tensor("invalid") - print("❌ Invalid data type: FAILED (should raise ValueError)") - except ValueError: - print("βœ… Invalid data type: PASSED") - tests_passed += 1 - except Exception as e: - print(f"❌ Invalid data type: FAILED (wrong exception: {e})") - - # Test 2: Invalid operation - total_tests += 1 - try: - a = Tensor([1, 2, 3]) - a + "invalid" - print("❌ Invalid operation: FAILED (should raise TypeError)") - except TypeError: - print("βœ… Invalid operation: PASSED") - tests_passed += 1 - except Exception as e: - print(f"❌ Invalid operation: FAILED (wrong exception: {e})") - - return tests_passed, total_tests - -def print_summary(basic_passed, basic_total, arithmetic_passed, arithmetic_total, - utility_passed, utility_total, error_passed, error_total): - """Print a summary of all tests.""" - print("\n" + "=" * 50) - print("πŸ“Š VERIFICATION SUMMARY") - print("=" * 50) - - total_passed = basic_passed + arithmetic_passed + utility_passed + error_passed - total_tests = basic_total + arithmetic_total + utility_total + error_total - - print(f"Basic Functionality: {basic_passed}/{basic_total} tests passed") - print(f"Arithmetic Operations: {arithmetic_passed}/{arithmetic_total} tests passed") - print(f"Utility Methods: {utility_passed}/{utility_total} tests passed") - print(f"Error Handling: {error_passed}/{error_total} tests passed") - print() - print(f"Overall: {total_passed}/{total_tests} tests passed") - - if total_passed == total_tests: - print("\nπŸŽ‰ CONGRATULATIONS! All tests passed!") - print("βœ… Your Tensor implementation is complete and working correctly!") - print("\nπŸ“‹ Next steps:") - print(" 1. Run: tito test --module tensor") - print(" 2. Submit: tito submit --module tensor") - print(" 3. Move to next module: cd ../mlp/") - else: - print(f"\n⚠️ {total_tests - total_passed} tests failed.") - print("πŸ’‘ Review the failed tests above and fix your implementation.") - print("\nπŸ“š Need help? Check the tutorial notebooks in tutorials/") - -def main(): - """Main verification function.""" - print_header() - - # Check if Tensor class exists - tensor_available, Tensor = check_tensor_import() - if not tensor_available: - print("\nπŸ’‘ To get started:") - print(" 1. Open: modules/tensor/notebook/tensor_dev.ipynb") - print(" 2. Implement the Tensor class step by step") - print(" 3. Run this verification again") - return False - - # Run all verification checks - basic_passed, basic_total = check_basic_functionality(Tensor) - arithmetic_passed, arithmetic_total = check_arithmetic_operations(Tensor) - utility_passed, utility_total = check_utility_methods(Tensor) - error_passed, error_total = check_error_handling(Tensor) - - # Print summary - print_summary(basic_passed, basic_total, arithmetic_passed, arithmetic_total, - utility_passed, utility_total, error_passed, error_total) - - return True - -if __name__ == "__main__": - success = main() - sys.exit(0 if success else 1) \ No newline at end of file diff --git a/modules/tensor/notebook/tensor_dev.ipynb b/modules/tensor/notebook/tensor_dev.ipynb deleted file mode 100644 index 0519ecba..00000000 --- a/modules/tensor/notebook/tensor_dev.ipynb +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/modules/tensor/test_tensor.py b/modules/tensor/test_tensor.py deleted file mode 100644 index 011e32aa..00000000 --- a/modules/tensor/test_tensor.py +++ /dev/null @@ -1,344 +0,0 @@ -#!/usr/bin/env python3 -""" -Automated tests for the Tensor module. - -This file contains comprehensive tests to verify that students have -correctly implemented the Tensor class with all required functionality. -""" - -import sys -import os -import numpy as np -import pytest - -# Add the parent directory to the path so we can import from tinytorch -sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..')) - -try: - from tinytorch.core.tensor import Tensor - TENSOR_AVAILABLE = True -except ImportError: - TENSOR_AVAILABLE = False - print("⚠️ Tensor class not found. Make sure to implement it first!") - -class TestTensorBasics: - """Test basic Tensor functionality.""" - - def test_tensor_creation_scalar(self): - """Test creating a tensor from a scalar.""" - if not TENSOR_AVAILABLE: - pytest.skip("Tensor class not implemented") - - # Test scalar creation - t = Tensor(5) - assert t.shape == (1,) - assert t.size == 1 - assert t.dtype == np.int64 or t.dtype == np.int32 - assert t.data[0] == 5 - - def test_tensor_creation_list(self): - """Test creating a tensor from a list.""" - if not TENSOR_AVAILABLE: - pytest.skip("Tensor class not implemented") - - # Test list creation - data = [1, 2, 3, 4] - t = Tensor(data) - assert t.shape == (4,) - assert t.size == 4 - assert np.array_equal(t.data, np.array(data)) - - def test_tensor_creation_matrix(self): - """Test creating a tensor from a 2D list.""" - if not TENSOR_AVAILABLE: - pytest.skip("Tensor class not implemented") - - # Test matrix creation - data = [[1, 2], [3, 4]] - t = Tensor(data) - assert t.shape == (2, 2) - assert t.size == 4 - assert np.array_equal(t.data, np.array(data)) - - def test_tensor_creation_numpy(self): - """Test creating a tensor from a numpy array.""" - if not TENSOR_AVAILABLE: - pytest.skip("Tensor class not implemented") - - # Test numpy array creation - data = np.array([[1, 2], [3, 4]]) - t = Tensor(data) - assert t.shape == (2, 2) - assert t.size == 4 - assert np.array_equal(t.data, data) - - def test_tensor_dtype(self): - """Test tensor data type handling.""" - if not TENSOR_AVAILABLE: - pytest.skip("Tensor class not implemented") - - # Test float dtype - t = Tensor([1, 2, 3], dtype=np.float32) - assert t.dtype == np.float32 - - # Test int dtype - t = Tensor([1.5, 2.5], dtype=np.int32) - assert t.dtype == np.int32 - -class TestTensorOperations: - """Test tensor arithmetic operations.""" - - def test_addition_tensor_tensor(self): - """Test adding two tensors.""" - if not TENSOR_AVAILABLE: - pytest.skip("Tensor class not implemented") - - a = Tensor([1, 2, 3]) - b = Tensor([4, 5, 6]) - c = a + b - - expected = np.array([5, 7, 9]) - assert np.array_equal(c.data, expected) - - def test_addition_tensor_scalar(self): - """Test adding a tensor and a scalar.""" - if not TENSOR_AVAILABLE: - pytest.skip("Tensor class not implemented") - - a = Tensor([1, 2, 3]) - c = a + 5 - - expected = np.array([6, 7, 8]) - assert np.array_equal(c.data, expected) - - def test_subtraction_tensor_tensor(self): - """Test subtracting two tensors.""" - if not TENSOR_AVAILABLE: - pytest.skip("Tensor class not implemented") - - a = Tensor([5, 6, 7]) - b = Tensor([1, 2, 3]) - c = a - b - - expected = np.array([4, 4, 4]) - assert np.array_equal(c.data, expected) - - def test_subtraction_tensor_scalar(self): - """Test subtracting a scalar from a tensor.""" - if not TENSOR_AVAILABLE: - pytest.skip("Tensor class not implemented") - - a = Tensor([5, 6, 7]) - c = a - 2 - - expected = np.array([3, 4, 5]) - assert np.array_equal(c.data, expected) - - def test_multiplication_tensor_tensor(self): - """Test multiplying two tensors.""" - if not TENSOR_AVAILABLE: - pytest.skip("Tensor class not implemented") - - a = Tensor([1, 2, 3]) - b = Tensor([4, 5, 6]) - c = a * b - - expected = np.array([4, 10, 18]) - assert np.array_equal(c.data, expected) - - def test_multiplication_tensor_scalar(self): - """Test multiplying a tensor by a scalar.""" - if not TENSOR_AVAILABLE: - pytest.skip("Tensor class not implemented") - - a = Tensor([1, 2, 3]) - c = a * 3 - - expected = np.array([3, 6, 9]) - assert np.array_equal(c.data, expected) - - def test_division_tensor_tensor(self): - """Test dividing two tensors.""" - if not TENSOR_AVAILABLE: - pytest.skip("Tensor class not implemented") - - a = Tensor([10, 20, 30]) - b = Tensor([2, 4, 5]) - c = a / b - - expected = np.array([5, 5, 6]) - assert np.array_equal(c.data, expected) - - def test_division_tensor_scalar(self): - """Test dividing a tensor by a scalar.""" - if not TENSOR_AVAILABLE: - pytest.skip("Tensor class not implemented") - - a = Tensor([10, 20, 30]) - c = a / 2 - - expected = np.array([5, 10, 15]) - assert np.array_equal(c.data, expected) - - def test_equality(self): - """Test tensor equality.""" - if not TENSOR_AVAILABLE: - pytest.skip("Tensor class not implemented") - - a = Tensor([1, 2, 3]) - b = Tensor([1, 2, 3]) - c = Tensor([1, 2, 4]) - - assert a == b - assert a != c - -class TestTensorUtilities: - """Test tensor utility methods.""" - - def test_reshape(self): - """Test tensor reshaping.""" - if not TENSOR_AVAILABLE: - pytest.skip("Tensor class not implemented") - - t = Tensor([[1, 2, 3], [4, 5, 6]]) - reshaped = t.reshape(3, 2) - - expected = np.array([[1, 2], [3, 4], [5, 6]]) - assert np.array_equal(reshaped.data, expected) - assert reshaped.shape == (3, 2) - - def test_transpose(self): - """Test tensor transposition.""" - if not TENSOR_AVAILABLE: - pytest.skip("Tensor class not implemented") - - t = Tensor([[1, 2, 3], [4, 5, 6]]) - transposed = t.transpose() - - expected = np.array([[1, 4], [2, 5], [3, 6]]) - assert np.array_equal(transposed.data, expected) - assert transposed.shape == (3, 2) - - def test_sum_no_axis(self): - """Test tensor sum without axis.""" - if not TENSOR_AVAILABLE: - pytest.skip("Tensor class not implemented") - - t = Tensor([[1, 2, 3], [4, 5, 6]]) - result = t.sum() - - expected = np.array(21) # 1+2+3+4+5+6 - assert np.array_equal(result.data, expected) - - def test_sum_with_axis(self): - """Test tensor sum with axis.""" - if not TENSOR_AVAILABLE: - pytest.skip("Tensor class not implemented") - - t = Tensor([[1, 2, 3], [4, 5, 6]]) - result = t.sum(axis=1) - - expected = np.array([6, 15]) # [1+2+3, 4+5+6] - assert np.array_equal(result.data, expected) - - def test_mean_no_axis(self): - """Test tensor mean without axis.""" - if not TENSOR_AVAILABLE: - pytest.skip("Tensor class not implemented") - - t = Tensor([[1, 2, 3], [4, 5, 6]]) - result = t.mean() - - expected = np.array(3.5) # (1+2+3+4+5+6)/6 - assert np.allclose(result.data, expected) - - def test_mean_with_axis(self): - """Test tensor mean with axis.""" - if not TENSOR_AVAILABLE: - pytest.skip("Tensor class not implemented") - - t = Tensor([[1, 2, 3], [4, 5, 6]]) - result = t.mean(axis=0) - - expected = np.array([2.5, 3.5, 4.5]) # [(1+4)/2, (2+5)/2, (3+6)/2] - assert np.allclose(result.data, expected) - - def test_max_no_axis(self): - """Test tensor max without axis.""" - if not TENSOR_AVAILABLE: - pytest.skip("Tensor class not implemented") - - t = Tensor([[1, 2, 3], [4, 5, 6]]) - result = t.max() - - expected = np.array(6) - assert np.array_equal(result.data, expected) - - def test_min_no_axis(self): - """Test tensor min without axis.""" - if not TENSOR_AVAILABLE: - pytest.skip("Tensor class not implemented") - - t = Tensor([[1, 2, 3], [4, 5, 6]]) - result = t.min() - - expected = np.array(1) - assert np.array_equal(result.data, expected) - - def test_flatten(self): - """Test tensor flattening.""" - if not TENSOR_AVAILABLE: - pytest.skip("Tensor class not implemented") - - t = Tensor([[1, 2, 3], [4, 5, 6]]) - flattened = t.flatten() - - expected = np.array([1, 2, 3, 4, 5, 6]) - assert np.array_equal(flattened.data, expected) - assert flattened.shape == (6,) - -class TestTensorErrors: - """Test tensor error handling.""" - - def test_invalid_data_type(self): - """Test error handling for invalid data types.""" - if not TENSOR_AVAILABLE: - pytest.skip("Tensor class not implemented") - - with pytest.raises(ValueError): - Tensor("invalid") - - def test_invalid_operation(self): - """Test error handling for invalid operations.""" - if not TENSOR_AVAILABLE: - pytest.skip("Tensor class not implemented") - - a = Tensor([1, 2, 3]) - - with pytest.raises(TypeError): - a + "invalid" - -def run_tests(): - """Run all tensor tests and return results.""" - print("πŸ§ͺ Running Tensor Tests...") - print("=" * 50) - - if not TENSOR_AVAILABLE: - print("❌ Tensor class not found!") - print("πŸ’‘ Make sure to implement the Tensor class in tinytorch/core/tensor.py") - return False - - # Run pytest - import pytest - result = pytest.main([__file__, "-v", "--tb=short"]) - - if result == 0: - print("\nβœ… All tensor tests passed!") - return True - else: - print("\n❌ Some tensor tests failed!") - return False - -if __name__ == "__main__": - success = run_tests() - sys.exit(0 if success else 1) \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..eeee1981 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,11 @@ +[build-system] +requires = ["setuptools>=64.0"] +build-backend = "setuptools.build_meta" + +[project] +name="tinytorch" +requires-python=">=3.8" +dynamic = [ "keywords", "description", "version", "dependencies", "optional-dependencies", "readme", "license", "authors", "classifiers", "entry-points", "scripts", "urls"] + +[tool.uv] +cache-keys = [{ file = "pyproject.toml" }, { file = "settings.ini" }, { file = "setup.py" }] diff --git a/settings.ini b/settings.ini new file mode 100644 index 00000000..9ce17b60 --- /dev/null +++ b/settings.ini @@ -0,0 +1,43 @@ +[DEFAULT] +# All sections below are required unless otherwise specified. +# See https://github.com/fastai/nbdev/blob/master/settings.ini for examples. + +### Python library ### +repo = TinyTorch +lib_name = tinytorch +version = 0.1.0 +min_python = 3.8 +license = apache2 +black_formatting = False + +### nbdev ### +doc_path = _docs +lib_path = tinytorch +nbs_path = notebooks +recursive = True +tst_flags = notest +put_version_in_init = True + +### Docs ### +branch = main +custom_sidebar = False +doc_host = https://tinytorch.github.io +doc_baseurl = /TinyTorch/ +git_url = https://github.com/tinytorch/TinyTorch/ +title = TinyTorch + +### PyPI ### +audience = Developers +author = TinyTorch Team +author_email = team@tinytorch.org +copyright = 2024 onwards, TinyTorch Team +description = Build ML Systems from Scratch - A hands-on systems course +keywords = machine learning, deep learning, systems, education +language = English +status = 3 +user = tinytorch + +### Optional ### +requirements = numpy>=1.20.0 matplotlib>=3.3.0 rich>=10.0.0 jupyter>=1.0.0 pytest>=6.0.0 +dev_requirements = nbdev>=2.3.0 black>=22.0.0 +console_scripts = tito=tinytorch.cli:main \ No newline at end of file diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 00000000..81f1168e --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1,7 @@ +""" +Tests for TinyTorch. + +All tests target the exported Python code in the tinytorch package, +not the notebook code directly. This ensures we test the actual +package that students build. +""" \ No newline at end of file diff --git a/tests/test_setup.py b/tests/test_setup.py new file mode 100644 index 00000000..fd82b91c --- /dev/null +++ b/tests/test_setup.py @@ -0,0 +1,77 @@ +""" +Tests for Module 01: Setup & Environment + +These tests validate the exported functions from notebooks/01_setup.ipynb +""" + +import pytest +from tinytorch.core.utils import hello_tinytorch, format_tensor_shape, validate_tensor_shapes + + +def test_hello_tinytorch_exists(): + """Test that the hello_tinytorch function exists and can be imported.""" + assert callable(hello_tinytorch), "hello_tinytorch should be a callable function" + + +def test_hello_tinytorch_returns_string(): + """Test that hello_tinytorch returns a string.""" + result = hello_tinytorch() + assert isinstance(result, str), f"hello_tinytorch() should return a string, got {type(result)}" + + +def test_hello_tinytorch_not_empty(): + """Test that hello_tinytorch returns a non-empty string.""" + result = hello_tinytorch() + assert len(result.strip()) > 0, "hello_tinytorch() should return a non-empty string" + + +def test_hello_tinytorch_contains_welcome(): + """Test that the greeting contains welcoming content.""" + result = hello_tinytorch().lower() + welcome_words = ['welcome', 'hello', 'tinytorch', 'ready'] + + assert any(word in result for word in welcome_words), \ + f"hello_tinytorch() should contain welcoming content. Got: {hello_tinytorch()}" + + +def test_hello_tinytorch_has_fire_emoji(): + """Test that the greeting contains the fire emoji (matching brand).""" + result = hello_tinytorch() + assert 'πŸ”₯' in result, \ + f"hello_tinytorch() should contain the πŸ”₯ emoji to match TinyTorch branding. Got: {result}" + + +def test_format_tensor_shape(): + """Test the format_tensor_shape utility function.""" + # Test various shapes + assert format_tensor_shape((3, 4, 5)) == "(3, 4, 5)" + assert format_tensor_shape((1,)) == "(1)" + assert format_tensor_shape(()) == "()" + assert format_tensor_shape((10, 20)) == "(10, 20)" + + +def test_validate_tensor_shapes(): + """Test the validate_tensor_shapes utility function.""" + # Compatible shapes + assert validate_tensor_shapes((3, 4), (3, 4)) == True + assert validate_tensor_shapes((1, 2, 3), (1, 2, 3), (1, 2, 3)) == True + + # Incompatible shapes + assert validate_tensor_shapes((3, 4), (2, 4)) == False + assert validate_tensor_shapes((1, 2), (1, 3)) == False + + # Edge cases + assert validate_tensor_shapes((3, 4)) == True # Single shape + assert validate_tensor_shapes() == True # No shapes + + +def test_function_docstrings(): + """Test that exported functions have proper docstrings.""" + assert hello_tinytorch.__doc__ is not None, "hello_tinytorch should have a docstring" + assert format_tensor_shape.__doc__ is not None, "format_tensor_shape should have a docstring" + assert validate_tensor_shapes.__doc__ is not None, "validate_tensor_shapes should have a docstring" + + # Check that docstrings are meaningful (not just empty) + assert len(hello_tinytorch.__doc__.strip()) > 10, "Docstring should be meaningful" + assert len(format_tensor_shape.__doc__.strip()) > 10, "Docstring should be meaningful" + assert len(validate_tensor_shapes.__doc__.strip()) > 10, "Docstring should be meaningful" \ No newline at end of file diff --git a/tests/test_tensor.py b/tests/test_tensor.py new file mode 100644 index 00000000..d222c05b --- /dev/null +++ b/tests/test_tensor.py @@ -0,0 +1,174 @@ +""" +Tests for the Tensor module. + +This file contains comprehensive tests for the Tensor class implementation. +Run with: python bin/tito.py test --module tensor +""" + +import pytest +import numpy as np +from tinytorch.core.tensor import Tensor + + +class TestTensorCreation: + """Test tensor creation and basic properties.""" + + def test_scalar_tensor(self): + """Test creating scalar tensors.""" + t = Tensor(5.0) + assert t.shape == () + assert t.size == 1 + assert float(t.data) == 5.0 + + def test_1d_tensor(self): + """Test creating 1D tensors.""" + t = Tensor([1, 2, 3]) + assert t.shape == (3,) + assert t.size == 3 + np.testing.assert_array_equal(t.data, [1, 2, 3]) + + def test_2d_tensor(self): + """Test creating 2D tensors.""" + t = Tensor([[1, 2], [3, 4]]) + assert t.shape == (2, 2) + assert t.size == 4 + np.testing.assert_array_equal(t.data, [[1, 2], [3, 4]]) + + def test_tensor_from_numpy(self): + """Test creating tensors from NumPy arrays.""" + arr = np.array([1, 2, 3]) + t = Tensor(arr) + assert t.shape == (3,) + np.testing.assert_array_equal(t.data, arr) + + +class TestTensorProperties: + """Test tensor properties.""" + + def test_shape_property(self): + """Test the shape property.""" + t1 = Tensor([1, 2, 3]) + assert t1.shape == (3,) + + t2 = Tensor([[1, 2], [3, 4]]) + assert t2.shape == (2, 2) + + def test_size_property(self): + """Test the size property.""" + t1 = Tensor([1, 2, 3]) + assert t1.size == 3 + + t2 = Tensor([[1, 2], [3, 4]]) + assert t2.size == 4 + + def test_dtype_property(self): + """Test the dtype property.""" + t_int = Tensor([1, 2, 3]) + t_float = Tensor([1.0, 2.0, 3.0]) + + # NumPy automatically infers types + assert np.issubdtype(t_int.dtype, np.integer) + assert np.issubdtype(t_float.dtype, np.floating) + + +class TestTensorArithmetic: + """Test tensor arithmetic operations.""" + + def test_tensor_addition(self): + """Test tensor + tensor addition.""" + a = Tensor([1, 2, 3]) + b = Tensor([4, 5, 6]) + result = a + b + + assert isinstance(result, Tensor) + np.testing.assert_array_equal(result.data, [5, 7, 9]) + + def test_scalar_addition(self): + """Test tensor + scalar addition.""" + a = Tensor([1, 2, 3]) + result = a + 10 + + assert isinstance(result, Tensor) + np.testing.assert_array_equal(result.data, [11, 12, 13]) + + def test_tensor_multiplication(self): + """Test tensor * tensor multiplication.""" + a = Tensor([1, 2, 3]) + b = Tensor([4, 5, 6]) + result = a * b + + assert isinstance(result, Tensor) + np.testing.assert_array_equal(result.data, [4, 10, 18]) + + def test_scalar_multiplication(self): + """Test tensor * scalar multiplication.""" + a = Tensor([1, 2, 3]) + result = a * 2 + + assert isinstance(result, Tensor) + np.testing.assert_array_equal(result.data, [2, 4, 6]) + + def test_2d_operations(self): + """Test operations on 2D tensors.""" + a = Tensor([[1, 2], [3, 4]]) + b = Tensor([[5, 6], [7, 8]]) + result = a + b + + assert isinstance(result, Tensor) + expected = [[6, 8], [10, 12]] + np.testing.assert_array_equal(result.data, expected) + + +class TestTensorUtils: + """Test tensor utility methods (if implemented).""" + + def test_sum_exists(self): + """Test that sum method exists (may not be implemented yet).""" + t = Tensor([1, 2, 3]) + if hasattr(t, 'sum'): + result = t.sum() + assert result == 6 or (hasattr(result, 'data') and result.data == 6) + + def test_mean_exists(self): + """Test that mean method exists (may not be implemented yet).""" + t = Tensor([1, 2, 3]) + if hasattr(t, 'mean'): + result = t.mean() + expected = 2.0 + assert abs(result - expected) < 1e-6 or (hasattr(result, 'data') and abs(result.data - expected) < 1e-6) + + def test_reshape_exists(self): + """Test that reshape method exists (may not be implemented yet).""" + t = Tensor([[1, 2], [3, 4]]) + if hasattr(t, 'reshape'): + result = t.reshape(1, 4) + assert result.shape == (1, 4) + + def test_transpose_exists(self): + """Test that transpose method exists (may not be implemented yet).""" + t = Tensor([[1, 2], [3, 4]]) + if hasattr(t, 'transpose'): + result = t.transpose() + expected = [[1, 3], [2, 4]] + np.testing.assert_array_equal(result.data, expected) + + +class TestTensorIntegration: + """Test tensor integration with the package.""" + + def test_tensor_import(self): + """Test that Tensor can be imported from the correct location.""" + from tinytorch.core.tensor import Tensor + assert Tensor is not None + + def test_tensor_representation(self): + """Test tensor string representation.""" + t = Tensor([1, 2, 3]) + repr_str = repr(t) + assert "Tensor" in repr_str + assert "shape" in repr_str or "Shape" in repr_str + + +if __name__ == "__main__": + # Run tests if this file is executed directly + pytest.main([__file__, "-v"]) \ No newline at end of file diff --git a/tinytorch/__init__.py b/tinytorch/__init__.py index dfb3c550..bc63645a 100644 --- a/tinytorch/__init__.py +++ b/tinytorch/__init__.py @@ -1,14 +1,14 @@ """ -TinyπŸ”₯Torch: A complete ML system built from scratch. +TinyTorch: Build ML Systems from Scratch -TinyTorch is a pedagogical project for learning how machine learning -systems work by implementing every component from first principles. +A comprehensive machine learning systems course where you implement +every component from tensors to production monitoring. + +This package is auto-generated from Jupyter notebooks using nbdev. +Students work in notebooks/, and all Python code is exported automatically. """ __version__ = "0.1.0" -__author__ = "TinyTorch Students" -# Core components will be imported here as they're implemented -# from .core.tensor import Tensor -# from .core.autograd import Variable -# from .core.modules import Module \ No newline at end of file +# Main exports will be added automatically by nbdev +# Students should not edit this file manually \ No newline at end of file diff --git a/tinytorch/_modidx.py b/tinytorch/_modidx.py new file mode 100644 index 00000000..b8636ed0 --- /dev/null +++ b/tinytorch/_modidx.py @@ -0,0 +1,12 @@ +# Autogenerated by nbdev + +d = { 'settings': { 'branch': 'main', + 'doc_baseurl': '/TinyTorch/', + 'doc_host': 'https://tinytorch.github.io', + 'git_url': 'https://github.com/tinytorch/TinyTorch/', + 'lib_path': 'tinytorch'}, + 'syms': { 'tinytorch.core.utils': { 'tinytorch.core.utils.format_tensor_shape': ( 'setup.html#format_tensor_shape', + 'tinytorch/core/utils.py'), + 'tinytorch.core.utils.hello_tinytorch': ('setup.html#hello_tinytorch', 'tinytorch/core/utils.py'), + 'tinytorch.core.utils.validate_tensor_shapes': ( 'setup.html#validate_tensor_shapes', + 'tinytorch/core/utils.py')}}} diff --git a/tinytorch/compression/__init__.py b/tinytorch/compression/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tinytorch/core/__init__.py b/tinytorch/core/__init__.py index cf9f179c..97a1613d 100644 --- a/tinytorch/core/__init__.py +++ b/tinytorch/core/__init__.py @@ -1,15 +1,12 @@ """ -TinyTorch Core Components +Core TinyTorch components. -This package contains the fundamental building blocks of the TinyTorch ML system: -- Tensor operations and storage -- Automatic differentiation engine -- Neural network modules and layers -- Training and optimization algorithms -""" +This module contains the fundamental building blocks: +- utils: Utility functions +- tensor: Core tensor implementation +- autograd: Automatic differentiation +- modules: Neural network layers +- optimizers: Training optimizers -# Core imports will be added as components are implemented -# from .tensor import Tensor -# from .autograd import backward -# from .modules import Linear, Conv2d -# from .optimizer import SGD, Adam \ No newline at end of file +All code is auto-generated from notebooks. Do not edit manually. +""" \ No newline at end of file diff --git a/tinytorch/core/autograd.py b/tinytorch/core/autograd.py deleted file mode 100644 index 6827c44d..00000000 --- a/tinytorch/core/autograd.py +++ /dev/null @@ -1,190 +0,0 @@ -""" -Automatic differentiation engine. - -This module implements the computational graph and automatic differentiation -system that enables gradient computation for neural network training. - -Key concepts: -- Computational graph representation -- Forward and backward pass orchestration -- Gradient accumulation and propagation -- Function objects for operations -""" - -from typing import List, Optional, Callable, Any -from .tensor import Tensor - - -class Function: - """ - Base class for all differentiable functions. - - Functions represent operations in the computational graph and define - how to compute gradients during the backward pass. - """ - - @staticmethod - def forward(ctx: 'Context', *args) -> Tensor: - """ - Forward pass of the function. - - Args: - ctx: Context object for saving information needed in backward - *args: Input tensors - - Returns: - Output tensor - """ - raise NotImplementedError("Forward pass must be implemented") - - @staticmethod - def backward(ctx: 'Context', grad_output: Tensor) -> tuple: - """ - Backward pass of the function. - - Args: - ctx: Context object with saved information from forward - grad_output: Gradient flowing back from later operations - - Returns: - Tuple of gradients for each input tensor - """ - raise NotImplementedError("Backward pass must be implemented") - - -class Context: - """ - Context object for saving information between forward and backward passes. - - This allows functions to store intermediate values needed for gradient - computation without keeping them in the tensor objects themselves. - """ - - def __init__(self): - """Initialize empty context.""" - self.saved_tensors = [] - self.saved_variables = {} - - def save_for_backward(self, *tensors: Tensor) -> None: - """ - Save tensors for use in backward pass. - - Args: - *tensors: Tensors to save - """ - self.saved_tensors = list(tensors) - - @property - def saved_tensors(self) -> List[Tensor]: - """Return saved tensors.""" - return self._saved_tensors - - @saved_tensors.setter - def saved_tensors(self, tensors: List[Tensor]) -> None: - """Set saved tensors.""" - self._saved_tensors = tensors - - -class Node: - """ - Node in the computational graph. - - Each tensor with requires_grad=True has an associated node that - tracks how it was computed and enables gradient flow. - """ - - def __init__(self, tensor: Tensor, grad_fn: Optional[Function] = None): - """ - Initialize graph node. - - Args: - tensor: The tensor this node represents - grad_fn: Function that created this tensor - """ - self.tensor = tensor - self.grad_fn = grad_fn - self.next_functions = [] # Functions to call during backward - - def add_next_function(self, function: Function, input_idx: int) -> None: - """ - Add a function to call during backward pass. - - Args: - function: Function to call - input_idx: Index of this tensor in the function's inputs - """ - self.next_functions.append((function, input_idx)) - - -def grad( - outputs: List[Tensor], - inputs: List[Tensor], - grad_outputs: Optional[List[Tensor]] = None, - retain_graph: bool = False, - create_graph: bool = False -) -> List[Tensor]: - """ - Compute gradients of outputs with respect to inputs. - - Args: - outputs: Tensors to compute gradients of - inputs: Tensors to compute gradients with respect to - grad_outputs: Gradients to backpropagate (defaults to ones) - retain_graph: Whether to keep computational graph after backward - create_graph: Whether to create graph for higher-order derivatives - - Returns: - List of gradients for each input tensor - """ - # TODO: Implement gradient computation in Chapter 7 - raise NotImplementedError("Gradient computation will be implemented in Chapter 7") - - -# Common differentiable functions (to be implemented) - -class AddFunction(Function): - """Addition operation: output = input1 + input2""" - - @staticmethod - def forward(ctx: Context, input1: Tensor, input2: Tensor) -> Tensor: - """Forward pass for addition.""" - # TODO: Implement in Chapter 7 - raise NotImplementedError("Addition forward will be implemented in Chapter 7") - - @staticmethod - def backward(ctx: Context, grad_output: Tensor) -> tuple: - """Backward pass for addition.""" - # TODO: Implement in Chapter 7 - raise NotImplementedError("Addition backward will be implemented in Chapter 7") - - -class MulFunction(Function): - """Multiplication operation: output = input1 * input2""" - - @staticmethod - def forward(ctx: Context, input1: Tensor, input2: Tensor) -> Tensor: - """Forward pass for multiplication.""" - # TODO: Implement in Chapter 7 - raise NotImplementedError("Multiplication forward will be implemented in Chapter 7") - - @staticmethod - def backward(ctx: Context, grad_output: Tensor) -> tuple: - """Backward pass for multiplication.""" - # TODO: Implement in Chapter 7 - raise NotImplementedError("Multiplication backward will be implemented in Chapter 7") - - -class MatMulFunction(Function): - """Matrix multiplication operation: output = input1 @ input2""" - - @staticmethod - def forward(ctx: Context, input1: Tensor, input2: Tensor) -> Tensor: - """Forward pass for matrix multiplication.""" - # TODO: Implement in Chapter 7 - raise NotImplementedError("Matrix multiplication forward will be implemented in Chapter 7") - - @staticmethod - def backward(ctx: Context, grad_output: Tensor) -> tuple: - """Backward pass for matrix multiplication.""" - # TODO: Implement in Chapter 7 - raise NotImplementedError("Matrix multiplication backward will be implemented in Chapter 7") \ No newline at end of file diff --git a/tinytorch/core/dataloader.py b/tinytorch/core/dataloader.py deleted file mode 100644 index 0b5943fe..00000000 --- a/tinytorch/core/dataloader.py +++ /dev/null @@ -1,144 +0,0 @@ -""" -Data loading and preprocessing utilities. - -This module provides efficient data loading for training neural networks: -- Dataset base class and common datasets (MNIST, CIFAR-10) -- DataLoader for batching and shuffling -- Data transformations and augmentation -- Memory-efficient data pipeline -""" - -import numpy as np -from typing import Iterator, Optional, Tuple, List, Callable, Any -from .tensor import Tensor - - -class Dataset: - """ - Base class for all datasets. - - All datasets should inherit from this class and implement __len__ - and __getitem__ methods. - """ - - def __len__(self) -> int: - """Return the number of samples in the dataset.""" - raise NotImplementedError("Subclasses must implement __len__") - - def __getitem__(self, index: int) -> Tuple[Tensor, Tensor]: - """ - Get a single sample from the dataset. - - Args: - index: Index of the sample to retrieve - - Returns: - Tuple of (data, target) tensors - """ - raise NotImplementedError("Subclasses must implement __getitem__") - - -class DataLoader: - """ - Data loader for iterating over datasets in batches. - - Provides batching, shuffling, and parallel loading capabilities. - - Args: - dataset: Dataset to load from - batch_size: Number of samples per batch - shuffle: Whether to shuffle the data each epoch - num_workers: Number of worker processes (not implemented yet) - """ - - def __init__( - self, - dataset: Dataset, - batch_size: int = 1, - shuffle: bool = False, - num_workers: int = 0 - ): - """Initialize the data loader.""" - self.dataset = dataset - self.batch_size = batch_size - self.shuffle = shuffle - self.num_workers = num_workers - - # Generate indices - self.indices = list(range(len(dataset))) - - def __len__(self) -> int: - """Return the number of batches per epoch.""" - return (len(self.dataset) + self.batch_size - 1) // self.batch_size - - def __iter__(self) -> Iterator[Tuple[Tensor, Tensor]]: - """ - Iterate over batches. - - Yields: - Batches of (data, targets) as tensors - """ - # TODO: Implement batching in Chapter 6 - raise NotImplementedError("DataLoader iteration will be implemented in Chapter 6") - - -class Transform: - """Base class for data transformations.""" - - def __call__(self, data: np.ndarray) -> np.ndarray: - """ - Apply transformation to data. - - Args: - data: Input data array - - Returns: - Transformed data array - """ - raise NotImplementedError("Subclasses must implement __call__") - - -class ToTensor(Transform): - """Convert numpy array to Tensor.""" - - def __call__(self, data: np.ndarray) -> Tensor: - """Convert to tensor.""" - return Tensor(data) - - -class Normalize(Transform): - """Normalize data with given mean and standard deviation.""" - - def __init__(self, mean: float, std: float): - """ - Initialize normalization transform. - - Args: - mean: Mean for normalization - std: Standard deviation for normalization - """ - self.mean = mean - self.std = std - - def __call__(self, data: np.ndarray) -> np.ndarray: - """Apply normalization.""" - return (data - self.mean) / self.std - - -class Compose(Transform): - """Compose multiple transforms together.""" - - def __init__(self, transforms: List[Transform]): - """ - Initialize composed transform. - - Args: - transforms: List of transforms to apply in sequence - """ - self.transforms = transforms - - def __call__(self, data: np.ndarray) -> Any: - """Apply all transforms in sequence.""" - for transform in self.transforms: - data = transform(data) - return data \ No newline at end of file diff --git a/tinytorch/core/mlops.py b/tinytorch/core/mlops.py deleted file mode 100644 index 7a8aaa32..00000000 --- a/tinytorch/core/mlops.py +++ /dev/null @@ -1,295 +0,0 @@ -""" -MLOps and production monitoring capabilities. - -This module provides tools for deploying and monitoring ML models in production: -- Data drift detection and monitoring -- Model performance tracking -- Automatic retraining triggers -- A/B testing framework -- Model versioning and registry -- Production serving infrastructure -""" - -import numpy as np -from typing import Dict, List, Optional, Tuple, Callable, Any -from datetime import datetime -import json -from .tensor import Tensor -from .modules import Module - - -class DataDriftDetector: - """ - Detect distribution shifts in input data. - - Uses statistical tests to identify when new data differs significantly - from the training distribution, indicating potential model degradation. - """ - - def __init__(self, reference_data: np.ndarray, threshold: float = 0.05): - """ - Initialize drift detector with reference data. - - Args: - reference_data: Training/validation data as reference distribution - threshold: P-value threshold for drift detection - """ - self.reference_data = reference_data - self.threshold = threshold - self.reference_stats = self._compute_statistics(reference_data) - - def _compute_statistics(self, data: np.ndarray) -> Dict[str, float]: - """Compute statistical summaries of data.""" - # TODO: Implement statistical computations in Chapter 13 - raise NotImplementedError("Statistical computations will be implemented in Chapter 13") - - def detect_drift(self, new_data: np.ndarray) -> Dict[str, Any]: - """ - Test for data drift using statistical tests. - - Args: - new_data: New batch of data to test - - Returns: - Dictionary with drift detection results - """ - # TODO: Implement drift detection in Chapter 13 - raise NotImplementedError("Drift detection will be implemented in Chapter 13") - - -class ModelMonitor: - """ - Monitor model performance in production. - - Tracks key metrics and alerts when performance degrades below thresholds. - """ - - def __init__(self, model: Module, baseline_metrics: Dict[str, float]): - """ - Initialize model monitor. - - Args: - model: Model to monitor - baseline_metrics: Expected performance metrics from validation - """ - self.model = model - self.baseline_metrics = baseline_metrics - self.performance_history = [] - self.alerts = [] - - def log_prediction( - self, - inputs: Tensor, - predictions: Tensor, - ground_truth: Optional[Tensor] = None, - latency: Optional[float] = None - ) -> None: - """ - Log a single prediction for monitoring. - - Args: - inputs: Model inputs - predictions: Model predictions - ground_truth: True labels (if available) - latency: Prediction latency in seconds - """ - # TODO: Implement prediction logging in Chapter 13 - raise NotImplementedError("Prediction logging will be implemented in Chapter 13") - - def check_performance(self) -> Dict[str, Any]: - """ - Check if model performance is degrading. - - Returns: - Performance summary and any alerts - """ - # TODO: Implement performance checking in Chapter 13 - raise NotImplementedError("Performance checking will be implemented in Chapter 13") - - -class ModelRegistry: - """ - Registry for managing model versions and metadata. - - Provides version control, metadata tracking, and deployment coordination - for ML models in production environments. - """ - - def __init__(self, registry_path: str): - """ - Initialize model registry. - - Args: - registry_path: Directory to store model artifacts and metadata - """ - self.registry_path = registry_path - self.models = {} - self.active_model = None - - def register_model( - self, - model: Module, - name: str, - version: str, - metadata: Dict[str, Any] - ) -> None: - """ - Register a new model version. - - Args: - model: Model to register - name: Model name - version: Version identifier - metadata: Model metadata (metrics, training config, etc.) - """ - # TODO: Implement model registration in Chapter 13 - raise NotImplementedError("Model registration will be implemented in Chapter 13") - - def deploy_model(self, name: str, version: str) -> None: - """ - Deploy a specific model version to production. - - Args: - name: Model name - version: Version to deploy - """ - # TODO: Implement model deployment in Chapter 13 - raise NotImplementedError("Model deployment will be implemented in Chapter 13") - - def rollback_model(self, name: str, target_version: str) -> None: - """ - Rollback to a previous model version. - - Args: - name: Model name - target_version: Version to rollback to - """ - # TODO: Implement model rollback in Chapter 13 - raise NotImplementedError("Model rollback will be implemented in Chapter 13") - - -class ABTestFramework: - """ - A/B testing framework for comparing model versions. - - Safely tests new model versions against production baselines with - statistical significance testing and traffic splitting. - """ - - def __init__(self, control_model: Module, treatment_model: Module): - """ - Initialize A/B test. - - Args: - control_model: Current production model (baseline) - treatment_model: New model to test - """ - self.control_model = control_model - self.treatment_model = treatment_model - self.test_results = [] - self.traffic_split = 0.5 # 50/50 split by default - - def assign_traffic(self, user_id: str) -> str: - """ - Assign user to control or treatment group. - - Args: - user_id: Unique identifier for user - - Returns: - 'control' or 'treatment' - """ - # TODO: Implement traffic assignment in Chapter 13 - raise NotImplementedError("Traffic assignment will be implemented in Chapter 13") - - def log_result( - self, - user_id: str, - group: str, - outcome: float - ) -> None: - """ - Log A/B test result. - - Args: - user_id: User identifier - group: 'control' or 'treatment' - outcome: Metric to optimize (e.g., accuracy, conversion rate) - """ - # TODO: Implement result logging in Chapter 13 - raise NotImplementedError("Result logging will be implemented in Chapter 13") - - def analyze_results(self) -> Dict[str, Any]: - """ - Analyze A/B test results for statistical significance. - - Returns: - Statistical analysis of test results - """ - # TODO: Implement statistical analysis in Chapter 13 - raise NotImplementedError("Statistical analysis will be implemented in Chapter 13") - - -class ProductionServer: - """ - Production model serving infrastructure. - - Provides REST API endpoints for model inference with monitoring, - logging, and error handling capabilities. - """ - - def __init__(self, model: Module, monitor: ModelMonitor): - """ - Initialize production server. - - Args: - model: Model to serve - monitor: Monitor for tracking performance - """ - self.model = model - self.monitor = monitor - self.request_count = 0 - self.error_count = 0 - - def predict(self, inputs: Dict[str, Any]) -> Dict[str, Any]: - """ - Handle prediction request. - - Args: - inputs: Request inputs as dictionary - - Returns: - Prediction response with metadata - """ - # TODO: Implement prediction serving in Chapter 13 - raise NotImplementedError("Prediction serving will be implemented in Chapter 13") - - def health_check(self) -> Dict[str, Any]: - """ - Health check endpoint for monitoring. - - Returns: - Server health status and metrics - """ - # TODO: Implement health check in Chapter 13 - raise NotImplementedError("Health check will be implemented in Chapter 13") - - -def trigger_retraining( - performance_threshold: float, - current_performance: float, - drift_detected: bool = False -) -> bool: - """ - Decide whether to trigger automatic model retraining. - - Args: - performance_threshold: Minimum acceptable performance - current_performance: Current model performance - drift_detected: Whether data drift was detected - - Returns: - True if retraining should be triggered - """ - # TODO: Implement retraining logic in Chapter 13 - raise NotImplementedError("Retraining logic will be implemented in Chapter 13") \ No newline at end of file diff --git a/tinytorch/core/modules.py b/tinytorch/core/modules.py deleted file mode 100644 index 744c5d15..00000000 --- a/tinytorch/core/modules.py +++ /dev/null @@ -1,322 +0,0 @@ -""" -Neural network modules and layers. - -This module contains the building blocks for constructing neural networks: -- Base Module class for all layers -- Linear (fully connected) layers -- Convolutional layers (Conv2d) -- Pooling layers (MaxPool2d) -- Activation functions -- Model composition utilities -""" - -import numpy as np -from typing import Optional, Tuple, Union, List -from .tensor import Tensor - - -class Module: - """ - Base class for all neural network modules. - - All layers and models should inherit from this class. It provides - the basic infrastructure for parameter management, forward/backward - passes, and training/evaluation modes. - """ - - def __init__(self): - """Initialize the module.""" - self.training = True - self._parameters = {} - self._modules = {} - - def forward(self, *args, **kwargs) -> Tensor: - """ - Forward pass of the module. - - This method should be overridden by all subclasses to define - the computation performed at every call. - - Returns: - Output tensor - """ - raise NotImplementedError("Subclasses must implement forward()") - - def __call__(self, *args, **kwargs) -> Tensor: - """Make the module callable.""" - return self.forward(*args, **kwargs) - - def parameters(self) -> List[Tensor]: - """ - Return all parameters of the module. - - Returns: - List of all parameter tensors - """ - params = [] - for param in self._parameters.values(): - if isinstance(param, Tensor): - params.append(param) - - # Recursively get parameters from submodules - for module in self._modules.values(): - if isinstance(module, Module): - params.extend(module.parameters()) - - return params - - def train(self, mode: bool = True) -> 'Module': - """Set the module in training mode.""" - self.training = mode - for module in self._modules.values(): - if isinstance(module, Module): - module.train(mode) - return self - - def eval(self) -> 'Module': - """Set the module in evaluation mode.""" - return self.train(False) - - -class Linear(Module): - """ - Linear (fully connected) layer. - - Applies a linear transformation: y = xW^T + b - - Args: - in_features: Size of input features - out_features: Size of output features - bias: Whether to include bias term - """ - - def __init__(self, in_features: int, out_features: int, bias: bool = True): - """Initialize the linear layer.""" - super().__init__() - self.in_features = in_features - self.out_features = out_features - self.bias_enabled = bias - - # Initialize parameters - # Xavier/Glorot initialization - std = np.sqrt(2.0 / (in_features + out_features)) - self.weight = Tensor( - np.random.normal(0, std, (out_features, in_features)), - requires_grad=True - ) - self._parameters['weight'] = self.weight - - if bias: - self.bias = Tensor(np.zeros(out_features), requires_grad=True) - self._parameters['bias'] = self.bias - else: - self.bias = None - - def forward(self, x: Tensor) -> Tensor: - """ - Forward pass of linear layer. - - Args: - x: Input tensor of shape (batch_size, in_features) - - Returns: - Output tensor of shape (batch_size, out_features) - """ - # TODO: Implement matrix multiplication in Chapter 3 - # y = x @ W^T + b - raise NotImplementedError("Linear forward pass will be implemented in Chapter 3") - - -class Conv2d(Module): - """ - 2D Convolutional layer. - - Applies 2D convolution over input tensor. - - Args: - in_channels: Number of input channels - out_channels: Number of output channels - kernel_size: Size of convolution kernel - stride: Stride of convolution - padding: Padding added to input - bias: Whether to include bias term - """ - - def __init__( - self, - in_channels: int, - out_channels: int, - kernel_size: Union[int, Tuple[int, int]], - stride: Union[int, Tuple[int, int]] = 1, - padding: Union[int, Tuple[int, int]] = 0, - bias: bool = True - ): - """Initialize the convolutional layer.""" - super().__init__() - self.in_channels = in_channels - self.out_channels = out_channels - - # Handle kernel size - if isinstance(kernel_size, int): - self.kernel_size = (kernel_size, kernel_size) - else: - self.kernel_size = kernel_size - - # Handle stride - if isinstance(stride, int): - self.stride = (stride, stride) - else: - self.stride = stride - - # Handle padding - if isinstance(padding, int): - self.padding = (padding, padding) - else: - self.padding = padding - - self.bias_enabled = bias - - # Initialize parameters - # He initialization for ReLU networks - fan_in = in_channels * self.kernel_size[0] * self.kernel_size[1] - std = np.sqrt(2.0 / fan_in) - - self.weight = Tensor( - np.random.normal(0, std, (out_channels, in_channels, *self.kernel_size)), - requires_grad=True - ) - self._parameters['weight'] = self.weight - - if bias: - self.bias = Tensor(np.zeros(out_channels), requires_grad=True) - self._parameters['bias'] = self.bias - else: - self.bias = None - - def forward(self, x: Tensor) -> Tensor: - """ - Forward pass of convolutional layer. - - Args: - x: Input tensor of shape (batch_size, in_channels, height, width) - - Returns: - Output tensor after convolution - """ - # TODO: Implement convolution in Chapter 4 - raise NotImplementedError("Conv2d forward pass will be implemented in Chapter 4") - - -class MaxPool2d(Module): - """ - 2D Max pooling layer. - - Applies 2D max pooling over input tensor. - - Args: - kernel_size: Size of pooling kernel - stride: Stride of pooling (defaults to kernel_size) - padding: Padding added to input - """ - - def __init__( - self, - kernel_size: Union[int, Tuple[int, int]], - stride: Optional[Union[int, Tuple[int, int]]] = None, - padding: Union[int, Tuple[int, int]] = 0 - ): - """Initialize the max pooling layer.""" - super().__init__() - - # Handle kernel size - if isinstance(kernel_size, int): - self.kernel_size = (kernel_size, kernel_size) - else: - self.kernel_size = kernel_size - - # Handle stride (default to kernel_size) - if stride is None: - self.stride = self.kernel_size - elif isinstance(stride, int): - self.stride = (stride, stride) - else: - self.stride = stride - - # Handle padding - if isinstance(padding, int): - self.padding = (padding, padding) - else: - self.padding = padding - - def forward(self, x: Tensor) -> Tensor: - """ - Forward pass of max pooling layer. - - Args: - x: Input tensor of shape (batch_size, channels, height, width) - - Returns: - Output tensor after max pooling - """ - # TODO: Implement max pooling in Chapter 4 - raise NotImplementedError("MaxPool2d forward pass will be implemented in Chapter 4") - - -class ReLU(Module): - """ - ReLU activation function. - - Applies ReLU: f(x) = max(0, x) - """ - - def __init__(self): - """Initialize ReLU activation.""" - super().__init__() - - def forward(self, x: Tensor) -> Tensor: - """ - Forward pass of ReLU activation. - - Args: - x: Input tensor - - Returns: - Output tensor after ReLU activation - """ - # TODO: Implement ReLU in Chapter 3 - raise NotImplementedError("ReLU forward pass will be implemented in Chapter 3") - - -class Sequential(Module): - """ - Sequential container for modules. - - Modules will be added in the order they are passed in the constructor. - The forward() method accepts any input and forwards it through each - module in sequence. - """ - - def __init__(self, *modules): - """ - Initialize sequential container. - - Args: - *modules: Variable number of modules to chain together - """ - super().__init__() - for i, module in enumerate(modules): - self._modules[str(i)] = module - - def forward(self, x: Tensor) -> Tensor: - """ - Forward pass through all modules in sequence. - - Args: - x: Input tensor - - Returns: - Output tensor after passing through all modules - """ - for module in self._modules.values(): - x = module(x) - return x \ No newline at end of file diff --git a/tinytorch/core/optimizer.py b/tinytorch/core/optimizer.py deleted file mode 100644 index 7bf46148..00000000 --- a/tinytorch/core/optimizer.py +++ /dev/null @@ -1,138 +0,0 @@ -""" -Optimization algorithms for training neural networks. - -This module contains optimizers that update model parameters based on gradients: -- Base Optimizer class -- Stochastic Gradient Descent (SGD) -- Adam optimizer -- Learning rate scheduling -""" - -import numpy as np -from typing import List, Optional, Union -from .tensor import Tensor - - -class Optimizer: - """ - Base class for all optimizers. - - All optimizers should inherit from this class and implement the step() method. - """ - - def __init__(self, parameters: List[Tensor], lr: float): - """ - Initialize the optimizer. - - Args: - parameters: List of parameters to optimize - lr: Learning rate - """ - self.parameters = parameters - self.lr = lr - self.step_count = 0 - - def zero_grad(self) -> None: - """Zero the gradients of all parameters.""" - for param in self.parameters: - if param.grad is not None: - param.grad.data.fill(0.0) - - def step(self) -> None: - """ - Perform a single optimization step. - - This method should be overridden by all subclasses. - """ - raise NotImplementedError("Subclasses must implement step()") - - -class SGD(Optimizer): - """ - Stochastic Gradient Descent optimizer. - - Implements SGD with optional momentum: - v = momentum * v + lr * grad - param = param - v - - Args: - parameters: List of parameters to optimize - lr: Learning rate - momentum: Momentum factor (default: 0) - weight_decay: Weight decay (L2 penalty) (default: 0) - """ - - def __init__( - self, - parameters: List[Tensor], - lr: float, - momentum: float = 0.0, - weight_decay: float = 0.0 - ): - """Initialize SGD optimizer.""" - super().__init__(parameters, lr) - self.momentum = momentum - self.weight_decay = weight_decay - - # Initialize momentum buffers - self.velocity = [] - for param in parameters: - self.velocity.append(np.zeros_like(param.data)) - - def step(self) -> None: - """ - Perform a single SGD optimization step. - """ - # TODO: Implement SGD update in Chapter 8 - self.step_count += 1 - raise NotImplementedError("SGD step will be implemented in Chapter 8") - - -class Adam(Optimizer): - """ - Adam optimizer. - - Implements Adam algorithm with bias correction: - m = beta1 * m + (1 - beta1) * grad - v = beta2 * v + (1 - beta2) * grad^2 - m_hat = m / (1 - beta1^t) - v_hat = v / (1 - beta2^t) - param = param - lr * m_hat / (sqrt(v_hat) + eps) - - Args: - parameters: List of parameters to optimize - lr: Learning rate (default: 0.001) - betas: Coefficients for computing running averages (default: (0.9, 0.999)) - eps: Term for numerical stability (default: 1e-8) - weight_decay: Weight decay (L2 penalty) (default: 0) - """ - - def __init__( - self, - parameters: List[Tensor], - lr: float = 0.001, - betas: tuple = (0.9, 0.999), - eps: float = 1e-8, - weight_decay: float = 0.0 - ): - """Initialize Adam optimizer.""" - super().__init__(parameters, lr) - self.beta1, self.beta2 = betas - self.eps = eps - self.weight_decay = weight_decay - - # Initialize moment estimates - self.m = [] # First moment (mean) - self.v = [] # Second moment (uncentered variance) - - for param in parameters: - self.m.append(np.zeros_like(param.data)) - self.v.append(np.zeros_like(param.data)) - - def step(self) -> None: - """ - Perform a single Adam optimization step. - """ - # TODO: Implement Adam update in Chapter 8 - self.step_count += 1 - raise NotImplementedError("Adam step will be implemented in Chapter 8") \ No newline at end of file diff --git a/tinytorch/core/tensor.py b/tinytorch/core/tensor.py deleted file mode 100644 index b416788c..00000000 --- a/tinytorch/core/tensor.py +++ /dev/null @@ -1,116 +0,0 @@ -""" -Tensor implementation with automatic differentiation support. - -This module implements the core Tensor class that serves as the foundation -for all computations in TinyTorch. It includes support for: -- N-dimensional arrays with NumPy backend -- Automatic differentiation (autograd) -- GPU-like operations (CPU implementation) -- Broadcasting and shape manipulation -""" - -import numpy as np -from typing import Union, Tuple, Optional, List, Any - - -class Tensor: - """ - A tensor with automatic differentiation capabilities. - - The Tensor class is the core data structure of TinyTorch, similar to - torch.Tensor in PyTorch. It wraps NumPy arrays and adds automatic - gradient computation for building neural networks. - - Attributes: - data (np.ndarray): The underlying NumPy array containing the data - grad (Optional[Tensor]): Gradient tensor (same shape as data) - requires_grad (bool): Whether to track gradients for this tensor - grad_fn (Optional[Function]): Function that created this tensor (for autograd) - """ - - def __init__( - self, - data: Union[np.ndarray, List, float, int], - requires_grad: bool = False, - dtype: Optional[np.dtype] = None - ): - """ - Initialize a new Tensor. - - Args: - data: The data to store in the tensor - requires_grad: Whether to track gradients - dtype: NumPy data type (defaults to float32) - """ - if dtype is None: - dtype = np.float32 - - self.data = np.array(data, dtype=dtype) - self.grad: Optional['Tensor'] = None - self.requires_grad = requires_grad - self.grad_fn = None # Will be set by autograd functions - - # Initialize gradient tensor if needed - if requires_grad: - self.grad = Tensor(np.zeros_like(self.data), requires_grad=False) - - @property - def shape(self) -> Tuple[int, ...]: - """Return the shape of the tensor.""" - return self.data.shape - - @property - def dtype(self) -> np.dtype: - """Return the data type of the tensor.""" - return self.data.dtype - - @property - def ndim(self) -> int: - """Return the number of dimensions.""" - return self.data.ndim - - def __repr__(self) -> str: - """String representation of the tensor.""" - grad_info = f", requires_grad={self.requires_grad}" if self.requires_grad else "" - return f"Tensor({self.data}{grad_info})" - - def backward(self, gradient: Optional['Tensor'] = None) -> None: - """ - Compute gradients using backpropagation. - - Args: - gradient: Gradient flowing back from later operations - """ - # TODO: Implement backward pass (Chapter 7 - Autograd) - raise NotImplementedError("Backward pass will be implemented in Chapter 7") - - # Mathematical operations (to be implemented) - def __add__(self, other) -> 'Tensor': - """Addition operation.""" - # TODO: Implement in Chapter 3 - raise NotImplementedError("Addition will be implemented in Chapter 3") - - def __mul__(self, other) -> 'Tensor': - """Multiplication operation.""" - # TODO: Implement in Chapter 3 - raise NotImplementedError("Multiplication will be implemented in Chapter 3") - - def __matmul__(self, other) -> 'Tensor': - """Matrix multiplication operation.""" - # TODO: Implement in Chapter 3 - raise NotImplementedError("Matrix multiplication will be implemented in Chapter 3") - - -def zeros(*shape: int, requires_grad: bool = False) -> Tensor: - """Create a tensor filled with zeros.""" - return Tensor(np.zeros(shape), requires_grad=requires_grad) - - -def ones(*shape: int, requires_grad: bool = False) -> Tensor: - """Create a tensor filled with ones.""" - return Tensor(np.ones(shape), requires_grad=requires_grad) - - -def randn(*shape: int, requires_grad: bool = False) -> Tensor: - """Create a tensor with random normal values.""" - return Tensor(np.random.randn(*shape), requires_grad=requires_grad) \ No newline at end of file diff --git a/tinytorch/core/trainer.py b/tinytorch/core/trainer.py deleted file mode 100644 index 1e3834b4..00000000 --- a/tinytorch/core/trainer.py +++ /dev/null @@ -1,165 +0,0 @@ -""" -Training orchestration and loop management. - -This module provides the main training infrastructure: -- Trainer class for managing training loops -- Metric tracking and logging -- Checkpointing and model saving -- Validation and testing workflows -""" - -from typing import Dict, List, Optional, Callable, Any -from .tensor import Tensor -from .modules import Module -from .optimizer import Optimizer -from .dataloader import DataLoader - - -class Trainer: - """ - Main training orchestrator. - - Manages the training loop, including forward/backward passes, - optimization steps, metric tracking, and checkpointing. - - Args: - model: Neural network model to train - optimizer: Optimizer for updating parameters - criterion: Loss function - device: Device to run training on - """ - - def __init__( - self, - model: Module, - optimizer: Optimizer, - criterion: Optional[Callable] = None, - device: str = "cpu" - ): - """Initialize the trainer.""" - self.model = model - self.optimizer = optimizer - self.criterion = criterion - self.device = device - - # Training state - self.current_epoch = 0 - self.global_step = 0 - self.best_metric = float('inf') - - # Metrics tracking - self.train_metrics = {} - self.val_metrics = {} - - def train_epoch( - self, - train_loader: DataLoader, - epoch: int - ) -> Dict[str, float]: - """ - Train for one epoch. - - Args: - train_loader: Training data loader - epoch: Current epoch number - - Returns: - Dictionary of training metrics - """ - # TODO: Implement training loop in Chapter 8 - raise NotImplementedError("Training loop will be implemented in Chapter 8") - - def validate( - self, - val_loader: DataLoader - ) -> Dict[str, float]: - """ - Validate the model. - - Args: - val_loader: Validation data loader - - Returns: - Dictionary of validation metrics - """ - # TODO: Implement validation in Chapter 8 - raise NotImplementedError("Validation will be implemented in Chapter 8") - - def fit( - self, - train_loader: DataLoader, - val_loader: Optional[DataLoader] = None, - epochs: int = 10, - callbacks: Optional[List[Callable]] = None - ) -> None: - """ - Train the model for multiple epochs. - - Args: - train_loader: Training data loader - val_loader: Optional validation data loader - epochs: Number of epochs to train - callbacks: Optional list of callback functions - """ - # TODO: Implement training orchestration in Chapter 8 - raise NotImplementedError("Training orchestration will be implemented in Chapter 8") - - def save_checkpoint( - self, - filepath: str, - include_optimizer: bool = True - ) -> None: - """ - Save model checkpoint. - - Args: - filepath: Path to save checkpoint - include_optimizer: Whether to save optimizer state - """ - # TODO: Implement checkpointing in Chapter 8 - raise NotImplementedError("Checkpointing will be implemented in Chapter 8") - - def load_checkpoint( - self, - filepath: str, - load_optimizer: bool = True - ) -> None: - """ - Load model checkpoint. - - Args: - filepath: Path to checkpoint file - load_optimizer: Whether to load optimizer state - """ - # TODO: Implement checkpoint loading in Chapter 8 - raise NotImplementedError("Checkpoint loading will be implemented in Chapter 8") - - -def accuracy(predictions: Tensor, targets: Tensor) -> float: - """ - Compute classification accuracy. - - Args: - predictions: Model predictions - targets: Ground truth targets - - Returns: - Accuracy as a float between 0 and 1 - """ - # TODO: Implement metrics in Chapter 8 - raise NotImplementedError("Metrics will be implemented in Chapter 8") - - -def cross_entropy_loss(predictions: Tensor, targets: Tensor) -> Tensor: - """ - Compute cross-entropy loss. - - Args: - predictions: Model predictions (logits) - targets: Ground truth class indices - - Returns: - Cross-entropy loss tensor - """ - # TODO: Implement loss functions in Chapter 8 - raise NotImplementedError("Loss functions will be implemented in Chapter 8") \ No newline at end of file diff --git a/tinytorch/core/utils.py b/tinytorch/core/utils.py index 09553c1e..29197df5 100644 --- a/tinytorch/core/utils.py +++ b/tinytorch/core/utils.py @@ -1,12 +1,27 @@ -""" -TinyTorch Utility Functions +# AUTOGENERATED! DO NOT EDIT! File to edit: ../../notebooks/01_setup.ipynb. -This module contains utility functions used throughout the TinyTorch system. -Students will implement various utility functions here as part of different projects. -""" +# %% auto 0 +__all__ = ['hello_tinytorch', 'format_tensor_shape', 'validate_tensor_shapes'] -from typing import Any, List, Dict +# %% ../../notebooks/01_setup.ipynb 4 +def hello_tinytorch() -> str: + """ + Return a greeting message for new TinyTorch users. + + This function serves as the "hello world" for the TinyTorch system. + It introduces students to the nbdev export workflow. + + Returns: + A welcoming message string that includes: + - Welcoming content + - TinyTorch branding (πŸ”₯ emoji) + - Encouraging message about building ML systems + """ + return "πŸ”₯ Welcome to TinyTorch! Ready to build ML systems from scratch! πŸ”₯" +# %% ../../notebooks/01_setup.ipynb 8 +from typing import Any, List, Dict, Tuple +import numpy as np def format_tensor_shape(shape: tuple) -> str: """ @@ -17,33 +32,32 @@ def format_tensor_shape(shape: tuple) -> str: Returns: Formatted string representation of the shape + + Example: + >>> format_tensor_shape((3, 4, 5)) + '(3, 4, 5)' """ return f"({', '.join(map(str, shape))})" - -def validate_tensor_operation(name: str, *tensors) -> None: +# %% ../../notebooks/01_setup.ipynb 9 +def validate_tensor_shapes(*shapes: tuple) -> bool: """ - Validate that tensors are compatible for an operation. + Validate that tensor shapes are compatible for operations. Args: - name: Name of the operation being performed - *tensors: Variable number of tensor objects to validate + *shapes: Variable number of shape tuples to validate - Raises: - ValueError: If tensors are incompatible + Returns: + True if shapes are compatible, False otherwise + + Example: + >>> validate_tensor_shapes((3, 4), (3, 4)) + True + >>> validate_tensor_shapes((3, 4), (2, 4)) + False """ - # TODO: Implement tensor validation logic - pass - - -# TODO: Implement hello_tinytorch() function here for the setup project -# -# def hello_tinytorch() -> str: -# """ -# Return a greeting message for new TinyTorch users. -# -# Returns: -# A welcoming message string -# """ -# # Your implementation goes here -# pass \ No newline at end of file + if len(shapes) < 2: + return True + + first_shape = shapes[0] + return all(shape == first_shape for shape in shapes[1:]) \ No newline at end of file diff --git a/tinytorch/deployment/__init__.py b/tinytorch/deployment/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tinytorch/distributed/__init__.py b/tinytorch/distributed/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tinytorch/mlops/__init__.py b/tinytorch/mlops/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tinytorch/models/__init__.py b/tinytorch/models/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tinytorch/profiling/__init__.py b/tinytorch/profiling/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tinytorch/training/__init__.py b/tinytorch/training/__init__.py new file mode 100644 index 00000000..e69de29b