LLM 성능의 숨은 변수: 하드웨어 친화적 설계
AI 모델의 성능을 이야기할 때 우리는 보통 정확도(Accuracy)만 떠올리기 쉽습니다. 하지만 실제 서비스를 운영하다 보면 **처리량(Throughput)**과 **상호작용성(Interactivity, 지연 시간)**이 정확도 못지않게 중요하다는 것을 깨닫게 됩니다. 아무리 뛰어난 모델도 응답이 느리다면 사용자 이탈로 이어지고, 처리량이 낮으면 서버 비용이 급증하니까요.
이 세 가지 목표는 서로 트레이드오프 관계에 있습니다. 정확도를 고정해 두면 문제는 2차원 파레토 프론티어(Pareto frontier)로 단순화됩니다. 즉, 처리량을 높이면 지연 시간이 늘어나고, 지연 시간을 줄이면 처리량이 떨어지는 상황에서 이 곡선 자체를 바깥으로 확장하는 것이 핵심 과제가 됩니다.
이 글에서는 LLM(Large Language Model)의 구조적 선택이 이 파레토 프론티어를 어떻게 바꾸는지 분석합니다. 특히 GPU 하드웨어의 동작 방식(GEMM 연산, 메모리 대역폭, 타일링)과 모델의 차원(H, H', L)이 어떻게 상호작용하는지 살펴보고, 실무에서 바로 적용할 수 있는 7가지 설계 원칙을 정리했습니다.
💡 핵심 포인트 모델을 설계할 때 하드웨어와의 정렬을 고려하면, 같은 연산량으로 더 높은 성능을 얻을 수 있습니다. 이는 GPU 활용도를 높여 서버 비용을 절감하고, 사용자 경험을 개선하는 두 마리 토끼를 잡는 길입니다.
이 글은 NVIDIA 기술 블로그의 AI 모델 설계와 하드웨어 친화적 LLM 설계 내용을 기반으로, 한국 개발자 생태계의 맥락에서 재해석했습니다.

GPU의 동작 원리: GEMM과 메모리 대역폭
GPU가 LLM 연산을 수행하는 방식은 크게 두 가지 요소에 의해 결정됩니다.
- 산술 강도(Arithmetic Intensity): 연산(FLOPs) 대비 메모리 이동(Byte)의 비율. 이 값이 낮으면 메모리 대역폭에 의해 성능이 제한되고(Memory-bound), 높으면 GPU의 연산 능력(Compute-bound)에 의해 제한됩니다.
- GEMM 타일링(Tiling): GPU는 출력 행렬을 작은 타일(tile)로 나누어 각 스트리밍 멀티프로세서(SM)가 병렬로 처리합니다. 이때 타일 크기와 모델 차원이 정확히 맞아떨어지지 않으면 타일 양자화(Tile Quantization)가 발생해 GPU 활용도가 떨어집니다.
GEMM 차원과 모델 구조의 관계
트랜스포머 블록의 각 선형 레이어는 GEMM 연산으로 표현됩니다. 입력 토큰 수(Tokens), 히든 차원(H), 중간 투영 차원(H')이 GEMM의 M, N, K 차원을 결정합니다.
| 레이어 | 투영 (in → out) | GEMM M | GEMM N | GEMM K |
|---|---|---|---|---|
| Q/K/V 입력 | H → 3H | Tokens | 3H | H |
| 어텐션 출력 | H → H | Tokens | H | H |
| FFN-1 (업투영) | H → H′ | Tokens | H′ | H |
| FFN-2 (다운투영) | H′ → H | Tokens | H | H′ |
실제 사례: 작은 H'의 함정
FFN-2 레이어에서 H'=512, H=8192인 경우를 가정해 보겠습니다. 4비트 입력, 8비트 출력, GB300 GPU에서의 연산 시간을 분석하면 다음과 같습니다.
| M (Tokens) | N | K | 연산 (µs) | FP4 읽기 (µs) | FP8 쓰기 (µs) |
|---|---|---|---|---|---|
| 256 | 8192 | 512 | 0.14 | 0.30 | 0.26 |
| 2048 | 8192 | 512 | 1.15 | 0.37 | 2.10 |
| 16384 | 8192 | 512 | 9.16 | 0.89 | 16.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 프로파일러를 사용하면 더 정확한 분석이 가능합니다.

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 자원으로 더 높은 처리량을 달성할 수 있습니다. 특히 대규모 언어 모델을 서비스하는 기업이라면 모델 구조를 하드웨어에 맞게 조정하는 것만으로도 상당한 비용 절감 효과를 볼 수 있습니다.

결론: 설계 단계에서부터 하드웨어를 생각하라
LLM의 성능은 단순히 모델 아키텍처만으로 결정되지 않습니다. 하드웨어와의 정렬이 얼마나 잘 되어 있느냐가 실제 서비스 품질을 좌우합니다. 이 글에서 소개한 7가지 원칙을 설계 체크리스트로 활용해 보세요.
- 차원을 정사각형에 가깝게, 128의 배수로 유지
- 깊이보다 너비를 선호
- 저비트 양자화(NVFP4)에 유리한 구조 설계
- 규칙적이고 균형 잡힌 레이어 패턴 사용
이러한 작은 선택들이 GPU 활용도를 크게 높여, 동일한 하드웨어에서 더 빠른 추론 속도와 더 높은 처리량을 달성할 수 있습니다. 실전 적용을 위해 NVIDIA Model Optimizer와 TensorRT-LLM의 전문가 병렬화 기능을 탐구해 보세요.