GPU 이용률은 계산량이 아니다

카드를 꽂고 모델을 올립니다. nvidia-smi를 띄우면 GPU-Util이 80%입니다. 잘 도는 줄 알고 창을 닫습니다.

스펙의 TFLOP/s와 실제로 나오는 토큰을 나란히 두면 숫자가 안 맞습니다. 312 TFLOP/s짜리 카드가 초당 내놓는 토큰은 그 숫자의 수백 분의 일입니다. 80%가 무엇을 가리켰는지는 여기서 갈립니다.

모니터의 GPU-Util은 계산이 얼마나 빽빽했는가가 아닙니다. 짧은 구간 동안 커널이 하나라도 돌고 있던 시간 비율입니다. 청구서는 토큰입니다. 시간은 재고, 돈은 나온 토큰으로 받습니다.

할부로 산 트럭과 같습니다. 할부는 매달 나갑니다. 짐칸이 비어 있어도 엔진은 돕니다. 계기판의 80%는 그 공회전을 고속도로로 보여 줍니다.

숫자는 벤치가 아니라 식입니다. 단위는 SI입니다. 1 MB = 10^6 B, 1 GB = 10^9 B.

1. 디코드는 곱셈이 아니라 읽기입니다

큰 언어 모델은 답을 한 글자(토큰)씩 붙입니다. 그 한 걸음을 디코드라고 합니다. 디코드 때 GPU가 주로 하는 일은 행렬을 끝없이 곱하는 일이 아닙니다. 이미 사 둔 가중치를 메모리에서 읽어 오는 일입니다.

70B를 FP16으로 두면 가중치는 70e9 × 2 B = 140 GB입니다. 토큰 하나를 만들 때 파라미터마다 대략 2 FLOP이면 70e9 × 2 = 1.4e11 FLOP이고, 읽는 양은 140 GB = 1.4e11 B입니다. 둘을 나누면 1 FLOP/B입니다.

이 값이 큰지는 그 카드가 메모리 1바이트당 몇 FLOP을 버티는지와 비교하면 압니다. A100 80GB SXM이면 Tensor 피크 312 TFLOP/s를 대역 2039 GB/s로 나눕니다. 나오는 값이 무릎 153 FLOP/B입니다. 디코드의 1 FLOP/B는 그 값의 150분의 1입니다. 40GB 쪽 대역은 약 1.6 TB/s라 무릎이 약 195로 바뀝니다. 비율은 비슷합니다. Util이 100%여도 Tensor 코어는 거의 놉니다. 칩이 안 쉰 시간과, 계산량이 꽉 찬 시간은 다릅니다.

Batch 1 weights vs KV
배치 1에서 읽는 양. 가중치 140 GB, 8K GQA KV 2.68 GB. 식입니다.

2. 해법은 배치입니다

엔진(Util)은 1톤을 싣든 20톤을 싣든 돕니다. 매출을 늘리려면 짐을 더 싣습니다.

디코드도 같습니다. 가중치 140 GB를 한 번 읽고, 그 위에 질문 여러 개를 얹습니다. 그 개수가 배치입니다. 읽기 비용을 시퀀스끼리 나눕니다.

짐칸은 무한하지 않습니다. 각 시퀀스는 지금까지 나온 토큰의 기억을 GPU 메모리에 남겨 둡니다. 그 기억이 KV 캐시입니다. 트레일러 크기 = 남는 HBM ÷ 토큰당 KV입니다.

3. 트레일러 크기, 여덟 배 차이

KV는 지금까지의 대화에서 모델이 다시 곱하지 않으려고 저장해 둔 표입니다. 토큰이 늘수록 표가 길어집니다. 캐시가 없으면 매 토큰마다 과거를 다시 곱해서, 일이 길이의 제곱으로 늡니다. 캐시가 있으면 새 토큰만 계산하고 과거는 표에서 읽습니다.

인터넷에 자주 도는 식은 이겁니다. 80층, 폭 8192, FP16이면 토큰당 2 × 80 × 8192 × 2 B = 2.62 MB. 8K면 21.5 GB입니다. 이 식은 쿼리 헤드와 KV 헤드가 같은 경우(MHA)입니다. LLaMA 1 65B에 가깝습니다.

LLaMA 2 70B는 GQA입니다. KV 헤드가 8개라 폭이 1024입니다. 같은 식은 토큰당 0.328 MB. 8K면 2.68 GB. 약 여덟 배입니다. 「70B는 토큰당 2.6 MB」라는 말은, 앞 식을 다른 모델에 그대로 붙인 것입니다.

같은 8K라도 21.5 GB를 쓰는 쪽과 2.68 GB를 쓰는 쪽은, 남는 메모리에 올리는 배치가 달라집니다. Util 80%는 이 차이를 알려 주지 않습니다.

MHA vs GQA KV per token
토큰당 KV. 2.62 MB는 MHA 식, 70B GQA는 0.328 MB입니다.

4. 남는 판단

「Util 80%면 잘 돌고 있다.」 계기판만 본 말입니다. 「컨텍스트만 늘리면 된다.」 트레일러를 안 잰 말입니다.

카드를 더 살지, 컨텍스트를 줄일지, GQA가 있는 모델을 고를지, KV를 양자화할지는 같은 식의 변수입니다. Util 숫자 하나가 답을 대신하지 않습니다.

참고

  • 무릎 153 FLOP/B: 312e12 / 2039e9. 80 GB SXM으로 읽는 숫자. 40 GB(약 1.6 TB/s)면 무릎은 약 195입니다. 1 대 150이라는 결론은 같습니다.
  • vLLM “24배”는 허깅페이스 대비, “23배”는 정적 배치 대비입니다. 다른 벤치입니다. 출력 길이 지수분포·EOS 무시는 그 벤치의 조건입니다. 우리 측정이 아닙니다.

댓글 남기기