10년 된 Xeon이면 충분하다

1 week ago 12
  • Gemma 4 26B-A4B를 2016년형 단일 Intel Xeon E5-2620 v4, DDR3 128GB, GPU 없는 서버에서 ik_llama.cpp 최적화로 읽기 속도 수준까지 실행함
  • LLM 디코더 패스는 연산보다 메모리 대역폭이 병목이며, CPU는 다음 가중치를 RAM에서 캐시로 가져오길 기다리는 시간이 커짐
  • --spec-type mtp, --cpu-moe, --merge-up-gate-experts, --run-time-repack 등은 MTP 추측 디코딩, MoE 라우팅, 캐시 친화적 메모리 배치로 DDR3 환경의 병목을 줄임
  • 로그 기준 전체 메모리 요구량은 82,355MiB이며, 전체 262K 컨텍스트에서 가중치 약 25GB보다 KV 캐시 약 56GB가 더 큼
  • ollama 같은 블랙박스 도구는 필요한 모델 지원과 세부 조정 노브가 부족하며, 오래된 하드웨어에서는 추론 엔진과 메모리 구조를 깊게 이해해야 성능을 끌어낼 수 있음

실행 환경과 핵심 병목

  • 테스트 서버는 재활용 장비이며, 사양은 Intel Xeon E5-2620 v4 @ 2.10GHz, 8코어 16스레드, AVX2, 20MiB L3 캐시, 2MiB L2, 128GB DDR3, GPU 없음
  • 이 CPU는 AVX-512, AVX-VNNI, BF16을 지원하지 않고, 통합 GPU도 없음
  • LLM 추론에서 토큰을 하나씩 생성하는 디코더 패스는 주로 연산량이 아니라 메모리 대역폭에 묶임
  • 다음 토큰을 계산하려면 모델의 학습 지식이 담긴 가중치를 RAM에서 CPU 캐시와 코어로 계속 옮겨야 하며, 프로세서는 행렬 계산보다 다음 가중치 이동을 기다리는 시간이 커짐
  • 이런 “메모리 벽(memory wall)”은 Xeon뿐 아니라 H100 같은 고성능 장비에서도 중요한 성능 장벽으로 작동함

블랙박스 도구 대신 필요한 실행 노브

  • 단순히 DDR3·무GPU 환경에서 llama-cli를 실행하면 매우 느리고, 일반 GPU 사용 사례에 맞춘 최적화 때문에 많은 개선 여지가 남음
  • ollama는 필요한 모델 지원이 없을 수 있고, 실행 성능을 제대로 끌어올릴 만큼 충분한 세부 설정을 노출하지 않음
  • 실제 실행은 ik_llama.cpp가 노출하는 다수의 플래그를 조합해야 가능함
  • 핵심 플래그 묶음은 다음과 같음
--spec-type mtp --draft-max 3 --draft-p-min 0.0 --spec-autotune -sm graph -smgs -sas -mea 256 --split-mode-f32 -t 8 --parallel 8 --cpu-moe --merge-up-gate-experts --flash-attn on --mla-use 3 --mlock --run-time-repack --no-kv-offload

추측 디코딩과 MoE 최적화

  • --spec-type mtp --draft-max 3 --draft-p-min 0.0 --spec-autotune는 26B 검증기(verifier)를 이전에 만든 작은 MTP 드래프터와 함께 사용함
  • --draft-max 3는 드래프트당 최대 3토큰, --draft-p-min 0.0은 모든 확률 수용, --spec-autotune은 워크로드에 맞춰 체인 길이를 조정함
  • 긴 추론 체인을 생성할 때 사용자에게 최종 답변만 짧게 보이더라도, 숨겨진 사고 토큰마다 전체 디코더 패스가 필요함
  • CPU에서는 검증기 가중치를 캐시로 스트리밍하는 비용이 크고, 작은 드래프터의 활성 레이어는 L3 캐시에 잘 맞기 때문에 추측 디코딩의 이점이 더 강해짐
  • Gemma 4 26B-A4B는 128개 전문가 중 토큰당 8개가 활성화되는 MoE 구조이며, 전체 약 25.2B 파라미터 중 활성 파라미터는 약 3.8B임
  • --cpu-moe는 CPU 캐시 계층에 맞춰 라우팅을 조정하고, 128개 전문가 사이를 계속 오가며 캐시를 비우고 DDR3에서 다시 가져오는 캐시 스래싱을 줄이도록 동작함
  • --merge-up-gate-experts는 전문가 내부의 up projection과 gate projection을 하나의 행렬 곱으로 융합하며, 로그에는 fused_up_gate = 1로 확인됨
  • -t 8은 물리 코어 8개에 맞춘 설정이며, 메모리 병목 워크로드에서 16개 SMT 스레드를 모두 쓰는 것은 처리량보다 스케줄링 비용을 늘릴 수 있음

