llama.cpp를 사용한 Gemma 4 E2B CPU 성능 측정: 실용적인 로컬 AI 실험
요약
본 글은 llama.cpp를 활용하여 Gemma 4 E2B 모델을 리소스가 제한적인 로컬 CPU 환경에서 구동하고 성능을 측정하는 초기 실험 기록입니다. 다양한 스레드 수와 서버 매개변수(예: -np, -ngl) 및 Flash Attention 활성화 여부가 추론 속도에 미치는 영향을 탐색적으로 분석했습니다.
핵심 포인트
- llama.cpp를 이용해 로컬 환경에서 LLM 구동 가능성을 확인했습니다.
- CPU 성능 측정은 다양한 스레드/배치 크기 조합을 통해 진행되었습니다.
- 스레드 수 증가가 항상 성능 향상을 보장하지는 않음을 알 수 있습니다.
- Flash Attention 활성화 등 추가 매개변수 테스트를 통해 속도 개선 여지를 탐색했습니다.
1. 이 실험을 하는 이유?
저는 클라우드 기반 AI 서비스에 전적으로 의존하지 않고, 일상적인 사무 업무를 위해 로컬 언어 모델을 구동하고 싶습니다.
제가 예상하는 사용 사례는 다음과 같습니다:
- 일반 질문에 대한 로컬 챗봇.
- 말레이시아어와 영어로 편지, 메모랜덤(memoranda), 이메일 초안 작성.
- 기술 문서 준비.
- 수천 또는 수백만 건이 아닌 수백 줄 규모의 기본 스프레드시트 분석.
- 다양한 컴퓨터에서 로컬 AI 모델을 배포하고 튜닝하는 방법을 학습하기 위함.
문제는 모든 컴퓨터가 동일한 CPU를 가지고 있지 않다는 것입니다. 일부 장치는 코어가 몇 개밖에 없는 구형 프로세서를 가지고 있는 반면, 다른 장치들은 더 많은 코어와 스레드를 가진 최신 CPU를 갖추고 있습니다.
어떤 하나의 설정이 어디서든 작동한다고 가정하기보다는, 기준점(baseline)을 설정하고 다양한 기기에서 동일한 벤치마킹 방법을 사용하고자 합니다.
본 글은 llama.cpp의 llama-server를 사용하여 Gemma 4 E2B로 진행한 초기 실험 기록입니다.
2. 테스트 환경
초기 실험은 리소스가 제한된(resource-constrained) 장치에서 수행되었습니다.
| 구성 요소 | 사양 |
|---|---|
| CPU | AMD Athlon 3000G |
| ... |
주요 모델 파일은 다음과 같습니다:
gemma-4-E2B-it-qat-UD-Q4_K_XL.gguf
이 모델은 QAT Q4_K_XL 양자화 변형을 사용한 instruction-tuned Gemma 4 E2B GGUF입니다.
목표는 이 모델의 보편적인 성능 수치를 확립하는 것이 아닙니다. 이 특정 장치에서 설정 선택이 추론(inference)에 어떻게 영향을 미치는지 이해하는 것입니다.
참고: 정확한 llama.cpp 버전/빌드 식별자는 이 초기 벤치마크에서는 기록되지 않았습니다. 향후 테스트에서는 성능과 사용 가능한 옵션이 빌드마다 달라질 수 있으므로 이를 기록해야 합니다.
3. 기준점 설정
저는 다음과 같은 보수적인(conservative) 설정을 시작했습니다:
llama-server \
-m ./gemma-4-E2B-it-qat-UD-Q4_K_XL.gguf \
-t 2 \
...
초기에 보고된 평균 생성 속도는 약 초당 4.6 토큰이었습니다.
이어서 다양한 스레드 수와 배치 크기를 테스트했습니다. 다음 표는 실험 중에 관찰된 결과를 기록합니다.
| Test | Main configuration change | Reported speed |
|---|---|---|
| A | -t 2 -tb 2 -c 2048 -b 64 -ub 16 | 4.6 t/s |
| ... | ||
| 이러한 결과는 이 CPU에서 생성 스레드(generation threads)를 세 개, 배치 처리 스레드(batch-processing threads)를 네 개 사용하는 것이 추가적으로 조사할 가치가 있음을 시사했습니다. |
스레드 수를 늘린다고 해서 성능이 자동으로 향상되는 것은 아니었습니다. 특히 이 시험들에서는 4개의 스레드를 사용한 테스트가 3개의 스레드 결과보다 느렸습니다.
하지만 이것들은 통제된 벤치마크라기보다는 탐색적인 측정(exploratory measurements)이었으므로, 세 개의 스레드가 항상 최적이라는 증거로 해석되어서는 안 됩니다.
4. 추가 서버 매개변수 테스트하기
다음으로 여러 매개변수를 추가했습니다:
-np 1
-ngl 0
--temp 0.7
...
보고된 속도는 약 6.4 토큰/초였습니다.
여러 옵션을 함께 추가했기 때문에, 이 결과만으로는 어떤 개별 매개변수(parameter)가 생성 속도를 개선했는지 알 수 없습니다.
이후 Flash Attention을 명시적으로 테스트했습니다:
-fa on
해당 시험의 보고된 속도는 약 6.2 토큰/초였습니다.
이 시험은 성능 향상을 보여주지 않았으므로, 현재로서는 선호하는 구성(preferred configuration)에서 Flash Attention을 제외했습니다. 다른 CPU나 빌드에서 도움이 되는지 확인하려면 더 통제된 테스트가 필요할 것입니다.
이 매개변수들은 무엇을 위한 것인가
5. 지금까지 보고된 최적의 설정
탐색적인 실험을 통해 얻은 가장 강력한 결과는 초당 약 6.6 토큰이었습니다.
설정은 다음과 같았습니다:
llama-server \
-m ./gemma-4-E2B-it-qat-UD-Q4_K_XL.gguf \
-t 3 \
...
이것은 제가 임시로 설정한 **기준점(baseline)**일 뿐, 이 설정이 보편적으로 최적이라는 주장은 아닙니다.
가장 좋은 결과를 얻었던 실험에서는 더 큰 배치(batch) 설정을 사용했습니다. 특히 배치 설정은 프롬프트 처리 방식과 토큰 생성 방식을 다르게 영향을 미칠 수 있기 때문에, 이것들이 일관되게 성능을 향상시키는지 확인하려면 더 반복적인 테스트가 필요합니다.
--no-mmap 옵션은 이번 실험에서 벤치마킹되지 않았으며, 테스트된 설정의 일부로 간주해서는 안 됩니다.
6. 실제 사무 업무 테스트
나중에 진행한 실험에서는 Laravel과 Debian Linux를 사용하여 내부적으로 개발된 시스템에 대한 주기적인 유지보수 관련 공식 메모(memorandum)를 요청하는 말레이어 프롬프트가 사용되었습니다.
생성된 메모에는 다음 내용이 포함되어 있었습니다:
- 보안 패치 적용 (Security patching).
- 패키지 업데이트 (Package updates).
- 로그 및 성능 모니터링 (Log and performance monitoring).
- 부적절한 유지보수와 관련된 위험 요소 (Risks associated with inadequate maintenance).
- 해당 부서의 운영 계획에 유지보수를 포함할 것을 권고하는 내용 (A recommendation to include maintenance in the department's operational plan.).
-np 1: 이 단일 사용자 실험을 위해 하나의 병렬 시퀀스 슬롯(parallel sequence slot)을 구성합니다.-ngl 0: 모델 레이어를 GPU로 오프로드하는 대신 CPU에서 모델 추론(model inference)이 이루어지도록 유지합니다.--cache-type-k q8_0및--cache-type-v q8_0: 키(key)와 값(value) 캐시를 위한 양자화된 데이터 유형을 선택합니다.--metrics: 서버의 메트릭스 엔드포인트(metrics endpoint)를 활성화합니다.--jinja: 관련 Jinja 채팅 템플릿 처리(chat-template handling)를 활성화합니다.--temp,--top-p, 및--top-k: 샘플링 동작(sampling behaviour)을 제어하며, 성능 향상이 보장되는 것은 아닙니다.--reasoning-format none: 서버의 추론 형식 처리(reasoning-format handling)를 구성합니다.
사용 가능한 옵션과 그 정확한 동작 방식은 공식 llama.cpp 서버 문서에서 확인해야 합니다.
보고된 통계는 다음과 같았습니다:
| 지표 (Metric) | 결과 (Result) |
|---|---|
| 프롬프트 토큰 (Prompt tokens) | 126 |
| ... |
제시된 시간은 보고된 토큰 수와 속도를 기반으로 계산한 추정치입니다. 직접적인 종단 간(end-to-end) 타이밍 측정값은 아닙니다.
출력 품질에 대한 관찰 (Observations about output quality)
작성된 메모는 인식 가능한 공식적 구조를 가졌으며, 그 권고 사항들은 일반적으로 요청된 주제와 관련성이 높았습니다.
하지만 프롬프트에서 해당 날짜를 제공하지 않았음에도 불구하고, 2024년 5월 26일이라는 특정 날짜를 생성했습니다. 이는 로컬 언어 모델이 지원되지 않는 세부 정보를 도입할 수 있다는 중요한 상기 사항입니다.
실제 사무용으로 사용하기 위해서는 날짜, 수신자 상세 정보, 참조 번호, 부서명 등 권위 있는 정보가 제공되어야 합니다. 생성된 서한이나 기술적 권고안은 발송되거나 조치되기 전에 여전히 검토되어야 합니다.
따라서 이 실험은 두 가지 별개의 차원을 평가합니다:
- 성능 (Performance): 모델이 출력을 얼마나 빠르게 생성하는지.
- 품질 (Quality): 생성된 출력이 정확하고, 관련성이 있으며, 적절하게 형식화되었고, 사용하기에 안전한지 여부.
토큰/초(tokens-per-second) 수치가 높다고 해서 반드시 더 나은 사무 비서 역할을 한다는 것을 의미하지는 않습니다.
7. 결과가 아직 예비적인 이유 (Why the Results Are Still Preliminary)
위의 측정값들은 상호작용적 실험 중에 수집되었습니다. 프롬프트와 출력 길이는 모든 시도에서 동일하지 않았으며, 일부 시도에서는 여러 매개변수가 한 번에 변경되었습니다.
결과적으로, 이 결과는 구성을 좁히는 데 유용하지만, 개별 옵션에 대해 확정적인 결론을 도출하기 위한 것은 아닙니다.
더 신뢰할 수 있는 벤치마크는 다음을 포함해야 합니다:
- 모든 비교에 동일한 프롬프트를 사용합니다.
- 동일한 최대 출력 토큰 제한을 설정합니다.
- 모델과 시스템이 비교 가능한 시작 상태에 도달하도록 합니다.
- 각 구성을 최소 세 번 반복합니다.
- 중앙값(median) 및 평균 생성 속도를 기록합니다.
- 가능하다면 프롬프트 처리 속도와 생성 속도를 분리하여 기록합니다.
- RAM 사용량, CPU 활용률, 열적 거동(thermal behaviour), 스와핑 여부를 모니터링합니다.
- 동일한 실용적인 작업을 사용하여 출력 품질을 확인합니다.
llama.cpp 서버는 --metrics를 활성화하면 Prometheus 호환 메트릭 엔드포인트를 지원합니다. 여기서 보고되는 메트릭은 프롬프트 처리 처리량(prompt-processing throughput)과 생성 처리량(generation throughput)을 구별하는 데 도움이 될 수 있습니다. 서버 메트릭 문서를 참조하십시오.
8. 다른 PC를 위한 재현 가능한 벤치마크 계획
장기적인 목표는 서로 다른 CPU 세대, 코어 수, 메모리 한계를 가진 컴퓨터 전반에 걸쳐 이 실험을 반복하는 것입니다.
각 기계마다 다음 사항을 기록할 것입니다:
| 항목 | 기록할 내용 |
|---|---|
| Machine ID | PC-01과 같은 간단한 레이블 |
| ... |
권장 테스트 순서
잠정적인 기준선(provisional baseline)으로 시작하여 한 번에 하나의 변수만 변경합니다.
단계 1 — 스레드 구성 (Thread configuration)
CPU의 토폴로지(topology)를 기반으로 -t와 -tb에 적합한 값을 비교합니다. 예를 들어, 물리적 코어 2개와 논리적 스레드 4개를 가진 CPU의 경우, 모든 논리적 스레드가 항상 도움이 될 것이라고 가정하기보다는 작은 범위의 스레드 설정을 테스트합니다.
단계 2 — 컨텍스트 크기 (Context size)
다른 매개변수는 일정하게 유지하면서 -c 1024와 -c 2048을 비교합니다. 더 작은 컨텍스트는 메모리 요구 사항을 줄일 수 있지만, 대화나 소스 자료가 담길 수 있는 양에도 제한을 둡니다.
-c 1024 구성은 이 실험에서 완료된 측정이 아니라 제안되는 미래 테스트입니다.
단계 3 — 배치 크기 (Batch sizes)
실용적인 측면에서 -b와 -ub를 개별적으로 테스트합니다. 프롬프트 처리량뿐만 아니라 생성 속도도 기록해야 합니다. 왜냐하면 이 두 가지 워크로드 간에 그 효과가 다를 수 있기 때문입니다.
4단계 — KV 캐시
안정적인 기준선(baseline)을 확립한 후에, q4_0와 같은 다른 지원되는 캐시 유형과 q8_0을 비교하는 것을 고려해 보세요. 메모리 사용량, 속도, 안정성 및 출력 품질을 측정합니다. 더 작은 캐시가 반드시 추론(inference)을 더 빠르게 만들 것이라고 가정하지 마십시오.
5단계 — 실질적인 워크로드
각 기계에서 동일한 작업 세트를 실행합니다:
- 짧은 챗봇 질문.
- 공식 말레이어 서신 또는 메모랜덤.
- 영어 이메일.
- 구조화된 기술 문서.
- 작은 스프레드시트 분석 작업.
이렇게 하면 단지 하나의 벤치마크 프롬프트를 최적화하는 것보다는 실제 사용에 적합한 구성이 무엇인지 판단하는 데 도움이 될 것입니다.
9. 지금까지의 실질적인 교훈
초기 실험은 몇 가지 유용한 교훈을 시사합니다:
- 로컬 모델만으로도 CPU 전용 기계에서 구조화된 말레이어 사무 메모랜덤을 생성할 수 있습니다.
- 지금까지 보고된 최고의 속도는 초당 6.6 토큰이었지만, 이 벤치마크는 더 통제된 반복이 필요합니다.
- 더 많은 CPU 스레드가 더 나은 생성 속도를 보장하지 않습니다.
- 샘플링 매개변수(Sampling parameters)는 성능 스위치로 취급할 것이 아니라 원하는 응답 동작을 위해 선택해야 합니다.
- 컨텍스트 크기, 배치 구성(batch configuration), 캐시 유형은 별도로 테스트되어야 합니다.
- 특히 오래되거나 리소스가 제한된 컴퓨터에서는 RAM 사용량과 열적 안정성(thermal stability)이 중요합니다.
- 출력 정확도는 생성 속도와 분리하여 평가해야 합니다.
- 스프레드시트 작업의 경우, 전체 워크북을 프롬프트로 보내는 대신 적절한 데이터 라이브러리를 사용하여 실제 스프레드시트를 처리하고 관련 결과를 모델에 전달할 수 있습니다.
10. 결론
이 실험은 비교적 사양이 낮은 CPU 하드웨어에서 llama.cpp를 사용하여 Gemma 4 E2B를 실행하기 위한 출발점을 마련합니다.
현재 임시 설정은 3개의 생성 스레드(generation threads), 4개의 배치 스레드(batch threads), 컨텍스트 크기 2048, 그리고 배치 설정 128 및 32를 사용합니다. 이 설정을 통해 탐색적 테스트에서 약 6.6 토큰/초의 최고 속도를 달성했습니다.
다음 목표는 단순히 하나의 컴퓨터를 더 빠르게 만드는 것이 아닙니다. 오래된 CPU부터 코어가 더 많은 최신 기기까지 여러 컴퓨터에 걸쳐 실용적인 구성을 찾아낼 수 있는 반복 가능한 방법을 구축하는 것입니다.
궁극적인 성공의 척도는 일상적인 사무 작업에 유용한 로컬 비서입니다. 대화에 충분히 반응적이고, 좋은 초안을 작성할 수 있으며, 적절한 인간 검토를 거쳐 문서화 및 기본적인 데이터 분석을 지원할 만큼 신뢰성이 있어야 합니다.
벤치마크 현황: 초기 탐색 단계가 완료되었습니다. 새로운 기기 또는 통제된 테스트 세션이 선택될 때까지 추가적인 매개변수 테스트는 일시 중단됩니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기