본문 바로가기
Python

[DL] Storage: PyTorch 텐서를 위한 메모리 관리

by ds31x 2024. 3. 21.

Storage는 Tensor 인스턴스의 실제 데이터가 저장되는 1D Numerical Array를 관리함.

여러 Tensor 인스턴스들이 같은 storage를 공유할 수 있음.

 

Storage

  • memory에서 contiguous data block를 관리하며,
    컴퓨터의 memory에서 homogeneous and contiguous array의 특징상 1D 임.
  • cpu 또는 gpu 등의 memory의 실제 data가 저장된 contiguous block을 관리.
  • 다양한 shape의 Tensor 인스턴스들은 자신의 storage인스턴스를 통해 data block을 관리함.

어찌 보면 Tensor 인스턴스들은 고유한 shape, stride, offset 을 가진 일종의 View에 해당한다.

 

참고: 다음 URL에서 contiguous array 에 확인할 것 (PyTorch의 Tensor는 결국 unboxed data type의 elements로 구성된 array).

https://dsaint31.tistory.com/456

 

[Programming] Primitive Data Type : C, C++, NumPy, Torch

Primitive Data Type이(Unboxed type)란? C, C++, NumPy, Torch, TensorFlow 등에서 numeric data type들은 보통 unboxed type이라고도 불리는 primitive data type들이다. unboxed type에서는 할당된 메모리 bit들이 해당 numeric data type

dsaint31.tistory.com

 

직접적으로 Storage를 통해 데이터를 접근하는 것은 권장되지 않지만, 

PyTorch에서 Tensor의 동작 및 저장 방식을 이해하기 위해 사용보는 것이 좋음. 


예제

Tensor 인스턴스의 Storage 인스턴스는 다음과 같이 얻어짐.

import torch

x = torch.randn(3,3)

x_storage = x.storage()

print(x.storage)

 

Storage는 실제 data가 저장되는 memory를 가르키는 위치를 반환하는 메서드를 가짐.

이를 통해 실제로 Tensor 인스턴스가 Data를 공유하는지를 확인할 수 있음.

 

다음 예제를 통해 Tensor 인스턴스와 이에 대한 slicing을 통한 Tensor 인스턴스의 관계를 확인할 것.

import torch

a = torch.tensor([range(i,i+3) for i in [0,3,6]])
a_sub = a[1:,0] # 부분에 대한 view

# Tensor a 와 a_sub 의 contiguous 여부 확인. 
print(a.is_contiguous(), a_sub.is_contiguous())

# Tensor a 와 a_sub 가 같은 메모리의 데이터를 공유하는지 여부.
print(a.storage().data_ptr() == a_sub.storage().data_ptr())

# Storage 인스턴스는 각 Tensor 인스턴스 별로 생성됨.
print(id(a.storage()) == id(a_sub.storage())

# Tensor 인스턴스의 meta data
print(f"{a.shape=}, {a.size()=}, {a.stride()=}, {a.storage_offset()=}")
print(f"{a_sub.shape=}, {a_sub.size()=}, {a_sub.stride()=}, {a_sub.storage_offset()=}")
  • stride각 축에서 index가 증가할 때 건너뛰어야하는 객체의 수를 의미.
  • storage_offset현재 Tensor 인스턴스가 Storage가 관리하는 memory block에서 몇 번째 객체에서 시작하는지를 나타냄.  

View 와 Reshape 에서의 underlying data 공유여부 

PyTorch의 Tensor 인스턴스의 shape는 view reshape  메서드를 통해 변경가능한데,

view 의 경우, 해당 인스턴스가 contiguous한 경우에만 사용가능함.

reshape 의 경우,

  • contiguous instance의 경우 view와 같은 동작임. ( underlying memory block 공유.),
  • 아닌 인스턴스에서 호출된 경우엔 contiguous() 메서드를 호출하고 view를 수행한 것에 해당함.
    (이 경우  underlying memory block이 새로 만들어짐.)

즉, reshape의 경우

  • memory를 공유할 수(contiguous인 인스턴스에서 호출된 경우)도 있고,
  • 아닐 수 (contiguous 하지 않은 인스터스에서 호출된 경우)도 있음.

 

PyTorch의 경우, viewdata를 attributes로 지원하면서
view 를 통해 shape를 변경하는 방식이었으나,
NumPy의 방식대로 reshape 메서드를 지원하면서
view를 굳이 shape를 바꾸는데 쓰지 않을 수 있게 됨.

 


Transpose와 Permute 에서의 underlying data 공유여부

기본적으로 Transpose와 Permute는
Tensor 인스턴스의 meta data (stride 등)을 수정하면 되기 때문에

underlying data 를 공유한다.

단, Transpose와 Permute를 통해 얻어진 인스턴스에서는
contiguous는 깨지게 된다.

 

이를 contiguous 메서드 호출을 하여

해당 인스턴스의 meta data를 기반으로 contiguous한 Tensor 인스턴스를 새로 얻는 경우에는

새로운 underlying data가 만들어지게 된다.

 


같이 확인하면 좋은 자료들

다음의 ipynb 는 PyTorch에서의 storage를 사용하여 앞서 설명한 내용들을 확인해 본 테스트 코드임.

https://gist.github.com/dsaint31x/422cbeeab92f28542090a44f23d63a07

 

dl_tensor_view_reshape_contiguous.ipynb

dl_tensor_view_reshape_contiguous.ipynb. GitHub Gist: instantly share code, notes, and snippets.

gist.github.com

 

다음은 Eli Stevens의 Deep Learning with PyTorch 를 웹에서 읽을 수 있는 URL임(강력추천).
여기서 3.7 Tenosrs: Scenic views of storage 를 참고할 것.

https://www.manning.com/books/deep-learning-with-pytorch

 

Deep Learning with PyTorch

Create neural networks and deep learning systems with PyTorch. Discover best practices for the entire DL pipeline, including the PyTorch Tensor API and loading data in Python.

www.manning.com

 

728x90

'Python' 카테고리의 다른 글

[DL] PyTorch: view, data, and detach  (0) 2024.03.22
[DL] PyTorch: TPU사용하기  (0) 2024.03.21
[Tensor] NaN Safe Aggregation Functions  (0) 2024.03.20
[Tensor] vectorized op. (or universal func)  (0) 2024.03.19
[ML] where: numpy 의 idx찾기  (2) 2024.03.19