NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #358 most downloaded on PyPI
Tensors and Dynamic neural networks in Python with strong GPU acceleration
Last release 18 days ago
02 Sep 2026
Ships fairly regularly
a new release about every 2 months
Nearly every release is documented
notes for 49 of 50 stable releases
Nothing withdrawn
no release was ever pulled
8 years old
50 releases · first in 2018
This is a backward compatibility-breaking change, please see this forum post for more details.
We are excited to announce the release of PyTorch® 2.6 (release notes)! This release features multiple improvements for PT2: torch.compile can now be used with Python 3.13; new performance-related knob torch.compiler.set_stance; several AOTInductor enhancements. Besides the PT2 improvements, another highlight is FP16 support on X86 CPUs.
NOTE: Starting with this release we are not going to publish on Conda, please see [Announcement] Deprecating PyTorch’s official Anaconda channel for the details.
For this release the experimental Linux binaries shipped with CUDA 12.6.3 (as well as Linux Aarch64, Linux ROCm 6.2.4, and Linux XPU binaries) are built with CXX11_ABI=1 and are using the Manylinux 2.28 build platform. If you build PyTorch extensions with custom C++ or CUDA extensions, please update these builds to use CXX_ABI=1 as well and report any issues you are seeing. For the next PyTorch 2.7 release we plan to switch all Linux builds to Manylinux 2.28 and CXX11_ABI=1, please see [RFC] PyTorch next wheel build platform: manylinux-2.28 for the details and discussion.
Also in this release as an important security improvement measure we have changed the default value for weights_only parameter of torch.load. This is a backward compatibility-breaking change, please see this forum post for more details.
This release is composed of 3892 commits from 520 contributors since PyTorch 2.5. We want to sincerely thank our dedicated community for your contributions. As always, we encourage you to try these out and report any issues as we improve PyTorch. More information about how to get started with the PyTorch 2-series can be found at our Getting Started page.
<table> <tr> <td>Beta </td> <td>Prototype </td> </tr> <tr> <td>torch.compiler.set_stance </td> <td>Improved PyTorch user experience on Intel GPUs </td> </tr> <tr> <td>torch.library.triton_op </td> <td>FlexAttention support on X86 CPU for LLMs </td> </tr> <tr> <td>torch.compile support for Python 3.13 </td> <td>Dim.AUTO </td> </tr> <tr> <td>New packaging APIs for AOTInductor </td> <td>CUTLASS and CK GEMM/CONV Backends for AOTInductor </td> </tr> <tr> <td>AOTInductor: minifier </td> <td> </td> </tr> <tr> <td>AOTInductor: ABI-compatible mode code generation </td> <td> </td> </tr> <tr> <td>FP16 support for X86 CPUs </td> <td> </td> </tr> </table>
*To see a full list of public feature submissions click here.
This feature enables the user to specify different behaviors (“stances”) that torch.compile can take between different invocations of compiled functions. One of the stances, for example, is
“eager_on_recompile”, that instructs PyTorch to code eagerly when a recompile is necessary, reusing cached compiled code when possible.
For more information please refer to the set_stance documentation and the Dynamic Compilation Control with torch.compiler.set_stance tutorial.
[Beta] torch.library.triton_op
torch.library.triton_op offers a standard way of creating custom operators that are backed by user-defined triton kernels.
When users turn user-defined triton kernels into custom operators, torch.library.triton_op allows torch.compile to peek into the implementation, enabling torch.compile to optimize the triton kernel inside it.
For more information please refer to the triton_op documentation and the Using User-Defined Triton Kernels with torch.compile tutorial.
[Beta] torch.compile support for Python 3.13
torch.compile previously only supported Python up to version 3.12. Users can now optimize models with torch.compile in Python 3.13.
[Beta] New packaging APIs for AOTInductor
A new package format, “PT2 archive”, has been introduced. This essentially contains a zipfile of all the files that need to be used by AOTInductor, and allows users to send everything needed to other environments. There is also functionality to package multiple models into one artifact, and to store additional metadata inside of the package.
For more details please see the updated torch.export AOTInductor Tutorial for Python runtime.
[Beta] AOTInductor: minifier
If a user encounters an error while using AOTInductor APIs, AOTInductor Minifier allows creation of a minimal nn.Module that reproduces the error.
For more information please see the AOTInductor Minifier documentation.
[Beta] AOTInductor: ABI-compatible mode code generation
AOTInductor-generated model code has dependency on Pytorch cpp libraries. As Pytorch evolves quickly, it’s important to make sure previously AOTInductor compiled models can continue to run on newer Pytorch versions, i.e. AOTInductor is backward compatible.
In order to guarantee application binary interface (ABI) backward compatibility, we have carefully defined a set of stable C interfaces in libtorch and make sure AOTInductor generates code that only refers to the specific set of APIs and nothing else in libtorch. We will keep the set of C APIs stable across Pytorch versions and thus provide backward compatibility guarantees for AOTInductor-compiled models.
[Beta] FP16 support for X86 CPUs (both eager and Inductor modes)
Float16 datatype is commonly used for reduced memory usage and faster computation in AI inference and training. CPUs like the recently launched Intel® Xeon® 6 with P-Cores support Float16 datatype with native accelerator AMX. Float16 support on X86 CPUs was introduced in PyTorch 2.5 as a prototype feature, and now it has been further improved for both eager mode and Torch.compile + Inductor mode, making it Beta level feature with both functionality and performance verified with a broad scope of workloads.
[Prototype] Improved PyTorch user experience on Intel GPUs
PyTorch user experience on Intel GPUs is further improved with simplified installation steps, Windows release binary distribution and expanded coverage of supported GPU models including the latest Intel® Arc™ B-Series discrete graphics. Application developers and researchers seeking to fine-tune, inference and develop with PyTorch models on Intel® Core™ Ultra AI PCs and Intel® Arc™ discrete graphics will now be able to directly install PyTorch with binary releases for Windows, Linux and Windows Subsystem for Linux 2.
For more information regarding Intel GPU support, please refer to Getting Started Guide.
[Prototype] FlexAttention support on X86 CPU for LLMs
FlexAttention was initially introduced in PyTorch 2.5 to provide optimized implementations for Attention variants with a flexible API. In PyTorch 2.6, X86 CPU support for FlexAttention was added through TorchInductor CPP backend. This new feature leverages and extends current CPP template abilities to support broad attention variants (e.x.: PageAttention, which is critical for LLMs inference) based on the existing FlexAttention API, and brings optimized performance on x86 CPUs. With this feature, it’s easy to use FlexAttention API to compose Attention solutions on CPU platforms and achieve good performance.
[Prototype] Dim.AUTO
Dim.AUTO allows usage of automatic dynamic shapes with torch.export. Users can export with Dim.AUTO and “discover” the dynamic behavior of their models, with min/max ranges, relations between dimensions, and static/dynamic behavior being automatically inferred.
This is a more user-friendly experience compared to the existing named-Dims approach for specifying dynamic shapes, which requires the user to fully understand the dynamic behavior of their models at export time. Dim.AUTO allows users to write generic code that isn’t model-dependent, increasing ease-of-use for exporting with dynamic shapes.
Please see torch.export tutorial for more information.
[Prototype] CUTLASS and CK GEMM/CONV Backends for AOTInductor
The CUTLASS and CK backend adds kernel choices for GEMM autotuning in Inductor. This is now also available in AOTInductor which can run in C++ runtime environments. A major improvement to the two backends is improved compile-time speed by eliminating redundant kernel binary compilations and dynamic shapes support.
There is a known regression (#144152) that torch.device(0) makes CUDA init fail in subprocess since PyTorch 2.5.0.
There was an attempt to fix the regressions, but it caused some complications and was reverted.
An easy workaround is to use torch.device('cuda') or torch.device('cuda:0') instead.
A regressions (https://github.com/pytorch/pytorch/issues/145220) was reported for PyTorch 2.6.0 with
compilation of the out= variant of the torch.all operator. This should be a rare use case, a workaround can be
rewriting the model code to avoid the out= variant.
We are closing the loop on the deprecation that started in 2.4 and flipped torch.load to use weights_only=True by default.
When this flag is set, instead of using the usual pickle module, torch.load uses a custom unpickler constrained to call only functions and classes needed for loading state dictionaries and basic types.
While this change is disruptive for users serializing more than basic types, we expect the increased security by default is a tradeoff that is worth it. Do note that, even though this default is safer, we still recommend only loading trusted checkpoints and rely on more constrained (and even safer) formats like safetensors for un-trusted checkpoints.
For full details, please refer to this dev-discuss post.
PyTorch will stop publishing Anaconda packages that depend on Anaconda’s default packages. We are directing users to utilize our official wheel packages from download.pytorch.org or PyPI, or switch to utilizing conda-forge (pytorch) packages if they would like to continue to use conda. For more details refer to this announcement
The PyTorch binaries shipped with CUDA 12.6.3 are built with CXX11_ABI=1 and are using the Manylinux 2.28 build platform. If you are building PyTorch extensions with custom C++ or CUDA extensions, please update these builds to use CXX_ABI=1 as well and report any issues you are seeing. For the next PyTorch 2.7 release we plan to switch all Linux builds to Manylinux 2.28 and CXX11_ABI=1, please see [RFC] PyTorch next wheel build platform: manylinux-2.28 for the details and discussion.
torch.onnx.export(..., dynamo=True) now creates ONNX models using IR version 10 (#141207)ONNX ir_version=10 is used to add support for UINT4, INT4 data types and include metadata in GraphProto and NodeProto. Make sure model consumers are able to accept IR version 10 ONNX models. You may read more about IRv10 on https://github.com/onnx/onnx/releases/tag/v1.16.0.
Some logging APIs, torch.onnx.ExportTypes, torch.onnx.export_to_pretty_string are removed. Users should remove usage of the APIs above.
torch.onnx.ONNXProgram has been reimplemented and improved (#136281)All ONNX "dynamo" APIs will return the new ONNXProgram class. Some notable methods available are save(), optimize(). It can also be directly applied on PyTorch tensors to leverage ONNX Runtime to verify the ONNX graph. Some legacy methods are no longer available.
The full release compatibility matrix matrix can be found in release.md
c10d::onCompletionHook (#142390)pg = dist.init_process_group()
def hook(work_info: torch._C._distributed_c10d.WorkInfo):
# do something
pg._register_on_completion_hook(hook)
# The hook will be triggered after the collective complete
pg.broadcast([tensor]).wait()
Instead of setting TORCHINDUCTOR_STACK_ALLOCATION, update your torch.compile call: torch.compile(options={"aot_inductor.allow_stack_allocation": True})(foo).
Tensor.dim_order() (#141632)ord argument for torch.linalg.{vector,matrix}_norm() (#137463)functional.affine_grid (#135494)device_id is given #138527)group_dst/group_src in c10d collectives (#140460, #139677, #140827, #140843, #140847)XCCL) in PyTorch distributed package (#141856)torch.compiler.set_stance to dynamically change torch.compile behavior without needing to re-apply torch.compile. (#137504)automatic_dynamic - automatically save and load automatic dynamic decisions to reuse on future runs (#139001)skip_guard_eval_unsafe compiler stance option for power users - skip guard checks when it is known to be safe to do so (#140251)torch.xpu.mem_get_info API: Introduces a new API to retrieve memory information for XPU devices. (#141230)elapsed_time method for XPU events: Introduces a method to measure elapsed time between XPU events. (#140865)torch.xpu.get_arch_list and torch.xpu.get_gencode_flags: Introduces new APIs to retrieve architecture lists and code generation flags for XPU. (#137773)torch.export.export_for_training() API to perform export that can run training. Note that this replaces the non-documented capture_pre_autograd_graph feature (#135374, #135918, #135549, #143224)torch._inductor.aoti_compile_and_package
torch._export.aot_compile), would return a path to a .so. However, this does not have a great user experience as actually there are other files that are used along with the .so, for example .cubin files and serialized extern kernels. So, we introduce a new package format, “PT2 archive”, which is what we intend to have AOTInductor return. This essentially contains a zipfile of all the files that need to be used by AOTInductor, and allows users to send to other environments. There is also functionality to package multiple models into one artifact, and to store additional metadata inside of the package.torch._inductor.aoti_compile_and_package, torch._indcutor.aoti_load_package, or running the loaded model of aoti_load_package on some inputs, you can use the AOTInductor Minifier to create a minimal nn.Module that reproduces the error. (#139351,#140999, #141159, #141156)export.export_for_inference and export.exported_program.core_aten_decompositions API. export_for_inference returns a functional, post-dispatch ATen IR. (#135912).torch.compile(options={"use_minimal_arrayref_interface": True})(foo) is now torch.compile(options={"aot_inductor.use_minimal_arrayref_interface": True})(foo) and torch.compile(options={"allow_stack_allocation": True})(foo) is now torch.compile(options={"aot_inductor.allow_stack_allocation": True})(foo).torch._utils.is_compiling to torch.compiler.is_compiling (#127690) Rewrite torch._utils.is_compiling() to torch.compiler.is_compiling().autotune_num_choices_displayed to control number of kernel options displayed (#138788)force_pointwise_cat concat support through inductor using pointwise kernels (#141966). This forces concat to be generated as a pointwise op with masked loads.annotate_training that adds Inductor annotations to NVTX. (#130429)triton_kernel_default_layout_constraint to tweak stride settings for user-defined Triton kernels, enhancing customization and flexibility (#135530).torch.compile(options={"triton_kernel_default_layout_constraint": "needs_fixed_stride_order"})(foo) (#135581).register_external_matmul for Matmul tuning candidates in Inductor (#130774).package_constants_in_so to exclude weights from .so files in AOTInductor (#141997).load_constants to the package API (#142246).torch.cond is supported (#137428)torch.cond is the recommended way to introduce control flows that can be converted to an ONNX model.
custom_translation_table to provide custom implementations for converting operators to ONNX (#135403)This is useful when you need to override an implementation or provide one that is not currently implemented. Refer to the tutorials for a more complete description of the operator registration mechanism.
# Define the translation using ONNX Script
from onnxscript import opset18 as op
def sym_not_onnx(input):
return op.Not(input)
torch.onnx.export(...
dynamo=True,
custom_translation_table = { # Then provide it here
torch.sym_not: sym_not_onnx,
})
ONNXProgram has a new optimize() method (#137667)Users can run optimize() to flatten nested structures in the ONNX graph, perform constant folding and remove redundancies in the ONNX model. Calling optimize() after exporting to ONNX is recommended.
onnx_program = torch.onnx.export(..., dynamo=True)
onnx_program.optimize() # Optimize the graph before saving is recommended
onnx_program.save(...)
torch.special.i1 (#137899)torch.save (#137735)torch.adaptive_pool3d on cpu (#136091)torch.masked_select (#141928)torch.{linalg.}norm complex half support (#133661)nn.utils.clip_grad_norm_ (#139662)weight argument to MSELoss, HuberLoss and L1Loss (#132049)torch.nn.Linear and torch.nn.Bilinear (#135596)ReduceLROnPlateau and Optimizer.add_param_group interaction by auto-updating min_lrs (#137637)SequentialLR to include ChainedScheduler (#133450)Operator decompositions, FakeTensors and meta tensors are used to trace out a graph in torch.compile and torch.export. They received several improvements:
aten.split_with_sizes (#135728)aten.max_unpool2d/aten.max_unpool3d (#133146)aten.dot (#138596)aten.layer_norm (#140557)aten.scaled_dot_product_attention (#135297)aten.matmul (#134568)aten._embedding_bag (#136774)aten.native_group_norm/aten.native_layer_norm (#137079)aten.to(..., non_blocking=True) (#136513)Aten.addmm (#138520)out= dtype checks for unary ops (#140288)aten.diagonal_copy (#136730)Dynamic shapes
We made many improvements and bugfixes to dynamic shapes in torch.compile
native_layer_norm_backward work with unbacked SymInts (#136798)masked_fill work with unbacked SymIntsl (#137060)torch.cat with large numbers of symbolic variables (#139653)canonicalize_bool_expr (#135621)sympy_generic_le (#135622)_maybe_evaluate_static (#135499)Add._from_args and Mul._from_args (#136143)_SympyT to enable more folding (#138235)new_unbacked_bindings if needed. (#140083)has_free_unbacked_symbols instead of bool(free_unbacked_symbols) (#140027)TORCHDYNAMO_EXTENDED_ADVICE (#137159) (#137196)get_implications (#139738)Custom operators
We improved the existing torch.library APIs and added new ones.
torch.library.triton_op API (#141880)torch.library.register_vmap to work with nested vmap (#137306)torch.library.custom_op APIs on torch.deploy (#139509)torch.library.custom_op overhead (#139513)torch.library.opcheck and register_autograd docs (#141883)cuStreamWriteValue32 (#136488)CudaDMAConnectivityDetector (#137530)world_size=0 to TCPStore (#137792)nccl_nonblocking_timeout (#138374)device_id provided (#140963)P2POp and batch_isend_irecv (#141054)CudaEventCache by default and add multi device support (#140975)PyProcessGroup (#141529)_reduce_scatter_base to c10d::ProcessGroupUCC (#138021)_set_unshard_async_op (#135523)fsdp_pre_all_gather (#136129)all-gather extensions (#137005)shard_placement_fn arg (#137496)set_unshard_in_backward(bool) (#137922)PipelineStage support meta initialization (#136243)rms_norm(), embedding_bag(), record_stream(), rad2deg(), embedding() backward, activation functions (#135872, #135888, #140736, #138627, #137099, #140290)torch.bmm(NST, NST) (#141380)torch.scatter_reduce (#135547)native_dropout_backward (#140140)torch.func.functional_call (#134643))X86InductorQuantizer (#136298)torch.uint16 in quantization and export (#136547)linear_dynamic_fp16 ops for OneDNN (#140376)linear_dynamic_fp16 for x86 (#141480)cuda_flip to unsigned types (#137781)upsample_bicubic2d as Metal op (#136123)scatter_reduce.two (#141948)torch.special.i1 op (#140196)unfold_backward on MPS (#135411)isposinf and isneginf (#136689)MetalShaderLibrary::getFunctionNames() (#141499)tri[lu]_indices (#137648)fmin/fmax/copysign and nextafter to bfloat16 (#136982)arange to bfloat16 (#136754)torch.linalg.cross for bfloat16 (#136984)nan_to_num for bfloat16 (#136986)c10::value_or_else (#138818)torch.Event for MPS (#142468)torch.float8e4m3fn dtype support to semi-structured sparse (#136397)num_threads before default (#136793, #137051)automatic_dynamic_shapes_mark_as - adds an option to cause automatic dynamic shapes to trigger unbacked SymInts rather than backed SymInts (#141415)torch.compile support for Python 3.13 (#139533)export preserves node.meta["custom"] field (#138266)neg and pos operator to serde/serialize (#138309, #143343)_inline_module util function to work with both args and kwargs (#136631)_replace_hook to a list of Callable (#142006)keep_original_order=True and no-op graph (#141340)fx.Graph (#139770)stride in TensorMetadata to always be a Tuple[int, ...] (#141106)from_node node meta to track source recursively (#142066)fuse_by_partitions to always return output as tuple (#142056)custom_op_default_layout_constraint in Inductor to optimize tensor layout (#135239).relu_nan_to_num option for handling NaNs in pre-grad passes in AOTInductor (#138545).env_name_default and env_name_force for better configuration management (#138956).from dynamic axes to shapes (#140488)torch.mean(..., out=) for fp16 and bf16 on CPU (#135174)torch.uint16, torch.uint32, torch.uint64 (#137184)torch.utils.module_tracker.ModuleTracker (#141960)nn.functional.softshrink returning 0 on NAN input (#138421)torch.nn.EmbeddingBag when per_sample_weights is differentiable but embedding weights are not (#142338)torch.compiling torch.scaled_dot_product_attention, in the case where the scale argument is a dynamic shape (#141728)torch.compiling torch.rrelu, in the case where it mutates any module buffers (#136008)destroy_process_group (#141510)ProcessGroup and Expose backend Options to reflect the correct code structure (#132931) (#135653)all-reduce (#137257)all-reduce (#137345)CUDAEventCache is enabled (#138040)alltoall (#141816)ncclCommSplit (#138781)IntraNodeComm::rendezvous() (#141200)_are_we_tracing() in dynamo for functional collectives (#142075)from_group when passing a tensor mesh (#137713)test_all_gather_extensions_monkey_patch (#136130).to(dtype) (#137593)stage_backward (#136507)_validate_schedule (#142211)torch.compile (#135819)sum(), unsqueeze(), to() on non-contiguous NJTs, where(), select(), chunk(), reductions (#131945, #141392, #137124, #141500, #139317, #141506, #141604)linear_backward() memory usage using a more efficient formula (#141163)nll_loss (#135434)torch.normal (#136863)channels_last_3d in nn.Conv3d (#141780)c10::Event unit test failure on XPU backend (#141800)F.logsigmoid (#141333)UnicodeDecodeError: 'utf-8' codec can't decode byte (#139062)ideep:lowp_kind to matmul_forward::compute on cache misses (#135058)torchao/quantization/utils.py to targeted device to avoid device mismatch issue (#135204)dilation in torch.quantized_max_pool3d() (#137845)prepare_pt2e graph with concat of the same node (#141651)bmm(COO, dense) illegal memory access for some shapes (#131977)sparse_csr layout (#134335)torch.package for 3.13 (#141409)_get_non_persistent_buffers for duplicate submodules (#136552)make_fx(#137240)export for constant outputs (#137547, #137993)export_for_training (#138292) AttrProxy._modules when module is overwritten as None (#139957)torch.Size (#137465)test_lazy_module_kwargs (#137705)is_export flag to FunctionalTensorMode in analysis pass (#138836)__init__.py to shape inference folder. (#135461)sympy.oo in bitwise_and/or value_ranges (#141522)abi_compatible (#136233)_dynamo.compiled_autograd.reset() (#137889)atomic_add_vec (#138744)clone_preserve_strides (#139224, #139458)torch.compile compiler error when march=aarch64+sve (#137795)Note truncated.
One column per quarter.
This release is meant to fix the following regressions:
This release is meant to fix the following regressions:
Besides the regression fixes, the release includes several documentation updates.
See release tracker https://github.com/pytorch/pytorch/issues/132400 for additional information.
The deprecated torch.onnx.SymbolicContext class has been removed. (Non-dynamo) custom symbolic functions can no longer take ctx: torch.onnx.SymbolicCo…
We are excited to announce the release of PyTorch® 2.5! This release features a new CuDNN backend for SDPA, enabling speedups by default for users of SDPA on H100s or newer GPUs. As well, regional compilation of torch.compile offers a way to reduce the cold start up time for torch.compile by allowing users to compile a repeated nn.Module (e.g. a transformer layer in LLM) without recompilations. Finally, TorchInductor CPP backend offers solid performance speedup with numerous enhancements like FP16 support, CPP wrapper, AOT-Inductor mode, and max-autotune mode. This release is composed of 4095 commits from 504 contributors since PyTorch 2.4. We want to sincerely thank our dedicated community for your contributions. As always, we encourage you to try these out and report any issues as we improve 2.5. More information about how to get started with the PyTorch 2-series can be found at our Getting Started page. As well, please check out our new ecosystem projects releases with TorchRec and TorchFix.
| Beta | Prototype |
|---|---|
| CuDNN backend for SDPA | FlexAttention |
| torch.compile regional compilation without recompilations | Compiled Autograd |
| TorchDynamo added support for exception handling & MutableMapping types | Flight Recorder |
| TorchInductor CPU backend optimization | Max-autotune Support on CPU with GEMM Template |
| TorchInductor on Windows | |
| FP16 support on CPU path for both eager mode and TorchInductor CPP backend | |
| Autoload Device Extension | |
| Enhanced Intel GPU support |
*To see a full list of public feature submissions click here.
The cuDNN "Fused Flash Attention" backend was landed for torch.nn.functional.scaled_dot_product_attention. On NVIDIA H100 GPUs this can provide up to 75% speed-up over FlashAttentionV2. This speedup is enabled by default for all users of SDPA on H100 or newer GPUs.
Regional compilation without recompilations, via torch._dynamo.config.inline_inbuilt_nn_modules which default to True in 2.5+. This option allows users to compile a repeated nn.Module (e.g. a transformer layer in LLM) without recompilations. Compared to compiling the full model, this option can result in smaller compilation latencies with 1%-5% performance degradation compared to full model compilation.
See the tutorial for more information.
This feature advances Inductor’s CPU backend optimization, including CPP backend code generation and FX fusions with customized CPU kernels. The Inductor CPU backend supports vectorization of common data types and all Inductor IR operations, along with the static and symbolic shapes. It is compatible with both Linux and Windows OS and supports the default Python wrapper, the CPP wrapper, and AOT-Inductor mode.
Additionally, it extends the max-autotune mode of the GEMM template (prototyped in 2.5), offering further performance gains. The backend supports various FX fusions, lowering to customized kernels such as oneDNN for Linear/Conv operations and SDPA. The Inductor CPU backend consistently achieves performance speedups across three benchmark suites—TorchBench, Hugging Face, and timms—outperforming eager mode in 97.5% of the 193 models tested.
We've introduced a flexible API that enables implementing various attention mechanisms such as Sliding Window, Causal Mask, and PrefixLM with just a few lines of idiomatic PyTorch code. This API leverages torch.compile to generate a fused FlashAttention kernel, which eliminates extra memory allocation and achieves performance comparable to handwritten implementations. Additionally, we automatically generate the backwards pass using PyTorch's autograd machinery. Furthermore, our API can take advantage of sparsity in the attention mask, resulting in significant improvements over standard attention implementations.
For more information and examples, please refer to the official blog post and Attention Gym.
Compiled Autograd is an extension to the PT2 stack allowing the capture of the entire backward pass. Unlike the backward graph traced by AOT dispatcher, Compiled Autograd tracing is deferred until backward execution time, which makes it impervious to forward pass graph breaks, and allows it to record backward hooks into the graph.
Please refer to the tutorial for more information.
Flight recorder is a new debugging tool that helps debug stuck jobs. The tool works by continuously capturing information about collectives as they run. Upon detecting a stuck job, the information can be used to quickly identify misbehaving ranks/machines along with code stack traces.
For more information please refer to the following tutorial.
Max-autotune mode for the Inductor CPU backend in torch.compile profiles multiple implementations of operations at compile time and selects the best-performing one. This is particularly beneficial for GEMM-related operations, using a C++ template-based GEMM implementation as an alternative to the ATen-based approach with oneDNN and MKL libraries. We support FP32, BF16, FP16, and INT8 with epilogue fusions for x86 CPUs. We’ve seen up to 7% geomean speedup on the dynamo benchmark suites and up to 20% boost in next-token latency for LLM inference.
For more information please refer to the tutorial.
Inductor CPU backend in torch.compile now works on Windows. We support MSVC (cl), clang (clang-cl) and Intel compiler (icx-cl) for Windows inductor currently.
See the tutorial for more details.
Float16 is a commonly used reduced floating point type for performance improvement in neural network inference/training. Since this release, float16 for both eager and TorchInductor is supported on the CPU path.
PyTorch now supports autoloading for out-of-tree device extensions, streamlining integration by eliminating the need for manual imports. This feature, enabled through the torch.backends entrypoint, simplifies usage by ensuring seamless extension loading, while allowing users to disable it via an environment variable if needed.
See the tutorial for more information.
Intel GPUs support enhancement is now available for both Intel® Data Center GPU Max Series and Intel® Client GPUs (Intel® Core™ Ultra processors with built-in Intel® Arc™ graphics and Intel® Arc™ Graphics for dGPU parts), which is to make it easier to accelerate your Machine Learning workflows on Intel GPUs in PyTorch 2.5 release. We also enabled the initial support of PyTorch on Windows for Intel® Client GPUs in this release.
These features are available through PyTorch preview and nightly binary PIP wheels. For more information regarding Intel GPU support, please refer to documentation.
[c10d] Remove Option for ProcessGroup and Expose backend Options to reflect the correct code structure (#132931)
# Users can pass in a basic option when creating an instance of ProcessGroup
base_pg_options = ProcessGroup.Options(backend=str(backend))
base_pg_options._timeout = timeout
pg: ProcessGroup = ProcessGroup(
store, rank, group_size, base_pg_options
)
# Users then need to create a backend option to create the comm backend (e.g., ProcessGroupNCCL)
pg_options = ProcessGroupNCCL.Options()
backend = ProcessGroupNCCL(
store, rank, group_size, pg_options
)
# No basic option is passed in when creating a instance of ProcessGroup
pg: ProcessGroup = ProcessGroup(store, rank, group_size)
pg._set_default_backend(Backend.backend_type_map[backend])
# Users then need to create a backend option to create the comm backend (e.g., ProcessGroupNCCL)
pg_options = ProcessGroupNCCL.Options()
backend = ProcessGroupNCCL(
store, rank, group_size, pg_options
)
dynamic_dim() (#134211)
dynamic_dim() method for specifying dynamic shapes in torch.export() has been removed. Please refer to the export tutorial for using Dims to specify dynamic shapes.[Torch] Support meta device in checkpoint (#132684)
Switch to internal benchmarking and update benchmarking path (#132827)
This change moves from using triton’s benchmarking utils to the internal inductor utils at torch._inductor.runtime.benchmarking. To update your benchmarking code:
# before
from torch._inductor.runtime.runtime_utils import do_bench_gpu
# ...
do_bench_gpu(kernel, rep=40, fast_flush=True)
# after
from torch._inductor.runtime.benchmarking import benchmarker
# ...
benchmarker.benchmark_gpu(kernel_call, rep=40, fast_flush=True)
Update fused kernels and call _safe_softmax from SDPA (#131863)
Before this PR, fully masked rows in the attn_mask passed to nn.functional.scaled_dot_product_attention would yield NANs in the output, after this PR, fully masked rows yield 0s.
Example:
2.4.0
B, S, D = 1, 1, 128
q = torch.randn(B, S, D, device='cuda')
k = torch.randn(B, S, D, device='cuda')
v = torch.randn(B, S, D, device='cuda')
attn_mask = torch.tensor([False], device='cuda')
F.scaled_dot_product_attention(q, k, v, attn_mask=attn_mask)
tensor([[[nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan,
nan, nan, nan, nan, nan, nan, nan, nan, nan]]], device='cuda:0')
2.5.0
B, S, D = 1, 1, 128
q = torch.randn(B, S, D, device='cuda')
k = torch.randn(B, S, D, device='cuda')
v = torch.randn(B, S, D, device='cuda')
attn_mask = torch.tensor([False], device='cuda')
F.scaled_dot_product_attention(q, k, v, attn_mask=attn_mask)
tensor([[[-0., -0., 0., -0., 0., 0., -0., -0., -0., -0., 0., -0., -0., -0., 0., -0., 0., 0., -0., -0., 0., -0., -0.,
0., 0., -0., 0., -0., -0., 0., -0., -0.]]], device='cuda:0')
GradScaler for respecting an already set grad_scale value (#123429)torch.onnx.export (except for the first three arguments) are now keyword-only (#131501)Options can be supplied by keywords only to allow for future addition and evolution of the torch.onnx.export API.
Example:
Version 2.4
torch.onnx.export(model, input, f, True, False)
Version 2.5:
torch.onnx.export(model, input, f, export_params=True, verbose=False)
torch.onnx._export has been removed (133824)torch.onnx._export is an internal API which is not meant for public consumption. Use the public torch.onnx.export instead.
Example:
Version 2.4
torch.onnx._export(...)
Version 2.5:
torch.onnx.export(...)
op_level_debug option from torch.onnx.ExportOptions has been removed (#134961)This option, designed to identify operator discrepancies, proved unreliable and has been removed. Instead, use torch.onnx.export(..., report=True, verify=True) option to validate exported models.
ONNXProgramSerializer class has been removed (#135261)The ONNX model in torch.onnx.ONNXProgram is now maintained and serialized by ONNX IR.
textproto, onnxtext, and json formats are supported by default when calling ONNXProgram.save() with a corresponding file extension.
SymbolicContext class has been removed (#132184)The deprecated torch.onnx.SymbolicContext class has been removed. (Non-dynamo) custom symbolic functions can no longer take ctx: torch.onnx.SymbolicContext as the first argument.
onnx_unpack_quantized_weights (#129021)is_caffe2_aten_fallback in torch.onnx.symbolic_helperCheckerError and InvalidExportOptionsError are removed. Users can always catch RuntimeError to handle torch.onnx export errors.
torch._dynamo.utils.CompileProfiler (#135133)None for specifying static dimensions in dynamic_shapes (#134877)<br>
The use of None at the dimension-level for specifying dynamic shapes is now deprecated, and a user warning will be raised, so please use Dim.STATIC in its place. Specifying None for an entire input, or an entire program, is still supported.search_autotune_cache (#133628)torch.onnx.export is deprecated (#131501)The ability to supply model keyword arguments as a final dictionary is deprecated. Users should use the kwargs parameter instead.
Deprecated:
torch.onnx.export(model, (arg1, arg2, {“kwarg1”: …}))
Future:
torch.onnx.export(model, (arg1, arg2), kwargs={“kwarg1”: …})
torch.onnx.OperatorExportTypes is deprecated (#131501)The ability to supply operator_export_type in torch.onnx.export() is deprecated. Exported ONNX graphs will always use the ONNX opset domain. Options ONNX_FALLTHROUGH, ONNX_ATEN and ONNX_ATEN_FALLBACK are no longer supported. The OperatorExportTypes class will be removed in a future release.
training option in torch.onnx.export is deprecatedSet the model training mode first before exporting instead.
Deprecated:
torch.onnx.export(model, inputs, path, training=torch.onnx.TrainingMode.EVAL)
Future:
model = model.eval()
torch.onnx.export(model, inputs, path)
torch.utils.checkpoint (#125795, #129262)all-gather and reduce-scatter (#130583)torch._dynamo.config.enable_compiler_collectives for syncing compilation across ranks (#130935)export_for_training [WIP/unstable] (#129092, #130062, #134677, #135549)FlexAttention API public (#130755)nn.Modules.set_submodule() like get_submodule (#127714)nn.Buffer like nn.Parameter (#125971)__torch_function__ handler to Tensor.get_device cpp (#132567)torch.serialization.skip_data context manager to create a metadata-only checkpoint (#134504)torch.serialization.safe_globals context manager to work with weights_only serialization (#127939)_numeric_debug_handle throguh deepcopy and re-export (#129287)numeric_debugger top level APIs (#130643)node.meta["custom"] field (#134040)dynamo=True option and new export logic (#132530, #133743, #134304, #134782, #135378, #135399, #135786, #136162, #135134, #134976, #135367, #135418, #135591, #135520)We introduce the dynamo=True option in torch.onnx.export(). This is recommended as a replacement for torch.onnx.dynamo_export starting in PyTorch 2.5.
Version 2.5:
onnx_program = torch.onnx.export(model, inputs, kwargs=kwargs, dynamo=True)
# Use the external_data option to save weights as external data
onnx_program.save(“model.onnx”, external_data=True)
# To save without initializers
onnx_program.save(“model.onnx”, include_initializers=False, keep_initializers_as_inputs=True)
torch.onnx.export(model, args, dynamo=True, report=True, verify=True) leverages torch.export and ONNX IR to convert captured ExportedPrograms to ONNX efficiently and robustly. This new process reduces memory consumption by half compared to dynamo_export in 2.4, while preserving rich tensor shape and stack trace information in the ONNX graph. You can leverage the report=True option to obtain a conversion report in markdown format to diagnose any conversion issues. Set verify=True to verify the ONNX model numerically with ONNX Runtime.
When using external_data=True to save model weights as external data to the .onnx file, weights larger than 1 MB are now aligned at 64 KB addresses. This allows runtimes to memory-map weights for better memory efficiency during inference.
[NOTE]
Thedynamo=Trueoption currently supports only ONNX opset 18. Future releases will expand support to newer opsets.
[NOTE]
Thedynamo=Trueoption requires the latest versions ofonnxscriptandonnxpackages.
torch.autograd.grad (#127766)torch.autograd.graph.increment_version accept List[Tensor] (#132652)torch.autograd.graph.Node.register_hook during Node execution are run (#134728)from __future__ import annotations (#128809)mutates_args=”unknown” for if you didn’t know the alias information of your custom op (#129614)register_flop_formula now actually does something for custom ops (#131777)Operator decompositions, FakeTensors and meta tensors are used to trace out a graph in torch.compile and torch.export. They received several improvements:
padding_side to pad_sequence with "left" and "right" options ("right" as default) (#131884)kwargs to composable AC API to enable full capabilities (#128516)ActivationWrapper an abstract class (#129808)somaxconn and enabled TCP_NODELAY to TCPStoreLibUvBackend (#128739)TCPStore (#129261)TCPStore (#129985)new_group eager when used with comm_split (#129284)split_group to create a process group (#130507)bfloat16 support for NAN check (#131131)ProcessGroupNCCL barrier all-reduce (#132701)ProcessGroupNCCL watchdog timeout (#133028)ncclCommAbort if comm is not initialized (#133630)DTensor to public namespace (#134203)slice_backward to use op strategy (#130287)from_local API with run_check (#130289)nn.init.orthogonal_ (#132104)scaled_dot_product_efficient_attention and scaled_dot_product_flash_attention more conservatively cached (#134146)DTensor for foreach ops so model doesn't have to be fully tp-ed when using 2D (#134551)DTensor (#132816)DTensor after torch.distributed.checkpoint.state_dict.set_optimizer_state_dict (#128004)state_dict (#128685)clip_grad_norm_ norm compute order deterministic (#134673)dataclass(frozen=True) (#135067)FSDPParamGroup record_functions (#128624)set_post_optim_event (#128975)contract to allow Sequence[nn.Module] (#127773) (#130947)List[nn.Module] as arg (#130949)fsdp.set_ op through lowering (#130786)set_reduce_scatter_divide_factor (#129286)_get_remote_device_str (#132120)FSDPParamGroup and FSDPParam (#132350)fsdp.set_ convey to functionalization that it mutates storage (#132322)FSDPParam.sharded_param in lazy_init (#132954)replicate and fully_shard (#133059)TCPStore by default when using c10d_rendezvous_backend (#128096)wait instead of get for store barrier (#130148)TCPStore backend type and rely on c10d to decide which backend to use (#134882)local_addr across all rendezvous implementations (#135262)mp.start_processes for forkserver (#134629)SequenceParallel and its documentation (#131346)dw_runner for PipelineStage (#128983)_Action from F1_1 to 1F1 (#129786)unshard/reshard pass (#129810)send/recv pass (#130378)zb1p schedule (#130210)get_schedule_class util (#132768)discard (#133317), intersection (#130672), remove (#132943))inspect.signature.bind (#132330) and inspect.signature.Parameter attribute access (#134636)random.Random objects (#133725)set on KeysView (#131389)dict conversion of objects derived from MutableMapping (#131367), constrained subclasses of dict and OrderedDict (#132558)__contains__ on __dict__ of user defined classes (#131378)abc.MutableMapping.get (#132363)frozenset (#134563)__new__ (#132977), object.__new__ (#133746)torch.cuda.device (#133385)id(Parameter) (#130100)str on UserDefinedObjectVariable (#130506)out-variant custom ops that return None (#129078)autograd.Function mark_non_differentiable (#134087), ctx.set_materialize_grads (#133978)ModelOutput class (#127780)mark_static can now be used on nn.Modules to make int attributes static (instead of automatic dynamic) (#134713)export_for_training (#128077, #129249, #134801)run_decompositions() (#130970, #131075)torch.amp.autocast_mode as a higher-order-op subgraph (#132677)ExportedProgram.validate() public-facing (#132777)“custom” metadata field (#131912)getitem deduplication pass (#133618, #134830)move_to_device_pass public-facing (#134263)while_loop higher-order-op public-facing (#128562)TORCHEXPORT_EXTENDED_DEBUG_CURRENT_LOC=1 flag for line-by-line debugging in non-strict mode (#134298)aten.full.default and aten.full_like.default (#130639)aten.to.dtype + mutation_op pattern for TSConverter (#132529)InterpreterModule to trace_rules (#132949)tracing_mode support for TorchBind (#129586)set_grad_enabled higher-order-op in dynamo to enable re-tracing (#134281)_foreach_sigmoid and _foreach_lgamma (#134253, #134344)get_isolated_graphmodule (#130886)meta["val"] that is a dict, for triton kernels and for the partitioner (#132466)max_acc_splits (#133041, #133724)fx.Graph.lint (#135069)python_code(verbose=True) (#132192)do_bench_using_profiling in TORCHINDUCTOR_PROFILE (#133523)TORCHINDUCTOR_CPP_GEMM_THREAD_FACTORS (#132730)nn.Module.mtia() (#131499)_init_group to allow better error checking in more cases (#131153)torch.serialization.set_default_mmap_options usable as a context manager (#134371)set_module_name_qconfig in X86InductorQuantizer (#126044)onnxruntime (#134662)torch.autograd.graph.register_multi_grad_hook (#132055)torch.autograd.graph.saved_tensors_hooks (#131700)torch.autograd.graph.saved_tensors_hooks to not detach when unpacking tensors that do not require grad (#127959)torch.utils.checkpoint (#128671)Fix interaction between torch.conj() tensor subclasses and scalar tensors (#131482)
Better complex number support for aliasing prim operators (#132699)
AOTDispatcher is a component in the torch.compile stack responsible for capturing a graph of normalized/functionalized ATen IR as well as capture the backward. A few bugfixes this release:
Dynamic Shapes
avg_pool_2d backward attempt 2 (#129818)commSplit bug by having every rank being called even though it is no-color (#128459)torch.distributed.barrier()'s streamSynchronize (#129908)ENABLE_INTRA_NODE_COMM=1 + multiple process groups leads to failure (#130269)all-reduce (#131244)split_group usage when there is a single rank (#131824)TCPStore (#131773) (#131913)DeviceMesh initialization (#133024)foreach_norm when ord is 2 (#130753)_MaskPartial when multiple embeddings coexist (#131264)unshard without lazy init (#129241)loss_parallel with BF16 logits (#130550).data mutations invisible to autograd (#131403)TorchDispatchMode is enabled (#131828)nn_module_stack is the same when inlining inbuilt nn.Modules (#128295)post_acc_grad_hooks (#134205) and ctx.saved_variables (#134286)OptimizedModule.training flag now mirrors the wrapped module. (#131546)map/zip and return map/zip instead of a tuple (#135074)list_backends (#132546)preserve_module_call_signature (#128260).requires_grad on FakeTensors in graph metadata (#128656)aot_export (#128844)source_fn_stack for training IR (#132033).requires_grad for unflattened parameters (#134353)aten::to for training IR (#134622)node.users when inlining higher-order-ops (#133144)linearize(grad(...)) call by moving DCE (#133364)linalg.lstsq (#130612)torch.[all|any] for 5+D tensors (#130542)toAccumulateType signature in Normalization.cpp (#134540)ldexp (#133519)scaled_dot_product_attention (#133314)scaled_dot_product_attention with float scale (#135594)nn.Module.__getattr__ (#129315)nn.Module._call_impl (#129285)torch.nn.Module.parameters (#129583)getitems (#130654)PolyfilledFunctionVariable.call_function (#134842)get_implications calls (#128410)Node.__update_args_kwargs (#135076)setattr in Node.__init__ (#135079)Note truncated.
This release is meant to fix the following issues (regressions / silent correctness):
This release is meant to fix the following issues (regressions / silent correctness):
Release tracker #132400 contains all relevant pull requests related to this release as well as links to related issues.
Vulnerability related updates of packages used in CI (#124614, #124675, #124976, #124983, #125698, #126805, #126989)
We are excited to announce the release of PyTorch® 2.4!
PyTorch 2.4 adds support for the latest version of Python (3.12) for torch.compile.
AOTInductor freezing gives developers running AOTInductor more performance based optimizations by allowing the
serialization of MKLDNN weights. As well, a new default TCPStore server backend utilizing libuv has been introduced
which should significantly reduce initialization times for users running large-scale jobs.
Finally, a new Python Custom Operator API makes it easier than before to integrate custom kernels
into PyTorch, especially for torch.compile.
This release is composed of 3661 commits and 475 contributors since PyTorch 2.3. We want to sincerely thank our dedicated community for your contributions. As always, we encourage you to try these out and report any issues as we improve 2.4. More information about how to get started with the PyTorch 2-series can be found at our Getting Started page.
<table> <tr> <td>Beta </td> <td>Prototype </td> <td>Performance Improvements </td> </tr> <tr> <td>Python 3.12 support for torch.compile </td> <td>FSDP2: DTensor-based per-parameter-sharding FSDP </td> <td>torch.compile optimizations for AWS Graviton (aarch64-linux) processors </td> </tr> <tr> <td>AOTInductor Freezing for CPU </td> <td>torch.distributed.pipelining, simplified pipeline parallelism </td> <td>BF16 symbolic shape optimization in TorchInductor </td> </tr> <tr> <td>New Higher-level Python Custom Operator API </td> <td>Intel GPU is available through source build </td> <td>Performance optimizations for GenAI projects utilizing CPU devices </td> </tr> <tr> <td>Switching TCPStore’s default server backend to libuv </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> </tr> </table>
*To see a full list of public feature submissions click here.
There is a reported issue (#131070) when using torch.compile if onnxruntime-training lib is
installed. The issue will be fixed (#131194) in v2.4.1. It can be solved locally by setting the environment variable
TORCHINDUCTOR_WORKER_START=fork before executing the script.
It was also reported (#130684) that the new version of triton uses cuda features that are not compatible with pre-cuda12 drivers.
In this case, the workaround is to set
TRITON_PTXAS_PATH manually as follows (adapt the code according to the local installation path):
TRITON_PTXAS_PATH=/usr/local/lib/python3.10/site-packages/torch/bin/ptxas python script.py
TreadPool size to number of physical cores (#125963)Changed the default number of threads used for intra-op parallelism from the number of logical cores to the number of physical cores. This should reduce core oversubscribing when running CPU workload and improve performance. Previous behavior can be recovered by using torch.set_num_threads to set the number of threads to the desired value.
torch.quasirandom.SobolEngine.draw default dtype handling (#126781)The default dtype value has been changed from torch.float32 to the current default dtype as given by
torch.get_default_dtype() to be consistent with other APIs.
torch._C._TensorBase directly (#125558)This is an internal subclass that a user used to be able to create an object that is almost a Tensor in Python and was advertised as such in some tutorials. This is not allowed anymore to improve consistency and all users should subclass torch.Tensor directly.
torch.compile will raise an error (#122502)The torch.compile flow involves functionalizing any mutations inside the region being compiled. Torch.as_strided is
an existing view op that can be used non-compositionally: meaning when you call x.as_strided(...), as_strided will only
consider the underlying storage size of x, and ignore its current size/stride/storage_offset when creating a new view.
This makes it difficult to safely functionalize mutations on views of as_strided that are created non-compositionally,
so we ban them rather than risking silent correctness issues under torch.compile.
An example of a non-compositional usage of as_strided followed by mutation that we will error on is below. You can avoid this issue by re-writing your usage of as_strided so that it is compositional (for example: either use a different set of view ops instead of as_strided, or call as_strided directly on the base tensor instead of an existing view of it).
@torch.compile
def foo(a):
e = a.diagonal()
# as_strided is being called on an existing view (e),
# making it non-compositional. mutations to f under torch.compile
# are not allowed, as we cannot easily functionalize them safely
f = e.as_strided((2,), (1,), 0)
f.add_(1.0)
return a
Previously, you could register a custom op through the operator registration APIs, but give it a schema that contained types unknown to the PyTorch Dispatcher. This behavior came from TorchScript, where “unknown” types were implicitly treated by the TorchScript interpreter as type variables. However, calling such a custom op through regular pytorch would result in an error later. As of 2.4, we will raise an error at registration time, when you first register the custom operator. You can get the old behavior by constructing the schema with allow_typevars=true.
TORCH_LIBRARY(my_ns, m) {
// this now raises an error at registration time: bar/baz are unknown types
m.def("my_ns::foo(bar t) -> baz");
// you can get back the old behavior with the below flag
m.def(torch::schema("my_ns::foo(bar t) -> baz", /*allow_typevars*/ true));
}
The torch.autograd.function.traceable(...) API, which sets the is_traceable class attribute on a torch.autograd.Function class was deprecated in 2.3 and is now being deleted. This API does not do anything and was only meant for internal purposes. The following raised an warning in 2.3, and now errors because the API has been deleted:
@torch.autograd.function.traceable
class Func(torch.autograd.Function):
...
SparseAdam weird allowance of raw Tensor input (#127081).Update get_group and add get_all_groups (#128097) In 2.3 and before, users can do:
mesh_2d = init_device_mesh(
"cuda", (2, 2), mesh_dim_names=("dp", "tp")
)
mesh_2d.get_group() # This will return all sub-pgs within the mesh
assert mesh_2d.get_group()[0] == mesh_2d.get_group(0)
assert mesh_2d.get_group()[1] == mesh_2d.get_group(1)
But from 2.4 forward, if users call get_group without passing in the dim, users will get a RuntimeError.
Instead, they should use get_all_groups:
mesh_2d = init_device_mesh(
"cuda", (2, 2), mesh_dim_names=("dp", "tp")
)
mesh_2d.get_group() # This will throw a RuntimeError
assert mesh_2d.get_all_groups()[0] == mesh_2d.get_group(0)
assert mesh_2d.get_all_groups()[1] == mesh_2d.get_group(1)
Retire torch.distributed.pipeline (#127354) In 2.3 and before, users can do:
import torch.distributed.pipeline # warning saying that this will be removed and users need to migrate to torch.distributed.pipelining
But from 2.4 forward, if users write the code above, users will get a ModuleNotFound error.
Instead, they should use torch.distributed.pipelining:
import torch.distributed.pipeline # -> ModuleNotFoundError
import torch.distributed.pipelining
Complete revamp of float/promotion sympy handling (#126905)
torch.load with default weights_only=False value (#129239, #129396, #129509).
A warning is now raised if the weights_only value is not specified during a call to torch.load, encouraging users to
adopt the safest practice when loading weights.torch.compile to provide a nice error
message when tracing custom ops into a graph that are not written in a PT2-friendly way (because, for example, they
try to directly access a tensor’s data pointer from a region of code being traced). More details on integrating custom
ops with torch.compile can be found here (#123292)torch.nn.hardtahn allowed min_val to be greater than max_val (#121627)model = AnyModel(device=torch.device("cuda"))
model_state_dict = get_model_state_dict(model)
set_model_state_dict(
model,
model_state_dict=new_model_state_dict,
options=StateDictOptions(strict=False),
)
# Below way of calling API is also legit
model_state_dict2 = get_model_state_dict(model, submodules={model.submodule})
set_model_state_dict(
model,
model_state_dict={model.submodule: new_submodel_state_dict},
options=StateDictOptions(strict=False),
)
But from 2.4 forward, if users call get_model_state_dict or set_model_state_dict with a submodule path or
state_dict, users will see a warning about the feature. To achieve the same functionality, users can manually
filter out the state_dict returned from get_state_dict API and preprocess the model_state_dict before
calling set_state_dict API:model = AnyModel(device=torch.device("cuda"))
model_state_dict = get_model_state_dict(model)
set_model_state_dict(
model,
model_state_dict=new_model_state_dict,
options=StateDictOptions(strict=False),
)
# Deprecating warnings thrown for the below way of calling API
model_state_dict2 = get_model_state_dict(model, submodules={model.submodule})
set_model_state_dict(
model,
model_state_dict={model.submodule: new_submodel_state_dict},
options=StateDictOptions(strict=False),
)
model = AnyModel(device=torch.device("cuda"))
fsdp_model = FSDP(model)
# Users can do both ways below
get_model_state_dict(model)
with FSDP.state_dict_type(fsdp_model, StateDictType.FULL_STATE_DICT):
fsdp_model.state_dict()
But from 2.4 forward, if users call state_dict or set state_dict with the FSDP.state_dict_type, users will see warnings. And the recommended solution now is to use get_model_state_dict and set_model_state_dict directly:model = AnyModel(device=torch.device("cuda"))
fsdp_model = FSDP(model)
get_model_state_dict(model)
# Deprecating warnings thrown for the below way of calling API
with FSDP.state_dict_type(fsdp_model, StateDictType.FULL_STATE_DICT):
fsdp_model.state_dict()
torch._aminmax operator (#125995).
torch._aminmax -> torch.aminmax insteadat::autocast::get_autocast_gpu_dtype() -> at::autocast::get_autocast_dtype(at::kCUDA)
at::autocast::get_autocast_cpu_dtype() -> at::autocast::get_autocast_dtype(at::kCPU)torch.get_autocast_gpu_dtype() -> torch.get_autocast_dtype(“cuda”),
torch.set_autocast_gpu_dtype(dtype) -> torch.set_autocast_dtype(“cuda”, dtype),
torch.is_autocast_enabled() -> torch.is_autocast_enabled(“cuda”),
torch.set_autocast_enabled(enabled) -> torch.set_autocast_enabled(”cuda”, enabled),
torch.get_autocast_cpu_dtype() -> torch.get_autocast_dtype(“cpu”)torch.cuda.amp.autocast(args…) -> torch.amp.autocast(“cuda”,args…),
torch.cpu.amp.autocast(args…) -> torch.amp.autocast(“cpu”, args…),torch.cuda.amp.GradScaler(args…) -> torch.amp.GradScaler(“cuda”, args…),
torch.cuda.amp.GradScaler(args…) -> torch.amp.GradScaler(“cpu”, args…),torch.cuda.amp.custom_fwd(args…) -> torch.amp.custom_fwd(args…, device_type=’cuda’),torch.compile support for LRScheduler with Tensor LRs (#123751, #123752, #123753, #127190)preferred_backend on ROCm backend.gemm implementation (#122106)allgather_matmul (#118038)all_to_all_single_grad (#123599)send/recv_object_list operations (#124379)PrivateUse1 (#124818)torch.compile is compatible with Python 3.12.torch.compile users to easily control TorchDynamo tracing of PyTorch internal code.torch.compile support for RAdam and Adamax optimizer. Compiler optimizers now demonstrate SOTA performance.torch.compile to reuse compiled
artifacts on repeated blocks in the models. This gives another point in the tradeoff space of compilation time and performance speedup.
By moving torch.compile from full model to a repeated block (e.g. moving torch.compile from full LLM to a repeated Transformer block),
we can now achieve faster compilation time with some performance dip compared to full model.
We plan to make this flag default to True in the 2.5 release.nn.functional.batch_norm: add forward AD rule for miopen backend (#125069)nn.functional.scaled_dot_product_attention: add backward rule for cuDNN backend (#122510)torch.compile and triton with Python 3.12 CI/CD (#127547, #123307, #126218)swap_tensors path to nn parametrizations (#124130)use_count constraints for swap_tensors when AccumulateGrad node holds a reference (#127313)int64_t indexing for Upsample2d backwards (#123682)LazyModuleMixin constructor (#123968)X86InductorQuantizer (#114853)X86InductorQuantizer (#122775)X86InductorQuantizer (#122776)qconv by reducing integration overhead (#123240)fake_quant_per_channel (#123186)TORCH_NCCL_HIGH_PRIORITY option for ProcessGroupNCCL (#122830)__repr__ to P2POp class (#126538)commCreateFromRanks to c10d (#127421, #127982)dist.get_node_local_rank helper (#123992)get_node_local_rank() accept fallback_rank (#126737)ProcessGroupWrapper support custom backend (#124447)DeviceMesh.from_group() (#124787)_validate_tp_mesh_dim support 3D (#125763)type_check param to copy state dict utils (#127417)DefaultPlanner (#123869)_extra_state (#125336)broadcast_from_rank0 option for model/optim state_dict (#125338, #125339)state_dict support torch.distributed is not initialized case (#127385)state_dict when saving and unflattening when loading (#127071)set_model_state_dict and set_optimizer_state_dict (#127384)scaled_dot_product_attention (flash-attention) (#122541)view_as_complex and view_as_real (#122569)fused_adam and fused_adamw when lr is a tensor (#126750)clip_grad_norm_ for DTensor by default (#126423), (2) optimizer for DTensor by default (#123394)pin_memory argument (#119878)clip_grad_norm_ (#122001)pre_backward_hook unserializable (#125464)parallelize_plan (#122968)prepare_module_input (#124114)torch.profiler:torch.cuda.memory._dump_snapshot:record_function:torch.compile + __torch_function__ support by onboarding Scaled Dot Product Attention (SDPA) and TensorDict.torch.load map_location for wrapper subclass and device being serialized through numpy (#126728)Aten.rrellu_: fix decomp when default values are missing (#126978)torch.compile stack that functionalizes and normalizes the graph, and adds
support for compiling the backward during training. There were several bugfixes and improvements to AOTDispatcher:
torch.compile used with triton kernels under inference_mode (#124489)torch.compile captures small graphs with outputs that alias graph inputs (#121007)__torch_dispatch__-based tensor subclasses, support custom layout overrides under torch dispatch mode (#125379)torch.utils.checkpoint: Use pytrees to improve determination of what RNG state to stash (#121462)swap_tensors path in nn.Module._apply for modules that inherit from RNNBase (RNN, GRU, LSTM) (#122800)ctc_loss zero/negative length corner cases (#123193)_LazyConvXdMixin.initialize_parameters and add related tests (#123756)load_state_dict with unexpected key whose prefix matches a valid key (#124385)requires_grad propagation in nn.utils.parametrize (#124888)nan with large bfloat16 values for FlashAttention backend of nn.functional.scaled_dot_product_attentionaffine_grid_backward when grad_grid is non-contiguous (#124370)thnn_conv2d (#121906)(#122135)svd_lowrank(..., M) in the presence of broadcasting (#122681)linalg.vector_norm when used with autocast(cuda) (#125175)coalescedCollective op Flight Recording (#120430)group_name/group_desc set up in eager initialization (#127053)_update_process_group API (#128262)TCPStoreLibUvBackend.cpp (#127230)_ProcessGroupWrapper check (#124233)USE_C10D_NCCL (#127501)wait_tensor() calls on graph inputs from getting DCEd for AsyncCollectiveTensor (#125677)_get_device_handle (#124390)init_device_mesh() consistent with directly calling DeviceMesh() (#123677)no_sync when find_unused_parameters is True (#124193)set_optimizer_state_dict() changes the parameters with some optimizers (#125708)broadcast_from_rank0 (#127635)torch.multiprocessing.ProcessContext.join() wait for all child procs to exit before return (#125969)linalg.vector_norm when reducing over a dimension of length 1 (#122143)gemv on ARM (#126297, #126745, #126746, #126877, #127033) and BF16 gemm fallback on ARM (#126592)TunableOp on ROCm (#124362)_foreach_copy now supports different source/dest dtypes on the fast path (#127186)_split_tensor (#125810) local_tensor under no_grad (#128145)monitor_interval for torchelastic default value to 0.1 sec (#124692)_find not update unchanged replacements (#124274)convert<float>(Vectorized<half>::loadu(ptr, 8)) on ARM (#125889)torch.compile issues (#122028)torch.autograd.Function: update docs for separate context and forward functions (#121955)torch.utils.checkpoint: Improve error message when use_reentrant=True is used with .grad() (#125155)torch.Tensor.backward doc (#127201)torch.autograd.Function with ctx-less forward (#122167)torch.compile links (#121823, #121824)KLDiv example (#126857)torch.nn.TripletMarginLoss allowing margin less or equal to 0 (#121978)nn.ChannelShuffle and nn.PReLU docs (#123959)nn.MaxUnpool2d example (#127850)nn.Linear docstring (#127240)NLLLoss documentation (#127346)torch.nn.utils.rnn (#123559)nn.Module.load_state_dict (#123637)torch.nn.utils.rnn.pad_sequence (#123183)is_causal explanation in the nn.functional.scaled_dot_product_attention doc (#127209)eig/eigvals (#127492)destroy_process_group usage (#122358)torch.distributed.new_subgroups docstring (#123492)distributed.new_group() (#122703)device_mesh arg (#126589)torch.compile with XPU support (#127879)torch.compile from more checks in Adamax (#123498)pg_name and pg_desc to logger (#126409)ncclunique_id (#123963)process_group_name when creating ProcessGroupNCCL (#123117)collective_seq_id and p2p_seq_id (#125727)CommDebugMode (#125475)all_reduce_coalesced tracing to CommDebugMode (#127025)ModuleList/ModuleDict (#124764)aoti_torch_item as a util function (#126352)importlib.load_module (#122542)IterationRangesEntry into triton.py (#126944)mutationlayout/aliasedlayout (#122474)DTYPE_TO_CPP mapping (#126915)opinfo tests (flattened diff) (#124657)config.trace.compile_profile (#127143)do_bench (#125736)This release is meant to fix the following issues (regressions / silent correctness):
This release is meant to fix the following issues (regressions / silent correctness):
torch.__dynamo (https://github.com/pytorch/pytorch/pull/124634)Plan failed with a cudnnException warning (https://github.com/pytorch/pytorch/pull/125790)format_utils executable, which was causing it to run as a no-op (https://github.com/pytorch/pytorch/pull/123407)device_mesh in 2.3.0 during initialization causing memory spikes (https://github.com/pytorch/pytorch/pull/124780)FSDP + DTensor with ShardingStrategy.SHARD_GRAD_OP (https://github.com/pytorch/pytorch/pull/123617)use_orig_params = False and activation checkpointing (https://github.com/pytorch/pytorch/pull/124698) (https://github.com/pytorch/pytorch/pull/126935)set_model_state_dict errors on compiled module with non-persistent buffer with distributed checkpointing (https://github.com/pytorch/pytorch/pull/125336) (https://github.com/pytorch/pytorch/pull/125337)Tensor.abs() for complex (https://github.com/pytorch/pytorch/pull/125662).pyi files (https://github.com/pytorch/pytorch/pull/124932)import torch failure when wheel is installed for a single user on Windows(https://github.com/pytorch/pytorch/pull/125684)tensor.dtype.to_complex() after ~100 calls in ipython kernel (https://github.com/pytorch/pytorch/pull/125154)Release tracker https://github.com/pytorch/pytorch/issues/125425 contains all relevant pull requests related to this release as well as links to related issues.
Fix breaking changes for ONNX Runtime Training
We are excited to announce the release of PyTorch® 2.3! PyTorch 2.3 offers support for user-defined Triton kernels in torch.compile, allowing for users to migrate their own Triton kernels from eager without experiencing performance complications or graph breaks. As well, Tensor Parallelism improves the experience for training Large Language Models using native PyTorch functions, which has been validated on training runs for 100B parameter models.
This release is composed of 3393 commits and 426 contributors since PyTorch 2.2. We want to sincerely thank our dedicated community for your contributions. As always, we encourage you to try these out and report any issues as we improve 2.3. More information about how to get started with the PyTorch 2-series can be found at our Getting Started page.
<table> <tr> <td> <strong>Stable</strong>
</td> <td> <strong>Beta</strong>
</td> <td> <strong>Prototype</strong>
</td> <td> <strong>Performance Improvements</strong>
</td> </tr> <tr> <td> </td> <td>User-defined Triton kernels in torch.compile </td> <td>torch.export adds new API to specify dynamic_shapes </td> <td>Weight-Only-Quantization introduced into Inductor CPU backend </td> </tr> <tr> <td> </td> <td>Tensor parallelism within PyTorch Distributed </td> <td>Asynchronous checkpoint generation </td> <td> </td> </tr> <tr> <td> </td> <td>Support for semi-structured sparsity </td> <td> </td> <td> </td> </tr> </table>
*To see a full list of public feature submissions click here.
This can cause significant first-time slowdown and instability when these packages are not fully compatible with PyTorch within a single process.
PyTorch support for Python 3.12 in general is considered experimental. Please use Python version between 3.8 and 3.11 instead. This is an existing issue since PyTorch 2.2.
Defining a subclass with a torch_dispatch entry will now automatically set torch_function to be disabled. This aligns better with all the use cases we’ve observed for subclasses. The main change of behavior is that the result of the torch_dispatch handler will not go through the default torch_function handler anymore, wrapping it into the current subclass. This allows in particular for your subclass to return a plain Tensor or another subclass from any op.
The original behavior can be recovered by adding the following to your Tensor subclass:
@classmethod
def __torch_function__(cls, func, types, args=(), kwargs=None):
return super().__torch_function__(func, types, args, kwargs)
no_dist and coordinator_rank from public DCP API's (#121317)As part of an overall effort to simplify our public facing API's for Distributed Checkpointing, we've decided to deprecate usage of the coordinator_rank and no_dist parameters under torch.distributed.checkpoint. In our opinion, these parameters can lead to confusion around the intended effect during API usage, and have limited value to begin with. One concrete example is here, https://github.com/pytorch/pytorch/issues/118337, where there is ambiguity in which Process Group is referenced by the coordinator rank (additional context: https://github.com/pytorch/pytorch/issues/118337). In the case of the no_dist parameter, we consider this an implementation detail which should be hidden from the user. Starting in this release, no_dist is inferred from the initialized state of the process group, assuming the intention is to use collectives if a process group is initialized, and assuming the opposite in the case it is not.
<table> <tr> <td> <strong>2.2</strong>
</td> <td> <strong>2.3</strong>
</td> </tr> <tr> <td>
# Version 2.2.2
import torch.distributed.checkpoint as dcp
dcp.save(
state_dict={"model": model.state_dict()},
checkpoint_id="path_to_model_checkpoint"
no_dist=True,
coordinator_rank=0
)
# ...
dcp.load(
state_dict={"model": model.state_dict()},
checkpoint_id="path_to_model_checkpoint"
no_dist=True,
coordinator_rank=0
)
</td> <td>
# Version 2.2.3
# no dist is assumed from pg state, and rank 0 is always coordinator.
import torch.distributed.checkpoint as dcp
dcp.save(
state_dict={"model": model.state_dict()},
checkpoint_id="path_to_model_checkpoint"
)
# ...
dcp.load(
state_dict={"model": model.state_dict()},
checkpoint_id="path_to_model_checkpoint"
)
</td> </tr> </table>
Starting from PyTorch 2.3, parallelize_module API only accepts a DeviceMesh (the tp_mesh_dim argument has been removed). If having a N-D DeviceMesh for multi-dimensional parallelism, you can use mesh_nd["tp"] to obtain a 1-D DeviceMesh for tensor parallelism.
Previously, the PT2 Export Quantization flow did not generate quantized weight by default, but instead used fp32 weight in the quantized model in this pattern: fp32 weight -> q -> dq -> linear. Setting fold_quantize=True produces a graph with quantized weights in the quantized model in this pattern by default after convert_pt2e, and users will see a reduction in the model size: int8 weight -> dq -> linear.
<table> <tr> <td> <strong>2.2</strong>
</td> <td> <strong>2.3</strong>
</td> </tr> <tr> <td>
folded_model = convert_pt2e(model, fold_quantize=True)
non_folded_model = convert_pt2e(model)
</td> <td>
folded_model = convert_pt2e(model)
non_folded_model = convert_pt2e(model, fold_quantize=False)
</td> </tr> </table>
All functions and classes under torch.jit.quantized will now raise an error if called/instantiated. This API has long been deprecated in favor of torch.ao.nn.quantized.
<table> <tr> <td> <strong>2.2</strong>
</td> <td> <strong>2.3</strong>
</td> </tr> <tr> <td>
# torch.jit.quantized APIs
torch.jit.quantized.quantize_rnn_cell_modules
torch.jit.quantized.quantize_rnn_modules
torch.jit.quantized.quantize_linear_modules
torch.jit.quantized.QuantizedLinear
torch.jit.QuantizedLinearFP16
torch.jit.quantized.QuantizedGRU
torch.jit.quantized.QuantizedGRUCell
torch.jit.quantized.QuantizedLSTM
torch.jit.quantized.QuantizedLSTMCell
</td> <td>
# Corresponding torch.ao.quantization APIs
torch.ao.nn.quantized.dynamic.RNNCell
torch.ao.quantization.quantize_dynamic APIs
torch.ao.nn.quantized.dynamic.Linear
torch.ao.nn.quantized.dynamic.GRU
torch.ao.nn.quantized.dynamic.GRUCell
torch.ao.nn.quantized.dynamic.LSTM
</td> </tr> </table>
TorchScript models that were exported with the deprecated torch.jit.quantized API will no longer be loadable, as the required internal operators have been removed. Please re-export your models using the newer torch.ao.quantization API instead.
List::get() const match List::operator[]() const (#117568)C10_IS_TRIVIALLY_COPYABLE (#120120)These decorators were previously marked for internal use only. They will be removed in version 2.4.
torch.utils.checkpoint: the use_reentrant parameter should be passed explicitly. In version 2.4 we will raise an exception if use_reentrant is not passed. use_reentrant=False is recommended, but if you need to preserve the current default behavior, you can pass use_reentrant=True. Refer to docs for more details on the differences between the two variants.
(Note that this was already deprecated in a previous release. In this version, we improve the deprecation message.)
This PR deprecated torch.backends.cuda.sdp_kernel, users can now use torch.nn.attention.sdpa_kernel instead. The old code will raise the following warning: FutureWarning: torch.backends.cuda.sdp_kernel() is deprecated. In the future, this context manager will be removed. Please see, torch.nn.attention.sdpa_kernel() for the new context manager, with updated signature.
<table> <tr> <td> <strong>2.2</strong>
</td> <td> <strong>2.3</strong>
</td> </tr> <tr> <td>
import torch
from torch.backends.cuda import sdp_kernel
with sdp_kernel(enable_math=False, enable_flash=False, enable_mem_efficient=True):
torch.nn.functional.scaled_dot_product_attention(...)
</td> <td>
import torch
from torch.nn.attention import sdpa_kernel, SDPBackend
with sdpa_kernel(backends=[SDPBackend.EFFICIENT_ATTENTION]):
torch.nn.functional.scaled_dot_product_attention(...)
</td> </tr> </table>
NO_SHARD (#119553)fully_shard deprecation warning (#120929)"any" mode to register_multi_grad_hook (#117984)foreach=False for clip_grad_norm_ (#120238)foreach=True for clip_grad_norm_ (#120910)permute_tensor in functional collectives (#115078)torch._dynamo.reset() to clear the cache. Now, we automatically clear the cache as soon as the nn module goes out of scope.operator.truth (#117463)torch.export._trace._export(..., predispatch=True). This returns a graph that contains ATen operators at a higher level (aten.linear.default will not become decomposed) and are also safe for training (#117278)torch.fft. support (#119670)swap_tensors path to nn.Module._apply (#117167)swap_tensors into nn.Module.load_state_dict ((#117913)assign argument to torch.Tensor.module_load (#121158)TransformerEncoder/MultiHeadAttention fastpath (#112212)add(sparse_compressed, dense) (#115432)Dynamic shapes:
TensorIteratorConfig::add_const_input to avoid COW materialize (#118053).detach in clip_grad_norm_ (#120612)no_dist if distributed is unavailable (#119813)storage() with untyped_storage() (#121538)_all_gather_keys in dcp.load (#118301)self._dim_group_infos (#118527)from_local backward partial() to replicate() pass through (#115967)to_local requires_grad warning (#118186)as_subclass is supported (#116091)torch.Tensor.new into torch.Tensor.new_empty method. (#121075)None in compiled optimizers (#121291)is_not (#113859)argument unused during compilation warning (#118077)num_children access (#116370)flatten_fn in flatten_with_keys_fn to ensure consistency (#117656)at::parallel_for/parallel_reduce (#120455), TensorAccessors with const type (#119501), and input materialization in more forward ops (#121070)MPSDataTypeComplexFloat[16|32] (#115513)sum and prod for complex types (#115554)MPSDataTypeComplexFloat[16|32] (#115513)sum and prod for complex types (#115554)torch.rand[n] for complex types (#115514)bfloat16 support on MacOS 14 (#119641)LPPool3d (#114199)nn.Module.to_empty() suggestion in the error message (#119353)nn.Module.set_extra_state return type to None (#120161)nn.Module._apply to not gate on should_use_set_data when swap_tensors is set (#120659)AdaptiveAvgPool1D to account for shmem limit for certain input sizes (#115231)avg_pool_backward (#114193)layer_norm on CPU (#99590)onnxrt dynamo backend (#120854)PT2 Export Quantization Flow:
move_exported_model_to_train (#113492)model_is_exported util function (#119726)model_is_exported input (#120720)XNNPACKQuantizer:
X86 CPU Inductor Backend:
DTypes:
Others:
MutableMapping and MutableSequence in pin_memory and collate_fn (#120553)fx_graph_cse graph pass (#119567)str on wide types (#117531)is_bf16_supported(). (#115924)get_rank under a non-default group. (#120481)device_mesh and auto wrap (#119064)no_dist=True in state_dict_loader.load (#115660)functools.reduce() function with None as initial (#116398)sum() function with start argument (#116389)__name__ on a reconstructed NestedUserFunctionVariable (#118768)model.h (#118075)RuntimeError: NYI: Named tensors are not supported with the tracer errors when using torch.jit.trace (#118393)torch.mm correctness for large matrices (#117549)use_metal_mm condition (#118830)dyspatch_sync_with_rethrow in searchsorted (#119646)conj and conj_physical (#119669)out resize logic in torch.where (#121476)AdaptiveMaxPool (#116482)TransformerEncoderLayer for bias=False (#116760)LSTM with wrong input shape (#115542)AdaptiveMaxPool1d (#118162)flash_attn_bw impl to match meta implementation when k and v have different strides (#119500)nonlinearity arg issue in RNN (#120234)requires_grad preservation for nn.Module.load_state_dict(assign=True) (#121157)PerChannelMinMaxObserver default _load_from_state_dict (#118659)Note truncated.
This release is meant to fix the following issues (regressions / silent correctness):
This release is meant to fix the following issues (regressions / silent correctness):
RuntimeError: cannot create std::vector larger than max_size() in torch.nn.functional.conv1d on non-contiguous cpu inputs by patching OneDNN (https://github.com/pytorch/builder/pull/1742) (https://github.com/pytorch/builder/pull/1744)torch.distributed.fsdp.StateDictType.FULL_STATE_DICT for when using torch.distributed.fsdp.FullyShardedDataParallel with the device_mesh argument (https://github.com/pytorch/pytorch/pull/120837)make triton command on release branch for users building the release branch from source (https://github.com/pytorch/pytorch/pull/121169)Release tracker https://github.com/pytorch/pytorch/issues/120999 contains all relevant pull requests related to this release as well as links to related issues.
This release is meant to fix the following issues (regressions / silent correctness):
This release is meant to fix the following issues (regressions / silent correctness):
_to_copy operation (https://github.com/pytorch/pytorch/pull/116426)param.grad_fn for next forward (https://github.com/pytorch/pytorch/pull/116792)AsyncCollectiveTensor in FSDP Extension (https://github.com/pytorch/pytorch/pull/116122)AssertionError on tensor subclass when setting sync_module_states=True (https://github.com/pytorch/pytorch/pull/117336)_gather_state_dict() to be synchronous with respect to the mian stream. (https://github.com/pytorch/pytorch/pull/118197) (https://github.com/pytorch/pytorch/pull/119716)torch.distributed.DistNetworkError: [WinError 32] The process cannot access the file because it is being used by another process (https://github.com/pytorch/pytorch/pull/118860)import torch on CPUs that do not support SSE4.1 (https://github.com/pytorch/pytorch/issues/116623)get_state_dict and set_state_dict (https://github.com/pytorch/pytorch/pull/119573)mixedmm on NVIDIA V100 (https://github.com/pytorch/pytorch/pull/118591)DTensor.from_local in trace_rule_look up (https://github.com/pytorch/pytorch/pull/119659)Release tracker https://github.com/pytorch/pytorch/issues/119295 contains all relevant pull requests related to this release as well as links to related issues.
This bc-breaking change fixes some unexpected behavior when set_grad_enabled is used as a decorator.
We are excited to announce the release of PyTorch® 2.2! PyTorch 2.2 offers ~2x performance improvements to scaled_dot_product_attention via FlashAttention-v2 integration, as well as AOTInductor, a new ahead-of-time compilation and deployment tool built for non-python server-side deployments.
This release also includes improved torch.compile support for Optimizers, a number of new inductor optimizations, and a new logging mechanism called TORCH_LOGS.
Please note that we are deprecating macOS x86 support, and PyTorch 2.2.x will be the last version that supports macOS x64.
Along with 2.2, we are also releasing a series of updates to the PyTorch domain libraries. More details can be found in the library updates blog.
This release is composed of 3,628 commits and 521 contributors since PyTorch 2.1. We want to sincerely thank our dedicated community for your contributions. As always, we encourage you to try these out and report any issues as we improve 2.2. More information about how to get started with the PyTorch 2-series can be found at our Getting Started page.
Summary:
scaled_dot_product_attention (SDPA) now supports FlashAttention-2, yielding around 2x speedups compared to previous versions.torch.distributed supports a new abstraction for initializing and representing ProcessGroups called device_mesh.torch.ao.quantization now offers a prototype torch.export based flow<table> <tr> <td> <strong>Stable</strong> </td> <td><strong>Beta</strong> </td> <td><strong>Prototype</strong> </td> <td><strong>Performance Improvements</strong> </td> </tr> <tr> <td> </td> <td>FlashAttentionV2 backend for scaled dot product attention </td> <td>PT 2 Quantization </td> <td>Inductor optimizations </td> </tr> <tr> <td> </td> <td> AOTInductor </td> <td> Scaled dot product attention support for jagged layout NestedTensors </td> <td>aarch64-linux optimizations (AWS Graviton) </td> </tr> <tr> <td> </td> <td> TORCH_LOGS </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td>torch.distributed.device_mesh </td> <td> </td> <td> </td> </tr> </tr> <tr> <td> </td> <td>torch.compile + Optimizers </td> <td> </td> <td> </td> </tr> </table>
*To see a full list of public 2.2 - 1.12 feature submissions click here.
We have noticed a performance regression introduced to all-reduce in NCCL 2.19.3. Please use version 2.19.1 instead.
We observe the loss will flatline randomly while training with FSDP + DTensor in some instances.
GCC 9.4 is the oldest version fully compatible with C++17, which the PyTorch codebase has migrated to from C++14.
scaled_dot_product_attention to use Flash Attention v2 (#105602)Previously, the v1 Flash Attention kernel had a Windows implementation. So if a user on Windows had explicitly forced the flash attention kernel to be run by using sdp_kernel context manager with only flash attention enabled, it would work. In 2.2, if the sdp_kernel context manager must be used, use the memory efficient or math kernel if on Windows.
with torch.backends.cuda.sdp_kernel(enable_flash=True, enable_math=False, enable_mem_efficient=False):
torch.nn.functional.scaled_dot_product_attention(q,k,v)
</td> <td>
# Don't force flash attention to be used if using sdp_kernel on Windows
with torch.backends.cuda.sdp_kernel(enable_flash=False, enable_math=True, enable_mem_efficient=True):
torch.nn.functional.scaled_dot_product_attention(q,k,v)
</td> </tr> </table>
In PyTorch 2.1 or before, users can use ParallelStyles like PairwiseParallel and specify input/output layout with functions like make_input_replicate_1d or make_output_replicate_1d. And we have default values for _prepare_input and _prepare_output. The UX of Tensor Parallel was like:
from torch.distributed.tensor.parallel.style import (
ColwiseParallel,
make_input_replicate_1d,
make_input_reshard_replicate,
make_input_shard_1d,
make_input_shard_1d_last_dim,
make_sharded_output_tensor,
make_output_replicate_1d,
make_output_reshard_tensor,
make_output_shard_1d,
make_output_tensor,
PairwiseParallel,
parallelize_module,
)
from torch.distributed.tensor import DeviceMesh
module = DummyModule()
device_mesh = DeviceMesh("cuda", list(range(self.world_size)))
parallelize_module(module, device_mesh, PairwiseParallel(_prepare_input=make_input_replicate_1d))
...
Starting from PyTorch 2.2, we simplified parallel styles to only contain ColwiseParallel and RowwiseParallel because other ParallelStyle can consist of these two. We also deleted the input/output functions, and started using input_layouts and output_layouts as kwargs instead to specify the sharding layout of both input/output tensors. Finally, added PrepareModuleInput/PrepareModuleOutput style, and no default arguments for layouts in these two styles and users need to specify them to think about the sharding layouts.
from torch.distributed.tensor.parallel.style import (
ColwiseParallel,
PrepareModuleInput,
RowwiseParallel,
parallelize_module,
)
from torch.distributed._tensor import init_device_mesh
module = SimpleMLPModule()
device_mesh = init_device_mesh("cuda", (self.world_size,)))
parallelize_module(
module,
device_mesh,
{
"fqn": PrepareModuleInput(
input_layouts=Shard(0),
desired_input_layouts=Replicate()
),
"fqn.net1": ColwiseParallel(),
"fqn.net2": RowwiseParallel(output_layouts=Shard(0)),
}
)
...
UntypedStorage.resize_ now uses the original device instead of the current device context (#113386)Before this PR, UntypedStorage.resize_ would move data to the current CUDA device index (given by torch.cuda.current_device()).
Now, UntypedStorage.resize_() keeps the data on the same device index that it was on before, regardless of the current device index.
<table> <tr> <th>2.1</th> <th>2.2</th> </tr> <tr> <td>
>>> import torch
>>> with torch.cuda.device('cuda:0'):
...: a = torch.zeros(0, device='cuda:1')
...: print(a.device)
...: a = a.untyped_storage().resize_(0)
...: print(a.device)
cuda:1
cuda:0
</td> <td>
>>> import torch
>>> with torch.cuda.device('cuda:0'):
...: a = torch.zeros(0, device='cuda:1')
...: print(a.device)
...: a = a.untyped_storage().resize_(0)
...: print(a.device)
cuda:1
cuda:1
</td> </tr> </table>
This bc-breaking change fixes some unexpected behavior when set_grad_enabled is used as a decorator.
<table> <tr> <th>2.1</th> <th>2.2</th> </tr> <tr> <td>
>>> import torch
>>> @torch.set_grad_enabled(False) # unexpectedly, this mutates the grad mode!
def inner_func(x):
return x.sin()
>>> torch.is_grad_enabled()
True
</td> <td>
>>> import torch
>>> @torch.set_grad_enabled(False) # unexpectedly, this mutates the grad mode!
def inner_func(x):
return x.sin()
>>> torch.is_grad_enabled()
False
</td> </tr> </table>
verbose parameter in LRscheduler constructors (#111302)As part of our decision to move towards a consolidated logging system, we are deprecating the verbose flag in LRScheduler.
If you would like to print the learning rate during execution, please use get_last_lr()
<table> <tr> <th>2.1</th> <th>2.2</th> </tr> <tr> <td>
optimizer = torch.optim.SGD(model.parameters(), lr=0.1, momentum=0.9)
scheduler = ReduceLROnPlateau(optimizer, 'min', verbose=True)
for epoch in range(10):
train(...)
val_loss = validate(...)
# Note that step should be called after validate()
scheduler.step(val_loss)
</td> <td>
optimizer = torch.optim.SGD(model.parameters(), lr=0.1, momentum=0.9)
scheduler = ReduceLROnPlateau(optimizer, 'min')
for epoch in range(10):
train(...)
val_loss = validate(...)
# Note that step should be called after validate()
scheduler.step(val_loss)
print(f"Epoch {epoch} has concluded with lr of {scheduler.get_last_lr()}")
</td> </tr> </table>
In PyTorch 2.1 or before, users can use our multi-gpu c10d collective APIs such as all_reduce_multigpu:
<table>
<tr>
<th>2.1</th>
<th>2.2</th>
</tr>
<tr>
<td>
import torch.distributed as dist
dist.broadcast_multigpu
dist.all_reduce_multigpu
dist.reduce_multigpu
dist.all_gather_multigpu
dist.reduce_scatter_multigpu
...
</td> <td>
optimizer = torch.optim.SGD(model.parameters(), lr=0.1, momentum=0.9)
scheduler = ReduceLROnPlateau(optimizer, 'min')
for epoch in range(10):
train(...)
val_loss = validate(...)
# Note that step should be called after validate()
scheduler.step(val_loss)
print(f"Epoch {epoch} has concluded with lr of {scheduler.get_last_lr()}")
</td> </tr> </table>
In PyTorch 2.2, these APIs are removed because PyTorch Distributed's preferred programming model is one device per thread, as exemplified by the APIs in its document. The multi-GPU functions (which stand for multiple GPUs per CPU thread) have been deprecated since PyTorch 1.13.
torch.onnx.ExportOutput* to ONNXProgram* (#112263)The torch.onnx.dynamo_export’s output was renamed from torch.onnx.ExportOutput to torch.onnx.ONNXProgram to better align with torch.export.export API terminology which returns a torch.export.ExportedProgram. With this change, any ambiguity that could arise with either API is eliminated.
<table> <tr> <th>2.1</th> <th>2.2</th> </tr> <tr> <td>
export_output: torch.onnx.ExportOutput = torch.onnx.dynamo(...)
</td> <td>
onnx_program: torch.onnx.ONNXProgram = torch.onnx.dynamo(...)
</td> </tr> </table>
functional::smooth_l1_loss signatures to not override beta (#109798)Previously, there were two possible options to pass in beta to smooth_l1_loss, either as a SmoothL1LossFuncOption parameter or a function parameter.
Before, the beta specified as a function parameter would override the other beta if it was set, which was unexpected behavior. Now, we throw an error when beta is passed in both cases.
use_reentrant kwarg to torch.utils.checkpoint.checkpoint_sequential explicitly (#114158)The use_reentrant parameter should be passed explicitly. In version 2.4 we will raise an exception if use_reentrant is not passed. use_reentrant=False is recommended, but if you need to preserve the current default behavior, you can pass use_reentrant=True. Refer to docs for more details on the differences between the two variants.
Note that not passing use_reentrant kwarg to torch.utils.checkpoint.checkpoint has been previously deprecated in a previous release.
<table> <tr> <th>2.1</th> <th>2.2</th> </tr> <tr> <td>
a = torch.randn(3, requires_grad=True)
modules_list = [
torch.nn.Linear(3, 3),
torch.nn.Linear(3, 3),
torch.nn.Linear(3, 3)
]
# This would produce a warning in 2.2
checkpoint_sequential(modules_list, 3, a)
</td> <td>
# Recommended
checkpoint_sequential(modules_list, 3, a, use_reentrant=False)
# To preserve existing behavior
checkpoint_sequential(modules_list, 3, a, use_reentrant=True)
</td> </tr> </table>
"fallthrough" as autograd fallback default (#113166)Custom operators that do not have a kernel registered to the Autograd keys (e.g. AutogradCPU and AutogradCUDA) will now produce a warning when used with autograd.
If your custom operator previously returned floating-point or complex Tensors that do not require grad, they will now require grad as long as grad mode is enabled and the inputs require grad.
For users who would like the old behavior, register torch::CppFunction::makeFallthrough() to your Autograd key, as shown here.
The below example uses the torch library API, but if you are writing an operator in a cpp extension, please read this doc for more information.
import torch
import numpy as np
# Define the operator
torch.library.define("mylibrary::sin", "(Tensor x) -> Tensor")
# Add implementations for the cpu device
@torch.library.impl("mylibrary::sin", "cpu")
def f(x):
return torch.from_numpy(np.sin(x.detach().numpy()))
x = torch.randn(3, requires_grad=True)
y = torch.ops.mylibrary.sin(x)
y.sum().backward()
<table> <tr> <th>2.1</th> <th>2.2</th> </tr> <tr> <td>
RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn
</td> <td>
UserWarning: mylibrary::sin: an autograd kernel was not registered to the Autograd key(s) but we are trying to backprop through it. This may lead to silently incorrect behavior. This behavior is deprecated and will be removed in a future version of PyTorch. If your operator is differentiable, please ensure you have registered an autograd kernel to the correct Autograd key (e.g. DispatchKey::Autograd, DispatchKey::CompositeImplicitAutograd). If your operator is not differentiable, or to squash this warning and use the previous behavior, please register torch::CppFunction::makeFallthrough() to DispatchKey::Autograd.
</td> </tr> </table>
torch.cross default behavior (#108760)Calling torch.cross without specifying the dim arg is now deprecated. This behavior will be changed to match that of torch.linalg.cross in a future release.
NVFuser functionality has been removed from TorchScript (#110124, #111447, #110881)Neural Network Compiler (NNC) has replaced NVFuser as the default GPU fuser for TorchScript in PyTorch 2.1, which also added a deprecation warning for NVFuser. The TorchScript functionality for NVFuser has now been fully removed and is no longer supported.
SparseAdam constructor will no longer accept raw Tensor type for params (#114425)SparseAdam is now consistent with the rest of our optimizers and only accepts containers instead of individual Tensors/Parameters/param groups.
<table> <tr> <th>2.1</th> <th>2.2</th> </tr> <tr> <td>
import torch
param = torch.rand(16, 32)
optimizer = torch.optim.SparseAdam(param)
</td> <td>
optimizer = torch.optim.SparseAdam([param])
</td> </tr> </table>
torch.distributions.InverseGamma distribution and fix sign bug in torch.distributions.PowerTransform (#104501)src/dst information to NCCL send/recv (#111811)| support for JIT (#109293)ONNXProgram.__call__ API to run model with ONNX Runtime (#113495)torch.cpu.set_device() and torch.cpu.current_device() (#110716, #110987)aten::randlike (#108086)aten::randn_like and aten::normal (#109075)aten::bmm (#109360)aten::baddbmm (#109360)aten::floor_divide (#110785, #112190)aten::mean.dim (#111609)aten::var.dim (#111965)aten::log and aten::log_softmax (#112828)aten::layer_norm (#112322, #114701)aten::native_layer_norm (#113573)itertools.{count, repeat, cycle} (#110967)max-autotune improvements
rand[n].generator with inductor prim if generator=None (#115051)masked_scatter (#108802), _segment_reduce (#109359), foreach ops (#112281), linear_backward (#114359), scaled_mm (#112609)linalg.vecdot (#108188)aten.dot/vdot (#108194)aten.tensor_split.tensor_indices_or_sections (#107251)view_as_complex (#108005)aten.take_along_dim (#108185)scaled_dot_product_attention (#108180, #108608, #108371, #113102)unsafe_split{,_with_sizes} (#109668)_weight_norm_interface (#112193)std.correction (#108733)unsafe_split.Tensor (#108544)clamp_min (#108717)clamp_max (#108718)_unsafe_view (#108713)baddbmm (#108534)floor_divide (#110046)aten.all (#110093)split.Tensor + unbind (#110323)aten.sum + aten.squeeze (#110645)std + std_mean (#109667)trunc (#109319, #109902)glu (#110043)torch.half support for torch.multinomial on CPU (#104178)torch.float8_* dtypes (#114662)torch.addc{mul,div} (#112682)__all__ for torch.nn.utils (#111026)AdaptiveAvgPool2d and AdaptiveMaxPool2d on CPU (#102079)GroupNorm on CPU (#100234)torch.nn.functional.{softmax/log_softmax} on CPU (#103315)torch.nn.functional.grid_sample (#112331)nn.utils.parametrizations.weight_norm (#114785)NAdam support for complex dtypes, with has_complex shortcut (#110634)lr) value of SGD to 1e-3 (#114467)torch.unsafe_chunk (#110862)Tensor.index_add_ (#112276)torch.linspace and torch.logspace (#105451)torch.linalg.eigh (#110640)torch.squeeze and alias (#107577)torch.is_same_size and torch.split_with_sizes (#111491)torch.utils.checkpoint.set_checkpoint_debug_enabled (#110728)cat for bits types (e.g.torch.bits8) in cuda (#115044)copy/clone/reshape/contiguous operations for bits types (#113508)input_qspec_map for weight quantization of linear (#107105)int16 quantization (#108453)cat (#108382), conv1d (#109830) and mul (#110428) in XNNPACKQuantizercudnn_batch_norm (#109908) and miopen_batch_norm (#110653) in QAT fusionDerivedQSpec (#112159)fx.Proxy (#108764)X86InductorQuantizer (#111280)ConvBNAdd(ReLU) Annotation (#111281), adaptive_avg_pool2d and flatten (#114442), Hardtanh and ReLU6 for conv2d (#114579) in X86InductorQuantizeroneDNN QConv (#112010) and QLinear (#112126) FP32/BF16 outputoneDNN QConv2d with hardtanh post op (#114578)quantize_per_tensor/quantize_per_channel to accept bfloat16 input (#112225)allow_implicit_sharing flag (#112929)transform_for_annotation method in Quantizer (#113115)SubgraphMatcherWithNameNodeMap (#113709)XNNPACKQuantizer skip quantization for input and output to workaround histogram observer problem (#113405)XNNPACKQuantizer (#113288)FloatFunctional in torch.ao.quantization.prepare (#109646)QConfig (#109288)new_qtensor support privateuseone allocator. (#111464)float8_e4m3fnuz and float8_e5m2fnuz (#107586)all_to_all_single and support it in Inductor (#110195)ProcessGroupNCCL default timeout to 10 min (#110947)_shutdown method to ProcessGroupNCCL (#111392)DETAIL debug mode (#111878)c10d::ProcessGroup and c10d::Work's pybind (#111997)init_process_group timeout kwarg override pg_options (#112611, #113094)ProcessGroupNCCL register (#112850)FakeProcessGroup traceable (#113314)ncclCommSplit when creating new NCCL groups (#114385)_set_group_name and group_name to track pg names in C++. (#108813)randn (#108285)to_local API (#110629)aten.where and enabled implicit scalar promotion (#110584)full_tensor API to DTensor (#112224, #113322)rand_like, randn_like, randint_like ops to shard propagation (#112576)min, max and prod sharding propagation rules (#112403)_Partial, Replicate frozen dataclasses (#113919)redistribute (#113924)from_local (#114134)distribute_tensor (#113930)grad_placements was tuple (#113925)checkpoint_wrapper default to NO_REENTRANT (#108435)ModuleWrapPolicy callable (#109117)cpu_offload config for optimizer state_dict (#108434)cpu_only and ranks_only support for _gather_state_dict (#112836)cpu_offload and full_state_dict for get_state_dict (#112837)fx.split_module (#113373)torch.autograd.gradcheck when fast_mode=True and default device is set (#114560)torch.prod double backward when input tensor contains more than one zero (#113969)interpolate (#108506)num_layers for RNN, LSTM, GRU (#108853)torch::nn::AdaptiveLogSoftmaxWithLoss: check length of cutoffs (#106777)matrix_exp function (#111539)ReduceLROnPlateau now subclasses LRScheduler (#113659)adagrad sparse handling due to incorrect early exit (#110454)state_dict (#110931)torch.{finfo,iinfo} calls (#109743)torch.isfinite, torch.isreal, and torch.log_sigmoid (#110896)torch.movedim, torch.tensor_split, Tensor.to, to.* (#110999)torch.flatten, torch.linalg.*, torch.linear, torch.log_softmax, torch.logdet, torch.special.* (#110985)torch.nn.LayerNorm on CPU (#108089)collections.namedtuple are preserved instead of being changed to tuple when there are backward hooks on nn.Module (#112433)memory_efficient_attention (#116026)nn.CosineEmbeddingLoss have the same size (#112782)nn.Module.to (#108767)torch.nn.utils.rnn.pad_sequence type hint to allow sequences to be an iterable (#108765)num_batches_tracked of nn.BatchNorm{*}D in load_state_dict to not be reset to 0 if the state_dict does not contain num_batches_tracked (#110850)convert_sync_batchnorm to return SyncBatchNorm layer with same training flag as BatchNorm layer being converted (#111998)index_select.out (#111364)meta_randperm (#109721)qlinear_pointwise (#112390)threshold_backward (#110689)aten.add with int32 + scalar input (#113965)aten.add non-contiguous out handling (#111758)aten.normal with strided layout input (#111205, #112467)aten.baddbmm (#109714)index_add (#108826)aten.split_with_sizes (#113984)torch.overrides.get_overridable_functions (#109890)sparse_allreduce dispatch (#111485)cuda to MPI backend capabilities (#109614)send()/recv() to make them respect the timeout same as non-p2p collectives (#109611)NCCL_ASYNC_ERROR_HANDLING to 3:SkipCleanUp to avoid calling ncclCommAbort which in some cases hangs (#110723)torch.cpu has no attribute current_device in checkpoint/optimizer.py (#110299)DTensor.from_local() returns DTensor with wrong size for uneven sharded tensor (#110781)_shard_utils.py to explicitly use the correct device from fsdp_state (#109631)requires_grad attribute to unsharded params (#109892)compute_device (#110929)SHARD_GRAD_OP and forward_prefetch is turned on (#110139)summon_full_params(..., with_grads=True) when grad precision is not fp32 (#112746)functorch.compile.minifier error of “'Node' object is not iterable” (#103011)
__annotations__ (#109853)make_fx invocations isolated (opaque to higher make_fx invocations) by default (#93290)optimize_for_inference to support modules that don't have a forward method (#110013)AdaptiveAvgPool3d (#109822)torch.mean backward (#109935)torch.matrix_exp performance (#110848)cholesky_solve_backward using output_mask (#112981)Optimizers to speedup inductor against list comprehensions (e.g. complex conversion) (#110613, #112722)bitwise operators (#91971), nansum & nanmean (#91372), all & any (#91966), torch.linalg.vander (#91749), slogdet (#86815), torch.index_fill (#91364), narrow_copy (#88130), view_copy (#88150), greater_equal.Scaler (#91324)_store_based_barrier to be adaptative based on the number of ranks. (#109218)device_type match (#110774)DTensorSpec (#113915)DTensorSpec hash lazily (#114322, #114379)isinstance call in is_shard (#114140)optim_state_dict when use_orig_params is True (#108298)torch.utils.data (#112244, #112817, #112765)PolynomialLR (#110151)maximize option in optimizer.py (#112724)torch/cuda/ and torch/optim/ (#112964)Timer.adaptive_autorange (#111612)torch.cholesky_inverse documentation (#110364)torch.from_file and UntypedStorage.from_file properly (#111688)Tensor.share_memory_ and torch.from_file (#111856)torch.unique docs (#113424)torch.lgamma docs (#108719)torch.take_along_dim docs to include dim=None case (#109120)torch.searchsorted docs (#109364)torch.multinomial usage (#112892)torch.export APItorch.cond doc (#108691)nn.CosineEmbeddingLoss(#108215)attn_bias in code block in scaled_dot_product_attention documentation (#109086)torch.nn.utils.parametrizations.weight_norm (#113783)scaled_dot_product_attention documentation to point to flash-attn-v2 (#114124)wait_for_workers (#111807)avoidRecordStreams_ so that correct name of Environment variable is shown in the warning message (#108759)dist.send (#108273)batch_isend_irecv example incorrect usage (#110408)apply_optimizer_in_backward in the document (#110903)NCCL_SUFFIX in NCCL version log at PG init (#112560)no_dist for in load_state_dict (save -> load) (#112217)_dynamo.optimize_ddp=True and _inductor.keep_output_stride=False together inside DDP (#108235)FSDP.optim_state_dict_to_load to reflect right ctors (#108383)FSDP.set_state_dict_type to contain missing Args (#103864)rendezvous/registry.py (#111352)torch.distributed.rpc example incorrect usage (#112367)torch.distributed.run init connect timeout by comparing host with the current IP list (#90221)prepare_pt2e, prepare_qat_pt2e and convert_pt2e (#110097)This release is meant to fix the following issues (regressions / silent correctness):
This release is meant to fix the following issues (regressions / silent correctness):
torch.set_num_threads (https://github.com/pytorch/pytorch/pull/113684)The Cherry pick tracker https://github.com/pytorch/pytorch/issues/113962 contains all relevant pull requests related to this release as well as links to related issues.
This release is meant to fix the following issues (regressions / silent correctness):
This release is meant to fix the following issues (regressions / silent correctness):
torch.distributed.checkpoint.optimizer.load_sharded_optimizer_state_dict (#111687)planner argument to torch.distributed.checkpoint.optimizer.load_sharded_optimizer_state_dict (#111393)torch.distributed.FSDP (#109116)torch.nn.functional.scaled_dot_product_attention (#112673)nn.functional.scaled_dot_product_attention (#110893)torch.sparse.mm for non-contiguous inputs (#111742)The https://github.com/pytorch/pytorch/issues/110961 contains all relevant pull requests related to this release as well as links to related issues.
Finish the deprecation cycle for non-bool masks. Functions now require the dtype of the mask to be torch.bool.
We are excited to announce the release of PyTorch® 2.1! PyTorch 2.1 offers automatic dynamic shape support in torch.compile, torch.distributed.checkpoint for saving/loading distributed training jobs on multiple ranks in parallel, and torch.compile support for the NumPy API.
In addition, this release offers numerous performance improvements (e.g. CPU inductor improvements, AVX512 support, scaled-dot-product-attention support) as well as a prototype release of torch.export, a sound full-graph capture mechanism, and torch.export-based quantization.
Along with 2.1, we are also releasing a series of updates to the PyTorch domain libraries. More details can be found in the library updates blog.
This release is composed of 6,682 commits and 784 contributors since 2.0. We want to sincerely thank our dedicated community for your contributions. As always, we encourage you to try these out and report any issues as we improve 2.1. More information about how to get started with the PyTorch 2-series can be found at our Getting Started page.
Summary:
torch.compile now includes automatic support for detecting and minimizing recompilations due to tensor shape changes using automatic dynamic shapes.torch.distributed.checkpoint enables saving and loading models from multiple ranks in parallel, as well as resharding due to changes in cluster topology.torch.compile can now compile NumPy operations via translating them into PyTorch-equivalent operations.torch.compile now includes improved support for Python 3.11.torch.export, a sound full-graph capture mechanism is introduced as a prototype feature, as well as torch.export-based quantization.torch.sparse now includes prototype support for semi-structured (2:4) sparsity on NVIDIA® GPUs.<table> <tr> <td> <strong> Stable </strong>
</td> <td> <strong> Beta </strong>
</td> <td> <strong>Prototype </strong>
</td> <td> <strong>Performance Improvements </strong>
</tr>
<tr>
</td> <td>
</td> <td>Automatic Dynamic Shapes
</td> <td> torch.export()
</td> <td>AVX512 kernel support
</tr>
<tr>
</td> <td> </td> <td>torch.distributed.checkpoint
</td> <td>torch.export-based Quantization
</td> <td>CPU optimizations for scaled-dot-product-attention (SDPA) </tr>
<tr> </td> <td> </td> <td>torch.compile + NumPy
</td> <td>semi-structured (2:4) sparsity
</td> <td>CPU optimizations for bfloat16
</tr>
<tr> </td> <td> </td> <td>torch.compile + Python 3.11
</td> <td>cpp_wrapper for torchinductor
</td> <td> </td> </tr>
<tr> <td> </td> <td>torch.compile + autograd.Function </td> <td> </td> <td>
</tr>
</tr> </td> <td> </td> <td>third-party device integration: PrivateUse1
</td> <td> </td> <td> </td> </tr> </table>
*To see a full list of public 2.1, 2.0, and 1.13 feature submissions click here.
For more details about these highlighted features, you can look at the release blogpost. Below are the full release notes for this release.
The PyTorch codebase has migrated from the C++14 to the C++17 standard, so a C++17 compatible compiler is now required to compile PyTorch, to integrate with libtorch, or to implement a C++ PyTorch extension.
torch.autograd.{backward, grad} for complex scalar output (#92753)Gradients are not defined for functions that don't return real outputs; we now raise an error if you try to call backward on complex outputs. Previously, the complex component of the output was implicitly ignored. If you wish to preserve this behavior, you must now explicitly call .real on your complex outputs before calling .grad() or .backward().
def fn(x):
return (x * 0.5j).sum()
x = torch.ones(1, dtype=torch.double, requires_grad=True)
o = fn(x)
o.backward()
o.real.backward()
autograd.grad (#90105)As a part of a larger refactor to torch.utils.checkpoint, we changed the interaction activation checkpoint and retain_graph=True. Previously in 2.0.1, recomputed activations are kept alive if retain_graph=True, in PyTorch 2.1, non-reentrant impl now clears recomputed tensors on backward immediately upon unpack, even if retain_graph=True. This has the following additional implications: (1) Accessing ctx.saved_tensor twice in the same backward will now raise an error. (2) Accessing _saved_tensors multiple times will silently recompute forward multiple times.
class Func(torch.autograd.Function):
@staticmethod
def forward(ctx, x):
out = x.exp()
ctx.save_for_backward(out)
return out
@staticmethod
def backward(ctx, x);
out, = ctx.saved_tensors
# Calling ctx.saved_tensors again will raise in 2.1
out, = ctx.saved_tensors
return out
a = torch.tensor(1., requires_grad=True)
def fn(x):
return Func.apply(x)
out = torch.utils.checkpoint(fn, (a,), use_reentrant=False)
def fn2(x):
return x.exp()
out = torch.utils.checkpoint(fn2, (a,), use_reentrant=False)
out.grad_fn._saved_result
# Calling _saved_result will trigger another unpack, and lead to forward being
# recomputed again
out.grad_fn._saved_result
broadcast_buffers is True (#100729)broadcast_buffers to be False:from torch.nn.parallel import DistributedDataParallel as DDP
module = torch.nn.Linear(4, 8)
module = DDP(module) # Buffer is synchronized across all devices.
module = DDP(module, broadcast_buffers=False) # Buffer is synchronized across all devices.
...
broadcast_buffers to be False, we don’t sync the buffer across devices:from torch.nn.parallel import DistributedDataParallel as DDP
module = torch.nn.Linear(4, 8)
module = DDP(module) # Buffer is synchronized across all devices.
module = DDP(module, broadcast_buffers=False) # Buffer is NOT synchronized across all devices
...
from torch.distributed.distributed_c10d import init_process_group
init_process_group(...) # Will call _store_based_barrier in the end.
...
TORCH_DIST_INIT_BARRIER controls whether we call store based barrier or not:from torch.distributed.distributed_c10d import init_process_group
import os
os.environ["TORCH_DIST_INIT_BARRIER"] = "1" # This is the default behavior
init_process_group(...) # Will call _store_based_barrier in the end.
os.environ["TORCH_DIST_INIT_BARRIER"] = "0"
init_process_group(...) # Will not call _store_based_barrier in the end.
...
torch.masked_{select, scatter, fill} (#96112, #97999, #96594)Finish the deprecation cycle for non-bool masks. Functions now require the dtype of the mask to be torch.bool.
>>> # 2.0.1
>>> inp = torch.rand(3)
>>> mask = torch.tensor([0, 1, 0], dtype=torch.uint8)
>>> torch.masked_select(inp, mask)
UserWarning: masked_select received a mask with dtype torch.uint8, this behavior is now deprecated,please use a mask with dtype torch.bool instead. (Triggered internally at ../aten/src/ATen/native/TensorAdvancedIndexing.cpp:1855.)
torch.masked_select(inp, mask)
>>> torch.masked_select(inp, mask.to(dtype=torch.bool))
# Works fine
>>> correct_mask = torch.tensor([0, 1, 0], dtype=torch.bool)
>>> torch.masked_select(inp, correct_mask)
# Works fine
>>> # 2.1
>>> inp = torch.rand(3)
>>> mask = torch.tensor([0, 1, 0], dtype=torch.uint8)
>>> torch.masked_select(inp, mask)
RuntimeError: masked_select: expected BoolTensor for mask
>>> correct_mask = torch.tensor([0, 1, 0], dtype=torch.bool)
>>> torch.masked_select(inp, correct_mask)
# Works fine
>>> torch.masked_select(inp, mask.to(dtype=torch.bool))
# Works fine
torch.unique to make it consistent with NumPy when dim is specified (#101693)The dim argument was clarified and its behavior aligned to match the one from NumPy to signify which sub-tensor to consider when considering uniqueness. See the documentation for more details, https://pytorch.org/docs/stable/generated/torch.unique.html
Prior to this change, for torch.nn.functional.grid_sample(mode='nearest') the forward 2D kernel used std::nearbyint whereas the forward 3D kernel used std::round in order to determine the nearest pixel locations after un-normalization of the grid. Additionally, the backward kernels for both used std::round. This PR fixes the inconsistencies to use std::nearbyint which rounds values that are exactly <>.5 to the nearest even which is consistent with the behavior of torch.round. Unnormalized indices that are exactly <>.5 will now be rounded to the nearest even instead of being rounded away from 0.
record_shapes) off by default for on-demand tracing (#97917)Profiler traces collected by on-demand tracing via IPC Fabric will have record_shapes off my default.
In v2.0.1:
By default, profiler trace files’ cpu_op activities will contain metadata fields: Input Dims, and Input type.
In v2.1.0:
By default, profiler trace files’ cpu_op activities will no longer contain metadata fields for input shapes. If turned on via Kineto config, it will show metadata fields: Input Dims, Input type and Concrete Inputs.
torch.aminmax would previously inconsistently return a 1D tensor output on CPU, but a 0D tensor output on CUDA. This has been fixed, so we consistently return a 0D tensor in both cases. (#96171).In v2.0.1:
>>> torch.aminmax(torch.tensor(1, device='cpu'), dim=0, keepdim=True)
__main__:1: UserWarning: An output with one or more elements was resized since it had shape [], which does not match the required output shape [1]. This behavior is deprecated, and in a future PyTorch release outputs will not be resized unless they have zero elements. You can explicitly reuse an out tensor t by resizing it, inplace, to zero elements with t.resize_(0). (Triggered internally at ../aten/src/ATen/native/Resize.cpp:24.)
torch.return_types.aminmax(
min=tensor([1]),
max=tensor([1]))
>>> torch.aminmax(torch.tensor(1, device='cpu'), dim=0, keepdim=False)
torch.return_types.aminmax(
min=tensor(1),
max=tensor(1))
In v2.1.0:
>>> torch.aminmax(torch.tensor(1, device='cpu'), dim=0, keepdim=True)
torch.return_types.aminmax(
min=tensor(1),
max=tensor(1))
>>> torch.aminmax(torch.tensor(1, device='cpu'), dim=0, keepdim=False)
torch.return_types.aminmax(
min=tensor(1),
max=tensor(1))
If you have a custom operator that has a CPU/CUDA kernel registered to the CPU/CUDA dispatch key, but has no implementation at the Autograd key, then:
Old behavior: When calling this operator with tensor inputs that require gradients, the tensor outputs would silently not require gradients.
New behavior: When calling this operator with tensor inputs that do require gradients, the tensor outputs would require gradients (as long as the outputs are floating-point or complex), and will error if you try to backpropagate through them.
There is more information on how to recover the old behavior in the PR: (#104481, #105078)
torch.autograd.Function Raise an error if input is returned as-is and saved for forward or backward in setup_context (#98051)If you are writing a custom autograd Function and you have implemented your autograd Function using setup_context, and if your forward function returns an input as-is as output, then saving that tensor for forward or backward now raises an error. You should return an alias of the input instead.
class Cube(torch.autograd.Function):
@staticmethod
def forward(x):
return x ** 3, x
@staticmethod
def setup_context(ctx, inputs, outputs):
cube, x = outputs
ctx.save_for_backward(x)
@staticmethod
def backward(ctx, grad_output, grad_x):
# NB: grad_x intentionally not used in computation
x, = ctx.saved_tensors
result = grad_output * 3 * x ** 2
return result
class Cube(torch.autograd.Function):
@staticmethod
def forward(x):
return x ** 3, x.view_as(x)
...
use_reentrant flag explicitly when using torch.utils.checkpoint (#100551)In PyTorch 2.1, if the use_reentrant flag is not explicitly passed, a warning is raised. To retain current behavior, pass use_reentrant=True. The default value will be updated to use_reentrant=False in the future. We recommend using use_reentrant=False.
torch.utils.checkpoint(fn, (a,)) # Warns in 2.1
torch.has_* attributes (#103279)Use the version in the particular backend module at torch.backends.* to access these flags.
Also note that we now properly differente is_built() (compile time availability) and is_available() (runtime availability) in these modules.
check_sparse_nnz argument for torch.autograd.gradcheck (#97187)torch.autograd.gradcheck(fn, inputs, check_sparse_nnz=True)
torch.autograd.gradcheck(fn, inputs, masked=True)
NVFuser integration with TorchScript is deprecated (#105185)NVFuser replaced Neural Network Compiler (NNC) as the default GPU fuser for TorchScript in PyTorch 1.13. In PyTorch 2.1, TorchScript switched its default fuser back to NNC. Additionally, NVFuser for TorchScript is now deprecated. Currently, users can still manually choose to use NVFuser instead of NNC, see fuser options for details on how to do this.
torch.device to be used as a context manager to change the default device (#106514)torch.Tensor.dim_order field to access current dimension permutation (#106835)torch.backends.cpu.get_cpu_capability() to expose cpu properties (#100164)PrivateUse1 device (out of tree device) for untyped storage (#100868)torch._foreach_pow (#92303)decoupled_weight_decay flag (#103881, #107706)load_state_dict() and state_dict() (#105953, #106209)torch.compile automatically finds dynamic dims and selectively turns on dynamism - (#106188, #98923)TORCH_LOGS to enable better logging UX for torch.compile - (#94858, #98564, #98776, #98795, #100664)torch.compile (#106211)torch.sparse.semi_structured (#100485, #103700, #107398, #103978, #103830, #104608, #101339)_foreach_zero_ (#101149)torch.nn.functional.logsigmoid (#99288)torch.renorm (#100798)scaled_dot_product_attention (#95259)nn.Module.to_empty option (#104197)LayerNorm (#101683)nn.Module global/non-global forward hooks (#104278)Transformer (#101687)torch.export: export() (#107609), dynamic_dim()(#107635), constrain_as_{size,value} APIs (#107735) and ExportedProgram (#107852)torch.compile composition (#98328, #106610, #107462, and others)functorch.einops.rearrange (#101957)PrivateUse1 for dispatching PyTorch Distributed Collectives to support custom device. (#98137)Store methods: append, multi_get, multi_set. (#100379)all_gather_into_tensor (#101157)reduce_scatter_tensor (#103561)reduce_scatter_tensor_coalesced (#104345)FakeTensor) is a process group which doesn't actually do any communication, but instead just just hallucinates communication. (#102180, #102238, #104213, #104428)init_process_group method without specifying the backend (#107113)DTensor constructor function: ones/empty/full (#100933, #101022, #103165)DTensor based Native sequence parallelism (#94369)deviceMesh to use dispatchable PG to support custom backend (#102336)DTensor (#101914)CustomPolicy in FSDP wrapping (#104986)DTensor based DCP (#94868)export_memory_timeline to save memory timeline plot to file (#96137, #96535)cuLaunchKernel in profiler traces for triton kernel launches including flow events in profiler traces (#99571)cudaLaunchKernelExC (#106293)torch.onnx.dynamo_exporttorch.onnx.ExportOptionstorch.onnx.ExportOutputExportOutput.save for models larger than 2GB (#107904)torch.onnx.enable_fake_mode()torch.compile ONNX Runtime backend (#107973, #106929, #106589)Usage: `torch.compile(..., backend="onnxrt")`
Available when `torch.onnx.is_onnxrt_backend_supported()` returns `True`
Additional Python package dependencies: `onnx`, `onnxscript`, `onnxruntime`
aten::_convolution_mode (#89107)aten::unflatten (#99056)aten::scaled_dot_product_attention (#99658)aten::tile (#99927)aten::atan2 (#100040)aten::broadcast_to (#101833)aten::scatter_reduce (#102048)aten::logit (#102377)aten::hstack, aten::vstack (#102872)aten::atleast_1d, aten::atleast_2d, aten::atleast_3d (#103061)aten::logical_not (#96315)aten::randint (#105089)aten::norm: Supports dtype argument (#95637)MPSProfiler (#100635, #101002, #101692)torch.jit.load (#102204)torch.mps.Event() APIs (#102121)source_fn based partitioner to partition modules that were flattened in export (#98628, #101121)aggressive_merge to CapabilityBasedPartitioner which merges independent subgraphs (#100195)torch.{bits1x8,bits2x4,bits4x2,bits8,bits16}) (#95860)float8 dtypes (#105807)XNNPACKQuantizer (#98507, #98569, #98560, #99063, #99399, #100566, #101122, #102394, #102395, #102396, #102397, #102398, #102703, #103526, #105551, #106087, #106094, #107872, #107992);EmbeddingQuantizer (#103088);ComposableQuantizer (#102846);X86InductorQuantizer and Kernels (#98730, #98826, #105639, #106836, #106781, #105818, #104580);torch.get_cpu_capability, Tensor.is_xla, so they can be captured by torchscript (#100723)__prepare_scriptable__ on non-nn.Module classes as an escape hatch to provide a scriptable alternate implementation (#106229)deepcopy a JIT module onto a new device (#106521)aten::unsqueezefor 2d to 3d (#101719), aten::cat operator for 1d, 2d, 3d and 4d (#102128), aten::expand (#103930), aten::flip (#106628), gelu (#102762), aten::masked_fill (#104444), aten::pow (#105550), at::softmax 1,2,3 dimension tensors (#105012), at::softmax along all dimensions for 4-dim Tensors (#102988), sum.dim_IntList (#105612), sum.dim_IntList with keepdim (#106159), at::select.int operator, 4 dim/rank tensor case (#96228), aten::stack (#103344), aten::uniform (#102431), aten::unsqueeze, 1d->2d, 3d->4d (#102987), aten::repeat (#103255), aten::tile (#103944), aten::zero_ (#103042), aten::zeros (#103703), convert_qconv2d_context (#97714), "height" and "width" dimension for select operator (#94612), t and transpose operators for 2d, 3d and 4d tensors (#101808), unary ops (#104994), upsample_bilinear2d (#98022), upsample_nearest2d and quantized_upsample_nearest2d (#97467), quantize_per_tensor vulkan backend function (#106641), quantized binary ops (add/sub/mul/div), and adding graph rewrites for quantized add, mul, conv2d and conv2d_relu (#97468)BinaryOp.cpp (#105380)torch.{save,load} (#99453)torch.library (#106086)torch.{save,load} (#94503)torch.storage.UntypedStorage.get_device method (#99818)torch.__init__.py (#106214, #103807), torch.Tensor.retains_grad (#103528)torch.bincount deterministic on CUDA if weights are not given (#105244)torch.distributions (#106458)itemsize and nbytes properties to Tensor (#98322)torch.expm1 (#96644)nonzero_static op to pytorch to unblock export (#97417)tensor.type() issue. (#96381)THPVariable_set_grad (#100683)new_full's fill_value argument type to be complex, for more accurate type checking (#91345)_foreach_mul (#106677)_foreach_copy (#107226)validate_input_col for partial functions (#95067)__getitems__ to description of Dataset API, and also better support within Subset (#100375)StackDataset (#101338)copy option to fork DataPipe (#96030)randperm in RandomSampler (#103339)embedding_bag's weight is 2D (#94931)nn.init.trunc_normal_ (#100810)clip_grad_norm to use torch.linalg.vector_norm (#102429)uint8 support for CPU images in interpolate(mode='bicubic’) (#103252)nn.ChannelShuffle to run without error on CUDA tensors (#105351)nn.CircularPad{3/4/5d and fixed no_batch_dim support for CircularPad (#106632)reset_parameters for torch.nn.PRelu (#106507)grid_sample on half precision inputs on CUDA (#96586)cpu uint8 channels last (#96848))mkldnn_rnn_layer_backward to support double backward of LSTM (#100627)is_causal API for TransformerDecoder (#97166)is_causal hints for Transformer (#106143)bfloat16 support for reflection and replication padding (#102949)SyncBatchNorm support for custom device (#104250)BatchNorm on CPU (#97774)torch.vmap support for torch.complex (#96032), overloads of float_power, where, and comparison ops. (#96744), linalg.lu_factor (#94328), ldl_factor (#97518), torch.copysign (#96018), torch.nn.functional.smooth_l1_loss (#98357), nn.functional.huber_loss (#99235, #99236), special bessel functions (#99543), torch.nn.functional.{max_pool1d, max_pool3d} batch_rule (#99517, #99522), Tensor.index_fill (#99229), torch.bucketize (#95783), smooth_l1_loss_backward (#99429)_foreach_zero_ in zero_grad (#97159)torch._foreach_lerp for SWA update (#103550)single_tensor_adamw (#102858)lerp(cpu): Add half support (#105607)norm(cpu): Accumulate in float when inputs are half or bfloat16 (#95166)matmul: Avoid unnecessary copies (#97355)matmul backwards: Don’t create large intermediary tensors (#95261)addmm: Call to mkldnn_matmul on AArch64 (#91763)addmm(cuda): Enable addmm + GELU epilogue fusion (#103811)dot/mv/gemm(cpu): Accumulate in float for bfloat16 inputs in the fallback path (#96074)bmm: Heuristics for AArch64 (#107167)baddbmm(cpu): Fix grain size setting (#98297)mm(cuda): Expose cuBLAS int8@int8 -> int32 (#96685)triu/tril: complete dtype support. (#101414)ADDMM_META(). (#105309)TORCH_LINALG_PREFER_CUSOLVER=1 to prefer cusolver as linear algebra library globally (#106226)ldl_factor(cuda): Enable hipSOLVER backend in ROCM (#102665)SymInt support for {tensordot,inner,linalg.{matrix_power,tensorinv}}. (#100356, #101940, #102465)torch.utils.checkpoint with use_reentrant=False:
context_fn= (#96783)debug= and determinism_check kwargs (#103859)torch.inference_mode, torch.no_grad, torch.enable_grad decorators to be used without parens (#107086)torch.autograd.set_multithreading_enabled to act as function and context manager (#105291)materialize_grads parameter to torch.autograd.grad() (#97015)torch.autograd.Function to save non-input leaf tensors for backward (#104039)sampled_addmm: backward performance improvements (#103544)zeros_like() and randn_like() for nested tensor (#96527, #96528)sub, sgn abs ops for nested tensor (#97837)split_with_sizes for NestedTensor(forward only, non-SymInt-ified) (#97446)_mm_prefetch is for Intel, changed to __prefetch for ARM64 (#96638)-Wnewline-eof (#99687)CMAKE_CUDA_STANDARD (#104240)USE_SYSTEM_ZSTD (#104611)MaxPool3d on CPU (#97775)logsigmoid, threshold, elu, gelu, hardtanh, hardsigmoid, hardswish, hardshrink, softshrink, leakyrelu, softplus, glu, silu, mish, and prelu on CPU (#98745)index_add_ error if input source shape is wrong (#100321)Half support for sigmoid on CPU (#96077)Half to cat fast path on CPU (#96078)float as accumulate type for reduce Ops: min, max, minmax on CPU (#96079)bf16 dtype for conv_depthwise3d and searchsorted (#97819, #99426)nn.EmbeddingBag bound check (#96022)set_device change (#94864)lerp implementation (#105470), logit (#95162), hardsigmoid (#95164),hypot (#95196), xlogy (#95213), log_sigmoid(#95280), fmax and fmin (#95191), roll(#95168), copysign (#95552), pow.Scalar (#95201), masked_scatter (#95743), index_fill (#98694), linalg.vector_norm (#99811), histogram (#96652), aminmax (#101691), aten::erfinv (#101507), cumprod (#104688), renorm (#106059), polar (#107324)is_macos13_or_newer (#95065)float16 input to float32 LayerNorm (#96430)max_pool2d (#98582)mps package in torch (#98837)ExportedProgram.transform updates graph_signature automatically (#107792)split.Tensor from core Aten (#107938)get_attr rather than putting all get_attr ahead (#95014(https://github.com/pytorch/pytorch/pull/95014 ))get_attr nodes in fx.Transformer (#95245)nn_module_stack metadata whenever we create a new node when tracing (#95358)self.symbol_to_source failure (#95972)torch.fx to take Modules that return dataclass (#99576)has_side_effect to add to a list of side effecting functions (#97288)fx.wrap idempotent (#104838)pixel_shuffle, pixel_unshuffle, narrow, ConvTranspose, ConvTranspose3d (#94769, #96160, #97126, #97125, #101926)LSTM and MultiheadAttention (#96343, #96436, #101299, #95636)hardswish (#94486)quantized_max_pool3d (#101654)fuse_modules (#105069)torch.matmul in FloatFunctional/QFunctional (#106831)record_inputs=True, record scalar lists of length <= 30 (#100593)stress_test (#105144)tb_plugin to support HDFS and improved memory view (#106672)export_memory_timeline (#99751, #101316)export_memory_timeline_raw (#105094)Autocast support to MatMul through explicit cast (#98346)Slice (#105755)deduplicate_initializers when keep_initializers_as_inputs is True (#96320)name field of GraphProto (#107408)Softmax op (#102861)autograd_inlining flag to torch.onnx.export (#104067)checkpoint_wrapper acccept auto_wrap_policy (#102672)PrefixStore. (#100380)_cast_forward_inputs (#102680)use_orig_params=True (#97667)requires_grad for use_orig_params=True (#98221)fully_shard (#104363)limit_all_gathers=True default for FSDP (#104900)record_function for explicit prefetching (#105985)div_ for Hybrid Sharding Data Parallel (HSDP) (#106034)ModuleWrapPolicy (#104427)ModuleWrapPolicy to take Iterable (#104999)sharded_grad assert to allow IDLE state (#96584)optim_state_dict aware of DDP prefix (#96415)optim_state_dict and optim_state_dict_to_load (#96534)named_parameters and named_modules (#99448)param_groups optional for FSDP optim.state_dict (#99117)rank0_only when use_orig_params is True (#99624)rank0_only load logic (#99647)fsdp device-agnostic for custom-backend which implements cuda-semantics (#99024)_foreach_non_finite_check_and_unscale_cpu_ (#100108)use_orig_param is True and sharding is NO_SHARD (#100189)set_state_type to SHARDED_STATE_DICT compatible with NO_SHARD sharding_strategy (#100208)fully_shard unit to cast foward inputs for mixed precision config (#100290)state_dict_config for NO_SHARD (#100855)NO_SHARD sharding strategy (#101095)ignored_states to FSDP/fully_shard (#102056)optim.state_dict() to get the initial empty states (#103609)_get_module_fsdp_state_if_fully_sharded_module for state_dict (#103783)ignored_modules, ignored_states (#104273)module.training for _root_cast_forward_inputs (#104223)optim_state_dict_to_load work with use_orig_param=False + NO_SHARD (#107185)state_dict config (#105949)fsdp checkpoint (#107289)_tenso.zero function (#95863)nn.Embedding op for DTensor (#96702, #104820)DTensor in submesh (#95458)DTensor and Tensor Parallel (#98198, #98577, #103235, #103910, #106535)aten.equal sharding prop for DTensor (#97170)cuda device automatically, and refactor error handling (#97583)DTensor ops on non-participating devices (#95852)torch.chunk (#98722, #106250)ColwiseParallel style when Pairwise cannot be used directly (#100137)DTensor ops (#100607, #101203)DTensor (#103106)DTensor to support cuda-like device (#102468)DeviceMesh (#104807)recordStream calls in ProcessGroupNCCL an option (#89880)_store_based_barrier implementation to reduce load on rank 0 (#98000)nccl collective launch for nccl 2.0+ (#97904)torch.distributed.ReduceOp.AVG in type stubs (#101534)_get_pg_default_device rather than from explicit cuda (#101533)nccl availability (#102470)is_backend_available for c10d backend. (#101945)workEnqueue when capturing cuda graph for NCCL process group (#103503)ncclCommAbort can abort stuck ncclCommInitRank (#103925)--standalone to bind to a random port (#107734)collective_utils (#101037)fsspec storage read/write to PT (#98387)FsspecWriter/Reader and internal FsspecWriter/Reader (#104724).back() in rpc/script_call.cpp (#94297)nn.Module forward hooks in Torch Dynamo (#92125)sum dtype handling to match eager (#103037)rad2deg, deg2rad, count_nonzero, bitwise_right_shift, quantized.max_pool2d, erfc, erfinv, all_reduce, squeeze_copy, aten.prod, softshrink, aten.unfold, diagonal, diagonal_copy, diagonal_scatter ( #98994, #98995, #94997, #105906, #101416, #101863, #93111, #96039, #99484, #105603, #105165, #103755 )aten.normal_, lerp, aten.angle, unfold_copy, aminmax, nansum, fmin, fmax, narrow_copy, expand_copy, view_copy, smooth_l1_loss, full_like, affine_grid_generator, aten.dist ( #91207, #104866 , #105609, #96038, #96039, #102077, #101963, #104709, #105586 )cudagraph and cudagraph trees (#97440 , #98254, #89146, #98529, #102273, #105148 )index_expr propagation pass to simplify indexing expressions (#101077 )max_pool2d_with_indices to eager rather than fail an assertion if dilation is not 1. (#100531 )tl.dot and MFMA support enabled in ROCm triton for conv/mm lowerings (#107600)miopen_batch_norm fallback, now lowering to triton (#100089)_unsafe_index in Inductor (#107882)LSTM (#103071)fused_attention pattern matcher (#107128)fused_attention pattern matcher with additional clone (#108141)jit.trace functions (#95544)tuple instead of Tuple (#98703)stack, squeeze.dims, cross_entropy_loss, conv_transpose (#92205, #93919, #98078, #97875, #102139)ForwardRef type annotations for NamedTuple attributes (#96933)std::string to python str. (#97282)torch.jit.load for custom device (#99535)__repr__ (#100724)nn.functional (#102918)weights_only option to load_state_dict_from_url (#98479)ExtraFilesMap without explicit mapping. (#99747)profile_plot generates snapshot objects (#103497)vmap Support for torch.tril and torch.triu (#94287)UpsamplingBilinear2d (#101248)torch.distributions.Dirichlet.log_prob when x=0 and alpha=1 (#103605)torch.distributions.Gumbel.cdf (#91698torch.asarray to use the default device (#106779)torch.Tensor on MTIA device (#107427)Tensor.resize_ (#104300)torch.pow to handle real negative base and complex exponent (#95198)LayerNorm(bias=False) error (#108060)torch.autograd.graph.register_multi_grad_hook to not keep tensor alive in closure (#102859)THP{Cpp,}Function_traverse PyObject traversals (#102860)Tensor::register_hook behavior on undefined tensors (#105587)torch{resize_, resize_as_} (#96598)foreach functions (#93901)complex x amsgrad support for Adam and AdamW (#104989, #104990)AveragedModel (#95979)weight_decay for Adam (#100973)optimizer state_dict casting to allow step to cast for fused/capturable (#102619)lr_scheduler.py to check the type of eta_min (#97003)lr_scheduler serialization containing bound methods (#102627)int() casting in torch.nn.RNN to have correctly traced JIT and ONNX graph. (#92970)nn.utils.rnn.unpad_sequence (#98042)torch.nn.FractionalMaxPool2d output_size error (#99507)torch.nn.MaxPool1d output on cpu and gpu (#99843)lengths in pack_padded_sequence when the default device is GPU (#103967)scaled_dot_product_attention (#107968)interpolate if size contains non-integer elements (#99243)stateless.functional_call is called with nn.DataParallel (#107403)torch.roll (#95048), nn.{PixelShuffle, PixelUnshuffle}(#96493)functorch.jacrev support for torch.take (#95772)functorch support for transforming over Tensor indexing (#98748)torch.vmap support for torch.searchsorted (#99698)torch.vmap support for Tensor.index_put` (#100516)functorch infrastructure (#101568)autograd.Function now raises an error with functorch transforms instead of being silently incorrect (#103957)nll_loss batch rule with negative ignore_idx (#106118)kDefaultTimeout multiple definition build failure in Gloo (#97270)TCPSTore to avoid deadlocks. (#100555)process_group_name when there are duplicate PGs (#100518)scatter_object_list (#100552)netName assignment for NCCL Config (#105776)FileStore for Windows if the file path is invalid (#103247)fully_shard may determine compute device incorrectly (#98831)use_orig_params=True mixed precision training when some ranks have no (non-zero sized) parameter shards (#99175)use_orig_params=True, CPU offload, no_sync() (#100180)device_id when buffer-only module (#103504)skip-sharded-views + mixed precision (#105346)ignored_states + auto wrap (for now) (#104418)optim_state_dict (#96263)should_cast_forward_inputs in _root_pre_forward() and _pre_forward() (#99546)ignored_states when they are passed as generators (#102575)state_dict (#107172)DeviceMesh logics in deciding which PG to use (#96861)_get_or_create_default_group() (#96961)DeviceMesh (#97384)DTensor equal op (#99014)to_local bwd (#102630)dim_groups attribute from DeviceMesh (#103105)requires_grad in distribute_tensor (#107606)new_empty_strided op’s crash on the shard placement (#108600))new_empty_strided op (#108600)requires_grad callsite (#108358)A lot of dynamic-shapes bugfixes, too many to enumerate one-by-one. Some important points:
Tensor.__contains__ accept SymInt/Float/Bool. (#98933)In addition, we have the following fixes broken down into roughly 4 parts:
The first three cover a large number of general improvements to torch.compile, since torch.compile captures a graph internally by using these major components (fake tensor, prims and decomps, and AOTAutograd, see docs(https://pytorch.org/get-started/pytorch-2.0/)).
There were a large number of fixes to the primtorch and ref decompositions, which are used in torch.compile during graph capture. These all fixed quite a few bugs in torch.compile:
Hardshrink: make decomp composite implicit (#107039)Fake Tensors and meta functions are used internally to perform “shape inference” during graph capture when running torch.compile. In particular: when we capture a graph of pytorch operators, we’d like detailed information on the shapes of intermediate and output tensors in the graph. There were a large number of bugfixes and improvements to these two subsystems over the last release.
Operator bugfixes:
Increased operator coverage:
multi_margin_loss: check weight shape, make contiguous on CPU, add tests (#104852)argsort.stable (#106025)searchsorted.Scalar (#106283)Other:
AOTAutograd is a major component of the torch.compile stack, and received many bugfixes and improvements over the last release.
baddbmm: Fix when out has nan value for beta=0 (#96086)tensordot, addmm(cpu) (even when input has zero numel), baddbmm}. (#98938, #100274, #102659)CapturedTraceback (#107438)kineto_activity for each event for on-demand profiling (#97550)record_shapes (#104320)LoggerCollector (#101952)tb_plugin regarding Distributed View and NCCL events (#103031)test_profiler_tree for HIP and enabled individual activity types for RocTracer (#106293)test_memory_timeline_no_id in test_memory_profiler.py (#103441)prelu workflow (#103455)zero_point from determine_qparams as a int64 (#98746)QuantizeAvx512 (#104400)index_put (#94849)BFloat16 and Half (#96962)x[[1,2], :] = 2 when torch.use_deterministic_algorithms(True)" (#105833)CUDA_VISIBLE_DEVICES into account for nvml calls (#94568)vec512 operator!= implementations (#97466)masked_scatter_: non-contiguous self (#100232)torch.addcmul (#96164)random_ overload (#98333)layer_norm_backward_mps key (#100295)bernoulli for int types (#100946)arange for int8 and uint8 dtypes (#101303)torch.std for negative dimentions (#107754)ReplicatePad3D (#96988)torch.eye unsupported bool constant on macOS 12 (#97027)softplus with f16 input (#101948)randperm with device mps (#104171)argmax and argmin clamp value on MPS (#104374)torch.empty* deterministic by filling with NaN or max int (#104995)copy_ broadcast (#105617)clamp with strided outputs/inputs (#97858).item() for multi-dim scalar (#107913, #108410)size_t (#104201)aten::cat for concatenation of 3D tensors at channel dim with channels as multiple of 4 (#103718)at::softmax 1,2,3 dimension tensors (#105082)vulkan_quantized_api_test.cpp (#97400)check_inputs (#105960)image->bool copy (#106752)USE_FAST_NVCC Windows (#95206)cast operator after reduce to match desired dtype (#100700)repeat_intereleave export for scalar-valued repeat (#100575){zeros, ones, full, empty, rand, randn}_like ops to onnx (#103048)output_padding for quantized tconv (#104207)AvgPool to support dynamic shapes (#105683)expand_as (#95962)aten::device variant to TorchScript (#97023)aten::slice (#104385)STFT Support (#92087)aten::flatten conversion with 0d input to onnx Reshape and 1d to Identity (#104089)max_pool (#106270)reshape and size for the ONNX exporter (#106629)aten::round op (#107920)peephole for eval mode when constant folding is enabled only (#95801)None constant during jit scalar type analysis (#101608)Gather constant folding (#101329)scipt -> script (#97850)Cast node (#106093)torch.onnx.export (#107829)torch/csrc/jit/passes/onnx/unpack_quantized_weights.cpp data_ptr-correct (#100681)op.Concat (#98509)aten::cat export when arg include parameters (#105373)torch.ops.aten (#99682)fx_to_onnxscript (#100050)tracing_mode through options.dynamic_shapes and enable dynamic tests in test_fx_to_onnx_runtime.py (#100212)RemoveConstantInputStep to adapt torch inputs to ONNX inputs (#100252)UnsupportedFxNodesAnalysis after onnx dispatcher changes (#105156)torch.device in FX exporter (#105757)FXSymbolicTracer from _assert_fake_tensor_mode (#107712)torch.onnx.ExportOutput.save_model_with_external_data (#105002)options.dynamic_shapes to dynamo API usage in fx exporter (#99199)split_module bug with unused keys (#95493)subgraph_rewriter after repeated replacements (#99039)node.meta (#107248)OpOverload (#102547)int/float as additional graph inputs (#96786)ndarray.__pow__ (#107746)NotImplemented for `np.sort(complex)`` (#107710)linalg, random and `fNote truncated.
Fix Ppotentially backwards incompatible change with DataLoader and is_shardable Datapipes #97287
This release is meant to fix the following issues (regressions / silent correctness):
_canonical_mask throws warning when bool masks passed as input to TransformerEncoder/TransformerDecoder (#96009, #96286)is_causal paremeter for torch.nn.TransformerEncoderLayer.forward #97214The release tracker should contain all relevant pull requests related to this release as well as links to related issues
Your coding agent can read these notes before it upgrades. Set up the MCP server →