- Posted on
- • Artificial Intelligence
Artificial Intelligence Performance Monitoring
- Author
-
-
- User
- linuxbash
- Posts by this author
- Posts by this author
-
Artificial Intelligence Performance Monitoring on Linux: From Guesswork to Measurable Gains
AI workloads are expensive, opaque, and unforgiving. One minute your GPU looks idle, the next it’s thermal-throttling while your training loop crawls. If you can’t see what’s happening in real time, you can’t fix it. This post shows you how to monitor AI performance on Linux using battle-tested command-line tools and a bit of Bash, so you can find bottlenecks, prove improvements, and stop wasting GPU hours.
What you’ll get:
A practical, Linux-first toolkit for AI performance monitoring
3–5 actionable steps to baseline, track, and optimize workloads
Real-world examples and scripts you can drop into your workflow
Why AI Performance Monitoring Is Non‑Optional
Bottlenecks hide in plain sight. Underutilized GPUs usually mean CPU, I/O, or data pipeline backpressure.
Cost control. Small utilization gains (e.g., 10–20%) compound to huge cloud savings over long training runs.
Reproducibility. Baseline metrics make performance regressions visible after code/data changes.
Capacity planning. Knowing throughput, latency, and resource headroom helps you scale responsibly.
Install the Toolbox
The tools below let you observe CPU, memory, GPU, disk, and end-to-end performance from the terminal. Install with your distro’s package manager.
Apt (Debian/Ubuntu):
sudo apt update
sudo apt install -y sysstat htop nvtop glances hyperfine jq numactl netdata
DNF (Fedora/RHEL/CentOS Stream):
sudo dnf install -y sysstat htop nvtop glances hyperfine jq numactl netdata
Zypper (openSUSE/SLE):
sudo zypper refresh
sudo zypper install -y sysstat htop nvtop glances hyperfine jq numactl netdata
Notes:
sysstat provides iostat, mpstat, pidstat.
nvtop requires working GPU drivers (NVIDIA: nvidia-smi available).
Optional service: Netdata web UI
sudo systemctl enable --now netdata # Visit http://localhost:19999
Pick the Right AI KPIs
Measure what matters for your workload:
Throughput and latency: images/sec, tokens/sec, QPS, p50/p95 latency.
GPU health: utilization (SM), memory used, memory utilization, power draw, temperature.
CPU pressure: per-process %CPU, run queue length, context switches.
Memory: RSS per process, swap activity (should be zero under load).
I/O: disk util (%util), read/write IOPS and await; network throughput if remote storage.
Data loader and augmentation: time spent waiting for batches vs. compute.
Stability: variance over time (jitter), thermal throttling, OOM/evictions.
Step 1 — Baseline Quickly with One-Liners
Start with live visibility, then capture short windows to CSV or logs.
System and CPU:
htop
mpstat -P ALL 1
pidstat -dlru 1
Disk/IO bottlenecks:
iostat -xz 1
GPU live view (NVIDIA):
nvtop
nvidia-smi dmon -s pucvmt -i 0
# p=power, u=util, c=mem util, v=vid enc/dec, m=mem, t=temperature
Quick throughput/latency benchmarks:
hyperfine -w 3 -r 10 'python infer.py --batch 32' 'python infer.py --batch 64'
Lightweight system dashboard:
glances # interactive TUI
glances -w # web server at http://localhost:61208
Tip: capture a 2–5 minute sample while your workload is steady. You’re hunting for mismatch: high GPU idle time + high CPU or disk utilization usually means input pipeline starvation.
Step 2 — Automate Sampling with a Tiny Bash Logger
Use this drop-in script to log key metrics every second to CSV. It targets one process (PID) and one GPU (index 0 by default).
Save as ai-mon.sh:
#!/usr/bin/env bash
set -euo pipefail
PID="${1:-}" # optional: target process ID (e.g., your python pid)
GPU="${GPU:-0}" # select GPU index
INTERVAL="${INTERVAL:-1}" # seconds
echo "ts,cpu_pct,mem_pct,mem_mb,gpu_util,gpu_mem_mb,gpu_mem_util,power_w"
while true; do
TS=$(date +%s)
if [[ -n "${PID}" ]]; then
# %CPU, %MEM, RSS(KB)
read -r CPU_P MEM_P RSS_KB < <(ps -p "$PID" -o %cpu,%mem,rss --no-headers | awk '{print $1" "$2" "$3}')
[[ -z "${CPU_P:-}" ]] && { echo "Process $PID ended"; exit 0; }
MEM_MB=$((RSS_KB/1024))
else
CPU_P=NA; MEM_P=NA; MEM_MB=NA
fi
# NVIDIA GPU metrics (requires nvidia-smi)
if command -v nvidia-smi >/dev/null 2>&1; then
IFS=, read -r GPU_UTIL GPU_MEM GPU_MEM_UTIL POWER < <(
nvidia-smi --id="$GPU" \
--query-gpu=utilization.gpu,memory.used,utilization.memory,power.draw \
--format=csv,noheader,nounits | sed 's/ //g'
)
else
GPU_UTIL=NA; GPU_MEM=NA; GPU_MEM_UTIL=NA; POWER=NA
fi
echo "$TS,$CPU_P,$MEM_P,$MEM_MB,$GPU_UTIL,$GPU_MEM,$GPU_MEM_UTIL,$POWER"
sleep "$INTERVAL"
done
Usage:
chmod +x ai-mon.sh
# Start your workload, note its PID, then:
./ai-mon.sh <PID> > run.csv
# Or without PID for system-wide GPU logging:
./ai-mon.sh > run.csv
Open run.csv in your favorite tool to visualize. Look for:
GPU underutilized while CPU% or iostat %util is high → CPU/I/O bottleneck.
GPU mem util near 100% with low GPU util → batch size too big or fragmentation.
Power/thermals oscillating → consider power limits or better cooling.
Step 3 — Visualize and Watch Trends
If you prefer a no-config web dashboard:
sudo systemctl enable --now netdata
# http://localhost:19999 shows CPU, memory, disk, network, processes
Glances web mode is an even lighter option:
glances -w
# http://localhost:61208
For GPU specifics, keep a terminal with:
nvidia-smi dmon -s pucvmt -i 0
This combo covers long-running training and batch inference services with minimal setup.
Step 4 — Turn Insights into Speed
Once you see where time goes, apply fixes and validate with hyperfine or your CSV logs.
Data pipeline starvation
- Increase data loader workers and prefetching.
- Pre-decode/resize to reduce per-batch CPU load.
- Keep datasets on local NVMe; watch iostat for queueing.
CPU/GPU affinity and NUMA
numactl --cpunodebind=0 --membind=0 python train.pyPinning reduces cross-socket latency on multi-socket machines.
Mixed precision and larger batches (when memory allows)
- Higher throughput with negligible accuracy loss in many models.
- Validate gains: GPU util should rise, time/batch should fall.
Power and stability on NVIDIA
sudo nvidia-smi -pm 1 # enable persistence mode sudo nvidia-smi -pl <watts> # set safe, stable power limit (know your GPU!)Stable clocks and temps reduce jitter in latency-sensitive inference.
Concurrency tuning
- For services, find the concurrency that saturates GPU without causing queue bloat (monitor p95 latency vs QPS).
Real-World Scenarios
Training throughput boost
- Symptom: GPU util ~40%, CPU ~300% across 64 cores, iostat %util 5%.
- Fix: Increase DataLoader workers from 4 to 16, enable pinned memory, move augmentations to GPU.
- Result: GPU util 85–95%, images/sec +60%.
Inference jitter
- Symptom: p95 latency spikes every few minutes, GPU util steady.
- Fix: Limit power to avoid periodic thermal throttling, isolate CPU cores for the process with taskset/numactl.
- Result: p95 stabilized, tail latency improved by 30–40%.
I/O bottleneck
- Symptom: iostat shows %util ~95% on a single HDD, GPU idle bursts.
- Fix: Stage data on NVMe and use sequential reads, cache hot shards.
- Result: Smooth GPU utilization, run time -25%.
Quick Reference: Useful Commands
System CPU breakdown:
mpstat -P ALL 1 pidstat -dlru 1Disk pressure:
iostat -xz 1GPU streams:
nvidia-smi dmon -s pucvmt -i 0Benchmark variations:
hyperfine -w 3 -r 10 'python train.py --batch 64' 'python train.py --batch 96 --amp'
Conclusion and Next Steps
Most AI slowdowns aren’t on the GPU—they’re between your GPU and your data. With a few Linux tools and a small Bash logger, you can make bottlenecks obvious, apply targeted fixes, and verify real gains.
Your move: 1) Install the toolbox with your package manager. 2) Run a 5-minute baseline using the one-liners and ai-mon.sh. 3) Apply one optimization (data pipeline, batch size, NUMA pinning, or power tuning) and re-measure. 4) Keep the scripts in your repo so every run has a performance paper trail.
If you want a follow-up post on exporting these metrics to a full dashboard stack (e.g., Netdata deep-dive or Prometheus/Grafana), say the word.