메모리 고정, 재배치, 그래프 분할

  • --run-time-repack은 추론 직전 가중치 행렬을 CPU 캐시 레이아웃에 맞게 재구성하며, 로그에는 Repacked 265 tensors로 나타남
  • 이 설정은 시작 시 몇 초의 비용을 들여 RAM 안의 숫자 테이블을 CPU가 더 잘 읽을 수 있는 형태로 재배치하고, 실제 텍스트 생성 중 메모리 대역폭을 최대한 활용하게 함
  • --mlock은 모델을 RAM에 고정해 운영체제가 디스크로 스왑하지 못하게 하는 설정임
  • 커널의 memlock 제한이 충분하지 않으면 failed to mlock 27628376064-byte buffer와 Try increasing RLIMIT_MEMLOCK 경고가 나오며, 이는 LLM 자체 문제가 아니라 기본 ulimit 설정 문제임
  • --no-kv-offload는 GPU가 없는 환경에서 KV 캐시를 GPU로 옮기려는 탐색을 건너뛰고, 시스템 RAM에 유지하게 함
  • -sm graph는 계산 그래프를 세로로 나눠 여러 처리 장치나 메모리 영역이 같은 레이어의 다른 부분을 동시에 계산하도록 하는 그래프 분할을 시도함
  • 이번 실행에서는 Split mode 'graph' is not supported for Gemma4 external MTP 로그와 함께 레이어 분할로 안전하게 낮춰짐
  • -sas는 물리 CPU 소켓 또는 NUMA 노드 간 워크로드 분할을 지시하고, --split-mode-f32는 분할 후 다시 결합되는 중간 지점에 32비트 부동소수점 정밀도를 쓰게 함

Attention, 메모리 사용량, 결론

  • ikawrakow는 CPU에서 Flash Attention을 처리하는 커스텀 커널을 작성해, 무거운 컨텍스트 처리에서 GPU 없이 동작하게 함
  • --flash-attn on은 attention softmax와 행렬 곱을 융합해 전체 N×N attention 행렬을 RAM에 물리적으로 쓰지 않고, 작은 청크 단위로 캐시 안에서 계산하고 소비하게 함
  • --mla-use 3은 Multi-Head Latent Attention을 활성화해 KV 캐시의 Key와 Value를 더 작은 잠재 표현으로 압축함
  • 로그에는 flash_attn = 1, fused_moe = 1, fused_up_gate = 1이 표시되어 해당 최적화가 실제로 적용됨
  • 메모리 로그 기준 전체 레이어 합계는 81,607.46MiB이고, 모델 텐서와 캐시에 필요한 메모리는 82,355MiB임
  • 전체 262K 컨텍스트에서 가중치는 약 25GB, KV 캐시는 약 56GB로, KV 캐시가 모델보다 큼
  • 이 설정은 25B 파라미터 MoE를 로드하고 MTP 드래프터로 추측 디코딩을 수행해, 2016년형 Xeon과 DDR3, GPU 없는 서버에서 읽기 속도로 텍스트를 생성함
  • 결론은 최신 오픈 가중치 AI의 로컬 실행 병목이 실리콘만이 아니라 추론 엔진의 동작과 메모리 구조를 이해하는 데 있으며, 올바른 포크, 보정된 양자화, 메모리 아키텍처 이해가 있으면 오래된 서버에서도 실행 가능하다는 것임
Read Entire Article