Open-source project
Ascend/pytorch avatar
Ascend/pytorch

TorchNPU: the PrivateUse1 adapter that puts Ascend NPUs behind torch.mm

Ascend PyTorch adapter (torch_npu). Mirror of https://gitcode.com/Ascend/pytorch

577 stars94 forksPythonNOASSERTION

At a glance

What is it?
TorchNPU is Huawei's PyTorch adapter plugin for Ascend NPUs, installed as the torch-npu wheel and registered through PyTorch's PrivateUse1 mechanism. It is the right dependency only if you already own Ascend hardware and need upstream PyTorch semantics preserved.
Who is it for?
Adopt TorchNPU if you already run Ascend NPUs and want to keep upstream PyTorch code, because the .npu() device and PrivateUse1 registration mean your model code changes little. Do not adopt it if you are still choosing hardware, or if you need a torch version outside the list in version.txt, since the adapter is bound to specific PyTorch and CANN releases rather than tracking upstream.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The gap TorchNPU fills between PyTorch and an Ascend card

PyTorch ships with device backends for CPU, CUDA and a few others. An Ascend NPU is none of those, so stock PyTorch has no way to allocate memory on it or dispatch a kernel to it. TorchNPU is the layer that closes that gap. The README describes it as a deep learning adapter plugin built by Ascend for PyTorch that enables the framework to directly invoke Ascend NPU. The audience is narrow and specific: engineers who already have Ascend hardware in a cluster and want to run PyTorch models on it without rewriting the model. It is not a framework, not a training library, and not useful on a machine with no NPU. The README's own positioning statement puts it as the core component of the Ascend for PyTorch community, which tells you the maintenance model is vendor-driven rather than a community fork.

PrivateUse1 is the mechanism, and it explains most of the constraints

The README names PrivateUse1 as the integration point: TorchNPU integrates operators and device resources into PyTorch via PrivateUse1. That is PyTorch's extension hook for out-of-tree device backends, and it is why a separate pip package can add a working device without patching the torch source. The visible consequence in user code is the .npu() method. The README's quick start example allocates two tensors with torch.randn(2, 2).npu(), multiplies them with x.mm(y), and prints a result whose device string reads device='npu:0'. So the device type is npu, the indexing follows the usual :0 convention, and ordinary tensor operations dispatch through it. The same hook is what makes the packaging awkward: the plugin has to match the exact PyTorch build it extends, which is why the project keeps a version.txt file and calls it the single source of truth for adapted PyTorch versions. A single source tree adapting multiple PyTorch versions, as the README states, means the branch carries compatibility code for several torch releases at once rather than one clean target.

What the adapter adds beyond a device string

The README lists several modules that go past basic dispatch. Distributed support covers FSDP2, DTensor on core compute APIs, collective primitives including AllGather, AllReduce and AllToAll, and point-to-point primitives Send and Recv. Graph mode is described as dynamic graph capture plus static graph optimization plus code generation, with offloading via NPUGraph, and the README states it is supported in v2.6.0 and above. Debug and tuning covers profiling of compute, communication and memory, plus what the README calls real-time communication anomaly monitoring via WatchDog. TorchNPU Core adds virtual memory management intended to reduce memory fragmentation, cross-stream memory reuse in distributed scenarios, and the PrivateUse1 integration itself. Treat the version note on graph mode as load-bearing: if you are pinned to an older TorchNPU, that whole module is not available to you, and the README does not say what the fallback path looks like.

Installing it means installing four things in the right order

The README's binary path is explicit and sequential. First CANN, the Ascend software stack; the example uses CANN 9.0.0 and points at the CANN installation guide. Second PyTorch, installed from the CPU wheel index: pip install torch==2.10.0 --index-url https://download.pytorch.org/whl/cpu. Third the adapter itself: pip install torch-npu==2.10.0.post2. Before any of that runs, the environment script has to be sourced, and the README gives source /usr/local/Ascend/ascend-toolkit/set_env.sh with a note to adjust the path to your actual installation location. The README also documents a source build, pointing to docs/zh/installation_guide/references/building_from_source.md, which is where you would go if no wheel matches your combination. One behavioural detail worth flagging: from TorchNPU 2.5.1 onward, import torch_npu is no longer mandatory because auto-registration occurs, but the README still recommends the explicit import to ensure device initialization. That recommendation is the kind of thing that costs nothing to follow and is hard to debug when ignored.

Version coupling is the failure mode, not a footnote

The README splits version information across three places: version.txt for the PyTorch versions the branch adapts, COMPATIBILITY.en.md for the released package matrix covering TorchNPU, PyTorch, CANN and Python, and a download page for other versions. That split is the clearest signal of where this project hurts. A PrivateUse1 adapter is compiled and tested against particular PyTorch internals; when upstream torch moves, the adapter has to follow. The README's own example ties a specific torch (2.10.0) to a specific torch-npu (2.10.0.post2) and a specific CANN (9.0.0). Nothing in the material suggests you can mix rows of that matrix. The practical consequence: if your environment already has a different torch installed, upgrading torch independently of torch-npu is the fastest way to break the device. There is also no release list in the supplied material, so the cadence of adapter releases relative to PyTorch releases cannot be judged from what is here. Check the compatibility file before assuming a recent torch is covered.

When a different approach is the better answer

TorchNPU's whole value proposition is that it keeps PyTorch code unchanged. If your requirement is portability across accelerators rather than fidelity to PyTorch, that proposition inverts. A framework that compiles a model graph to its own runtime, such as a compiler-based stack, targets hardware through a separate graph representation instead of registering a device inside torch. The trade is concrete: you give up the ability to call arbitrary PyTorch ops and expect them to work, and in exchange you are not tied to a torch version matrix at all. TorchNPU's README claims support for extensive PyTorch native APIs plus custom APIs, which is exactly the property a compiler-based stack does not offer, and it is the reason to pick this adapter when your model uses ops that a compiler would reject. If your code is standard, well-supported layers, the compiler path removes an entire class of version-matching work. If it is not, TorchNPU is the option that keeps your code as it is.

Maintenance, licensing and what to check before you commit

Two maintenance facts are visible in the repository metadata. The default branch is master and the last push is dated 2026-09-10, so the repository is active rather than archived. The GitHub repository is described as a mirror of https://gitcode.com/Ascend/pytorch, which means issue tracking and contribution flow likely live on the GitCode side; the README's community section lists Special Interest Groups for development and maintenance. If your team's process assumes upstream GitHub issues, that is a mismatch to resolve before you file anything. On licensing, the metadata reports NOASSERTION while the README badge states BSD-3-clause and links to a LICENSE file. Those two signals disagree, and the README badge is not the license text. Read the LICENSE file in the repository and have your own counsel interpret it; nothing here should be taken as legal advice. The upgrade cost follows from the version coupling: every torch bump is a coordinated change across torch, torch-npu and CANN, and the README's compatibility file is the artifact that tells you whether a given combination is a supported one. Budget for that coordination rather than treating the adapter as a dependency that updates itself.

Editorial conclusion

Adopt TorchNPU if you already run Ascend NPUs and want to keep upstream PyTorch code, because the .npu() device and PrivateUse1 registration mean your model code changes little. Do not adopt it if you are still choosing hardware, or if you need a torch version outside the list in version.txt, since the adapter is bound to specific PyTorch and CANN releases rather than tracking upstream. Before installing anything, open version.txt and COMPATIBILITY.en.md and confirm that your exact torch, CANN and Python versions appear together in the same row; that single check decides whether the wheel will load at all.

Official sources

  1. Ascend/pytorch on GitHub
  2. Issues
  3. Project website
  4. README
Community notes

Community notes