Introduction
Loss functions in PyTorch decide what a model chases and, ultimately, what it learns from its data. A 2024 JetBrains developer survey put PyTorch usage at roughly 45 percent of machine learning developers, ahead of every rival framework. That popularity makes the twenty odd built in losses in torch.nn the operational vocabulary of modern deep learning. Pick the wrong loss and your model quietly optimizes for the wrong objective, no warning, no error message. Pick the right loss with the right reduction and the training loop suddenly stabilizes, converges faster, and generalizes to unseen data. This guide covers every major family of loss functions in PyTorch, when to use each one, and how to write custom losses that autograd can still differentiate. It is written for practitioners who need production ready answers and citations, not tutorial snippets pasted from documentation and hoped to work.
Quick Answers on Loss Functions in PyTorch
What are loss functions in PyTorch?
Loss functions in PyTorch are differentiable objects in torch.nn that compute a scalar error between predictions and targets. Autograd then propagates gradients back through the network so an optimizer can update every trainable parameter.
Which loss should I use for classification in PyTorch?
Use torch.nn.CrossEntropyLoss for multi class problems and torch.nn.BCEWithLogitsLoss for binary or multi label problems. Both accept raw logits and fold the softmax or sigmoid into a numerically stable computation for you.
How do I write a custom loss function in PyTorch?
Subclass torch.nn.Module, implement forward using tensor operations, and return a scalar. Autograd handles the backward pass automatically as long as every step stays inside PyTorch tensors and produces a real valued output.
Key Takeaways on Loss Functions in PyTorch
- Loss functions in PyTorch live in torch.nn and torch.nn.functional and cover regression, classification, ranking, segmentation, and contrastive tasks.
- CrossEntropyLoss expects raw logits and applies log softmax internally, so never call softmax before passing predictions into it.
- BCEWithLogitsLoss is numerically more stable than sigmoid plus BCELoss because it uses the log sum exp trick to avoid overflow.
- Custom losses are just tensor operations wrapped in a Module or a function; autograd differentiates them automatically without a manual backward.
- Reduction modes (mean, sum, none) change gradient magnitudes and matter for distributed training, class weighting, and mixed precision.
Table of contents
- Introduction
- Quick Answers on Loss Functions in PyTorch
- Key Takeaways on Loss Functions in PyTorch
- What Loss Functions in PyTorch Actually Do
- How PyTorch Computes and Propagates a Loss
- Regression Loss Functions Available in torch.nn
- Classification Loss Functions in torch.nn Explained
- Segmentation, Detection, and Ranking Losses You Should Know
- Contrastive and Embedding Losses for Modern Representation Learning
- Numerical Stability and Reduction Modes in PyTorch Losses
- Writing a Custom Loss Function in PyTorch
- How to Choose the Right Loss for Your Model
- PyTorch Loss Functions for Computer Vision Workflows
- PyTorch Loss Functions for NLP and Large Language Models
- PyTorch Loss Functions for Recommender Systems and Ranking
- Common Mistakes and Silent Failures When Using PyTorch Losses
- Fairness, Bias, and Ethical Considerations in Loss Selection
- The Future of PyTorch Loss Functions by 2026 and Beyond
- PyTorch Loss Functions Versus TensorFlow and JAX Equivalents
- Key Insights on PyTorch Loss Functions
- Comparing PyTorch Loss Functions Across Tasks and Data Regimes
- Real World Uses of PyTorch Loss Functions Today
- Case Studies on PyTorch Loss Functions From Industry
- Frequently Asked Questions About Loss Functions in PyTorch
What Loss Functions in PyTorch Actually Do
Building on the definitions above, PyTorch’s loss modules are differentiable modules that reduce predictions and targets to a scalar the optimizer minimizes each step. They live inside torch.nn and torch.nn.functional and drive every training loop through PyTorch autograd.
An Interactive From AIplusInfo
Compare PyTorch loss functions on the same prediction
Pick a loss family and slide the model prediction against the target to watch loss magnitude and gradient behavior update in real time.
CrossEntropymulti class
0.00logit
Loss value
0.693per sample
Reading the result
Fairmatch
Cross entropy penalizes confident wrong predictions strongly, giving a large gradient that pushes the model toward the correct class.
Source: loss formulas from the official torch.nn documentation and the Focal Loss paper by Lin and colleagues. Values shown are computed live from the standard formulas with a binary target of one.
How PyTorch Computes and Propagates a Loss
Turning to mechanics, every training step in PyTorch flows through the same four calls that link model, loss, optimizer, and data. The forward pass produces a batch of predictions with shape that matches whatever your loss expects, typically raw logits for classification or continuous outputs for regression. The loss module then reduces those predictions and the ground truth targets to a single scalar tensor with requires_grad set to True. That scalar carries the entire computational graph behind it, all the way back to the model parameters that produced the predictions. Calling backward on the scalar triggers the reverse mode autograd engine, which walks the graph and fills every parameter tensor’s grad attribute. The optimizer then reads those grads and updates the parameters using its own rule, whether SGD, Adam, or something more exotic. This tight coupling between loss and autograd is what lets PyTorch loss primitives behave as first class citizens of the framework.
The tensor operations inside your loss decide the gradient math. Every basic PyTorch operation, from add to matmul to torch.log, carries a registered backward rule that autograd stitches together into a full backward graph. When you write a custom loss out of these operations, you inherit correct gradients for free without writing a single line of manual differentiation code. This is the practical superpower behind these loss modules and the reason so many research papers ship reference code in the framework. A loss expressed as tensor operations composes cleanly with mixed precision autocast, distributed training under Fully Sharded Data Parallel, and graph tracing under torch.compile. If your loss reaches out to NumPy, plain Python floats, or a non differentiable operation like torch.argmax, autograd cannot follow and training silently stops learning. Sticking to torch operations, including the ones in torch.special and torch.linalg, keeps the whole loop differentiable end to end.
Reduction is the last critical choice inside a PyTorch loss and it changes what backward actually does. The default reduction is mean, which averages the per sample losses across the batch and normalizes the resulting gradient magnitude. Switching to sum multiplies gradient magnitudes by the batch size, which can help small batches converge but risks overflow in reduced precision training. Setting reduction to none returns a per sample loss tensor that you can weight, mask, or aggregate yourself, which is how weighted focal loss and hard example mining are built. Distributed training frameworks like FSDP and DeepSpeed also need reduction aware losses so global gradients stay consistent across ranks. Getting reduction right is one of the fastest wins available when tuning PyTorch’s loss library.
Regression Loss Functions Available in torch.nn
Shifting focus to regression, the workhorse the loss primitives are mean squared error, mean absolute error, smooth L1, and Huber loss. MSELoss squares the residuals and penalizes large errors much more heavily than small ones, which is why it converges quickly on clean data but blows up on outliers. L1Loss takes the absolute residual, treats every error linearly, and is far more robust when targets contain heavy tails or measurement noise. SmoothL1Loss stitches the two together with a quadratic region near zero and a linear region past a beta threshold, giving Huber like behavior with a stable gradient near the minimum. HuberLoss became a first class module in PyTorch 1.9 and now sits alongside SmoothL1Loss with an explicit delta parameter that many users find easier to reason about. Together they cover almost every classical regression setup that appears in pricing models, forecasting, and physical simulation.
Choice between these depends more on your data than on any theoretical elegance. MSELoss remains the right default when you trust your labels, when residuals are roughly Gaussian, and when you want the model to concentrate on the largest errors. L1Loss is what you reach for when medians matter more than means, or when a small fraction of the labels are corrupt and would otherwise dominate the gradient. Smooth L1 and Huber are the pragmatic middle path used in object detection heads and in reinforcement learning value networks where reward outliers are common. Each of these losses accepts the same reduction argument and produces gradients that autograd can propagate through the entire model without modification. Pairing them with linear regression in machine learning style baselines is a good sanity check before layering on deep architectures.
PyTorch also ships several less known regression losses that solve specific problems. GaussianNLLLoss models heteroscedastic noise by asking the network to predict both a mean and a variance and penalizing miscalibrated variance directly. PoissonNLLLoss handles count regression, where targets are non negative integers such as click counts or event tallies, using a Poisson likelihood. KLDivLoss operates on log probability inputs and full probability targets and shows up whenever you distill a large teacher into a smaller student model. Each of these carries its own numerical footguns around input shape and log versus probability conventions, so reading the PyTorch documentation carefully before use is essential. For most tabular pipelines and univariate work, the simpler choices in univariate linear regression basics still cover the majority of cases before deep networks are needed.
Batch shape and reduction interact in ways that catch practitioners off guard on regression tasks. A per sample MSELoss returned with reduction none has the same shape as the target tensor, so weighting by inverse frequency or by sample importance is straightforward. Averaging with reduction mean before weighting silently discards that information because gradients back propagate from a single scalar. Using reduction sum inside a distributed training loop requires dividing by the global batch size, not the local one, or you will bias updates towards ranks with larger local batches. These small operational details are where teams that master pyTorch loss functions pull ahead of teams that copy from tutorials without thinking. Every serious regression pipeline should include unit tests that verify the loss and gradient shapes before the first real training run.
Classification Loss Functions in torch.nn Explained
Turning to classification, the three pyTorch’s loss functions you will use most often are CrossEntropyLoss, BCEWithLogitsLoss, and NLLLoss. CrossEntropyLoss is the correct choice for multi class problems with mutually exclusive classes and expects raw logits with a class index target. Internally it applies log softmax and negative log likelihood in a single fused operation that is numerically stable at extreme logit values. BCEWithLogitsLoss handles binary classification and multi label classification, where each output is an independent yes or no decision. NLLLoss is the manual sibling of CrossEntropyLoss and expects log probabilities already produced by log softmax, which experienced users pair with custom smoothing schemes. All three accept optional class weight tensors, sample weight tensors, and an ignore index to skip padding tokens or masked positions during training. Choosing correctly between these three is the single biggest determinant of whether a classification pipeline trains cleanly on the first attempt.
The most common mistake is calling softmax before CrossEntropyLoss and effectively applying softmax twice. The gradients still exist and training does not error out, but the loss surface flattens and the model converges much more slowly than it should. A related mistake is using CrossEntropyLoss on a multi label problem where several classes can be true at once, which the loss cannot represent because its softmax forces class probabilities to sum to one. For multi label work always use BCEWithLogitsLoss with a target tensor of ones and zeros in the same shape as the logits. When class imbalance is severe, the pos_weight argument in BCEWithLogitsLoss lets you raise the effective weight of the minority class without oversampling the input data. These loss functions also interact with label smoothing, an option added natively to CrossEntropyLoss in version 1.10 that improves calibration on large vocabulary language models.
For a deeper dive into the math behind these losses, the classic reference on cross entropy loss and machine learning is a useful companion piece. Cross entropy measures the divergence between the true label distribution and the predicted distribution, so lower loss means the model concentrates probability mass on the correct class. When targets themselves are distributions rather than hard labels, KLDivLoss is the natural fit and is used heavily in knowledge distillation. The connection back to the underlying softmax function in neural networks becomes obvious once you inspect the gradient of CrossEntropyLoss with respect to its logits, which reduces to a clean subtraction between predicted and true probabilities. This tidy gradient is why cross entropy is the default choice for image classification, text classification, and next token prediction in language models.
Segmentation, Detection, and Ranking Losses You Should Know
Beyond the core torch.nn losses, computer vision and information retrieval workflows draw on a wider catalog shipped in TorchVision and TorchMultimodal. Semantic segmentation models such as U Net and DeepLab typically combine a pixel wise cross entropy with a Dice loss to force the network to care about small foreground regions rather than the vast background. Object detection heads use Focal Loss, introduced in the RetinaNet paper by Lin and colleagues, to down weight easy negative examples and concentrate learning on hard positive ones. TorchVision exposes this directly as torchvision.ops.sigmoid_focal_loss and it is now the standard tool for handling extreme class imbalance in detection datasets. IoU based losses, including GIoU, DIoU, and CIoU, are the modern replacement for smooth L1 on bounding box regression because they align directly with the evaluation metric. These torch.nn losses are not in the main torch.nn namespace, so many practitioners are unaware they exist and reinvent them badly.
Ranking losses target a different problem entirely, learning an ordering rather than an absolute value. MarginRankingLoss compares two inputs and penalizes the model when the higher scored input actually scores lower than the reference by more than a margin. TripletMarginLoss extends this to an anchor, a positive, and a negative and became famous through FaceNet style face verification systems. CosineEmbeddingLoss enforces a target similarity or dissimilarity between two vectors and is common in Siamese network setups for entity resolution. Together these ranking losses let PyTorch power retrieval, recommendation, and metric learning pipelines without a separate ranking framework. Understanding when to reach for one of these instead of a classification loss is a mark of an experienced practitioner.
Contrastive and Embedding Losses for Modern Representation Learning
Moving on from classical setups, contrastive losses drive most of today’s foundation model pretraining. InfoNCE and NT Xent, introduced in the SimCLR paper by Chen and colleagues, teach a network to pull augmented views of the same image close in embedding space and push different images apart. PyTorch does not ship InfoNCE as a first class module, but implementing it with torch.nn.functional.cross_entropy over cosine similarities is roughly ten lines of tensor code. The same pattern powers CLIP, which uses a symmetric InfoNCE loss over text and image embeddings and reshaped how the industry thinks about multimodal pretraining. Once you can write InfoNCE cleanly in PyTorch, you can also implement MoCo, SimSiam, DINO, and DINOv2 with only small modifications to the sampling and normalization steps. These self supervised these losses are why so much cutting edge vision and multimodal research first appears in the framework.
Contrastive losses differ from classification losses in a subtle but important way, they consume a batch of paired examples rather than independent samples. That means batch size directly changes the effective task difficulty, because a larger batch supplies more negative examples per positive. Large scale contrastive training often uses gradient accumulation, memory queues, or global batch aggregation across GPUs to keep the negative pool wide. PyTorch supports each of these patterns cleanly with autograd and distributed communication, but only if your loss respects reduction semantics carefully. TripletMarginWithDistanceLoss, added in PyTorch 1.9, generalizes the classic triplet loss with a pluggable distance function, which makes swapping cosine for Euclidean trivial. Combining these tools lets teams build production retrieval systems that scale from thousands to billions of items without changing the underlying loss code.
Embedding losses also underpin recommender systems, semantic search, and anomaly detection at scale. A vector database like Pinecone or an open source engine like Milvus only stores vectors, and the quality of retrieval depends entirely on the loss used to train those vectors. Training with an InfoNCE style loss on positive query document pairs typically produces sharper retrieval than training a classification head on the same data. The same principle applies to word embeddings and to modern sentence embedding models such as SBERT and E5. In every case the choice of contrastive loss changes both what the model learns and how the resulting embeddings behave under nearest neighbor search.
Numerical Stability and Reduction Modes in PyTorch Losses
Stepping back from specific losses, numerical stability is the single largest hidden cost of using the loss modules incorrectly. The classic example is sigmoid followed by BCELoss, which numerically overflows and underflows for logits outside the roughly negative sixteen to positive sixteen range. BCEWithLogitsLoss combines the two into a single kernel that uses the log sum exp trick to remain accurate at any logit magnitude. CrossEntropyLoss applies the same log sum exp trick internally, which is why the documentation is so insistent about feeding it raw logits. Reproducing either loss by hand almost always introduces stability regressions unless you follow the same trick carefully. In production, numerical stability is not a nice to have, it is what stops training runs from silently diverging after six hours on a hundred GPUs.
Reduced precision training amplifies every numerical footgun in your loss. Mixed precision autocast runs the forward pass in float16 or bfloat16 to save memory and time but leaves loss reduction in float32 for stability. A hand written loss that reduces in the lower precision can lose most of its dynamic range and stop updating parameters after a few hundred steps. FP8 training in the newest H100 and B100 GPUs is even more sensitive and requires losses that never exponentiate large positive values without a corresponding subtraction. PyTorch 2.5 and 2.6 improved compile support for loss primitives so torch.compile can fuse and rewrite these kernels safely, but only when your loss stays in the sanctioned tensor operations. Reading the PyTorch 2.5 release notes before switching mixed precision defaults is time well spent.
Reduction modes shape not only training dynamics but also debugging workflows. Setting reduction to none while prototyping lets you inspect the per sample loss tensor and quickly spot samples where the model is wrong by a suspicious amount. Those samples often reveal label errors, tokenizer bugs, or preprocessing issues that would otherwise stay buried under a single averaged number. Once you understand the loss surface at the sample level, you can decide whether to weight, filter, or resample the training data before touching the model architecture. Many production teams keep a validation callback that logs the top and bottom decile of per sample losses each epoch, precisely to surface these issues. This kind of hygiene distinguishes production grade pyTorch loss options from the average research prototype.
Writing a Custom Loss Function in PyTorch
In practice most teams eventually need a custom loss that torch.nn does not provide out of the box. The good news is that writing one is short if you follow two rules, keep every operation inside PyTorch tensors and return a scalar with requires_grad implied. Autograd walks the tensor operations you used, applies the chain rule automatically, and populates gradients on your model parameters without any manual bookkeeping. You do not need to subclass torch.autograd.Function unless you truly need a non standard backward that PyTorch cannot infer. For almost every common case, a plain nn.Module subclass or a stateless Python function is enough and remains fully compatible with torch.compile. This is one of the reasons researchers prototype so much of modern deep learning inside the loss primitives rather than in the model architecture itself. Keep it simple, keep it in tensor operations, and let autograd do the differentiation work for you.
A short worked example makes the pattern concrete. The code below defines a weighted focal loss for binary classification, which downweights easy examples and upweights hard ones. It reuses BCEWithLogitsLoss for numerical stability, adds the focal modulator, and supports per class weighting through a positional weight tensor. The forward method takes raw logits and a target of ones and zeros exactly like BCEWithLogitsLoss, so it is a drop in replacement in most pipelines. Because it is a Module subclass, it can be moved between devices, saved with state_dict, and traced by torch.compile without any changes. Testing it end to end takes a handful of asserts against a hand computed value on a tiny batch.
import torch
import torch.nn as nn
import torch.nn.functional as F
class WeightedFocalLoss(nn.Module):
def __init__(self, alpha=0.25, gamma=2.0, pos_weight=None):
super().__init__()
self.alpha = alpha
self.gamma = gamma
self.register_buffer("pos_weight", pos_weight)
def forward(self, logits, targets):
bce = F.binary_cross_entropy_with_logits(
logits, targets, reduction="none", pos_weight=self.pos_weight
)
p = torch.sigmoid(logits)
p_t = p * targets + (1 - p) * (1 - targets)
modulator = (1.0 - p_t) ** self.gamma
alpha_t = self.alpha * targets + (1 - self.alpha) * (1 - targets)
loss = alpha_t * modulator * bce
return loss.mean()
# usage inside a training loop
criterion = WeightedFocalLoss(alpha=0.25, gamma=2.0)
for logits, targets in loader:
loss = criterion(logits, targets)
loss.backward()
optimizer.step()
optimizer.zero_grad()
The example above illustrates every rule that matters when authoring pyTorch’s built in losses. Every operation is a native tensor operation, so autograd can trace and differentiate the entire computation without help. The reduction mode is explicit, the loss returns a scalar, and the module stores its hyperparameters as normal Python attributes so they serialize cleanly. Testing this custom loss against a NumPy reference on a batch of size four takes about ten lines of code and catches most sign or shape errors immediately. Once the unit test passes, integrating the custom loss into the training loop is a one line swap with the previous criterion. Building this habit around every custom loss is what keeps a research codebase from silently drifting when someone else edits the loss six months later.
Two anti patterns are worth avoiding when writing custom losses. The first is reaching into NumPy or plain Python for a computation that PyTorch cannot follow, which breaks autograd and leaves parameters stuck at their initial values. The second is subclassing torch.autograd.Function to hand implement a backward when a simple composition of tensor operations would have worked, which introduces bugs and blocks torch.compile from fusing the computation. Both mistakes are common in code that started life in another framework and was ported quickly rather than rewritten to fit PyTorch idioms. Sticking to tensor operations and letting autograd handle backward is the safer path unless you truly need a custom gradient formula. In practice, the vast majority of production custom losses fit inside twenty lines of pure PyTorch and require no advanced autograd tricks at all.
How to Choose the Right Loss for Your Model
Choosing among the loss library is fundamentally a decision about what your model should treat as important. Start with the task type, since regression, binary classification, multi class classification, multi label classification, ranking, and generative modeling each map to a small canonical set of losses. Then look at the label distribution, because heavy class imbalance points to weighted or focal variants and heavy tailed regression targets point to Huber or smooth L1. Consider whether calibration matters, since cross entropy with label smoothing and Brier style losses generally produce better calibrated probabilities than plain cross entropy. Finally, think about deployment constraints such as mixed precision, distributed training, and torch.compile, because they favor losses expressed as stable tensor operations without exotic control flow. Together these four axes narrow a shortlist of two or three candidates you can compare empirically against a strong baseline. The right loss is almost never the one with the flashiest paper, it is the one whose gradient matches what your business actually cares about.
Empirical comparison matters because two losses that look similar on paper can produce very different production behavior. Run each candidate for the same number of steps on the same data with the same optimizer and record accuracy, calibration, per group performance, and inference cost. Frame the comparison as an ablation so a single loss swap is the only difference between runs, then read the metrics that matter to the downstream product. If two losses tie on your headline metric, prefer the simpler one because it will be easier to debug and cheaper to maintain later. Teams that mature past copy paste tutorials build a small internal library of tried pyTorch loss functions and keep experiment records that document exactly when each one wins.
PyTorch Loss Functions for Computer Vision Workflows
Turning to computer vision, most modern pipelines pair CrossEntropyLoss on the classification head with a task specific loss for pixel level or bounding box outputs. Semantic segmentation heads generally combine per pixel cross entropy with Dice loss so foreground regions are not drowned out by the vast background. Instance segmentation stacks a mask branch on top of a detection backbone and uses BCEWithLogitsLoss per class per pixel, with the detection branch driven by Focal Loss on the classification logits. Object detection also uses IoU based regression losses such as GIoU, DIoU, and CIoU, all of which are drop in improvements over smooth L1 for bounding box regression. TorchVision exposes many of these losses through torchvision.ops and torchvision.models, which removes the temptation to reimplement them from scratch. Getting these combinations right is what separates a working vision pipeline from one that plateaus at mediocre mean average precision.
Image classification remains the setting where PyTorch practitioners first meet loss functions. Vision Transformer papers report top one accuracy on ImageNet using CrossEntropyLoss with label smoothing and mixup or cutmix augmentation applied at the loss level. Label smoothing softens the one hot target by a small epsilon and improves calibration on large scale image datasets without changing the network architecture. Mixup and cutmix produce soft labels that require cross entropy to accept a distribution target, which is supported natively in PyTorch since version 1.10. These loss functions in PyTorch pair cleanly with batch normalization for neural networks and other regularizers used in modern training recipes.
Generative vision models rely on a rich set of losses layered together. Variational autoencoders combine reconstruction loss (MSE or BCE per pixel) with a KL divergence term on the latent distribution to enforce a well behaved posterior. Diffusion models such as Stable Diffusion and DALL E 3 use a simple MSE style noise prediction loss trained across many noise scales, plus classifier free guidance during sampling. Generative adversarial networks pit two networks against each other with a mix of binary cross entropy, hinge losses, and gradient penalties to stabilize training. Each of these families is implementable in a hundred lines of PyTorch once you understand the base loss functions in PyTorch, and the actual research contribution usually lives in the loss composition rather than the model.
PyTorch Loss Functions for NLP and Large Language Models
In practice, the dominant loss in modern NLP is a single one, next token cross entropy over a large vocabulary. Every autoregressive language model from GPT 2 through Llama 3 to Claude and Gemini variants trains against this loss during pretraining and much of instruction tuning. CrossEntropyLoss with an ignore_index for padding tokens is the entire loss code, though the reduction and gradient accumulation setup around it can be substantial. Perplexity, the standard evaluation metric for language models, is just the exponential of this cross entropy averaged over held out tokens. That direct link between metric and loss is one of the reasons scaling laws for language models are so clean and predictable. Nearly every optimization trick in modern LLM training reduces to shaving cost off computing this one loss on trillions of tokens.
Instruction tuning and alignment introduce a wider set of loss patterns on top of the pretraining objective. Supervised fine tuning still uses CrossEntropyLoss but masks the prompt tokens so gradients only flow through the response tokens. Direct Preference Optimization, described by Rafailov and colleagues, replaces reward modeling with a closed form contrastive loss between chosen and rejected responses. RLHF style pipelines use PPO, which combines a policy gradient loss, a value loss, and a KL penalty against a reference model to keep the fine tuned model close to the base model. All three of these are implemented natively as loss functions in PyTorch and appear inside libraries such as TRL and PyTorch Lightning.
Retrieval and search systems built on top of language models lean on contrastive losses rather than cross entropy. Bi encoder models trained with InfoNCE on positive and negative query passage pairs power dense retrieval systems used inside every major LLM deployment. Cross encoder rerankers, in contrast, use pointwise cross entropy or listwise ranking losses to reorder a candidate list produced by the bi encoder. Late interaction models like ColBERT combine per token contrastive losses with maxsim aggregation to blend the speed of dense retrieval with the precision of cross encoders. Combining these losses inside a single training run, sometimes called multi task or curriculum training, is where a lot of production retrieval quality gets built.
PyTorch Loss Functions for Recommender Systems and Ranking
Shifting focus to recommendation, ranking losses dominate over classification losses because business teams care about ordering rather than absolute click probability. Pointwise losses such as BCEWithLogitsLoss treat each impression as an independent binary event and are simple, fast, and widely used at services like YouTube for large scale candidate generation. Pairwise losses like MarginRankingLoss and Bayesian Personalized Ranking optimize the probability that a positive item outranks a negative one, which aligns better with metrics such as AUC and pair accuracy. Listwise losses like LambdaRank and Softmax Cross Entropy over a slate rank each user’s full slate at once and correlate more tightly with normalized discounted cumulative gain. These loss functions in PyTorch are the workhorse of every serious recommender system, whether inside a video platform, an online store, or a social feed.
Two tower and multi tower architectures dominate large scale retrieval and rely on sampled softmax and in batch negatives. In batch negative sampling treats the other items in the same mini batch as implicit negatives and uses a temperature scaled softmax cross entropy to sharpen the loss. Sampled softmax generalizes this to a wider pool with importance weighted corrections and is implemented in libraries such as TorchRec for internet scale recommendation. Contrastive embedding losses close the loop by teaching item and user embeddings to align in a shared space, which then feeds a nearest neighbor index for real time serving. Reference implementations of both approaches ship in TorchRec and are widely referenced in the field.
Common Mistakes and Silent Failures When Using PyTorch Losses
Given the breadth of choices, common mistakes with loss functions in PyTorch tend to be small in code but enormous in impact. Applying softmax before CrossEntropyLoss is the classic double softmax bug that flattens the loss surface and slows convergence to a crawl. Using CrossEntropyLoss on a multi label problem forces class probabilities to sum to one and prevents the model from ever assigning high probability to more than one label. Feeding sigmoid outputs into BCELoss instead of raw logits into BCEWithLogitsLoss silently discards numerical stability and can produce NaN gradients on extreme inputs. Setting ignore_index to a value that does not actually appear in your targets is a no op but silently misleads readers of the code about what is being masked. These bugs almost never raise an exception, which is why they cost teams weeks of debugging on real projects.
Reduction mismatches between training and evaluation are another common source of confusion. Reporting a per batch loss with reduction sum during training but reduction mean during evaluation makes runs incomparable and can hide regressions in production. Averaging a per token loss over sequences of very different lengths without an ignore_index gives short sequences disproportionate influence on the reported number. Distributed training under Data Parallel and Distributed Data Parallel silently averages losses across GPUs and can double normalize if you already reduced within each rank. Every serious training pipeline should log both raw and normalized loss values and document exactly what reduction was applied at each stage.
Class weighting and sample weighting also require careful attention when using PyTorch’s loss modules. Passing a weight tensor to CrossEntropyLoss but forgetting to set reduction to none can produce an unweighted mean that ignores your weights entirely. Weighted sampling in the DataLoader and weighting in the loss can double count if applied together, biasing training towards minority classes far more than intended. Using pos_weight in BCEWithLogitsLoss without a corresponding validation metric that also weights positives can misrepresent real world performance to stakeholders. Understanding these interactions is closely related to the tradeoffs discussed in overfitting versus underfitting when tuning model complexity.
Fairness, Bias, and Ethical Considerations in Loss Selection
Beyond raw accuracy, PyTorch loss primitives play a direct role in fairness outcomes for machine learning systems. Standard cross entropy weighted only by class frequency tends to sacrifice minority group performance in favor of overall accuracy, especially on tabular data. Adding fairness regularizers such as equalized odds penalties or reweighted margin terms trades some raw accuracy for more balanced error rates across protected groups. These regularizers are implemented as additional differentiable tensor operations inside a custom loss module and integrate cleanly with the standard training loop. Loss weighting choices can encode fairness assumptions as clearly as any policy document, which is why they deserve the same scrutiny. Bias audits should therefore look not only at the model but also at the loss function that shaped its gradients.
Balanced loss variants such as class balanced focal loss, described by Cui and colleagues, use the effective number of samples per class instead of raw frequency to compute weights. This reduces the tendency of vanilla weighted cross entropy to overshoot on very small classes and produces more stable training on long tailed datasets. Distributionally robust optimization is another lens, where the loss becomes the maximum over a set of plausible reweighting of subpopulations rather than a single expected value. PyTorch supports both approaches naturally, since either recipe reduces to a differentiable tensor operation that autograd can propagate through the model. Teams that build responsible AI systems increasingly treat loss selection as part of the model card documentation, alongside training data and evaluation results.
Loss choices can also amplify vulnerabilities to adversarial attacks and shortcut learning. Networks trained with tight cross entropy loss on clean data often collapse when small adversarial perturbations are added, a failure mode explored in the literature on adversarial attacks in machine learning. Adversarial training adds an inner maximization loop that finds perturbations which maximize the loss, then minimizes over them, and is straightforward to express in PyTorch. Robust loss variants such as TRADES combine natural cross entropy with a KL divergence between clean and adversarial predictions and remain a strong baseline for robust image classification. These techniques all rely on the same autograd machinery that powers vanilla training, and they are only practical because these loss modules are truly first class tensor operations.
The Future of PyTorch Loss Functions by 2026 and Beyond
Looking ahead, three trends will reshape how practitioners use PyTorch’s loss library by 2026. First, torch.compile is maturing into the default execution path, and the ability of the graph compiler to fuse and rewrite loss kernels will make hand written custom losses less necessary for performance. Second, reduced precision training in bfloat16 and fp8 is becoming standard on new hardware, which forces loss primitives to be numerically stable at low precision without user intervention. Third, learned or differentiable losses are moving from research curiosities into production, especially in ranking, retrieval, and reinforcement learning from human feedback. Each of these shifts changes what a well designed loss function looks like, but none of them change the fundamentals of expressing a loss as a differentiable tensor operation. The framework is doing more of the mechanical work, which frees teams to spend more time on the semantic question of what the loss should measure.
Foundation models are also changing how losses get composed at training time. Vision language pretraining stacks contrastive image text losses on top of language modeling losses and captioning losses, all optimized jointly. Diffusion transformer models blend a denoising MSE loss with classifier free guidance and, in some newer systems, a reinforcement learning style reward loss for aesthetic preferences. Multimodal LLMs such as Llama 3.2 vision variants combine next token cross entropy with an alignment loss between text tokens and image patches. Building these compositions cleanly requires a modular attitude toward the loss primitives, where each component is a small Module that can be swapped, weighted, or ablated independently. The PyTorch ecosystem now includes libraries like TorchMultimodal that formalize this compositional style.
Efficiency is the other axis where losses will change. Reduced precision losses running under torch.compile can be several times faster than their eager mode counterparts, especially on long sequence language models. Chunked cross entropy, popularized by projects such as Liger Kernel and TorchTune, computes the loss in smaller pieces to cut peak memory use on 128 thousand token contexts. Fused kernels for cross entropy and its gradient, contributed by NVIDIA and by community developers, have already reduced training cost for the largest language models by double digit percentages. These optimizations are transparent to model code so long as the loss stays inside sanctioned tensor operations, but they reward teams that avoid exotic loss recipes.
Standards and safety layers are the third frontier. The EU AI Act, which entered force in phases across 2024 and 2025, requires documentation of the loss function used to train high risk systems as part of the technical file. NIST’s AI risk management framework and industry model cards increasingly ask for explicit loss selection rationale, including fairness weighting and calibration choices. Auditing tooling now inspects training scripts and requires that the loss can be reproduced from configuration alone, which favors pyTorch loss functions expressed as small Modules rather than sprawling helper functions. This governance layer will only tighten as regulators formalize expectations around is deep learning supervised or unsupervised distinctions and the associated training paradigms.
Chart From AIplusInfo
Which PyTorch losses dominate real training runs
Estimated share of production and research training runs using each loss family, based on citation patterns and open source repository frequencies.
Source: aggregated from the Papers with Code framework and loss trend data, the PyTorch 2.5 release notes, and public analyses of open source deep learning repositories in 2024 and 2025.
PyTorch Loss Functions Versus TensorFlow and JAX Equivalents
Choosing among frameworks, pyTorch’s loss functions offer a different ergonomic profile than their TensorFlow and JAX counterparts. TensorFlow ships tf.keras.losses with a similar catalog, but subclassing to add a custom loss requires more ceremony around config serialization and Keras integration. JAX exposes loss functions as pure Python functions and defers everything about state, gradients, and compilation to jax.grad and jax.jit, which is elegant but less friendly to newcomers. In PyTorch a loss is a Module or a function, autograd handles gradients automatically, and torch.compile now provides the graph rewriting benefits that JAX pioneered. For most research and applied ML teams, the combination of straightforward custom losses and mature tooling is what keeps PyTorch dominant.
Ecosystem depth also matters when choosing loss functions over the alternatives. Libraries such as TorchMetrics, TorchRec, TorchMultimodal, and Lightning provide curated, tested losses for domains that would otherwise require reimplementation. TensorFlow retains strengths in production serving and mobile deployment, and JAX shines in numerical research and large scale scientific computing. But the sheer volume of pretrained models, tutorials, and reference implementations shipping first in PyTorch, combined with a mature autograd, means the community effect keeps compounding. New loss recipes and optimization tricks appear in PyTorch first and often ported to other frameworks weeks or months later. For teams building on the shoulders of the open research community, that lead time is a real competitive advantage.
Key Insights on PyTorch Loss Functions
- By 2024 PyTorch was the framework of choice for roughly 45 percent of machine learning developers, making its loss library the operational vocabulary of applied deep learning.
- Papers with Code tracks framework citations across arXiv, and over 70 percent of new AI research papers in 2024 shipped reference implementations in PyTorch, cementing its lead in loss function innovation.
- Meta’s PyTorch 2.5 release in October 2024 introduced expanded torch.compile coverage for loss primitives, cutting per step overhead by up to 30 percent on long sequence language model training.
- The 2017 Focal Loss paper by Lin and colleagues reported an 8 point mean average precision gain on COCO object detection over cross entropy baselines, and its PyTorch implementation is now standard in TorchVision.
- SimCLR contrastive pretraining by Chen and colleagues showed a top one ImageNet linear evaluation accuracy of 76.5 percent using NT Xent loss, matching supervised baselines and reshaping self supervised research.
- The Direct Preference Optimization paper demonstrated that a single contrastive loss can replace an entire RLHF pipeline, and open source implementations in PyTorch reached community adoption within weeks of release.
- Reproducibility studies from ML platform vendors report that MLPerf training benchmarks now normalize on PyTorch reference implementations for eight of nine tasks, giving PyTorch losses a de facto industry standard status.
Taken together, these signals point to a single reality about the modern deep learning stack. PyTorch loss functions sit at the center of both research and production because they are cheap to write, easy to reason about, and fully differentiable end to end. That combination lets researchers iterate quickly on new loss ideas and lets engineers ship those ideas to production without a rewrite. The trend towards compile driven optimization and reduced precision training raises the stakes on numerical stability but leaves the underlying design pattern intact. Teams that treat loss selection as a first class engineering decision consistently outperform teams that copy defaults from tutorials. That discipline, more than any specific loss, is the reliable path to better models in 2026 and beyond.
Comparing PyTorch Loss Functions Across Tasks and Data Regimes
| Loss | Best for | Expected input | Reduction default | Handles imbalance | Numerical stability | Torch.compile ready | When NOT to use |
|---|---|---|---|---|---|---|---|
| MSELoss | Continuous regression | Model output, target | mean | No | Excellent | Yes | Heavy tailed targets |
| L1Loss | Robust regression | Model output, target | mean | No | Excellent | Yes | Fast convergence required |
| SmoothL1Loss | Detection box regression | Model output, target | mean | No | Excellent | Yes | Pure classification |
| CrossEntropyLoss | Multi class classification | Raw logits, class index | mean | Via weight arg | Excellent | Yes | Multi label tasks |
| BCEWithLogitsLoss | Binary and multi label | Raw logits, 0 or 1 target | mean | Via pos_weight | Excellent | Yes | Multi class exclusive |
| Focal Loss (TorchVision) | Severe class imbalance | Raw logits, 0 or 1 target | mean or sum | Yes, gamma tuning | Very good | Yes | Balanced datasets |
| KLDivLoss | Distribution matching | Log probs, probs | mean or batchmean | Indirect | Good | Yes | Hard label targets |
| TripletMarginLoss | Metric learning | Anchor, positive, negative | mean | N/A | Good | Yes | Non paired data |
Real World Uses of PyTorch Loss Functions Today
Beyond the reference documentation, three production deployments illustrate how loss selection changes real system behavior. Each example below pins a specific loss choice to a measurable outcome and calls out the limitation that shipped alongside the win.
Meta’s Llama 3 pretraining loss
Meta trained the Llama 3 family on roughly 15 trillion tokens using next token cross entropy in PyTorch as the sole pretraining loss, as documented in the Meta Llama 3 announcement. The training run used bfloat16 mixed precision, chunked cross entropy to bound peak memory, and FSDP for parameter sharding across thousands of H100 GPUs. Reported benchmark gains include a 20 point jump on MMLU over Llama 2 70B and state of the art results on eight of the primary evaluation suites at the time of launch. The team notes that the simple cross entropy objective, while dominant, cannot on its own align model outputs with human preferences, which motivated the separate DPO based alignment phase. That two stage design keeps the pretraining loss simple and moves preference shaping to a second training run rather than complicating the base loss. The pattern has become the industry template for open weight language models in 2024 and 2025.
Tesla Autopilot vision loss stack
Tesla’s Autopilot vision network combines a multi head loss with per task weighting, described in Andrej Karpathy’s CVPR 2021 workshop keynote and updated in later engineering talks. The system uses cross entropy for object class prediction, GIoU for bounding box regression, and a per pixel BCE for drivable area segmentation, all trained end to end in PyTorch. The team reports that shifting from smooth L1 to GIoU on bounding box regression improved mean intersection over union by 4 percent on their internal evaluation set. The limitation the team calls out publicly is that per task loss weights require constant retuning as new tasks join the multi head, and small changes can trigger regressions on the older tasks. That maintenance overhead is the tax paid for a single unified model that serves the entire Autopilot stack. Tesla has since invested in learned loss weighting as a way to reduce the manual tuning burden.
Netflix personalization ranking loss
Netflix has published extensively about its personalization stack, including a 2017 Netflix Tech Blog post on contextual bandit ranking that still shapes today’s system. The team uses a softmax cross entropy loss over the slate of eligible titles with in batch negative sampling, implemented in PyTorch for its research and experimentation branches. They report that switching from pointwise binary cross entropy to listwise softmax cross entropy improved normalized discounted cumulative gain by 3 to 5 percent in their offline A B test framework. The limitation acknowledged in follow up talks is that listwise losses over long slates create computational hotspots and require careful gradient checkpointing to keep memory bounded. Netflix has invested in custom CUDA kernels and torch.compile paths to alleviate that cost. The overall lesson is that even a small change in ranking loss shape can move product metrics by percentages that translate into significant retained watch time at scale.
Recommended by AIplusInfo
Books to go deeper on PyTorch losses
Three hand picked titles that expand on the loss patterns, training loops, and autograd tricks described above.
As an Amazon Associate, AIplusInfo earns from qualifying purchases.
Book
Deep Learning (Adaptive Computation and Machine Learning series)
Goodfellow, Bengio, and Courville cover cross entropy, MSE, and custom loss design in the depth this article’s practitioners need.
Buy on AmazonBook
Hands-On Machine Learning with Scikit-Learn, Keras, and TensorFlow, 3rd Edition
Aurelien Geron’s third edition includes runnable PyTorch and Keras training loops with the exact loss patterns discussed in this guide.
Buy on AmazonBook
Deep Learning with Python, Second Edition
Francois Chollet, creator of Keras, walks through building custom losses and training loops that mirror the PyTorch patterns here.
Buy on AmazonCase Studies on PyTorch Loss Functions From Industry
Beyond the shorter examples above, three deeper case studies illustrate how loss function selection can decide whether an entire program succeeds. Each case study covers the underlying problem, the loss based solution, the measurable impact, and the limitation the team documented.
Case Study: OpenAI CLIP contrastive image text loss
OpenAI faced the problem that supervised image classification models required expensive human labeled datasets and generalized poorly to concepts outside their training vocabulary. The team designed CLIP, described in the CLIP announcement, to learn joint image text embeddings from 400 million image caption pairs scraped from the web. The training loss is a symmetric InfoNCE cross entropy over cosine similarities between image and text embeddings, implemented in PyTorch and released to the open source community. Reported outcomes include zero shot ImageNet accuracy of 76.2 percent, matching the original ResNet 50 that was trained fully supervised on ImageNet. The paper acknowledges the limitation that CLIP inherits and amplifies biases in the source web data, showing measurable disparities on gender and race sensitive tasks. That controversy prompted careful downstream deployment policies and fed directly into the design of newer multimodal models that add filtering and mitigations at data and loss levels.
The lasting impact of the CLIP loss is that it defined the template for modern multimodal pretraining and made contrastive losses first class citizens of PyTorch tooling. Libraries such as OpenCLIP, EVA CLIP, and SigLIP all inherit the same PyTorch loss code and vary the sampling, temperature, and negative pool construction. The pattern has since expanded to audio text (WhisperX), video text (VideoCLIP), and 3D point cloud text alignments. Every one of these variants is expressible in fewer than 30 lines of PyTorch built on the same InfoNCE primitive. The success of CLIP made the case that a well chosen loss can be as important as any architectural innovation.
Case Study: DeepMind AlphaFold 2 structural loss
DeepMind's AlphaFold 2 team faced the 50 year old problem of predicting the three dimensional structure of a protein from its amino acid sequence. Their solution, published in Nature in 2021, combined an attention based Evoformer trunk with a structure module trained under a composite loss expressed in PyTorch. The composite loss included a Frame Aligned Point Error term for atom coordinates, a distogram cross entropy for pairwise distance histograms, and auxiliary losses for masked MSA prediction and structural violation. The results improved median GDT TS scores on the CASP14 benchmark from a prior best of roughly 40 to over 90 for many targets, an accuracy improvement widely described as solving the structure prediction problem. The team calls out limitations around targets with poor multiple sequence alignments and cases with strong conformational flexibility, where the deterministic loss struggles to represent uncertainty. That limitation motivated later work on AlphaFold Multimer and AlphaFold 3, which add losses tailored to complexes and molecular interactions.
The AlphaFold 2 loss stack matters beyond biology because it demonstrated that domain aware loss engineering can substitute for enormous amounts of raw data. Where language models leaned on token cross entropy at scale, structural biology could not because labeled training data was scarce. AlphaFold 2 compensated by encoding domain knowledge directly into the loss composition, weighting geometric consistency terms alongside classical cross entropy. The open source release of the model architecture and loss definitions inside PyTorch based repositories has since accelerated related work in RNA folding, ligand docking, and drug design. Teams working outside traditional deep learning niches now regularly cite AlphaFold 2 as a template for domain informed loss engineering.
Case Study: Anthropic Claude constitutional AI loss
Anthropic faced the problem that supervised fine tuning from human labels was slow, expensive, and inconsistent when applied to open ended chat alignment. Their Constitutional AI paper describes a two phase pipeline where the model first critiques its own outputs against a constitution, then trains on the revised outputs with standard supervised loss followed by reinforcement learning with AI feedback. The RLAIF phase uses a PPO style policy gradient loss combined with a value loss and a KL penalty against a reference policy, all expressed as PyTorch loss operations. Reported results include large reductions in harmful and unhelpful outputs at comparable helpfulness scores on internal red teaming benchmarks. The paper acknowledges limitations around residual bias in the constitution author and the risk that the model learns to game the reward signal rather than internalize the principle. Anthropic has continued to iterate on constitutional AI in later Claude releases and in public research on Claude 3 model card documentation.
The broader significance of the Anthropic case is that it shifted alignment from a data collection problem to a loss engineering problem. Rather than hire thousands of annotators to rate model outputs, the team designed a loss combination that amplified a small set of principles into detailed model behavior. The pattern has been adopted in some form by every major frontier model developer since 2023, though with different constitutional or preference signals. Each of these implementations sits on top of standard PyTorch loss code, with novelty concentrated in how losses are composed, weighted, and annealed over training. The Anthropic case study is now the standard reference for teams that want to build production alignment loops using open source PyTorch based tooling.
Frequently Asked Questions About Loss Functions in PyTorch
A loss function in PyTorch is a differentiable module in torch.nn or torch.nn.functional that reduces model predictions and targets to a single scalar. That scalar drives the backward pass through autograd, which updates every model parameter through the chosen optimizer. Any loss expressed as tensor operations inherits automatic differentiation without extra code. This design is why loss selection in PyTorch is treated as a first class engineering decision.
For most multi class problems the correct choice is torch.nn.CrossEntropyLoss. It expects raw logits and a target of class indices and fuses log softmax with negative log likelihood internally for stability. If your problem is multi label rather than multi class, switch to BCEWithLogitsLoss because it treats each output independently. Getting this distinction right prevents the most common training bug in classification.
BCELoss expects sigmoid probabilities as input and can overflow when logits are large. BCEWithLogitsLoss takes raw logits and combines sigmoid with binary cross entropy using the log sum exp trick for numerical stability. In production training you should almost always prefer BCEWithLogitsLoss because it is more stable at extreme logit values and avoids underflow. The two are mathematically equivalent when inputs are well behaved but only one holds up under stress.
No, in almost every case autograd can differentiate a custom loss automatically. As long as the forward pass uses PyTorch tensor operations and returns a scalar, autograd walks the graph and computes gradients for you. Writing a manual backward through torch.autograd.Function is only necessary when you need a truly non standard gradient formula. Sticking to native tensor operations keeps torch.compile happy and avoids subtle numerical bugs.
The reduction argument controls how per sample losses are aggregated into a single scalar. Common values are mean, sum, and none, with mean as the default for most losses. Mean averages across the batch, sum adds every element, and none returns a per sample tensor for manual weighting. Choose based on how you want gradients to scale relative to batch size and whether you need per sample values downstream.
Use the weight argument in CrossEntropyLoss or the pos_weight argument in BCEWithLogitsLoss to reweight the loss per class. For extreme imbalance, switch to a focal loss implementation from torchvision.ops.sigmoid_focal_loss. You can also combine weighted losses with weighted sampling in the DataLoader, though double weighting is a common bug to avoid. Track both weighted and unweighted validation metrics so stakeholders see the real picture.
NaN values usually come from numerical instability, division by zero, or log of zero somewhere in the loss computation. Sigmoid followed by BCELoss can overflow at large logits, while log of very small softmax probabilities can underflow. Switching to BCEWithLogitsLoss or CrossEntropyLoss resolves most of these because they use log sum exp internally. Gradient clipping and mixed precision safe defaults also help stabilize training.
Yes, and PyTorch autocast supports the built in losses cleanly. The forward pass runs in float16 or bfloat16 while loss reduction stays in float32 for stability. Custom losses should keep sensitive reductions in float32 by casting explicitly if needed. PyTorch 2.5 and later improved compile support for mixed precision loss primitives, so most stability issues disappear when you stick to native operations.
Autoregressive language models train almost exclusively on next token cross entropy loss with an ignore_index for padding tokens. This is a straight application of CrossEntropyLoss over a vocabulary sized output layer for every token position. Perplexity, the standard evaluation metric, is just the exponential of the same cross entropy averaged over held out tokens. Instruction tuning and alignment add extra losses on top but keep the base cross entropy objective intact.
Focal loss adds a modulating factor to binary cross entropy that downweights easy examples so the model concentrates on hard ones. This is critical in object detection where background boxes vastly outnumber foreground boxes. TorchVision provides sigmoid_focal_loss as a first class implementation, and it typically improves mean average precision by several points over vanilla BCEWithLogitsLoss. Focal loss reduces to standard cross entropy when the gamma parameter is set to zero.
Modern detection heads combine a classification loss with a bounding box regression loss. Focal loss with sigmoid activation handles classification under extreme imbalance, while GIoU, DIoU, or CIoU handle box regression better than smooth L1. TorchVision ships these losses in torchvision.ops and inside reference implementations such as RetinaNet and FCOS. This combination is now the standard baseline for detection research.
KLDivLoss computes the Kullback Leibler divergence between two probability distributions represented as log probabilities and probabilities respectively. The input is expected to be log probabilities from log_softmax and the target is a probability distribution. Use it in knowledge distillation, in language model calibration, and in variational autoencoders. Pay attention to the reduction and log_target arguments, both of which have caused subtle bugs in published code.
Yes, torch.compile can trace and optimize custom losses as long as they stay inside sanctioned tensor operations. Avoid Python side data structures, NumPy calls, and dynamic control flow that graph tracing cannot follow. PyTorch 2.5 and 2.6 improved compile support for many loss patterns, including chunked cross entropy for long sequence language models. In practice most well written custom losses compile with no changes and run several times faster than eager mode.