Theme
How to Choose Frameworks and Tools
One-sentence definition: a deep learning framework is a three-way trade-off among "research velocity × engineering efficiency × ecosystem compatibility." There is no absolute best — only the option that best matches your task, team, and infrastructure.
This article first compares the three mainstream frameworks side by side, then surveys training infrastructure, inference frameworks, and ecosystem tools vertically, and ends with a decision tree. For onboarding paths, see Learning Paths: Three Routes; this article assumes you already understand the basic training workflow (see Build Your Own DL Project).
The Big Three: Side-by-Side Comparison
| Dimension | PyTorch | JAX | TensorFlow / Keras |
|---|---|---|---|
| Graph paradigm | Dynamic graph (eager), with torch.compile for compilation | Functional pure transformations (jit compiled to XLA) | Static graph by default; Keras provides "eager-like" interfaces |
| Usability | ★★★★★ intuitive, easy to debug | ★★★ functional + pure functions, steep learning curve | ★★★ was chaotic early on, improved in 2.x |
| Debugging | print/breakpoints/pdb work directly | Hard to print intermediates (need jax.debug hooks) | tf.debugging tools; more user-friendly under Keras |
| Performance | Good; torch.compile/inductor further optimize | Strong (XLA compilation, jit, pmap/shard_map for large-scale parallelism) | Strong; mature deployment pipelines |
| Distributed training | DDP/FSDP are mature, native in PyTorch 2 | pmap/pjit/shard_map offer lower-level, more flexible abstractions | tf.distribute has a complete ecosystem |
| Ecosystem | De facto standard in research; full HuggingFace support | Google + DeepMind research, TPU, scaling law studies | Industrial legacy, Keras for rapid prototyping, mobile |
| Community / hiring | Currently the most mainstream | Growing fast | Largest stock base but slowing growth |
One-line summary: Research, paper reproduction, HuggingFace ecosystem → PyTorch. Large-scale parallelism / TPU / functional scientific computing / scaling law research → JAX. Existing TF codebases / rapid prototyping / cross-platform deployment (mobile) → TensorFlow/Keras.
A pragmatic note
Fewer and fewer new projects use TensorFlow nowadays, but TF codebases remain widespread in companies. Being able to read TF code is still a plus for interviews and work (see JD Checklist), but prioritize PyTorch or JAX for new projects.
Training Infrastructure: From Single-GPU to Multi-GPU
1. Single-GPU
The starting point for everything. Get three things right: VRAM management (mixed precision, gradient accumulation — see Training Recipes and Hyperparameter Tuning), device-agnostic code (device = "cuda" if torch.cuda.is_available() else "cpu"), and monitoring (nvidia-smi, W&B/TensorBoard).
2. Multi-GPU: DDP and FSDP
| Approach | Use case | Mechanism | Scale |
|---|---|---|---|
| DataParallel (deprecated) | Entry-level single-machine multi-GPU | Model replicated per GPU per batch, gradients synced to primary GPU | <4 GPUs |
| DistributedDataParallel (DDP) | Standard single-machine / multi-machine multi-GPU | One model replica per process, gradient all-reduce sync | 8–64 GPUs |
| FullyShardedDataParallel (FSDP) | Large models (fine-tuning / pre-training) | Parameters, gradients, and optimizer states sharded across GPUs | Models that don't fit on a single GPU |
| Tensor / Pipeline Parallelism | Extra-large scale | Split within a layer / split layers pipeline-style | >64 GPUs, 10B+ params |
Minimal PyTorch DDP example:
python
import torch.distributed as dist
from torch.nn.parallel import DistributedDataParallel as DDP
def init(rank, world_size):
dist.init_process_group("nccl", rank=rank, world_size=world_size)
torch.cuda.set_device(rank)
model = DDP(YourModel().to(rank))
return model
if __name__ == "__main__":
import torch.multiprocessing as mp
mp.spawn(init, args=(torch.cuda.device_count(),), nprocs=torch.cuda.device_count())Launch command: torchrun --nproc_per_node=4 train.py.
Key FSDP experience: choosing sharding_strategy, the overhead of CPU offload, and the VRAM gains when combined with mixed precision and gradient checkpointing. FSDP is one of the default pairings for HuggingFace large model fine-tuning (LoRA, etc.).
3. Cloud Platforms and Experiment Management
- GPU clouds: Rent GPUs by the hour for experiments (various cloud providers' GPU instances); manage training jobs with
accelerate/torchrun. - Experiment tracking: W&B, Neptune, MLflow for logging metrics and configs; start locally with TensorBoard +
config.yaml(see DL Design Principles). - Scaled training: Kubernetes + job orchestration falls under MLOps; see MLOps and Model Deployment.
Inference Frameworks: Turning Models into Products
Once training is done, deploying a model uses an entirely different set of tools than training:
| Framework | Positioning | Characteristics | Use case |
|---|---|---|---|
| ONNX Runtime | Cross-framework interoperability standard | Export ONNX from PyTorch/TF, runs on CPU/GPU | Moderate requirements, strongest compatibility |
| TensorRT | NVIDIA GPU only | Layer fusion, quantization (FP16/INT8), lowest latency | High-throughput GPU inference |
| OpenVINO | Intel hardware | Optimized for CPU/GPU/NPU | Edge devices with Intel hardware |
| TVM / Apache TVM | Compiled inference stack | Auto-tuning (AutoTVM), multi-hardware backends | Heterogeneous hardware, custom operators |
| vLLM | LLM-specific inference engine | PagedAttention, continuous batching, high throughput | Self-hosted large model inference |
Selection logic:
- General models: PyTorch → export ONNX → ONNX Runtime, lowest cost.
- Maximum performance (single GPU): convert to TensorRT, typically 2–5× speedup with lower latency.
- Large language model serving: use vLLM or TGI directly, don't write your own inference scripts (KV cache, batching strategies in Large Language Models (LLM)).
- Edge devices: consider quantized models (INT8) from TensorRT/OpenVINO, or use TFLite directly if going the TF route.
bash
# Minimal ONNX export example
torch.onnx.export(model, dummy_input, "model.onnx",
input_names=["input"], output_names=["output"],
dynamic_axes={"input": {0: "batch"}, "output": {0: "batch"}})HuggingFace Ecosystem: The "Standard Library" of Modern Deep Learning
HuggingFace (HF) has become the de facto standard distribution channel for models, datasets, and tools. Four core libraries:
| Library | Purpose | Typical usage |
|---|---|---|
transformers | Unified interface for pre-trained models | Load/fine-tune BERT, GPT, ViT, Whisper, etc. |
datasets | Unified dataset loading and processing | Streaming large datasets, map preprocessing, multi-process caching |
diffusers | Diffusion model toolkit | Text-to-image, LoRA fine-tuning of Stable Diffusion (see Diffusion Models and Generative AI) |
peft | Parameter-efficient fine-tuning | LoRA/QLoRA fine-tuning, fine-tune a 7B model on a consumer GPU |
python
from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import LoraConfig, get_peft_model
model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.1-8B")
lora = LoraConfig(r=8, lora_alpha=16, task_type="CAUSAL_LM")
model = get_peft_model(model, lora) # Only train LoRA params, trainable params drop dramatically
# datasets example: stream read and batch preprocess
from datasets import load_dataset
ds = load_dataset("imdb", split="train").select(range(1000))Why invest in the HF ecosystem: it compresses "download model/data, fine-tune, evaluate, publish" into a unified API, serving as an accelerator for research reproduction, competitions, and portfolio projects; peft makes fine-tuning large models feasible on consumer-grade GPUs (see Portfolio Projects). More resources at Curated Resource List.
Decision Tree: How Do I Choose?
Follow a path based on your scenario:
What is your primary goal?
├─ Learning DL / reproducing papers / doing research
│ └─ PyTorch (boosted by HF ecosystem) ──────────→ PyTorch + transformers
├─ Large-scale pre-training / scientific computing / TPU
│ └─ JAX (functional, XLA, pmap) ────────────────→ JAX
├─ Company legacy systems / mobile deployment / Keras rapid prototyping
│ └─ TensorFlow/Keras ───────────────────────────→ TF2 + TFLite
└─ Deploying an existing model
├─ General serving → ONNX Runtime
├─ Max GPU performance → TensorRT
├─ LLM serving → vLLM
└─ Edge devices → OpenVINO / TFLite
Training scale?
├─ Fits on one GPU → mixed precision + gradient accumulation (no distributed training)
├─ Single-machine multi-GPU → DDP
└─ Doesn't fit on one GPU → FSDP / LoRA (HF peft) → distributed training if necessaryCombination example: a typical 2026 personal project stack = PyTorch + HuggingFace (transformers/datasets/peft) + ONNX Runtime (deployment) + W&B or TensorBoard (tracking), adding DDP/FSDP for multi-GPU.
Trade-offs and Boundaries
Frameworks are not eternal. Three reminders:
- Don't treat a framework as dogma. PyTorch was once the poster child for "dynamic graphs," but
torch.compilenow brings static optimization capabilities too; JAX also provides more eager-mode debugging tools — the boundaries are constantly shifting. - Switching frameworks is expensive. The ecosystem lock-in that projects and teams accumulate (model libraries, operators, toolchains) far exceeds "just rewrite the training loop." Don't switch unless there's a hard payoff (performance, deployment, team skills).
- Framework wars are less important than toolchain wars. What actually affects your output is whether ecosystem tools — HF, W&B, vLLM — have the best support on your chosen framework. Before picking a framework, verify that the ecosystem toolchain you need is well-supported.
Further Reading
- Learning Paths: Three Routes — pick a tech stack aligned with your career direction
- MLOps and Model Deployment — the complete path from model to product
- Build Your Own DL Project — carrier for the minimal PyTorch project
- Large Language Models (LLM) — model knowledge behind vLLM/peft
- Curated Resource List — official tutorial indexes for each framework
- JD Checklist — see which frameworks target roles actually require
References
- PyTorch. Distributed data parallel — official DDP documentation
- JAX. JAX: Autograd and XLA — official JAX documentation
- Hugging Face. Transformers Documentation — official HF ecosystem documentation
- ONNX Runtime. Official Documentation — cross-framework inference standard