텐서
Tensor
다차원 배열. 딥러닝의 기본 데이터 구조. TensorFlow, PyTorch에서 연산 단위.
Tensor
다차원 배열. 딥러닝의 기본 데이터 구조. TensorFlow, PyTorch에서 연산 단위.
텐서(Tensor)는 다차원 배열(Multi-dimensional Array)을 일반화한 수학적 개념으로, 딥러닝과 과학 컴퓨팅의 기본 데이터 구조입니다. 스칼라(0차원), 벡터(1차원), 행렬(2차원)을 포함하며, 3차원 이상의 고차원 데이터까지 표현합니다. PyTorch와 TensorFlow 같은 딥러닝 프레임워크에서 모든 데이터와 연산은 텐서 단위로 이루어집니다.
텐서라는 용어는 원래 물리학과 수학에서 좌표 변환에 대해 특정 방식으로 변환되는 객체를 지칭했습니다. 머신러닝에서는 이 개념을 빌려와 다차원 숫자 배열을 표현하는 데 사용합니다. 2015년 TensorFlow의 등장과 함께 이 용어가 대중화되었고, PyTorch, JAX, MLX 등 현대 딥러닝 프레임워크 모두 텐서를 핵심 자료구조로 채택하고 있습니다.
텐서의 핵심 속성으로는 형태(Shape), 데이터 타입(dtype), 디바이스(device)가 있습니다. Shape은 각 차원의 크기를 나타내며 (배치크기, 채널, 높이, 너비)처럼 표현됩니다. dtype은 float32, float16, int64 등 데이터 정밀도를 결정하고, device는 CPU나 GPU(cuda) 등 연산이 수행되는 하드웨어를 지정합니다. 텐서 연산은 브로드캐스팅, 인덱싱, 슬라이싱 등 NumPy와 유사한 문법을 지원하면서도 GPU 가속과 자동 미분을 제공합니다.
2024-2025년 실무에서는 mixed precision training(FP16/BF16)과 양자화(INT8, INT4)가 표준이 되어 텐서 연산 효율성이 크게 향상되었습니다. NVIDIA의 Tensor Core, Apple의 Neural Engine, Google의 TPU 모두 텐서 연산에 최적화된 하드웨어입니다. 또한 Triton, torch.compile() 같은 JIT 컴파일러가 텐서 연산을 자동으로 최적화하여 성능을 극대화합니다.
PyTorch 텐서의 기본 사용법입니다.
# PyTorch 텐서 기초
# pip install torch
import torch
# 다양한 방법으로 텐서 생성
zeros = torch.zeros(3, 4) # 3x4 영행렬
ones = torch.ones(2, 3, 4) # 2x3x4 일행렬
rand = torch.rand(3, 3) # 0~1 균등분포
randn = torch.randn(3, 3) # 표준정규분포
arange = torch.arange(0, 10, 2) # [0, 2, 4, 6, 8]
# 리스트/NumPy에서 변환
from_list = torch.tensor([[1, 2], [3, 4]])
import numpy as np
from_numpy = torch.from_numpy(np.array([1.0, 2.0, 3.0]))
# 텐서 속성 확인
print(f"Shape: {rand.shape}") # torch.Size([3, 3])
print(f"Dtype: {rand.dtype}") # torch.float32
print(f"Device: {rand.device}") # cpu
# GPU로 이동 (CUDA 사용 가능시)
if torch.cuda.is_available():
gpu_tensor = rand.to('cuda')
print(f"GPU Device: {gpu_tensor.device}") # cuda:0
# 텐서 연산
a = torch.tensor([[1, 2], [3, 4]], dtype=torch.float32)
b = torch.tensor([[5, 6], [7, 8]], dtype=torch.float32)
print(f"덧셈: {a + b}")
print(f"행렬곱: {a @ b}") # 또는 torch.matmul(a, b)
print(f"요소별 곱: {a * b}")
# 형태 변환
c = torch.arange(12)
print(f"원본: {c.shape}") # [12]
print(f"reshape: {c.reshape(3, 4).shape}") # [3, 4]
print(f"view: {c.view(2, 6).shape}") # [2, 6]
print(f"unsqueeze: {c.unsqueeze(0).shape}") # [1, 12]
# 자동 미분 (딥러닝의 핵심)
x = torch.tensor([2.0, 3.0], requires_grad=True)
y = x ** 2 + 2 * x + 1
loss = y.sum()
loss.backward()
print(f"기울기 (dy/dx): {x.grad}") # [6.0, 8.0]
TensorFlow 텐서와 실전 활용 예제입니다.
# TensorFlow 텐서 기초
# pip install tensorflow
import tensorflow as tf
# 텐서 생성
zeros = tf.zeros([3, 4])
ones = tf.ones([2, 3, 4])
rand = tf.random.uniform([3, 3])
constant = tf.constant([[1, 2], [3, 4]])
# 텐서 속성
print(f"Shape: {rand.shape}")
print(f"Dtype: {rand.dtype}")
# 딥러닝 모델에서의 텐서 흐름 예시
# 이미지 배치: [batch_size, height, width, channels]
batch_images = tf.random.normal([32, 224, 224, 3])
# 컨볼루션 레이어 시뮬레이션
conv_layer = tf.keras.layers.Conv2D(64, (3, 3), padding='same')
output = conv_layer(batch_images)
print(f"입력: {batch_images.shape}") # (32, 224, 224, 3)
print(f"출력: {output.shape}") # (32, 224, 224, 64)
# Mixed Precision (FP16) 예시
tf.keras.mixed_precision.set_global_policy('mixed_float16')
print(f"Global Policy: {tf.keras.mixed_precision.global_policy()}")
# 텐서 타입 변환
float_tensor = tf.cast(constant, tf.float32)
int_tensor = tf.cast(rand * 10, tf.int32)
# GPU 메모리 확인
gpus = tf.config.list_physical_devices('GPU')
print(f"사용 가능한 GPU: {len(gpus)}개")
2025년 1월 기준 텐서 연산 성능 비교입니다.
| 하드웨어 | FP32 TFLOPS | FP16 TFLOPS | 메모리 | 가격(대략) |
|---|---|---|---|---|
| NVIDIA H100 | 67 | 1,979 | 80GB HBM3 | $30,000+ |
| NVIDIA A100 | 19.5 | 312 | 80GB HBM2e | $10,000+ |
| NVIDIA RTX 4090 | 82.6 | 165 | 24GB GDDR6X | $1,600 |
| Apple M3 Max | ~14 | ~28 | 128GB 통합 | $3,000+ |
데이터 타입별 메모리 사용량:
| 데이터 타입 | 비트 | 사용 사례 | 메모리 절감 |
|---|---|---|---|
| float32 (FP32) | 32bit | 기본 학습 | 기준 |
| float16 (FP16) | 16bit | Mixed Precision | 50% |
| bfloat16 (BF16) | 16bit | LLM 학습 | 50% |
| int8 | 8bit | 양자화 추론 | 75% |
CPU 텐서와 GPU 텐서를 직접 연산하면 에러가 발생합니다. 연산 전에 모든 텐서가 같은 device에 있는지 확인하고, .to(device)로 통일하세요.
a.add_(b) 같은 in-place 연산은 자동 미분 그래프를 손상시킬 수 있습니다. 특히 requires_grad=True인 텐서에서 주의가 필요합니다.
텐서 생성 시 device와 dtype을 명시적으로 지정하세요. 메모리 프로파일링 도구(torch.cuda.memory_summary())를 활용하여 메모리 누수를 조기에 발견하세요.