DeePMD-kit Performance Optimization#
Overview#
DeePMD-kit exposes three independent levels of parallelism, each controlled by separate environment variables. Correct tuning requires the product of parallel-process counts not to exceed available CPU cores . Performance work splits into two concerns: (1) CPU/GPU thread tuning for single-node inference and training, and (2) multi-GPU / multi-node distributed training.
Thread-Level Parallelism (CPU)#
The full reference for all runtime environment variables is at env.html .
| Variable | Alias | Default | Controls |
|---|---|---|---|
DP_INTER_OP_PARALLELISM_THREADS | TF_INTER_OP_PARALLELISM_THREADS | 0 (auto) | Parallelism between independent operators (TF/Eigen, PyTorch — CPU only) |
DP_INTRA_OP_PARALLELISM_THREADS | TF_INTRA_OP_PARALLELISM_THREADS | 0 (auto) | Parallelism within individual operators (TF/Eigen, PyTorch — CPU only) |
OMP_NUM_THREADS | — | system default | OpenMP threads for TF/OneDNN, PyTorch/OpenMP, DeePMD-kit custom CPU OPs, and NumPy |
OMP_NUM_THREADS is the broadest lever: it controls DeePMD-kit's custom CPU kernels, the OneDNN path in TensorFlow, and the OpenMP path in PyTorch. GPU users should still set it because some DeePMD-kit OPs lack GPU implementations .
DP_INTER_OP_PARALLELISM_THREADS (inter-op) manages multiple CPU streams running independent operators concurrently. For GPU devices, TensorFlow and PyTorch use only one compute stream, so inter-op threads matter mainly for CPU-only workloads .
Additional OpenMP knobs such as KMP_BLOCKTIME can help; see Intel TF performance guide (TF) or PyTorch tuning recipes (PyTorch) .
Empirical Starting Points#
For 3 cores across 2 CPUs on one node, set OMP_NUM_THREADS=3 and DP_INTRA_OP_PARALLELISM_THREADS=3 with DP_INTER_OP_PARALLELISM_THREADS=1 .
For a 128-core node, a good starting point is:
OMP_NUM_THREADS=16
DP_INTRA_OP_PARALLELISM_THREADS=16
DP_INTER_OP_PARALLELISM_THREADS=8 # 16 × 8 = 128
No single configuration is universally optimal — empirical testing is expected .
Other Performance-Relevant Variables#
| Variable | Default | Scope | Purpose |
|---|---|---|---|
DP_INFER_BATCH_SIZE | 1024 (CPU) / max possible (GPU) | Python | Frames × atoms batch size for inference |
NUM_WORKERS | min(4, ncpus) | Python / PyTorch | Subprocess count for DataLoader |
DP_AUTO_PARALLELIZATION | 0 | Python / TF | Auto-parallelization for CPU OPs |
DP_JIT | 0 | Python / TF | JIT compilation (may help or hurt) |
CUDA_VISIBLE_DEVICES | — | All | Restrict visible GPU cards |
Multi-GPU / Multi-Node Parallel Training#
Parallel training uses data parallelism: each worker sees a different mini-batch; per-batch training time does not decrease, but throughput scales. See Parallel training docs .
TensorFlow — Horovod#
Install Horovod and MPI4py, then launch with horovodrun :
horovodrun -np 4 dp train input.json
Each process binds to one GPU via CUDA_VISIBLE_DEVICES. DeePMD-kit auto-detects the MPI context and switches to distributed mode (visible in the log as world size > 1, distributed) .
Learning rate scaling: With N workers the effective batch size is N × batch_size. The learning rate is automatically scaled by N (linear mode); alternatives sqrt and none are available via scale_by_worker .
Observed speedups on 8 GPUs (se_e2_a, water example): 6.72× throughput with 8 GPUs vs. single GPU .
PyTorch — torchrun / DDP#
Uses PyTorch DistributedDataParallel (DDP) :
# Single node, 4 GPUs
torchrun --nproc_per_node=4 dp train input.json
For multi-node, set --nnodes, --node_rank, and --rdzv_endpoint .
ZeRO memory optimization is supported in the PyTorch backend via the zero_stage input config key :
| Stage | Strategy | Memory Saving |
|---|---|---|
| 0 (default) | Standard DDP | None |
| 1 | DDP + ZeRO-1 | Optimizer states / N |
| 2 | FSDP2 SHARD_GRAD_OP | Gradients + optimizer states / N |
| 3 | FSDP2 FULL_SHARD | Parameters + gradients + optimizer states / N |
Stage 3 incurs 50% more communication (3Ψ vs. 2Ψ); use it only when lower stages still exhaust GPU memory. Stage 2 can slow down models with many small layers — mitigate with torch.compile .
NUM_WORKERS (default: min(8, ncpus)) controls the DataLoader subprocess count in the PyTorch backend .
Paddle — paddle.distributed.fleet#
Use CUDA_VISIBLE_DEVICES and paddle.distributed.launch or mpirun. Multi-node setup follows the same nnodes/node_rank pattern as torchrun .
Inference Parallelism#
MPI is not directly supported for inference in DeePMD-kit; instead, third-party tools like LAMMPS handle distributed MD via their own MPI layer . Set CUDA_VISIBLE_DEVICES and thread variables as described above for single-process GPU inference.