LLM 성능의 숨은 변수: 하드웨어 친화적 설계

AI 모델의 성능을 이야기할 때 우리는 보통 정확도(Accuracy)만 떠올리기 쉽습니다. 하지만 실제 서비스를 운영하다 보면 **처리량(Throughput)**과 **상호작용성(Interactivity, 지연 시간)**이 정확도 못지않게 중요하다는 것을 깨닫게 됩니다. 아무리 뛰어난 모델도 응답이 느리다면 사용자 이탈로 이어지고, 처리량이 낮으면 서버 비용이 급증하니까요.

이 세 가지 목표는 서로 트레이드오프 관계에 있습니다. 정확도를 고정해 두면 문제는 2차원 파레토 프론티어(Pareto frontier)로 단순화됩니다. 즉, 처리량을 높이면 지연 시간이 늘어나고, 지연 시간을 줄이면 처리량이 떨어지는 상황에서 이 곡선 자체를 바깥으로 확장하는 것이 핵심 과제가 됩니다.

이 글에서는 LLM(Large Language Model)의 구조적 선택이 이 파레토 프론티어를 어떻게 바꾸는지 분석합니다. 특히 GPU 하드웨어의 동작 방식(GEMM 연산, 메모리 대역폭, 타일링)과 모델의 차원(H, H', L)이 어떻게 상호작용하는지 살펴보고, 실무에서 바로 적용할 수 있는 7가지 설계 원칙을 정리했습니다.

💡 핵심 포인트 모델을 설계할 때 하드웨어와의 정렬을 고려하면, 같은 연산량으로 더 높은 성능을 얻을 수 있습니다. 이는 GPU 활용도를 높여 서버 비용을 절감하고, 사용자 경험을 개선하는 두 마리 토끼를 잡는 길입니다.

이 글은 NVIDIA 기술 블로그의 AI 모델 설계와 하드웨어 친화적 LLM 설계 내용을 기반으로, 한국 개발자 생태계의 맥락에서 재해석했습니다.

AI model design concept with GPU chips and neural network layers Dev Environment Setup

GPU의 동작 원리: GEMM과 메모리 대역폭

GPU가 LLM 연산을 수행하는 방식은 크게 두 가지 요소에 의해 결정됩니다.

  1. 산술 강도(Arithmetic Intensity): 연산(FLOPs) 대비 메모리 이동(Byte)의 비율. 이 값이 낮으면 메모리 대역폭에 의해 성능이 제한되고(Memory-bound), 높으면 GPU의 연산 능력(Compute-bound)에 의해 제한됩니다.
  2. GEMM 타일링(Tiling): GPU는 출력 행렬을 작은 타일(tile)로 나누어 각 스트리밍 멀티프로세서(SM)가 병렬로 처리합니다. 이때 타일 크기와 모델 차원이 정확히 맞아떨어지지 않으면 타일 양자화(Tile Quantization)가 발생해 GPU 활용도가 떨어집니다.

GEMM 차원과 모델 구조의 관계

트랜스포머 블록의 각 선형 레이어는 GEMM 연산으로 표현됩니다. 입력 토큰 수(Tokens), 히든 차원(H), 중간 투영 차원(H')이 GEMM의 M, N, K 차원을 결정합니다.

레이어투영 (in → out)GEMM MGEMM NGEMM K
Q/K/V 입력H → 3HTokens3HH
어텐션 출력H → HTokensHH
FFN-1 (업투영)H → H′TokensH′H
FFN-2 (다운투영)H′ → HTokensHH′

실제 사례: 작은 H'의 함정

FFN-2 레이어에서 H'=512, H=8192인 경우를 가정해 보겠습니다. 4비트 입력, 8비트 출력, GB300 GPU에서의 연산 시간을 분석하면 다음과 같습니다.

M (Tokens)NK연산 (µs)FP4 읽기 (µs)FP8 쓰기 (µs)
25681925120.140.300.26
204881925121.150.372.10
1638481925129.160.8916.8

보시다시피, K 차원(512)이 작아서 GEMM이 메모리 바운드(Memory-bound) 상태에 머무릅니다. 연산 시간보다 데이터 이동 시간이 훨씬 크기 때문이죠. 이는 모델 차원이 배치 크기만큼이나 GPU 활용도를 결정하는 중요한 요소임을 보여줍니다.

# 예시: PyTorch에서 GEMM 연산의 메모리 vs 연산 비용 분석
import torch
import time

# H'=512 (작은 K), H=8192 (큰 N)
# FFN-2: (M, K) @ (K, N) 형태
M, K, N = 2048, 512, 8192

# FP4 연산을 모방한 낮은 정밀도 텐서 (실제로는 FP16으로 테스트)
a = torch.randn(M, K, dtype=torch.float16, device='cuda')
b = torch.randn(K, N, dtype=torch.float16, device='cuda')

# 메모리 이동 시간 측정 (대략적인 비교)
start = time.time()
c = a @ b  # GEMM 연산
torch.cuda.synchronize()
gemm_time = time.time() - start

# 메모리 읽기/쓰기 시간 (대역폭 가정: 2TB/s)
read_bytes = (M * K + K * N) * 2  # FP16 = 2 bytes
write_bytes = M * N * 2
memory_time = (read_bytes + write_bytes) / (2e12) * 1e6  # 마이크로초

print(f"GEMM 연산 시간: {gemm_time*1e6:.2f} µs")
print(f"메모리 이동 시간 (이론): {memory_time:.2f} µs")
print(f"산술 강도: {2*M*N*K / (read_bytes + write_bytes):.2f} FLOPs/byte")
# 산술 강도가 낮으면 메모리 바운드 -> GPU 연산 유닛이 놀고 있음

이 코드는 GEMM 연산의 산술 강도를 계산해 메모리 바운드 여부를 판단하는 방법을 보여줍니다. 실제 GPU 프로파일러를 사용하면 더 정확한 분석이 가능합니다.

Data center server racks with GPU clusters for large language model inference System Abstract Visual

7가지 설계 원칙: GPU 활용도를 극대화하는 모델 만들기

원칙 1: 정사각형에 가까운 가중치 행렬 유지

고정 파라미터 예산에서 GEMM의 M, N, K 차원이 모두 비슷한 크기일 때 산술 강도가 최대화됩니다. 특정 차원이 지나치게 작으면 메모리 바운드 상태에 빠져 GPU의 연산 능력을 낭비하게 됩니다.

원칙 2: 차원을 128의 배수로 설계 (가능하면 256 또는 512)

GPU의 타일 크기와 캐시 라인 너비에 맞추기 위해 모델 차원을 128의 배수로 설정하세요. Blackwell 아키텍처의 clusterMMA(256)와 CGA(512)를 활용하려면 더 큰 배수가 유리합니다.

원칙 3: 깊이보다 너비 (Wider is Better)

같은 파라미터 수라면 더 넓고 얕은 모델이 하드웨어 친화적입니다. 가중치 재사용이 증가하고 순차적 임계 경로가 짧아져 처리량과 지연 시간 모두 개선됩니다. 단, 정확도가 유지되는 범위 내에서만 적용해야 합니다.

원칙 4: 양자화에 유리한 구조 설계

NVFP4와 같은 저비트 양자화는 연산 속도와 메모리 효율을 동시에 높입니다. 모델 설계 단계에서 양자화를 고려하면 배포 시 성능 저하 없이 큰 이득을 얻을 수 있습니다.

원칙 5: 대규모 전문가 병렬화 (Expert Parallelism) 활용

MoE(Mixture-of-Experts) 모델에서 전문가 병렬화(EP)는 처리량을 극대화하는 핵심 전략입니다. 어텐션은 데이터 병렬화, FFN 전문가는 GPU에 분산 배치하여 모든 리소스를 효율적으로 활용합니다.

원칙 6: 균형 잡힌 파이프라인 병렬화 설계

프리필(Prefill)과 디코드(Decode)를 분리하고, 레이어를 균등하게 분할할 수 있는 규칙적인 패턴으로 모델을 설계하세요. 이는 청크 파이프라인 병렬화(CPP)의 효율성을 높입니다.

원칙 7: 어텐션과 FFN의 독립적 병렬화

저지연 서비스에서는 어텐션과 FFN을 별도로 최적화해야 합니다. 어텐션은 KV 병렬화, FFN은 텐서 병렬화(TP) 또는 전문가 병렬화(EP)를 적용하는 하이브리드 전략이 효과적입니다.

주의사항 및 한계점

이 가이드라인은 하드웨어 효율성에 초점을 맞추고 있습니다. 실제 모델 설계에서는 정확도, 학습 안정성, 데이터 분포 등 다양한 요소를 함께 고려해야 합니다. 특히:

  • 모델 품질 저하: 너비를 과도하게 늘리면 표현력이 떨어질 수 있습니다.
  • 통신 오버헤드: 병렬화 전략이 많아질수록 통신 비용이 증가합니다.
  • 하드웨어 의존성: GPU 아키텍처가 바뀌면 최적 차원도 달라질 수 있습니다.

한국 개발자 생태계에서의 적용

국내 AI 서비스 기업들은 대부분 클라우드 환경에서 GPU 인스턴스를 사용합니다. 이 경우 인프라 비용 최적화가 핵심 과제인데, 위 원칙들을 적용하면 동일한 GPU 자원으로 더 높은 처리량을 달성할 수 있습니다. 특히 대규모 언어 모델을 서비스하는 기업이라면 모델 구조를 하드웨어에 맞게 조정하는 것만으로도 상당한 비용 절감 효과를 볼 수 있습니다.

Data analyst reviewing performance metrics charts for LLM throughput optimization IT Technology Image

결론: 설계 단계에서부터 하드웨어를 생각하라

LLM의 성능은 단순히 모델 아키텍처만으로 결정되지 않습니다. 하드웨어와의 정렬이 얼마나 잘 되어 있느냐가 실제 서비스 품질을 좌우합니다. 이 글에서 소개한 7가지 원칙을 설계 체크리스트로 활용해 보세요.

  • 차원을 정사각형에 가깝게, 128의 배수로 유지
  • 깊이보다 너비를 선호
  • 저비트 양자화(NVFP4)에 유리한 구조 설계
  • 규칙적이고 균형 잡힌 레이어 패턴 사용

이러한 작은 선택들이 GPU 활용도를 크게 높여, 동일한 하드웨어에서 더 빠른 추론 속도와 더 높은 처리량을 달성할 수 있습니다. 실전 적용을 위해 NVIDIA Model Optimizer와 TensorRT-LLM의 전문가 병렬화 기능을 탐구해 보세요.

함께 보면 좋은 글

본 콘텐츠는 신뢰할 수 있는 출처를 바탕으로 AI 도구를 활용하여 초안이 작성되었으며, 편집자의 검토를 거쳐 발행되었습니다. 전문가의 조언을 대체하지 않습니다.