A 4 GB Laptop GPU vs a 6-Core CPU on Gemma 4, Re-Measured in ABBA Order: 4.1x
Gemma 4 추론에서 4GB 노트북 GPU와 6코어 CPU 비교 — ABBA 재측정 결과 4.1배
같은 노트북에서 llama.cpp로 Gemma 4 E2B를 실행해 GTX 1650 Ti와 i7-10750H를 비교했습니다. GPU는 디코딩에서 4.14배, 프리필에서 3.42배 빨랐으며, ABBA 순서 측정으로 발열에 따른 측정 오차도 확인했습니다.
- 주제
AI 요약
GTX 1650 Ti와 Intel Core i7-10750H를 같은 노트북에서 비교해 Gemma 4 E2B 추론 속도를 측정했습니다. 두 장치는 같은 GGUF 모델과 llama.cpp 커밋으로 각각 서버를 실행했습니다. CPU 빌드에서는 GPU 백엔드를 끄고, GPU 빌드에서는 CUDA를 켰습니다. 실행 명령의 차이는 GPU 오프로딩 옵션인 -ngl뿐입니다. 측정 대상은 3.35GB 양자화 모델 google/gemma-4-E2B-it-qat-q4_0-gguf입니다.
환경과 재현성
실험 장비는 6코어 12스레드 i7-10750H와 4GB 메모리를 탑재한 GTX 1650 Ti Max-Q를 장착한 Lenovo Yoga 9입니다. Debian sid, gcc 16.2, CUDA 13.4, llama.cpp 커밋 f95b0d9으로 두 빌드를 구성했습니다. GPU는 CUDA 13.4가 지원하는 가장 오래된 아키텍처인 compute capability 7.5에 맞춰 빌드했습니다. 작성자는 CUDA 컴파일 작업을 무제한 병렬 실행하면 노트북 메모리가 부족해진다고 설명합니다. 빌드 병렬도를 -j6으로 제한하자 CUDA 빌드 중 최대 메모리 사용량은 4.0GB였고 스왑은 사용하지 않았습니다.
두 서버는 모두 127.0.0.1:8080에서 같은 요청을 받습니다. CPU는 -ngl 0, GPU는 -ngl 99로 실행하고, 스레드 설정은 양쪽 모두 -t 6 -tb 12로 맞췄습니다. 서버가 실제로 어떤 장치에서 실행됐는지는 응답만으로 알 수 없으므로 /proc 정보를 검사합니다. 실행 파일 경로와 명령행 인자, 프로세스가 불러온 CUDA 라이브러리를 확인하고 실행 파일의 SHA-256도 기록합니다. GPU 백엔드는 실행 중 동적으로 로드되므로 ldd 대신 /proc/<pid>/maps를 확인합니다. 벤치마크 스크립트는 예상한 장치가 응답하지 않으면 실행을 거부합니다.
측정 순서와 결과
노트북의 CPU와 GPU는 냉각 시스템을 공유합니다. 한 장치를 먼저 재면 다음 장치가 앞선 작업의 열 영향을 받으므로, CPU·GPU·GPU·CPU 순서로 각각 두 번 측정하는 ABBA 방식을 적용했습니다. 각 측정 전 최소 120초 기다리고 CPU 온도가 50°C 이하, GPU 온도가 45°C 이하일 때 시작했습니다. 프롬프트 길이 네 종류와 출력 길이 두 종류를 조합한 8개 조건을 사용했고, 조건마다 세 번 반복했습니다. 각 장치의 최종 수치는 두 차례 측정에서 얻은 조건별 중앙값의 평균입니다. 프롬프트 캐시 재사용도 측정값을 낮출 수 있어 각 프롬프트에 고유한 시작 부분을 넣었습니다. 서버 지표에서 28,553개 프롬프트 토큰이 모두 캐시되지 않았음을 확인했습니다.
8개 조건의 디코딩 속도는 CPU 16.10~18.31토큰/초, GPU 68.22~71.89토큰/초였습니다. 조건별 GPU 우위는 3.93~4.30배였고 중앙값은 4.14배입니다. 프리필은 GPU가 3.42배 빨랐으며, 전체 요청 완료 시간 기준으로는 3.62배 빨랐습니다. 입력 길이가 94토큰에서 1,959토큰으로 늘어날 때 디코딩 속도는 양쪽 모두 비교적 일정했습니다. 반면 첫 토큰까지 걸리는 시간(TTFT)은 입력 길이에 따라 증가했습니다. 프리필에서 GPU가 앞서는 폭은 짧은 프롬프트의 2.84배에서 긴 프롬프트의 3.56배로 커졌습니다.
측정 순서만 달리해 비교하면 CPU를 먼저 실행했을 때 디코딩 격차는 4.09배, GPU를 먼저 실행했을 때는 4.17배였습니다. 이 노트북에서는 순서에 따라 비율이 약 2% 달라졌습니다. CPU 측정의 패스 간 변화는 최대 9.3%였고, 한 패스 안 반복값의 편차도 최대 14.05%였습니다. GPU는 패스 간 변화가 최대 1.3%였으며 반복값 편차도 최대 1.14%였습니다. CPU의 열 스로틀링 누적 횟수는 각 패스에서 9,604회와 19,279회였고, GPU 패스에서는 420회와 2,879회였습니다. 작성자는 관측된 잡음이 CPU에 집중됐으며 스로틀링과 함께 움직였다고 보고합니다.
결과 해석과 한계
이 결과는 노트북 한 대, 모델 하나, llama.cpp 버전 하나에서 얻었습니다. 이전 측정 결과인 디코딩 4.27배와 이번 4.14배를 직접 비교하기는 어렵습니다. llama.cpp 커밋과 스레드 설정, 실행 순서를 한꺼번에 바꿨기 때문에 차이가 어느 요인에서 왔는지 분리하지 못했습니다. GPU 디코딩 속도는 응답 스트림 청크 시간을 기준으로 계산하면 실제보다 낮게 나올 수 있어, 완료 토큰 수와 측정 시간을 이용해 다시 계산했습니다. 재계산한 절대 속도는 CPU 16.77~20.27토큰/초, GPU 69.87~79.58토큰/초였고, 중앙값 비율은 여전히 4.14배였습니다. 다만 이 보정은 다른 서버의 절대 수치와 비교할 때 그대로 상쇄되지 않습니다.
dev.to 반응
- @mickyarun — ABBA 방식에 온도 기준까지 더한 것은 보통 공개 벤치마크보다 훨씬 꼼꼼합니다. 유용한 결과는 2%라는 수치라고 봅니다. 다만 그 2%가 무엇의 2%인지 짚고 싶습니다. ABBA는 네 번의 측정 동안 거의 선형으로 변하는 드리프트를 상쇄합니다. 하지만 노트북의 열 동작은 대개 선형이 아닙니다. Max-Q 스로틀링은 한동안 변화가 없다가 임계점을 넘으면 클럭이 떨어지는 계단형에 가깝습니다. 이 변화가 세 번째 패스 중 발생하고 두 번째 패스에는 발생하지 않았다면 A와 B를 평균 내도 제거되지 않습니다. 서로 다른 상태의 측정값을 나눠 담고, 스로틀링이 없는 수치인 것처럼 중간값을 보고하게 됩니다. 패스 시작 전 온도 기준은 더 큰 영향을 주는 문제를 다루므로 유지할 만합니다. 하지만 패스 중 온도 변화는 제한하지 않습니다. GPU와 CPU 작업은 같은 섀시를 서로 다른 속도로, 서로 다른 시간 동안 가열합니다. 이미 데이터가 있다면 패스 내부 분산과 패스 간 분산을 비교해 보세요. 패스 안에서 속도가 일정하고 같은 장치의 두 패스가 다르면 드리프트이며 ABBA가 제 역할을 한 것입니다. 한 패스 안에서 처리량이 꺾인다면 4.14배는 서로 다른 두 상태의 평균입니다. 패스 내내 클럭과 온도를 토큰/초와 함께 기록하면 이 점을 확인할 수 있습니다. 이 정도로 꼼꼼하게 측정했으니 어느 쪽인지 알고 싶습니다.
- @xbill — 타당한 질문입니다. 하드웨어와 소프트웨어 작업에 따라 달라지는 열 관련 이벤트도 있습니다. 두 번째 장비에서 재현해 보면 흥미롭겠지만, 이제는 이 노트북을 어디서 구해야 할지 찾기 어려울 것 같습니다.
원문: dev.to / 번역·요약: Trawling