ml-ablation-design
Use when designing ablation studies to compare model components, loss functions, or architectural choices. Covers synthetic data experiments, variant loops, production metrics, and W&B grouping. Triggers: "ablation", "ablation study", "variant comparison", "controlled experiment", "synthetic data experiment"
Best use case
ml-ablation-design is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Use when designing ablation studies to compare model components, loss functions, or architectural choices. Covers synthetic data experiments, variant loops, production metrics, and W&B grouping. Triggers: "ablation", "ablation study", "variant comparison", "controlled experiment", "synthetic data experiment"
Teams using ml-ablation-design should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/ml-ablation-design/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How ml-ablation-design Compares
| Feature / Agent | ml-ablation-design | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Use when designing ablation studies to compare model components, loss functions, or architectural choices. Covers synthetic data experiments, variant loops, production metrics, and W&B grouping. Triggers: "ablation", "ablation study", "variant comparison", "controlled experiment", "synthetic data experiment"
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# ML Ablation Design
## When to Use
- Comparing model components (e.g., CTC vs AR heads, different loss functions)
- Designing controlled experiments with synthetic data before committing GPU hours
- Building self-contained ablation scripts that run end-to-end without external dependencies
- Setting up multi-variant experiments with proper W&B tracking
## Workflow
- [ ] **Hypothesis**: Define what you're testing and expected outcome
- [ ] **Synthetic first**: Build toy data, run all variants (~10 min)
- [ ] **Analyze synthetic**: Check if signal separates variants
- [ ] **Real pipeline**: Run on real data only if synthetic results are promising
- [ ] **Compare**: W&B grouped runs, dual-table console output
- [ ] **Decide**: Pick winner based on production metrics, not proxies
## Core Pattern: Self-Contained Ablation Script
One script, zero external dependencies (no dataset downloads, no pretrained models), production metrics, W&B grouping. Runs in minutes on a single GPU.
```
scripts/ablate_<experiment_name>.py # Self-contained script
slurm_scripts/ablate_<name>.sbatch # Slurm launcher (passes "$@")
```
## Two-Tier Strategy
1. **Synthetic first** (~10 min): Build a toy dataset that captures the essential structure of your real data. Train all variants. If a component shows no benefit on synthetic data, it won't help on real data either. This catches design flaws cheaply.
2. **Real pipeline second** (hours/days): Only after synthetic results look promising, run the full experiment on real data with the production training loop.
## Synthetic Data Design
### Orthogonal Embeddings via QR Decomposition
Create maximally separable class embeddings so the learning signal is clean:
```python
def make_embeddings(num_classes: int, feature_dim: int, seed: int = 0) -> torch.Tensor:
rng = torch.Generator().manual_seed(seed)
raw = torch.randn(num_classes, feature_dim, generator=rng)
q, _ = torch.linalg.qr(raw.T)
return q.T[:num_classes] # (num_classes, feature_dim)
```
### Single Noise Knob
Control task difficulty with one parameter (`noise_sigma`). Higher noise = harder classification. This lets you sweep difficulty to find where each variant breaks:
```python
noise = torch.randn(T, feature_dim, generator=rng) * noise_sigma
features = clean_embedding.expand(T, -1) + noise
```
### Shared Embeddings, Different Seeds
Train and eval datasets must use the **same** class embeddings (same underlying signal) but **different** random seeds (different noise realizations):
```python
chord_embs = make_embeddings(num_classes, feature_dim) # shared
train_ds = SyntheticDataset(seed=42, embeddings=chord_embs)
eval_ds = SyntheticDataset(seed=1042, embeddings=chord_embs) # different seed
```
## Variant Loop
### Fresh Model Per Variant
Never share weights between ablated components. Each variant gets a fresh model from the **same** initialization seed:
```python
for variant in args.variants:
torch.manual_seed(args.seed) # same init every time
model = MyModel(...).to(device)
# Surgical freezing — not new model classes
if variant == "ctc_only":
for p in model.ar_params:
p.requires_grad_(False)
elif variant == "ar_only":
for p in model.ctc_params:
p.requires_grad_(False)
```
### Selective Reruns via CLI
Allow partial reruns without re-training all variants:
```python
p.add_argument("--variants", nargs="+", default=["ctc_only", "ar_only", "combined"])
```
```bash
# Re-run just one variant after a fix
python scripts/ablate_experiment.py --variants combined
```
## Evaluation: Use Production Metrics
Never use proxy metrics that diverge from your real evaluation pipeline. If your production pipeline uses `mir_eval.chord`, your ablation must too:
```python
# Good: same metrics as production
scores = mir_eval.chord.evaluate(ref_intervals, ref_labels, est_intervals, est_labels)
# Bad: accuracy on synthetic token IDs (doesn't catch Harte conversion bugs)
acc = (pred_tokens == gt_tokens).float().mean()
```
### Robust Per-Sample Evaluation
Wrap each sample in `try/except` so one bad sample doesn't crash the whole eval:
```python
for i, sample in enumerate(eval_samples):
try:
scores = evaluate_sample(sample)
for key in METRIC_KEYS:
all_scores[key].append(scores[key])
except Exception:
pass # skip malformed samples, don't crash
```
## W&B Integration
### One Run Per Variant, Grouped for Comparison
```python
job_id = os.environ.get("SLURM_JOB_ID", "local")
wandb_group = args.wandb_group or f"ablate-{experiment}_{job_id}"
for variant in args.variants:
wb_run = wandb.init(
project="my-ablations", # separate from production project
name=f"ablate-{variant}_{job_id}",
group=wandb_group, # groups all variants together
config=vars(args) | {"variant": variant},
reinit=True, # multiple wandb.init() in one process
)
# ... train ...
wandb.finish()
```
### `final/` Summary Metrics
Write final results to `wandb.run.summary` so they appear in the W&B runs table without scrolling through charts:
```python
for key, value in final_results.items():
if isinstance(value, float):
wandb.run.summary[f"final/{key}"] = value
wandb.finish()
```
### Separate W&B Project
Keep ablation/synthetic runs in a different W&B project from production training. This prevents cluttering the main dashboard with hundreds of short exploratory runs.
## Slurm Launcher
Pass `"$@"` through so all CLI args work from the sbatch command line:
```bash
#!/bin/bash
#SBATCH --job-name=ablate-experiment
#SBATCH --time=00:30:00
#SBATCH --gpus=1
# ... conda init, env vars ...
python scripts/ablate_experiment.py --wandb "$@"
```
```bash
# Override from command line
sbatch slurm_scripts/ablate.sbatch --lr 1e-4 --noise_sigma 0.5 --wandb_group "sweep-lr"
```
## Console Results: Dual-Table Output
For multi-objective ablations, print separate tables for each objective class so results are scannable:
```
Temporal alignment (frame-level):
Variant | Frame Acc | Seg | OverSeg | UnderSeg
ctc_only | 92.3% | 85.1% | 91.2% | 88.4%
combined | 93.1% | 86.0% | 91.8% | 89.1%
Chord label quality:
Variant | Head | Root | Thirds | MIREX | Time
ctc_only | CTC | 95.2% | 91.0% | 88.3% | 12s
ar_only | AR | 93.8% | 89.5% | 86.1% | 15s
combined | CTC | 95.5% | 91.3% | 88.7% | 18s
| AR | 94.1% | 90.0% | 86.8% |
```
## Anti-Patterns
- **Shared weights between ablated components**: If CTC encoder and AR encoder share parameters, you can't attribute improvement to either head. Use fully decoupled architectures for clean ablations.
- **Inconsistent init seeds**: Different random seeds across variants mean you're comparing initialization luck, not architecture. Always `torch.manual_seed(args.seed)` before each variant.
- **Proxy metrics that diverge from production**: Token-level accuracy on synthetic IDs won't catch bugs in your Harte conversion, segmentation, or interval computation. Use the real evaluation pipeline.
- **Polluting the main W&B project**: Hundreds of short ablation runs drown out production fullruns. Use a separate W&B project for exploration.
- **Giant ablation scripts**: The script should be self-contained but focused. If it exceeds ~500 lines, you're probably reimplementing your training loop instead of testing a specific hypothesis.
## See Also
- `wandb-experiment-tracking` — Grouping ablation runs in W&B, `final/` summary metrics
- `hydra-experiment-config` — Variant configs using Hydra config groups
- `slurm-gpu-training` — Slurm launcher pattern for ablation scripts
- `idea-feasibility` — Run this *before* ablation design; ablation work on a `Blocked` idea is wasted
- `idea-box` — Per-idea lifecycle that consumes this skill's output as the `feasible → building` gate. When invoked from inside `./idea_box/<slug>/`, write the ablation plan to `./idea_box/<slug>/ablations.md`Related Skills
gpu-training-acceleration
Use when optimizing PyTorch training speed or memory on CUDA GPUs — global flags, torch.compile, fused optimizers, mixed precision, gradient checkpointing, kernel fusion, memory layout, or latent-space training. Applies to any PyTorch training workload. Triggers: "torch.compile", "TF32", "fused optimizer", "mixed precision", "bf16", "fp16", "gradient checkpointing", "Triton kernel", "CUDA flags", "GPU slow", "GPU memory"
genai-evaluation-metrics
Use when evaluating generative models — choosing metrics (FID, IS, KID, sFID, FDD, FVD, PRDC, LPIPS, SSIM, AuthPct, Vendi), setting up online or offline evaluation, feature extractor selection, distributed computation, memory management during sampling. Triggers: "FID", "IS", "KID", "inception score", "frechet", "LPIPS", "SSIM", "evaluation metrics", "generative evaluation", "FVD"
youtube-wiki
Use when reading a YouTube video (especially an AI/ML interview, podcast, or technical talk) and producing a faithful, timestamped wiki entry the user can return to weeks later. Fetches the transcript via yt-dlp, sections by chapters or LLM-detected topics, summarizes per-section with parallel subagents, preserves verbatim quotes with speaker attribution, and runs a coverage test against the raw transcript. Triggers: "youtube wiki", "video wiki", "summarize this youtube", "watch this interview", "read this talk", "digest this video", "https://youtu.be/", "https://www.youtube.com/watch"
pdf-reader
Use when reading PDF papers, reports, or long documents where text, figures, and tables must all be captured and chunk-summarized without truncation. Converts PDF to a markdown + paper_content.json workspace, extracts figures and tables as standalone files, then delegates to arxiv-latex-reader's progressive two-layer reading (section index + on-demand deep reads). Triggers: "read pdf", "pdf to markdown", "summarize pdf", "pdf paper", "extract figures from pdf", "extract tables from pdf", "marker pdf", "pymupdf", "docling", "paper digest", "pdf reader"
insert-wiki
Use when capturing a single URL (X tweet, LinkedIn post, HN thread, short blog, news article, GitHub gist or issue) as a small persistent markdown entry the user can re-read later for motivation or grep across future sessions. Verbatim body + author + tags + a one-line "Why I saved this" hook. Writes to docs/wikis/YYYY-MM-DD-<slug>.md. WebFetch by default; CDP via Playwright MCP for login-walled hosts (x.com, twitter.com, linkedin.com). Redirects YouTube / arXiv / GitHub repo URLs to their specialized skills. Triggers: "insert wiki", "add to wiki", "insert this", "save this tweet", "capture this post", "add this to my wiki", "remember this link", "https://x.com/", "https://twitter.com/", "https://linkedin.com/posts/"
idea-feasibility
Use when evaluating whether a research or product idea is actually feasible — buildable, evaluable, and de-risked by available checkpoints, code, datasets, and GPU budget. Normalizes the idea, gathers primary-source evidence (arXiv, GitHub, project pages, model hosts), scores it against four mandatory hard gates, and emits a verdict + falsifiable MVP. Triggers: "idea feasibility", "is this idea feasible", "feasibility check", "can we do this", "is this practical", "worth pursuing", "评估想法可行性", "可行性分析", "这个 idea 能做吗", "这个想法靠谱吗"
idea-explore
Use when proposing new research ideas grounded in a seed paper or method — surfaces the gaps that the citation cone hasn't filled, the drawbacks the community already complains about in the official repo's GitHub issues, and the adjacent angles the literature suggests. Orchestrates followup-analysis (already-done exclusion), GitHub-issue mining (known drawbacks), and academic-deep-research (adjacent literature) into a ranked candidate-ideas report. Triggers: "idea explore", "idea-explore", "propose ideas", "explore ideas", "new directions", "research gaps", "what's missing", "build on this paper", "探索想法", "提出新想法", "研究空白"
idea-box
Use when promoting an idea from a fleeting thought into a tracked artifact with a lifecycle. Defines a per-idea on-disk directory (./idea_box/<slug>/) and a hard-gated state machine (explored → feasible/blocked → building → built/killed) that the existing reader/evaluator skills (idea-feasibility, ml-ablation-design, academic-deep-research, followup-analysis, arxiv-latex-reader, pdf-reader, github-reader, blog-reader) plug into. Public repo ships only the convention; idea data lives in the user's private idea-box repo. Triggers: "idea box", "idea-box", "new idea", "advance idea", "list ideas", "kill idea", "想法箱", "新想法", "推进想法", "列出想法"
github-reader
Use when reading a GitHub repository (especially a research code release with an accompanying paper) and producing a faithful digest that covers the implementation logic, the main insight, and the key reported results. Research-first with graceful fallback for non-paper repos. Handles arXiv link detection and delegates paper reading to arxiv-latex-reader / pdf-reader. Triggers: "read repo", "read this github", "analyze github", "digest repo", "github reader", "extract from github", "summarize this codebase", "read this code", "https://github.com/"
blog-reader
Use when reading a long technical blog post (ML research, engineering deep-dives, Distill/Lil'Log-style posts) and producing a faithful, figure-aware summary. Handles context-over-limit via section-based chunking, captures important figures via multimodal Read, and runs a coverage test to catch missing information. Triggers: "read this blog", "summarize this post", "read blog", "digest this article", "long blog post", "read this article", "blog summary", "distill post", "summarize url", "chunk and summarize"
arxiv-latex-reader
Use when reading large arxiv papers without context overflow. Progressive two-layer reading: index all sections (~2k tokens), then deep-read on demand. Never truncates. Triggers: "read paper", "paper sections", "section index", "progressive reading", "paper_content.json", "section summary"
academic-deep-research
Use when evaluating academic papers or surveying a research topic. Gathers venue, citations, GitHub stats, social buzz, reproducibility, and author signals to produce a scored markdown report. Triggers: "evaluate paper", "paper review", "research survey", "literature review", "is this paper good", "find papers on", "compare papers", "paper impact"