

Also from Kynth Studios


Also from Kynth Studios


Also from Kynth Studios
1# AI/ML Python Projects — Cursor Rules2# Production ML: PyTorch, data pipelines, experiment tracking, and deployment34# Project Context5You are building an AI/ML project with Python. The project uses PyTorch for model training,6handles data pipelines with proper validation, tracks experiments systematically, and follows7production ML engineering practices. Code is type-hinted, tested, and reproducible.89# Project Structure10```11project/12 src/13 data/14 datasets.py # PyTorch Dataset classes15 transforms.py # Data augmentation and preprocessing16 loaders.py # DataLoader configurations17 validation.py # Data quality checks18 models/19 architectures/ # Model definitions20 resnet.py21 transformer.py22 losses.py # Custom loss functions23 metrics.py # Evaluation metrics24 training/25 trainer.py # Training loop26 callbacks.py # Training callbacks (early stopping, checkpointing)27 optimizers.py # Optimizer configurations28 inference/29 predictor.py # Inference pipeline30 postprocess.py # Output postprocessing31 utils/32 config.py # Configuration management33 logging.py # Experiment logging34 reproducibility.py # Seed setting, deterministic mode35 configs/36 train_config.yaml # Training hyperparameters37 model_config.yaml # Model architecture config38 scripts/39 train.py # Training entry point40 evaluate.py # Evaluation script41 export.py # Model export (ONNX, TorchScript)42 notebooks/43 exploration.ipynb # Data exploration (not production code)44 tests/45 test_data.py46 test_models.py47 test_training.py48```4950# PyTorch Model Patterns51- Inherit from `nn.Module`. Always call `super().__init__()`.52- Type hint all method signatures:53```python54 class ClassificationHead(nn.Module):55 def __init__(self, in_features: int, num_classes: int, dropout: float = 0.1) -> None:56 super().__init__()57 self.dropout = nn.Dropout(dropout)58 self.fc = nn.Linear(in_features, num_classes)5960 def forward(self, x: torch.Tensor) -> torch.Tensor:61 x = self.dropout(x)62 return self.fc(x)63```64- Use `nn.Sequential` or `nn.ModuleList` for dynamic layer construction — never regular Python lists.65- Register buffers for non-parameter tensors: `self.register_buffer('mean', torch.zeros(3))`.66- Use `@torch.no_grad()` for inference methods.67- DON'T: Use numpy operations inside `forward()` — they break autograd.68- DON'T: Create tensors in `forward()` without sending to the correct device.6970# Data Pipeline Patterns71- Create custom `Dataset` classes with proper `__len__` and `__getitem__`:72```python73 class ImageDataset(Dataset):74 def __init__(self, root: Path, transform: Compose | None = None) -> None:75 self.paths = sorted(root.glob("*.jpg"))76 self.transform = transform7778 def __len__(self) -> int:79 return len(self.paths)8081 def __getitem__(self, idx: int) -> dict[str, torch.Tensor]:82 image = read_image(str(self.paths[idx]))83 if self.transform:84 image = self.transform(image)85 label = self._extract_label(self.paths[idx])86 return {"image": image, "label": label}87```88- Validate data before training: check for NaNs, correct shapes, label distribution.89- Use `DataLoader` with `num_workers > 0` and `pin_memory=True` for GPU training.90- Implement data augmentation in transforms, not in the dataset class.91- Cache preprocessed data when preprocessing is expensive.92- DON'T: Load entire dataset into memory — use lazy loading in `__getitem__`.93- DON'T: Use random transforms without seeding for reproducibility.9495# Training Loop Best Practices96- Use a structured training loop with proper phases:97```python98 def train_epoch(99 model: nn.Module,100 loader: DataLoader,101 optimizer: Optimizer,102 criterion: nn.Module,103 device: torch.device,104 ) -> dict[str, float]:105 model.train()106 total_loss = 0.0107 correct = 0108 total = 0109110 for batch in loader:111 inputs = batch["image"].to(device, non_blocking=True)112 targets = batch["label"].to(device, non_blocking=True)113114 optimizer.zero_grad(set_to_none=True) # More efficient than zero_grad()115 outputs = model(inputs)116 loss = criterion(outputs, targets)117 loss.backward()118 torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)119 optimizer.step()120121 total_loss += loss.item() * inputs.size(0)122 correct += (outputs.argmax(dim=1) == targets).sum().item()123 total += inputs.size(0)124125 return {"loss": total_loss / total, "accuracy": correct / total}126```127- Use gradient clipping to prevent exploding gradients.128- Use `optimizer.zero_grad(set_to_none=True)` for better memory efficiency.129- Use `torch.cuda.amp` for mixed precision training (significant speedup):130```python131 scaler = GradScaler()132 with autocast(device_type='cuda'):133 outputs = model(inputs)134 loss = criterion(outputs, targets)135 scaler.scale(loss).backward()136 scaler.step(optimizer)137 scaler.update()138```139- Save checkpoints with model state, optimizer state, epoch, and metrics.140141# Experiment Tracking142- Use Weights & Biases (wandb), MLflow, or TensorBoard for experiment tracking.143- Log ALL hyperparameters at experiment start:144```python145 wandb.init(project="my-project", config={146 "learning_rate": 3e-4,147 "batch_size": 32,148 "epochs": 100,149 "architecture": "resnet50",150 "optimizer": "AdamW",151 "weight_decay": 0.01,152 "scheduler": "cosine",153 })154```155- Log metrics every epoch: train loss, val loss, learning rate, custom metrics.156- Log artifacts: model checkpoints, confusion matrices, sample predictions.157- Name experiments descriptively: `resnet50-lr3e4-bs32-cosine-augv2`.158- DON'T: Manually track experiments in spreadsheets — use proper tooling.159- DON'T: Overwrite previous experiment results.160161# Configuration Management162- Use YAML or TOML files for configuration, not hardcoded values:163```yaml164 # configs/train_config.yaml165 training:166 epochs: 100167 batch_size: 32168 learning_rate: 0.0003169 weight_decay: 0.01170 scheduler: cosine171 warmup_epochs: 5172 model:173 architecture: resnet50174 pretrained: true175 num_classes: 10176 dropout: 0.1177```178- Parse configs with Pydantic for validation:179```python180 class TrainingConfig(BaseModel):181 epochs: int = Field(ge=1)182 batch_size: int = Field(ge=1)183 learning_rate: float = Field(gt=0)184```185- Support config overrides via CLI arguments.186- Save the full config with every experiment for reproducibility.187188# Reproducibility189- Set seeds explicitly at the start of every experiment:190```python191 def set_seed(seed: int) -> None:192 random.seed(seed)193 np.random.seed(seed)194 torch.manual_seed(seed)195 torch.cuda.manual_seed_all(seed)196 torch.backends.cudnn.deterministic = True197 torch.backends.cudnn.benchmark = False198```199- Pin dependency versions in `requirements.txt` or `pyproject.toml`.200- Use `torch.use_deterministic_algorithms(True)` when exact reproducibility is required.201- Log the git commit hash with every experiment.202- Save train/val/test split definitions (indices or file lists), not just random seeds.203204# Model Evaluation205- Always evaluate on a held-out test set that was NEVER used during training or validation.206- Report multiple metrics: accuracy, precision, recall, F1, AUC-ROC (as appropriate).207- Use confusion matrices for classification tasks.208- Report confidence intervals or standard deviation across multiple runs.209- Analyze failure cases — don't just report aggregate metrics.210211# Model Export and Deployment212- Export models to ONNX or TorchScript for production serving:213```python214 # ONNX export215 dummy_input = torch.randn(1, 3, 224, 224, device=device)216 torch.onnx.export(model, dummy_input, "model.onnx", opset_version=17)217```218- Validate exported model outputs match PyTorch model outputs.219- Version models with metadata: architecture, training config, metrics, data version.220- Use batch inference for throughput, single inference for latency.221222# Notebook Discipline223- Notebooks are for exploration ONLY — never production code.224- Move any code that works into proper Python modules.225- Clear all outputs before committing notebooks.226- Keep notebooks numbered and documented: `01-data-exploration.ipynb`, `02-baseline-model.ipynb`.227228# Testing ML Code229- Test data loading: correct shapes, dtypes, value ranges.230- Test model forward pass: output shape matches expected for given input.231- Test training step: loss decreases after one gradient update on a small batch.232- Test data transforms: correct output shapes, value ranges, augmentation effects.233- Use small datasets and few epochs for fast testing.234- Test edge cases: empty batch, single sample, maximum sequence length.235236# Common Mistakes to Avoid237- DON'T: Train and evaluate on the same data split.238- DON'T: Tune hyperparameters on the test set — use a validation set.239- DON'T: Use Python lists for tensors in `forward()` — use `nn.ModuleList`.240- DON'T: Forget to call `model.eval()` during inference.241- DON'T: Forget to move data to the same device as the model.242- DON'T: Ignore data leakage between train and validation splits.243- DON'T: Skip normalization or standardization of input features.244
One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| survivorforge/cursor-rulesrules/langchain-ai/.cursorrules · 16 | .cursorrules | testlint-formatstylearch+4 | 84/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/aws-serverless/.cursorrules · 16 | .cursorrules | teststylearchtypes+6 | 73/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/tailwindcss/.cursorrules · 16 | .cursorrules | lint-formatstylearchui+3 | 81/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/mern-stack/.cursorrules · 16 | .cursorrules | setupteststylearch+6 | 81/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/api-design-rest/.cursorrules · 16 | .cursorrules | lint-formatstylesecurityapi+3 | 69/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/api-microservices/.cursorrules · 16 | .cursorrules | buildteststylearch+5 | 92/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/chrome-extension/.cursorrules · 16 | .cursorrules | teststylearchtesting-strategy+4 | 81/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/clean-code/.cursorrules · 16 | .cursorrules | styledo-notagent-behaviourdocs | 57/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/database-sql/.cursorrules · 16 | .cursorrules | styletypessecuritydatabase+3 | 65/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/devops-docker/.cursorrules · 16 | .cursorrules | setupbuildteststyle+4 | 93/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/devops-infrastructure/.cursorrules · 16 | .cursorrules | buildteststylesecurity+3 | 93/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/django-rest/.cursorrules · 16 | .cursorrules | buildteststylearch+5 | 84/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/docker-devops/.cursorrules · 16 | .cursorrules | setupteststylearch+6 | 85/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/flutter-dart/.cursorrules · 16 | .cursorrules | teststylearchtypes+5 | 89/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/fullstack-nextjs-prisma/.cursorrules · 16 | .cursorrules | teststylearchtypes+7 | 96/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/go-gin/.cursorrules · 16 | .cursorrules | testlint-formatstylearch+5 | 84/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/mobile-react-native/.cursorrules · 16 | .cursorrules | teststylearchtypes+7 | 89/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/nextjs-14-app-router/.cursorrules · 16 | .cursorrules | teststyletypestesting-strategy+3 | 71/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/nextjs-app-router/.cursorrules · 16 | .cursorrules | teststylearchtypes+5 | 81/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/nextjs-typescript/.cursorrules · 16 | .cursorrules | teststylearchtypes+5 | 81/100 | 13 days ago |
A badge carrying the measured quality of the strongest agent config file in this repository, out of 100. It reads from this index every time somebody loads your page, so it changes when the measurement changes and there is nothing to keep up to date. Free, no account, and the value is not something you or we can set by hand.
[](https://rulestack.kynth.studio/configs/survivorforge-cursor-rules-rules-ai-ml-python-cursorrules)Would rather not hotlink us? Every badge is also served in shields.io’s endpoint schema, so shields renders the image and your readers never talk to our domain:
Published by Toolproof, the masthead over this index and eight others. The method behind the number is at toolproof.kynth.studio/methodology, and the whole thing is readable as JSON with no key at /api.