āļāļāļāļ§āļēāļĄāļāļĩāđāļāđāļēāļāļāļīāļāļāļēāļāļāļĨāļāļēāļĢāļ§āļīāļāļąāļĒāļāļēāļāļāļēāļĢāļŠāļ·āļāļŠāļ§āļāļāļēāļĢāđāļāļĢāļāđāļāļāļāļĩāđāļĢāļ°āļāļąāļāđāļāļāļĢāđāđāļāļĨāđāļāļĒāđāļāđ eBPF uprobes āđāļāļāļąāļāļŦāļē PyTorch āļāļĢāļīāļ (#154318) āļāļēāļāļāđāļāļĄāļđāļĨāļāļēāļĢāđāļāļĢāļāđāļāļāđāļāļĒāđāļāļĢāđāđāļäŧåšŦ Ingero āļāļĩāđāđāļāļīāļāļāļ§āđāļēāļāļŠāļģāļŦāļĢāļąāļāļāļēāļĢāļāļĢāļ§āļāļŠāļāļāļāļīāļŠāļĢāļ°
TL;DR
DataLoader āļāļāļ PyTorch āļŠāļēāļĄāļēāļĢāļāļāđāļēāļāļ§āđāļēāļāļēāļĢāļāđāļēāļāļāļīāļāđāļāļāđāļāļāļĢāđāđāļāļĒāļāļĢāļ 50-124 āđāļāđāļēāļŠāļģāļŦāļĢāļąāļāļāļēāļāđāļāļŦāļāđāļ§āļĒāļāļ§āļēāļĄāļāļģ GPU āđāļĢāļēāđāļāđāļāļģāļāđāļģāļāļąāļāļŦāļē PyTorch āļāļĢāļīāļāļāļ RTX 4090 āđāļĨāļ°āļāļīāļāļāļēāļĄāļāļēāļĢāđāļĢāļĩāļĒāļ API CUDA āļāļļāļāļāļĢāļąāđāļāđāļĨāļ°āđāļŦāļāļļāļāļēāļĢāļāđāđāļāļāļĢāđāđāļāļĨ Linux āđāļāļ·āđāļāļāđāļāļŦāļēāļŠāļēāđāļŦāļāļļāļāļāļāļāļąāļāļŦāļē GPU āđāļĄāđāļāđāļē â āļĄāļąāļāļāļđāļāļāļāļāļāļīāđāļ āđāļŦāđāļāļģāļāļēāļ DataLoader āļŠāđāļāļāļĨāđāļŦāđāđāļāļīāļāļāļēāļĢāđāļāļĨāļĩāđāļĒāļāļāļĢāļīāļāļ CPU 200,000 āļāļĢāļąāđāļāđāļĨāļ°āļāļēāļĢāļāļąāļāļŠāļĢāļĢāļŦāļāđāļē 300,000 āļāļĢāļąāđāļāđāļ 40 āļ§āļīāļāļēāļāļĩ āļāļģāđāļŦāđ GPU āļāđāļāļāļĢāļāđāļāļĨāļĩāđāļĒ 301 āļĄāļīāļĨāļĨāļīāļ§āļīāļāļēāļāļĩāđāļāļāļēāļĢāļāđāļēāļĒāđāļāļāļāđāļāļĄāļđāļĨāļāļĩāđāļāļ§āļĢāđāļāđāđāļ§āļĨāļēāđāļĄāđāļāļĢāļ§āļīāļāļēāļāļĩ
āļāļąāļāļŦāļē
āļāļđāđāđāļāđ PyTorch āļĢāļēāļĒāļŦāļāļķāđāļ āļĢāļēāļĒāļāļēāļ āļ§āđāļē DataLoader āļāđāļēāļāļ§āđāļēāļāļēāļĢāļāđāļēāļāļāļīāļāđāļāļāđāļāļāļĢāđāđāļāļĒāļāļĢāļ 7-22 āđāļāđāļēāļŠāļģāļŦāļĢāļąāļāļāļēāļāļāļāļļāļĄāļēāļ MLP āļāļĩāđāļāđāļēāļĒ āđāļĄāđāļ§āđāļēāļāļ°āļĄāļĩ num_workers=12, pin_memory=True āđāļĨāļ° prefetch_factor=12 āļāđāļāļāļ§āđāļēāļāļĒāļąāļāļāļāļĄāļēāļ āļāļēāļĢāđāļāđ GPU āļāļĒāļđāđāļāļĩāđ 10-20%
āđāļĢāļēāļāļģāļāđāļģāļĄāļąāļ āļāđāļāļāļ§āđāļēāļāļĒāļąāļāļāļāļĄāļēāļāļāļķāđāļāļāļāļŪāļēāļĢāđāļāđāļ§āļĢāđāļāļāļāđāļĢāļē:
| āļ§āļīāļāļĩāļāļēāļĢ | āđāļ§āļĨāļē | āđāļāļĩāļĒāļāļāļąāļāļāļēāļĢāļāđāļēāļāļāļīāļāđāļāļĒāļāļĢāļ |
|---|---|---|
| āļāļēāļĢāļāđāļēāļāļāļīāļāđāļāļāđāļāļāļĢāđāđāļāļĒāļāļĢāļ | 0.39 āļ§āļīāļāļēāļāļĩ | 1 āđāļāđāļē |
| DataLoader (shuffle=True) | 48.49 āļ§āļīāļāļēāļāļĩ | āļāđāļēāļāļ§āđāļē 124 āđāļāđāļē |
| DataLoader (āļāļĢāļąāļāđāļŦāđāđāļŦāļĄāļēāļ°āļŠāļĄ, 4 āļāļāļāļēāļ, pin_memory) | 43.29 āļ§āļīāļāļēāļāļĩ | āļāđāļēāļāļ§āđāļē 111 āđāļāđāļē |
āļāļēāļāļāļĩāđāđāļāđāļāđāļĢāļ·āđāļāļāļāđāļēāļĒ: 7 āļĨāđāļēāļāļāļąāļ§āļāļĒāđāļēāļ, 100 āļāļļāļāļĨāļąāļāļĐāļāļ°, 2-āļāļąāđāļ MLP, āļāļāļēāļāđāļāļāļāđ 1 āļĨāđāļēāļ āļĄāļāļāļđāļĨāļāļĢāļ°āļĄāļ§āļĨāļāļĨāđāļāļāļāđāđāļāđāļĄāđāļāļĩāđāļ§āļīāļāļēāļāļĩ āļāļąāļāļāļąāđāļāđāļ§āļĨāļēāđāļāđāļŦāļ?
āļŠāļīāđāļāļāļĩāđ nvidia-smi āđāļŠāļāļ
āđāļĄāđāļĄāļĩāļāļ°āđāļĢāļāļĩāđāļĄāļĩāļāļĢāļ°āđāļĒāļāļāđ āļāļēāļĢāđāļāđ GPU āļĄāļĩāđāļŠāļāļĩāļĒāļĢāļ āļēāļāļĢāļ°āļŦāļ§āđāļēāļ 0% āļāļķāļ 30% āļāļēāļĢāđāļāđāļŦāļāđāļ§āļĒāļāļ§āļēāļĄāļāļģāļĄāļĩāđāļŠāļāļĩāļĒāļĢāļ āļēāļ āļāļļāļāļŦāļ āļđāļĄāļīāđāļāđāļāļāļāļāļī GPU āļāļĒāļđāđāđāļāļŠāļāļēāļāļ°āļāļĩāđāđāļĄāđāđāļāđāđāļāđāļāļēāļ āđāļāđ nvidia-smi āđāļĄāđāļŠāļēāļĄāļēāļĢāļāļāļāļāđāļāđāļ§āđāļēāļāļģāđāļĄ
āļŠāļīāđāļāļāļĩāđ torch.profiler āđāļŠāļāļ
āļāļđāđāļĢāļēāļĒāļāļēāļāļāļĒāļēāļĒāļēāļĄāđāļāđāđāļāļĢāļ·āđāļāļāļĄāļ·āļāļ§āļīāđāļāļĢāļēāļ°āļŦāđāļāļĢāļ°āļŠāļīāļāļāļīāļ āļēāļāļāļĩāđāļĄāļĩāļāļĒāļđāđāđāļ PyTorch āđāļĨāļ° âāđāļĄāđāđāļāđāļĢāļąāļāļāđāļāļĄāļđāļĨāļāļēāļĢāļ§āļīāđāļāļĢāļēāļ°āļŦāđāļāļĩāđāļĄāļĩāļāļ§āļēāļĄāļŦāļĄāļēāļĒâ āļŠāļīāđāļāļāļĩāđāđāļāđāļāļāļ§āļēāļĄāļāļīāļāļŦāļ§āļąāļāļāļąāđāļ§āđāļ â āđāļāļĢāļ·āđāļāļāļĄāļ·āļāļ§āļīāđāļāļĢāļēāļ°āļŦāđāļĢāļ°āļāļąāļāđāļāļāļāļĨāļīāđāļāļāļąāļāļŠāļēāļĄāļēāļĢāļāđāļŠāļāļāđāļŦāđāđāļŦāđāļāļ§āđāļēāļāļāļĢāđ CUDA āļāļģāļĨāļąāļāļāļģāļāļēāļ āđāļāđāđāļĄāđāļŠāļēāļĄāļēāļĢāļāđāļŦāđāļāđāļŦāļāļļāļāļēāļĢāļāđāļāļēāļĢāļāļąāļāļāļēāļĢāļēāļāļāļēāļĢāļāļģāļāļēāļāļāļāļāđāļŪāļŠāļāđ āļāļēāļĢāļāļąāļāļāļēāļĢāļŦāļāđāļ§āļĒāļāļ§āļēāļĄāļāļģ āđāļĨāļ°āļāļēāļĢāļāļģāđāļāļīāļāļāļĢāļ°āļāļ§āļāļāļēāļĢāļāļĩāđāļāļģāļŦāļāļāļ§āđāļēāļāđāļāļĄāļđāļĨāļāļ°āļĄāļēāļāļķāļ GPU āđāļĄāļ·āđāļāđāļŦāļĢāđ
āļŠāļīāđāļāļāļĩāđāļāļēāļĢāđāļāļĢāļāđāļāļāļāļĩāđāļĢāļ°āļāļąāļāđāļāļāļĢāđāđāļāļĨāđāļŠāļāļ
āđāļĢāļēāļāļģāļāļēāļĢāļ§āļąāļāļāļĢāļ°āļŠāļīāļāļāļīāļ āļēāļāđāļāļāļāļ°āļāļĩāđāļāļīāļāļāļēāļĄāļāļēāļĢāđāļĢāļĩāļĒāļ API CUDA (āļāđāļēāļ eBPF uprobes āļāļ libcudart.so) āđāļĨāļ°āđāļŦāļāļļāļāļēāļĢāļāđāđāļāļāļĢāđāđāļāļĨ Linux (āļāļēāļĢāđāļāļĨāļĩāđāļĒāļāļāļĢāļīāļāļ, āļāļēāļĢāļāļąāļāļŠāļĢāļĢāļŦāļāđāļē, āļāļēāļĢāļŠāļĢāđāļēāļāļāļĢāļ°āļāļ§āļāļāļēāļĢ) āļāļĢāđāļāļĄāļāļąāļ āļāļĨāļĨāļąāļāļāđāđāļĨāđāļēāđāļĢāļ·āđāļāļāļĢāļēāļ§āļāļĩāđāļŠāļĄāļāļđāļĢāļāđ
āļ§āļīāļāļĩāđāļāļāļąāļ§āļĢāđāđāļāđāļĄāļĢāļđāļāđāļāļ: https://asciinema.org/a/RGwhPeXAPJdhXqxp
āđāļč§éĒ āđāļĢāļēāđāļāļ·āđāļāļĄāļāđāļ LLM āļāļĩāđāđāļāļīāļāļāļ§āđāļēāļ (MiniMax-M2.7) āļāļąāļāļāļēāļāļāđāļāļĄāļđāļĨāļāļēāļĢāđāļāļĢāļāđāļāļāļāđāļēāļ MCP (Model Context Protocol):
ollmcp -m minimax-m2.7:cloud -j /tmp/ingero-mcp-dataloader.jsonāđāļāļĨāđ JSON āļāļāļāļāļīāļāļāļāļ MCP client āļ§āđāļēāļāļ§āļĢāļŦāļēāļŠerver Ingero āđāļĨāļ°āļāļēāļāļāđāļāļĄāļđāļĨāļāļēāļĢāđāļāļĢāļāđāļāļāđāļāļāļĩāđāļāļ°āđāļŦāļĨāļ:
{
"mcpServers": {
"ingero": {
"command": "./bin/ingero",
"args": ["mcp", "--db", "investigations/pytorch-dataloader-starvation.db"]
}
}
}
āļŠāļīāđāļāļāļĩāđāļāļģāđāļŦāđ LLM āļŠāļēāļĄāļēāļĢāļāđāļāđāļēāļāļķāļāļāđāļāļĄāļđāļĨāļāļēāļĢāđāļāļĢāļāđāļāļāļāđāļēāļāđāļāļĢāļ·āđāļāļāļĄāļ·āļ 7 āļāļīāđāļ: get_trace_stats, get_causal_chains, get_per_process_breakdown āđāļĨāļ°āļāļ·āđāļāđ AI āļŠāļēāļĄāļēāļĢāļāļŠāļ·āļāļāđāļāļāļēāļāļāđāļāļĄāļđāļĨ, āļŠāļāļāļāļĨāđāļāļāļāļąāļāđāļŦāļāļļāļāļēāļĢāļāđ CUDA āļāļąāļāļāđāļāļĄāļđāļĨāļāļēāļĢāļāļģāļŦāļāļāļāļēāļĢāļēāļāļāļēāļĢāļāļģāļāļēāļāļāļāļāđāļāļāļĢāđāđāļāļĨ āđāļĨāļ°āļŠāļĢāđāļēāļāļāļēāļĢāļ§āļīāļāļīāļāļāļąāļĒāļ āļēāļĐāļēāļāļĢāļĢāļĄāļāļēāđāļāļĒāđāļĄāđāļāđāļāļāļĄāļĩāļāļēāļĢāļ§āļīāđāļāļĢāļēāļ°āļŦāđāđāļāļāļĄāļ·āļ
4 āđāļāđāļŠāļēāđāļŦāļāļļāļĢāļ°āļāļąāļāļāļ§āļēāļĄāļĢāļļāļāđāļĢāļāļŠāļđāļ
āđāļāļĢāļ·āđāļāļāļĄāļ·āļāđāļāđāļŠāļēāđāļŦāļāļļāļāļĢāļ§āļāļāļ 4 āļĢāļđāļāđāļāļāļāļĩāđāļĄāļĩāļāļ§āļēāļĄāļĢāļļāļāđāļĢāļāļŠāļđāļ āļāļąāđāļāļŦāļĄāļāļĄāļĩāļŠāļēāđāļŦāļāļļāđāļāļĩāļĒāļ§āļāļąāļ:
[HIGH] cudaStreamSync p99=42ms (1,638x p50=25us) - CPU 100% + 1,880 sched_switch events Timeline: [SYSTEM] CPU 100% [HOST ] 1,880 context switches (21s off-CPU) [CUDA ] p99=42ms (1,638x p50=25us) Root cause: DataLoader workers āļāđāļāļŠāļđāđāļāļąāļāđāļāļ·āđāļ CPU, āļāļ§āļēāļĄāļāļāļāļąāļāļāļēāļĢāļāļąāļāļŠāļĢāļĢāļŦāļāđāļēāļĄāļēāļ
[HIGH] cudaLaunchKernel p99=24.67ms (349x p50=70us) - CPU 100% Root: 34 sched_switch events [HIGH] cuMemAlloc p99=627us (4.0x p50) - CPU 100% [HIGH] cuLaunchKernel p99=106us (4.0x p50) - CPU 100%
cudaStreamSync p99 āļāļ·āļ 1,638 āđāļāđāļēāļāļāļ p50 āļāļąāđāļāđāļĄāđāđāļāđāļāļ§āļēāļĄāļāđāļēāļāļāļ GPU â āļāļąāđāļāļāļ·āļ GPU āļāļĩāđāļĢāļāļāđāļāļĄāļđāļĨāļāļĩāđāđāļĄāđāļĄāļēāļāļķāļāļāļąāļāđāļ§āļĨāļē
āļĢāļđāļāļāļĩāđ 1: āļāļēāļĢāļ§āļīāđāļāļĢāļēāļ°āļŦāđāļāļĩāđāļŠāļĢāđāļēāļāđāļāļĒ AI āļŦāļĨāļąāļāļāļēāļĢāļ§āļīāđāļ /investigate āļĄāļāļāļđāļĨāđāļāđāđāļāļĢāļ·āđāļāļāļĄāļ·āļ MCP 7 āļāļīāđāļāļāļāļ Ingero āđāļāļ·āđāļāļŠāļ·āļāļāđāļāļāļēāļāļāđāļāļĄāļđāļĨāļāļēāļĢāđāļāļĢāļāđāļāļāđāļĨāļ°āļŠāļĢāđāļēāļāļāļģāļāļāļīāļāļēāļĒāļ āļēāļĐāļēāļāļĢāļĢāļĄāļāļēāļāļĩāđāļĄāļĩāļāļģāđāļāļ°āļāļģāļāļĩāđāļŠāļēāļĄāļēāļĢāļāļāļģāđāļāļīāļāļāļēāļĢāđāļāđāđāļāļĒāļāļĢāļāļāļēāļāļāđāļāļĄāļđāļĨāļāļēāļĢāđāļāļĢāļāđāļāļ

āļāļēāļĢāđāļāđāļāļāļĢāļ°āļāļ§āļāļāļēāļĢ
āļŠāļīāđāļāļāļĩāđāļāļąāļāđāļāļ āļāļĢāļ°āļāļ§āļāļāļēāļĢāļŦāļĨāļąāļāđāļĨāļ°āļāļāļāļēāļ DataLoader 4 āļāļāļāļāļāļĄāļąāļāļāļĢāļēāļāļāđāļāđāļāļŦāļāđāļ§āļĒāļāļĩāđāđāļĒāļāļāļēāļāļāļąāļ:
āļāļĢāļ°āļāļ§āļāļāļēāļĢāļŦāļĨāļąāļ:
- cudaMemcpyAsync (āļāļēāļĢāļāđāļēāļĒāđāļāļāļāļēāļāđāļŪāļŠāļāđāđāļāļĒāļąāļāļāļļāļāļāļĢāļāđ): āļāđāļēāđāļāļĨāļĩāđāļĒ 301ms, āļŠāļđāļāļŠāļļāļ 2.9 āļ§āļīāļāļēāļāļĩ - cudaStreamSync: p99 = 42ms (āļāļāļāļī 25us) - 1,567 context switches, āļāđāļēāđāļāļĨāļĩāđāļĒ 16ms off-CPU, āļāļēāļĢāļŦāļĒāļļāļāļāļąāđāļ§āļāļĢāļēāļ§āļāļĩāđāđāļĒāđāļāļĩāđāļŠāļļāļ 5 āļ§āļīāļāļēāļāļĩ - 799,018 page allocations
DataLoader worker 1: 52,863 context switches, 89,338 page allocations, āļāļēāļĢāļŦāļĒāļļāļāļāļąāđāļ§āļāļĢāļēāļ§āļāļĩāđāđāļĒāđāļāļĩāđāļŠāļļāļ 5s DataLoader worker 2: 50,638 context switches, 83,509 page allocations, āļāļēāļĢāļŦāļĒāļļāļāļāļąāđāļ§āļāļĢāļēāļ§āļāļĩāđāđāļĒāđāļāļĩāđāļŠāļļāļ 5s DataLoader worker 3: 49,361 context switches, 70,035 page allocations, āļāļēāļĢāļŦāļĒāļļāļāļāļąāđāļ§āļāļĢāļēāļ§āļāļĩāđāđāļĒāđāļāļĩāđāļŠāļļāļ 5s DataLoader worker 4: 38,862 context switches, 56,354 page allocations, āļāļēāļĢāļŦāļĒāļļāļāļāļąāđāļ§āļāļĢāļēāļ§āļāļĩāđāđāļĒāđāļāļĩāđāļŠāļļāļ 5s
āļāļąāđāļāļŦāļĄāļāļāļąāđāļ§āļāļāļāļēāļ: ~191,000 context switches āđāļĨāļ° ~299,000 page allocations āđāļ 40 āļ§āļīāļāļēāļāļĩ
āļŠāļīāđāļāļāļĩāđāļŦāļĄāļēāļĒāļāļķāļ
āļāļāļāļēāļ DataLoader āļāļģāļŠāļīāđāļāļāļĩāđāļĄāļĩāļāđāļēāđāļāđāļāđāļēāļĒāļŠāļđāļāļŠāļēāļĄāļŠāļīāđāļāļāļĩāđāļāļēāļĢāļāđāļēāļāļāļīāļāđāļāļĒāļāļĢāļāļŦāļĨāļĩāļāđāļĨāļĩāđāļĒāļ:
- āļāļēāļĢāđāļāđāļēāļāļķāļāđāļāļāļŠāļļāđāļĄāđāļĨāļ°āļāļąāļāļāļĩ: DataLoader āļāļĩāđāļĄāļĩ shuffle=True āļŠāļĢāđāļēāļāļāļēāļĢāđāļĢāļĩāļĒāļāļŠāļąāļāđāļāļĨāļĩāđāļĒāļāđāļāļāļŠāļļāđāļĄāļāļāļāļāļąāļāļāļĩ āļāļēāļāļāļąāđāļāļāļāļāļēāļāđāļāđāļĨāļ°āļāļāđāļĨāļ·āļāļāļāļīāđāļāļŠāđāļ§āļāļāļāļāļĄāļąāļ āļāļķāđāļāļāđāļāļāđāļāđāļēāļāļķāļāļŦāļāđāļ§āļĒāļāļ§āļēāļĄāļāļģāđāļāļāļŠāļļāđāļĄāļāļąāđāļ§āļāļąāđāļāđāļāļāđāļāļāļĢāđ 7 āļĨāđāļēāļāļāļąāļ§āļāļĒāđāļēāļ â āļāļķāđāļāđāļĄāđāļāļĩāļŠāļģāļŦāļĢāļąāļāļāļēāļĢāļāļąāļāđāļāđāļāđāļāđāļāļāđāļĨāļ°āļāļģāđāļŦāđāđāļāļīāļ page faults
- āļāļēāļĢāļĢāļ§āļāļĢāļ§āļĄāđāļĨāļ°āļāļąāļāļĨāļāļ: āļāļāļāļēāļāđāļāđāļĨāļ°āļāļāļĢāļ§āļāļĢāļ§āļĄāļāļąāļ§āļāļĒāđāļēāļāļāļĩāđāļāļĢāļ°āļāļēāļĒāļāļĒāļđāđāđāļāđāļēāļāđāļ§āļĒāļāļąāļāđāļāđāļāđāļāļāđāļāļāļĢāđāđāļāļāļāđāļāļĩāđāļāđāļāđāļāļ·āđāļāļāļāļąāļ āļāļķāđāļāļŦāļĄāļēāļĒāļāļķāļāļāļēāļĢāļāļąāļāļŠāļĢāļĢāļŦāļāđāļ§āļĒāļāļ§āļēāļĄāļāļģāđāļŦāļĄāđ (page allocations), āļāļąāļāļĨāļāļāļāđāļāļĄāļđāļĨāļāļēāļāļāļģāđāļŦāļāđāļāđāļāļāļŠāļļāđāļĄ (cache misses) āđāļĨāļ°āļāļēāļĢāļāļāļļāļāļĢāļĄāļāđāļāļĄāļđāļĨāļāļĨāļąāļāđāļāļĒāļąāļāļāļĢāļ°āļāļ§āļāļāļēāļĢāļŦāļĨāļąāļāļāđāļēāļāļŦāļāđāļ§āļĒāļāļ§āļēāļĄāļāļģāļĢāđāļ§āļĄāļŦāļĢāļ·āļāļāļīāļ§
- āļāļēāļĢāđāļāđāļāļāļąāļāļŠāļģāļŦāļĢāļąāļ CPU: āļāļāļāļēāļ 4 āļāļ + āļāļĢāļ°āļāļ§āļāļāļēāļĢāļŦāļĨāļąāļāļāļāđāļāļĢāļ·āđāļāļ 4-vCPU āļŦāļĄāļēāļĒāļāļķāļāļāļēāļĢāļāļĢāļĩāđāļāļĄāļāđāļāđāļāļāļāđāļāđāļāļ·āđāļāļ āļāļāļāļēāļāđāļāđāļĨāļ°āļāļāļāļđāļāļāļĢāļĩāđāļāļĄāļāđāļ 50,000 āļāļĢāļąāđāļ āļāļēāļĢāļŦāļĒāļļāļāļāļąāđāļ§āļāļĢāļēāļ§āļāļĩāđāđāļĒāđāļāļĩāđāļŠāļļāļāļāļ·āļ 5 āļ§āļīāļāļēāļāļĩ â āđāļāļāđāļ§āļāđāļ§āļĨāļēāļāļąāđāļ GPU āđāļĄāđāļĄāļĩāļāļ°āđāļĢāļāļĩāđāļāļ°āļāļĢāļ°āļĄāļ§āļĨāļāļĨ
āļāļēāļĢāļāđāļēāļāļāļīāļāđāļāļĒāļāļĢāļ: X[i:i+batch_size] āđāļāđāļāļĄāļļāļĄāļĄāļāļāļāļĩāđāđāļĄāđāļĄāļĩāļāļēāļĢāļāļąāļāļĨāļāļāļāļāļāđāļāļāđāļāļāļĢāđāļāļĩāđāļāđāļāđāļāļ·āđāļāļāļāļąāļāļāļĒāļđāđāđāļĨāđāļ§āđāļāļŦāļāđāļ§āļĒāļāļ§āļēāļĄāļāļģ .to(device)č§ļåāļāļēāļĢāļāđāļēāļĒāđāļāļ DMA āļāļēāļāļ āļđāļĄāļīāļ āļēāļāļāļĩāđāļāđāļāđāļāļ·āđāļāļāļāļąāļāđāļāļĩāļĒāļāļāļĢāļąāđāļāđāļāļĩāļĒāļ§ āđāļĄāđāļĄāļĩāļāļāļāļēāļ, āđāļĄāđāļĄāļĩāļāļēāļĢāļŠāļļāđāļĄ, āđāļĄāđāļĄāļĩāļāļēāļĢāļĢāļ§āļāļĢāļ§āļĄ, āđāļĄāđāļĄāļĩāļāļēāļĢāļāļąāļāļĨāļāļāļāđāļēāļĄāļāļĢāļ°āļāļ§āļāļāļēāļĢ, āđāļĄāđāļĄāļĩāļāļēāļĢāđāļāļĨāļĩāđāļĒāļāļāļĢāļīāļāļ āđāļĄāđāļĄāļĩāļāļēāļĢāļŦāļĒāļļāļāļāļąāđāļ§āļāļĢāļēāļ§ GPU āđāļāđāļĢāļąāļāļāđāļāļĄāļđāļĨāđāļāđāļĄāđāļāļĢāļ§āļīāļāļēāļāļĩ āđāļĄāđāđāļāđāļŦāļĨāļēāļĒāļĢāđāļāļĒāļĄāļīāļĨāļĨāļīāļ§āļīāļāļēāļāļĩ
āļāļēāļĢāđāļāđāđāļ
āļŠāļģāļŦāļĢāļąāļāļāļēāļāđāļāļŦāļāđāļ§āļĒāļāļ§āļēāļĄāļāļģ GPU āļāļĩāđāļāļąāđāļāđāļāļāļāđāļāļĄāļđāļĨāļŠāļēāļĄāļēāļĢāļāđāļŠāđāđāļ RAM:
- āđāļĄāđāđāļāđ DataLoader. āļāļēāļĢāļāđāļēāļāļāļīāļāđāļāļĒāļāļĢāļāļāđāļ§āļĒāļāļēāļĢāđāđāļĢāļĒāđāļāļąāļāļāļĩāļāļĩāđāļŠāļļāđāļĄāļĨāđāļ§āļāļŦāļāđāļēāđāļāđāļāļ§āļīāļāļĩāļāļĩāđāļāđāļēāļĒāļāļ§āđāļēāđāļĨāļ°āđāļĢāđāļ§āļāļ§āđāļē 100 āđāļāđāļē:
indices = torch.randperm(num_samples) for i in range(0, num_samples, batch_size): batch = X[indices[i:i+batch_size]].to(device) output = model(batch)
- āļŦāļēāļāļāļļāļāļāđāļāļāđāļāđ DataLoader, āļāļąāļāļāļđāđ num_workers āļāļąāļāđāļāļ CPU āļāļĢāļīāļāļāļāļāļāļļāļāļĨāļ 1 āļāļāđāļāļĢāļ·āđāļāļ 4-āđāļāļ āļāļąāļāļāļđāđ num_workers=2 āđāļāļ·āđāļāļĨāļāļāļēāļĢāļāļąāļāđāļĒāđāļāļāļąāļ āđāļāļīāđāļĄ persistent_workers=True āđāļāļ·āđāļāļŦāļĨāļĩāļāđāļĨāļĩāđāļĒāļāļāļēāļĢāļŠāļĢāđāļēāļāļāļĢāļ°āļāļ§āļāļāļēāļĢāđāļŦāļĄāđ
- āļŠāļģāļŦāļĢāļąāļāđāļāļāļāđāļāļĄāļđāļĨāļāļĩāđāđāļŦāļāđāļāļ§āđāļēāļŦāļāđāļ§āļĒāļāļ§āļēāļĄāļāļģ āļāļĩāđāļāđāļāļāđāļāđ DataLoader āļāļļāļāļāļļāļāļāļąāļāļāļĢāļīāļāđ āļāļ·āļ I/O āļāļīāļŠāļāđ āđāļāđ prefetch_factor=2 (āđāļĄāđāđāļāđāļĄāļēāļāļāļ§āđāļēāļāļąāđāļ â āļāļēāļĢāļāļĢāļĩāđāļāļāļāļīāđāļāļāļĩāđāļĄāļēāļāļāļķāđāļāļŦāļĄāļēāļĒāļāļķāļāļāļ§āļēāļĄāļāļāļāļąāļāļŦāļāđāļ§āļĒāļāļ§āļēāļĄāļāļģāļāļĩāđāļĄāļēāļāļāļķāđāļ) āđāļĨāļ°āļāļĢāļ§āļāļŠāļāļāđāļŦāđāđāļāđāđāļāļ§āđāļēāļĢāļ°āļāļāļāļąāļāđāļāđāļāļāđāļāļĄāļđāļĨāļāļāļāļāļļāļāļŠāļēāļĄāļēāļĢāļāļĢāļāļāļĢāļąāļāđāļāđ
āļ āļēāļāļĢāļ§āļĄāļāļĩāđāđāļŦāļāđāļāļ§āđāļē
āļāļēāļĢāļŠāļāļāļŠāļ§āļāļāļĩāđāđāļŠāļāļāļĢāļđāļāđāļāļāļāļĩāđāđāļĢāļēāđāļŦāđāļāļāđāļāļĒāđ āđāļāļāļēāļ GPU: GPU āđāļĢāđāļ§, āđāļŪāļŠāļāđāļāđāļē, āđāļĨāļ°āđāļĄāļāļĢāļīāļ GPU āđāļĄāđāļŠāļēāļĄāļēāļĢāļāļĄāļāļāđāļŦāđāļāđāļāđ nvidia-smi āļĢāļēāļĒāļāļēāļāļāļēāļĢāđāļāđāļāļēāļāļāđāļģ āđāļāđāđāļĄāđāļŠāļēāļĄāļēāļĢāļāļāļāļīāļāļēāļĒāđāļāđāļ§āđāļēāļāļģāđāļĄ
āļ§āļīāļāļĩāđāļāļĩāļĒāļ§āļāļĩāđāļāļ°āđāļŦāđāļāļ āļēāļāļāļĩāđāļŠāļĄāļāļđāļĢāļāđāļāļ·āļāļāļīāļāļāļēāļĄāļāļąāđāļāļŠāļāļāļāđāļēāļāļāļĢāđāļāļĄāļāļąāļ â āļāļēāļĢāđāļĢāļĩāļĒāļ API CUDA āđāļĨāļ°āđāļŦāļāļļāļāļēāļĢāļāđāđāļāļāļĢāđāđāļāļĨ Linux â āđāļĨāļ°āļŠāļāļāļāļĨāđāļāļāļāļąāļāđāļāļĒāđāļ§āļĨāļēāđāļĨāļ° ID āļāļĢāļ°āļāļ§āļāļāļēāļĢ āđāļāđāļŠāļēāđāļŦāļāļļ âCPU 100% -> 1,880 sched_switch -> cudaMemcpyAsync 301ms -> cudaStreamSync 42msâ āđāļĨāđāļēāđāļĢāļ·āđāļāļāļĢāļēāļ§āļāļĩāđāļŠāļĄāļāļđāļĢāļāđāđāļāļŦāļāļķāđāļāļāļĢāļĢāļāļąāļ āļŦāļēāļāđāļĄāđāļĄāļĩāļāļēāļĢāđāļāļĢāļāđāļāļāļāļĩāđāļāļĢāļāļāļāļĨāļļāļĄ āļŠāļīāđāļāļāļĩāđāļāļ°āļĒāļąāļāļāļāđāļāđāļāļāļĢāļīāļĻāļāļē â āđāļāđāļāđāļāļĩāļĒāļ§āļāļąāļāļāļĩāđāļāļđāđāļĢāļēāļĒāļāļēāļāđāļāļīāļĄāļāļĩāđāđāļāđāđāļ§āļĨāļēāļŦāļĨāļēāļĒāļŠāļąāļāļāļēāļŦāđāđāļāļāļēāļĢāđāļāđāļāļąāļāļŦāļē
āļĢāļđāļāļāļĩāđ 2: āđāļĄāļ·āđāļāļāļēāļĄ âāļŠāļēāđāļŦāļāļļāļŦāļĨāļąāļāļāļ·āļāļāļ°āđāļĢ?â āļĄāļāļāļđāļĨāļĢāļ°āļāļļāļ§āđāļē CPU āļĄāļĩāļāļēāļĢāļāļąāļāļŠāļĢāļĢāļĄāļēāļāđāļāļīāļāđāļāļāļģāđāļŦāđāđāļāļīāļāļāļ§āļēāļĄāļĨāđāļēāļāđāļēāđāļāļāļēāļĢāļāļąāļāļāļēāļĢāļēāļāļāļēāļĢāļāļģāļāļēāļāļāļāļāđāļŪāļŠāļāđ cudaLaunchKernel āļĨāđāļēāļāđāļēāļāļēāļ 73us āđāļāđāļāđāļ 25.8ms (356 āđāļāđāļē)

āļĨāļāļāļāđāļ§āļĒāļāļąāļ§āđāļāļ
āļāļģāļāđāļģāļāļēāļĢāļ§āļąāļāļāļĢāļ°āļŠāļīāļāļāļīāļ āļēāļ:
import torch, time from torch.utils.data import DataLoaderX = torch.randn(7_000_000, 100) model = torch.nn.Sequential( torch.nn.Linear(100, 512), torch.nn.ReLU(), torch.nn.Linear(512, 512), torch.nn.ReLU(), torch.nn.Linear(512, 10) ).cuda()
# Fast path start = time.time() with torch.no_grad(): for i in range(0, len(X), 1_048_576): model(X[i:i+1_048_576].cuda()) torch.cuda.synchronize() print(f'Direct: {time.time()-start:.3f}s')
# Slow path loader = DataLoader(X, batch_size=1_048_576, shuffle=True) start = time.time() with torch.no_grad(): for batch in loader: model(batch.cuda()) torch.cuda.synchronize() print(f'DataLoader: {time.time()-start:.3f}s')
āļāļīāļāļāļēāļĄāļāđāļ§āļĒ Ingero āđāļāļ·āđāļāļāļđāļŠāļīāđāļāļāļĩāđāđāļāļīāļāļāļķāđāļāđāļāļ·āđāļāļāļŦāļĨāļąāļ:
git clone https://github.com/ingero-io/ingero.git cd ingero && make build sudo ./bin/ingero trace --duration 60s # in one terminal python3 benchmark.py # in another terminal ./bin/ingero explain --since 60s # after benchmark completes
āļŦāļĢāļ·āļāđāļĨāļĩāđāļĒāļāļāļēāļĢāļāļģāļāđāļģāđāļĨāļ°āļŠāļģāļĢāļ§āļāļāļēāļāļāđāļāļĄāļđāļĨāļāļēāļĢāđāļāļĢāļāđāļāļāļāļāļāđāļĢāļēāđāļāļĒāļāļĢāļ āļāļēāļāļāđāļāļĄāļđāļĨāļāļēāļĢāļŠāļāļāļŠāļ§āļ (764KB) āļāļĒāļđāđāđāļäŧåšŦ:
# View causal chains from the investigation ./bin/ingero explain --db investigations/pytorch-dataloader-starvation.db --since 5m# Per-process breakdown (see DataLoader workers vs main process) ./bin/ingero explain --db investigations/pytorch-dataloader-starvation.db --per-process --since 5m
# Connect your AI assistant for interactive investigation ./bin/ingero mcp --db investigations/pytorch-dataloader-starvation.db
āļŠāļ·āļāļāđāļāļāđāļ§āļĒ AI (āđāļāļ°āļāļģ). āļ§āļīāļāļĩāļāļĩāđāđāļĢāđāļ§āļāļĩāđāļŠāļļāļāđāļāļāļēāļĢāļ§āļīāđāļāļĢāļēāļ°āļŦāđāļāļēāļĢāđāļāļĢāļāđāļāļāļāļ·āļāļāļēāļĢāđāļāļ·āđāļāļĄāļāđāļ AI āļāļĩāđāļĢāļāļāļĢāļąāļ MCP āđāļāđ āļāļąāļāļāļēāļāļāđāļāļĄāļđāļĨāđāļāļĒāļāļĢāļ āđāļĄāđāļāđāļāļāļĄāļĩāļāļēāļĢāļ§āļīāđāļāļĢāļēāļ°āļŦāđāđāļāļāļĄāļ·āļ
āļŠāļĢāđāļēāļāđāļāļĨāđāļāļāļāļāļīāļ:
cat > /tmp/ingero-mcp-dataloader.json << 'EOF'
{
"mcpServers": {
"ingero": {
"command": "./bin/ingero",
"args": ["mcp", "--db", "investigations/pytorch-dataloader-starvation.db"]
}
}
}
EOF
āļāļēāļāļāļąāđāļāđāļāļ·āđāļāļĄāļāđāļāļĄāļāļāļđāļĨāļāļāļāļāļļāļ:
# With Ollama + MiniMax (what we used in the video) ollmcp -m minimax-m2.7:cloud -j /tmp/ingero-mcp-dataloader.json# With Claude Code claude --mcp-config /tmp/ingero-mcp-dataloader.json
# With any MCP-compatible client # Add the config above to your AI's MCP settings
āļāļīāļĄāļāđ /investigate āđāļāļ·āđāļāļāļĢāļ°āļāļļāđāļāļāļēāļĢāļ§āļīāđāļāļĢāļēāļ°āļŦāđāļāļĩāđāļĄāļĩāļāļģāđāļāļ°āļāļģ āļŦāļĢāļ·āļāļāļēāļĄāļāļģāļāļēāļĄāđāļāđ: âāļŠāļēāđāļŦāļāļļāļāļāļāļāļēāļĢāļāļēāļāđāļāļĨāļ GPU āļāļ·āļāļāļ°āđāļĢ?â AI āļĄāļĩāđāļāļĢāļ·āđāļāļāļĄāļ·āļ 7 āļāļīāđāļāļāļĩāđāļŠāļ·āļāļāđāļāļāļēāļāļāđāļāļĄāļđāļĨāļāļēāļĢāđāļāļĢāļāđāļāļāđāļāļĒāļāļĢāļ
GitHub: github.com/ingero-io/ingero
āļāļąāļāļŦāļēāđāļāļīāļĄ: pytorch/pytorch#154318
āļ§āļīāļāļĩāđāļāļāļąāļ§āļĢāđ: https://asciinema.org/a/RGwhPeXAPJdhXqxp
āļāļēāļĢāļŠāļāļāļŠāļ§āļāļāļĩāđāļāļģāļāļ TensorDock RTX 4090 (24GB), Ubuntu 22.04, PyTorch 2.10.0+cu128.













