CPU에서 LLM 모델 성능 최적화하기
요약
CPU 환경에서 LLM 추론 성능을 최적화하기 위한 기술적 가이드를 제공합니다. 양자화 포맷 선택, 메모리 대역폭 관리, 스레드 최적화 및 NUMA 노드 활용법을 다룹니다.
핵심 포인트
- GGUF 포맷과 4비트 양자화를 통해 메모리 대역폭 요구량 감소
- SMT(논리 코어) 대신 물리 코어에 스레드를 고정하여 캐시 스래싱 방지
- LLM 추론은 계산보다 메모리 대역폭 제한(Memory-bandwidth bound) 문제임
- use_mlock 설정으로 운영체제의 가중치 스와핑 방지
- NUMA 환경에서는 메모리와 CPU 노드를 로컬로 결합하여 지연 시간 최소화
CPU에서 대규모 언어 모델 (LLM)을 실행하는 것은 더 이상 고장 난 CUDA 드라이버를 위한 차선책이 아닙니다. 에지 배포 (edge deployments), 에어갭 환경 (air-gapped environments), 그리고 비용에 민감한 전처리 파이프라인의 경우, CPU 추론 (inference)은 의도적인 아키텍처 선택입니다. 문제는 트랜스포머 (transformers) 모델이 메모리 대역폭 제한 (memory-bandwidth bound)을 받는다는 것이며, 소비자용 CPU는 현대적인 GPU의 고대역폭 메모리 (HBM)가 부족하다는 점입니다. x86 또는 ARM에서 LLM 처리량 (throughput)을 최적화하려면 공격적인 양자화 (quantization), 세심한 스레드 관리 (thread management), 그리고 하드웨어 병목 현상 (bottleneck)이 실제로 어디에 위치하는지에 대한 현실적인 기대치가 필요합니다.
양자화 (Quantization) 및 포맷 선택
CPU에서는 DRAM에서 가져오는 모든 바이트가 지연 시간 (latency)을 발생시킵니다. 표준적인 접근 방식은 GGUF 포맷을 사용하여 가중치 (weights)를 4비트 정밀도로 압축하고, AVX2 및 AVX-512 명령어 세트를 타겟팅하는 llama.cpp 또는 유사한 런타임을 통해 실행하는 것입니다. Q4_K_M 및 Q5_K_M 포맷은 일반적으로 최대 70B 파라미터 모델에 대해 퍼플렉시티 (perplexity)와 대역폭 감소 사이에서 가장 좋은 균형을 제공합니다.
모델을 변환하거나 이미 양자화된 GGUF를 다운로드하는 것부터 시작하세요. llama-cpp-python을 사용하는 최소한의 Python 추론 스크립트는 다음과 같습니다:
from llama_cpp import Llama
llm = Llama(
...
운영 체제가 가중치를 디스크로 스와핑 (swapping)하는 것을 방지하려면 use_mlock=True를 설정하세요. 스와핑은 CPU에서 지연 시간을 파괴합니다. 또한 컨텍스트 윈도우 (context window)를 현실적으로 유지하세요. CPU에서 32K 컨텍스트는 매력적으로 들리지만, DDR5 채널 대역폭이 이미 가중치 스트리밍 (weight streaming)으로 포화 상태라면, KV 캐시 (KV cache)를 확장하는 것은 디코딩 (decoding) 속도를 느리게 만들 뿐입니다.
메모리 대역폭 (Memory Bandwidth) 및 스레딩 (Threading)
CPU에서의 LLM 추론은 계산 제한 (compute bound)이 아니라 거의 항상 메모리 대역폭 제한 (memory-bandwidth bound)입니다. DDR5-4800은 채널당 약 38 GB/s를 제공하는 반면, 데이터 센터 GPU의 단일 HBM 스택은 1 TB/s를 초과합니다. 그 격차는 당신의 최적화 목표가 FLOPs를 최대화하는 것이 아니라 메모리 트래픽 (memory traffic)을 최소화하는 것임을 의미합니다.
스레드를 물리 코어(physical cores)에 고정하고 동시 다중 스레딩 (SMT, Simultaneous Multithreading)을 피하십시오. 16코어 Ryzen 칩의 경우, n_threads를 32가 아닌 16으로 설정하십시오. 논리 코어(Logical cores)는 L1 및 L2 캐시를 공유하며, SMT로 인한 캐시 스래싱 (cache thrashing)은 행렬 곱셈 커널 (matrix multiplication kernels)의 유효 대역폭을 절반으로 감소시킵니다. 듀얼 소켓 서버를 사용 중이라면, numactl --cpunodebind=0 --membind=0을 사용하여 메모리가 가중치 (weights)를 소유한 NUMA 노드에 로컬로 유지되도록 하십시오.
병목 현상을 확인하려면 Linux perf로 프로파일링하십시오:
perf stat -e cycles,instructions,cache-misses,LLC-load-misses \
./main -m qwen3-32b-q4_k_m.gguf -p "Explain RSA" -n 64 --threads 16
명령어(instructions) 대비 LLC-load-misses가 높다면, 워킹 셋 (working set)이 L3 캐시를 초과하여 DRAM 바운드 (DRAM bound) 상태임을 의미합니다. 유일한 해결책은 더 작은 양자화 (quants), 더 작은 모델, 또는 더 많은 캐시를 사용하는 것입니다.
프리필 (Prefill) 및 디코딩 (Decoding) 단계
CPU 추론 작업에는 두 가지 뚜렷한 단계가 있습니다. 프리필 (Prefill)은 KV 캐시 (KV cache)를 구축하기 위해 전체 입력 프롬프트를 병렬로 처리합니다. 디코딩 (Decoding)은 한 번에 하나의 토큰을 생성하며, 각 토큰은 이전 토큰에 의존합니다. 프리필은 연산 집약적 (compute-heavy)이며 잠시 동안 모든 코어를 사용합니다. 디코딩은 메모리 대역폭 집약적 (memory-bandwidth heavy)이며, 대부분의 실제 실행 시간 (wall-clock time)이 여기서 소요됩니다.
대화형 애플리케이션의 경우, 프리필 지연 시간 (prefill latency)이 모델이 응답을 시작하는 속도를 결정합니다. 프롬프트를 짧게 유지하거나, 재사용 가능한 시스템 프롬프트에 대해 KV 상태를 캐싱하십시오. 일부 런타임 (runtimes)은 프롬프트 캐시 파일을 제공합니다. 첫 실행 후 이를 저장하고 이후 요청에서 다시 로드하십시오. 이렇게 하면 프리필 과정을 완전히 건너뛰고 즉시 디코딩으로 넘어갈 수 있습니다.
CPU에서 클라우드로 전환해야 할 때
CPU 최적화에는 물리적인 한계가 있습니다. Q4로 양자화하고, 스레드를 고정하고, DDR5 채널을 포화시키고, 모든 재사용 가능한 프롬프트를 캐싱한 후에도 남은 유일한 수단은 하드웨어 교체뿐입니다. 프로덕션 워크로드, 특히 긴 컨텍스트 (long contexts)나 에이전틱 루프 (agentic loops)를 가진 워크로드의 경우, 로컬 CPU 플릿 (fleet)을 유지하는 비용이 관리형 추론 (managed inference)보다 엔지니어링 시간과 전기 요금 측면에서 더 많이 들 수 있습니다.
이 지점이 바로 Oxlo.ai가 논리적인 다음 단계가 되는 이유입니다. 입력 길이가 비용을 직접적으로 증가시키는 토큰 기반 (token-based) 제공업체와 달리, Oxlo.ai는 요청당 고정 가격 (flat per-request pricing)을 사용합니다. 128K 컨텍스트 (context) 프롬프트는 1K 프롬프트와 동일한 비용이 발생합니다. 긴 컨텍스트 요약, 검색 증강 생성 (RAG) 파이프라인, 또는 컨텍스트 윈도우 (context window)에 토큰을 반복적으로 추가하는 다단계 에이전트 (multi-step agents)의 경우, 이러한 가격 모델은 애초에 CPU 추론 (inference)이 매력적으로 보이게 만들었던 페널티를 제거해 줍니다.
Oxlo.ai는 Qwen 3 32B, Llama 3.3 70B, DeepSeek R1 671B를 포함하여 7개 카테고리에 걸쳐 45개 이상의 모델을 제공하며, OpenAI SDK와 완벽하게 호환되고 인기 있는 모델에 대해 콜드 스타트 (cold starts)가 없습니다. llama.cpp를 사용하여 CPU에서 프로토타입을 제작한 다음, 클라이언트 코드를 다시 작성할 필요 없이 베이스 URL (base URL)을 https://api.oxlo.ai/v1로 전환하기만 하면 됩니다. 에이전트 기반 워크로드 (agentic workloads)를 실행하거나 대규모 문서를 처리하는 팀의 경우, Oxlo.ai는 토큰 기반 대안보다 종종 한 자릿수(order of magnitude)만큼 더 저렴합니다.
현재의 로컬 인프라 지출과 요청 기반 비용을 비교하려면 Oxlo.ai 가격 페이지를 확인하세요.
CPU 추론 프로파일링 (Profiling CPU Inference)
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기