PyTorch
tensors
detach
clone
deepcopy

What is the difference between detach, clone and deepcopy in Pytorch tensors in detail?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In PyTorch, detach, clone, and deepcopy all produce “something new,” but they are not interchangeable. The real differences are about three questions: does the new object share storage with the original, does it stay connected to autograd history, and is it the right API for tensors at all. Once you separate those concerns, the behavior becomes much easier to reason about.

detach() Breaks Autograd but Shares Storage

detach() returns a tensor that is no longer part of the original computation graph.

python
1import torch
2
3x = torch.tensor([1.0, 2.0], requires_grad=True)
4y = x * 3
5z = y.detach()
6
7print(y.requires_grad)  # True
8print(z.requires_grad)  # False

The important detail is that z shares the same underlying storage as y. That means data changes can still affect both views.

python
z[0] = 999
print(y)  # tensor([999.,   6.], grad_fn=<MulBackward0>)

So detach() is about gradient history, not about independent memory.

clone() Copies Data but Keeps the Graph Relationship

clone() allocates new storage and copies the tensor data.

python
1x = torch.tensor([1.0, 2.0], requires_grad=True)
2y = x * 3
3c = y.clone()
4
5print(c.requires_grad)  # True
6print(c.data_ptr() == y.data_ptr())  # False

Unlike detach(), the clone has its own memory. But it is still connected to autograd. Gradients flowing through c still contribute back to x.

python
loss = c.sum()
loss.backward()
print(x.grad)  # tensor([3., 3.])

This is the key idea: clone() copies the data, but it does not sever the computation graph.

detach().clone() Is the Common “Independent Tensor Copy” Pattern

If you want both:

  • independent storage
  • no autograd connection

then the usual PyTorch pattern is:

python
safe_copy = y.detach().clone()

Now you have a fresh tensor with copied data and no gradient tracking back to the source graph.

This is often what people actually mean when they say “make a real copy I can modify safely.”

Where deepcopy Fits

copy.deepcopy is a Python object-copying tool, not primarily a tensor API. For ordinary tensor work, it is usually not the recommended first choice.

python
1import copy
2import torch
3
4x = torch.tensor([1.0, 2.0], requires_grad=True)
5d = copy.deepcopy(x)
6
7print(d)
8print(d.data_ptr() == x.data_ptr())  # False

For plain tensors, deepcopy creates an independent object with separate storage. But it is conceptually a Python-level recursive copy mechanism, and its behavior is most useful for larger Python objects such as modules, containers, or nested structures.

For tensor-only code, PyTorch idioms are clearer:

  • use detach() to cut autograd connection
  • use clone() to copy data
  • use detach().clone() to get an independent tensor copy outside the graph

Compare the Three Directly

A useful mental table is:

  • 'detach(): new tensor object, same storage, no grad history'
  • 'clone(): new tensor object, new storage, autograd connection preserved'
  • 'deepcopy(): new Python object and new storage, usually independent, but not the normal tensor-specific API'

The confusing part is that all three look like “copy-like” operations from the outside. They are not solving the same problem.

Example of the Most Common Mistake

A frequent bug is using detach() when the code really needed an independent copy.

python
1x = torch.tensor([1.0, 2.0], requires_grad=True)
2y = x * 2
3view = y.detach()
4view[0] = -1
5print(y)

Because storage is shared, modifying view modifies y as well. If you wanted isolation, you needed y.detach().clone() instead.

Use the Right Tool for the Intent

A simple decision rule works well:

  • I want no gradient tracking, but shared data is okay: detach()
  • I want copied data and still want gradients to flow: clone()
  • I want copied data and no gradient relationship: detach().clone()
  • I want to recursively copy a larger Python object: consider copy.deepcopy

That rule removes most of the ambiguity.

Common Pitfalls

A common mistake is assuming detach() makes a fully independent copy. It does not. It shares storage.

Another issue is assuming clone() breaks gradient flow. It does not. The clone still participates in autograd.

Developers also sometimes reach for deepcopy on tensors when a clearer tensor-native operation would express intent better.

Finally, if you are modifying tensor data in place, always think about both storage sharing and autograd implications. Those are separate concerns.

Summary

  • 'detach() breaks autograd tracking but shares underlying storage.'
  • 'clone() copies the data into new storage but keeps gradient relationships.'
  • 'detach().clone() is the standard way to get a true independent tensor copy outside the graph.'
  • 'deepcopy is a Python object-copying mechanism and is usually not the clearest first choice for plain tensor operations.'
  • The right method depends on whether you care about storage independence, gradient flow, or both.

Course illustration
Course illustration

All Rights Reserved.