PyTorch张量与NumPy数组转换的内存共享时机及代码疑问
PyTorch张量与NumPy数组转换的内存共享规则
核心结论
PyTorch张量与NumPy数组之间的内存共享与否,完全取决于转换方式、设备位置(CPU/GPU)以及数据类型兼容性,以下结合你的测试代码逐一分析:
你的测试代码分析
第一段代码:修改新张量不影响原张量/数组
import torch c = torch.ones(3, 3) d = c.numpy() e = torch.tensor(d) e[0, 0] = 100.0 print(c) print(d)
输出:
tensor([[1., 1., 1.], [1., 1., 1.], [1., 1., 1.]]) [[1. 1. 1.] [1. 1. 1.] [1. 1. 1.]]
c.numpy():CPU张量c生成的NumPy数组d与c共享内存。torch.tensor(d):这个函数默认会复制数据到新内存生成张量e,因此e和d/c没有内存关联。修改e的值自然不会影响c和d。
第二段代码:两种不同转换的差异
import torch import numpy as np a = np.ones((3, 3)) b = torch.tensor(a) b[0, 0] = 100 print(a) print(b) c = torch.ones(3, 3) d = c.numpy() d[0, 0] = 100.0 print(c) print(d)
输出:
[[1. 1. 1.] [1. 1. 1.] [1. 1. 1.]] tensor([[100., 1., 1.], [ 1., 1., 1.], [ 1., 1., 1.]], dtype=torch.float64) tensor([[100., 1., 1.], [ 1., 1., 1.], [ 1., 1., 1.]]) [[100. 1. 1.] [ 1. 1. 1.] [ 1. 1. 1.]]
torch.tensor(a)部分:和第一段代码的逻辑一致,torch.tensor()默认复制数据,生成的张量b与原NumPy数组a内存独立,修改b不影响a。c.numpy()部分:CPU张量c生成的NumPy数组d与c共享内存,因此修改d的同时,c的底层数据也会被同步修改,两者输出一致。
内存共享与独立的完整规则
共享内存的场景
只有满足以下所有条件时,转换后的对象才会共享内存:
- 原对象位于CPU(GPU张量无法直接与NumPy共享内存);
- 使用特定转换方法:
- PyTorch张量 → NumPy数组:调用
tensor.numpy(); - NumPy数组 → PyTorch张量:调用
torch.from_numpy(np_array);
- PyTorch张量 → NumPy数组:调用
- 数据类型完全兼容(比如
torch.float32对应np.float32,torch.int64对应np.int64),无需类型转换。
不共享内存的场景
只要触发以下任意一种情况,转换时就会创建新内存,对象之间独立:
- 使用
torch.tensor()转换NumPy数组(默认参数copy=True,强制复制); - 原张量位于GPU,调用
tensor.numpy()时会先将数据拷贝到CPU,生成新的NumPy数组; - 转换过程中需要进行数据类型转换(比如
np.int32转torch.float32); - 对张量执行过某些会改变内存布局的操作(比如
transpose后未调用contiguous(),此时numpy()会先复制数据)。
内容的提问来源于stack exchange,提问作者Frankenstein
相关产品推荐
相关产品推荐

