10년 된 Xeon이면 충분하다

1 week ago 5
  • 2016년 Xeon E5-2620 v4와 128GB DDR3, GPU 없는 서버에서도 Gemma 4 26B-A4B를 실행할 수 있음
  • LLM 디코더는 토큰마다 가중치를 RAM에서 캐시로 가져와야 해, 순수 연산보다 메모리 대역폭이 핵심 병목이 됨
  • ik_llama.cpp는 추측 디코딩, CPU MoE 라우팅, Flash Attention, 런타임 재패킹으로 DDR3 환경의 병목을 줄임
  • 262K 컨텍스트에서는 약 25GB 가중치와 56GB KV 캐시가 필요하며, 로그상 모델·캐시 총량은 82GB 수준임
  • 공개 가중치 AI의 접근성은 최신 GPU뿐 아니라 재활용 서버, 추론 엔진, 메모리 구조 이해에도 크게 좌우됨

2016년 Xeon 서버에서 Gemma 4 실행하기

  • 하드웨어 조건과 병목

    • 테스트 장비는 Intel Xeon E5-2620 v4 @ 2.10GHz, 물리 8코어/16스레드, AVX2 지원, AVX-512·AVX-VNNI·BF16 미지원, L3 20MiB, 총 L2 2MiB, 128GB DDR3 메모리, GPU 없음으로 구성됨
    • LLM 추론의 디코더 단계는 다음 토큰을 만들 때마다 모델 가중치를 RAM에서 CPU 캐시로 계속 가져와야 하므로, 순수 연산 성능보다 메모리 대역폭이 병목이 됨
    • ChatGPT 같은 도구에서 텍스트가 단어별로 흘러나오는 과정은 출력 토큰을 하나씩 생성하는 디코더 패스이며, 숨겨진 긴 추론 체인이 있어도 각 토큰마다 같은 디코더 패스가 필요함
    • 이 병목은 Xeon뿐 아니라 H100에서도 중요한 성능 장벽으로 작용하는 메모리 장벽이며, DDR3 기반 CPU-only 환경에서는 더 크게 드러남
    • 일반 llama-cli, ollama, 표준 llama-cpp 방식만으로는 이 환경에서 충분한 최적화 노출과 모델 지원을 얻기 어려워, ik_llama.cpp의 세부 플래그를 직접 조합해야 함

실행 명령과 핵심 최적화

  • 전체 실행 구성

    • 실제 실행은 gemma-4-26B-A4B-it-Q8_0.gguf 검증기와 MTP 드래프터 GGUF를 함께 쓰고, --spec-type mtp, --cpu-moe, --flash-attn on, --mlock, --run-time-repack 같은 플래그를 한 번에 적용함
    • 블랙박스 도구에서는 이런 명령줄을 확인하기 어렵고, 오래된 하드웨어에서는 각 플래그의 역할을 이해해야 성능을 끌어낼 수 있음
    • 일부 플래그는 적용되지 않거나 엔진이 조용히 우회할 수 있어 로그 확인이 필수임
  • 추측 디코딩

    • --spec-type mtp --draft-max 3 --draft-p-min 0.0 --spec-autotune은 26B 검증기와 작은 MTP 드래프터를 묶어 최대 3개 토큰을 초안으로 만들고, 워크로드에 맞춰 체인 길이를 자동 조정함
    • 추측 디코딩은 메모리 대역폭에 묶인 디코더 패스 수를 줄이는 소프트웨어적 우회로로 작동함
    • CPU에서는 작은 드래프터의 활성 계층이 L3 캐시에 들어갈 수 있고, 검증기는 캐시를 훨씬 넘어서므로 드래프터에 추가 연산을 쓰는 비용이 상대적으로 작음
    • CPU 환경에서는 검증기 가중치를 캐시로 계속 스트리밍하는 비용이 커, 추측 디코딩의 효과가 GPU보다 더 강하게 나타날 수 있음
  • CPU와 MoE 라우팅

    • Gemma 4 26B-A4B는 128개 전문가 중 토큰당 8개가 활성화되며, 전체 약 25.2B 파라미터 중 약 3.8B 활성 파라미터를 사용함
    • --cpu-moe는 CPU 캐시 계층에 맞춰 MoE 라우팅을 조정해, 128개 전문가 사이를 계속 이동하며 캐시를 비우고 DDR3에서 다시 가져오는 캐시 스래싱을 줄이도록 설계됨
    • --merge-up-gate-experts는 전문가 내부의 두 projection을 하나의 행렬 곱으로 합쳐 메모리 버스를 여러 번 오가는 비용을 줄이며, 로그의 fused_up_gate = 1로 적용 여부를 확인할 수 있음
    • -t 8은 물리 코어 수와 맞춘 설정이며, 이 작업은 DDR3 대기 시간이 병목이므로 16개 SMT 스레드까지 늘리면 처리량보다 스케줄링 비용이 커질 수 있음
    • --parallel 8은 병렬 실행 설정과 함께 물리 코어 중심의 CPU 활용을 맞추는 구성으로 쓰임

메모리 고정, 재패킹, KV 캐시

  • 런타임 재패킹

    • --run-time-repack은 추론 직전에 가중치 행렬을 CPU 캐시 레이아웃에 맞게 메모리에서 재구성함
    • 로그에는 Repacked 265 tensors가 출력되어 265개 텐서가 재배치됐음을 확인할 수 있음
    • 일반 레이아웃의 가중치 행렬을 그대로 읽으면 CPU가 데이터를 어색한 조각 단위로 가져와 캐시 미스가 발생할 수 있음
    • 시작 시 약간의 시간을 들여 메모리 배치를 바꾸는 대신, 실제 텍스트 생성 단계에서 메모리 대역폭을 최대한 쓰도록 만드는 최적화임
  • mlock과 스왑 방지

    • --mlock은 모델을 물리 RAM에 고정해 운영체제가 디스크로 스왑하지 못하게 하는 설정임
    • AI 가중치 27GB가 디스크로 스왑되면 다시 읽는 동안 생성 속도가 사실상 멈출 수 있음
    • 로그에 failed to mlock 27628376064-byte buffer와 Try increasing RLIMIT_MEMLOCK ('ulimit -l' as root)가 나오면, 플래그 문제가 아니라 커널의 memlock 제한이 27GB 버퍼를 고정하기에 낮은 상태임
    • 이는 LLM 고유의 문제가 아니라 기본 ulimit 설정에서 생기는 운영체제 제한이며, 블랙박스 도구는 해당 최적화를 요청하지 않는 방식으로 문제를 감출 수 있음
  • KV 캐시 배치

    • --no-kv-offload는 엔진이 KV 캐시를 GPU로 옮기려 하지 않도록 하는 설정임
    • KV 캐시는 현재 대화 문맥을 저장하는 단기 기억 역할을 하며, 새 토큰마다 전체 프롬프트를 다시 읽지 않게 해줌
    • 일반적으로 AI 엔진은 읽기·쓰기가 잦은 KV 캐시를 더 빠른 GPU 메모리로 오프로드하려 하지만, 이 구성에는 GPU가 없으므로 하드웨어 버스 검색과 오류 가능성을 줄이는 편이 나음
    • 이 설정은 KV 캐시를 가중치와 함께 시스템 RAM에 유지하도록 명시함

그래프 분할과 Attention 최적화

  • 그래프 레이아웃

    • -sm graph -smgs -sas -mea 256 --split-mode-f32는 계산 그래프를 메모리 영역에 어떻게 배치하고 분할할지 제어하는 설정임
    • -sm graph는 계산 그래프를 수직으로 나눠 여러 프로세서나 메모리 영역이 같은 계층의 서로 다른 부분을 동시에 계산하는 방식을 목표로 함
    • 기본 또는 대체 방식인 레이어 분할은 모델을 계층 단위로 나눠, 한 프로세서가 앞 계층을 계산한 뒤 다음 프로세서로 넘기는 구조라 일부 하드웨어가 대기할 수 있음
    • 이번 실행 로그에는 Split mode 'graph' is not supported for Gemma4 external MTP => changing split mode to 'layer'가 출력되어, Gemma4 외부 MTP 구성에서는 그래프 분할이 지원되지 않아 레이어 분할로 안전하게 내려감
    • MTP는 네트워크 끝단의 수학적 연결을 더 복잡하게 만들기 때문에, 이 엔진은 아직 MTP 아키텍처를 안전하게 그래프 분할하지 못하는 상태임
    • -sas는 여러 물리 CPU 소켓 또는 NUMA 노드가 있는 서버에서 워크로드 분할 방식을 지정하는 플래그이며, 단일 CPU 시스템에서도 향후 다중 CPU 구성의 벤치마크 후보가 됨
    • --split-mode-f32는 분할된 계산 결과를 다시 합칠 때 중간 연결 지점에 32비트 부동소수점 정밀도를 사용해 반올림 오류로 인한 품질 저하를 막는 설정임
  • Flash Attention과 MLA

    • --flash-attn on --mla-use 3은 CPU에서 Flash Attention과 Multi-Head Latent Attention을 활성화하는 구성임
    • ikawrakow는 ik_llama.cpp에서 GPU 없이 무거운 컨텍스트 처리를 다룰 수 있도록 CPU용 Flash Attention 커널을 작성함
    • Flash Attention은 attention softmax와 행렬 곱을 융합해 전체 N×N attention 행렬을 RAM에 물리적으로 쓰지 않고, 작은 청크 단위로 계산해 CPU 캐시 안에서 소비되도록 함
    • 긴 문서처럼 토큰 수가 커질수록 N×N 행렬의 메모리 부담이 폭발하므로, 전체 attention 행렬을 실체화하지 않는 방식이 중요해짐
    • Flash Attention은 원래 GPU용으로 만들어진 하드웨어 특화 최적화이며, 이를 표준 CPU에서 작동하도록 포팅한 점이 핵심임
    • --mla-use 3은 KV 캐시의 Key와 Value를 원시 형태로 모두 저장하는 대신 더 작은 latent 표현으로 압축하는 Multi-Head Latent Attention의 특정 구현 단계를 활성화함
    • 로그의 flash_attn = 1, fused_moe = 1, fused_up_gate = 1로 Flash Attention, MoE 융합, up/gate 융합이 실제 적용됐음을 확인할 수 있음

메모리 사용량과 결론

  • 로그상 메모리 계산

    • 로그의 총계는 모델 텐서와 캐시에 필요한 메모리를 82355 MiB로 표시함
    • 전체 262K 컨텍스트에서 약 25GB 가중치56GB KV 캐시가 사용되며, KV 캐시가 모델 자체보다 큼
    • 로그상 합계는 24852.46 MiB, 56755.00 MiB, 81607.46 MiB로 나타나며, 모델 텐서와 캐시 필요량이 82GB 수준으로 계산됨
    • 이 구성은 2016년 Xeon과 DDR3 메모리, GPU 없는 서버에서 25B급 MoE 모델과 MTP 드래프터를 함께 올리는 형태임
  • 사용성 장벽

    • 동작하는 설정에는 약 25개 플래그가 필요하고, 그중 상당수는 문서화가 부족하거나 조용히 실패할 수 있어 첫 번째 글에서 다룬 사용성 장벽을 실제로 드러냄
    • 앞선 과정에서는 특수 포크인 ik_llama.cpp를 빌드하고, 정밀한 추측 디코딩 드래프터를 만들고, GGUF 메타데이터에서 인프라 데이터 누출을 제거하는 스크립트를 작성했음
    • 이번 구성은 오래된 엔터프라이즈 서버에서 26B Mixture-of-Experts 아키텍처를 읽는 속도로 실행하도록, 배포 파이프라인과 물리 하드웨어 특성을 직접 맞춘 결과임
    • 로컬 최신 AI 실행의 병목은 실리콘만이 아니라, 추론 엔진의 동작 방식과 메모리 아키텍처를 깊이 이해해야 한다는 요구에도 있음
    • 데이터센터 GPU 클러스터, 기업 API 토큰, 대규모 예산은 특정 워크로드에 유용하지만, 공개 가중치 모델의 실사용 범위에서는 재활용 하드웨어와 적절한 포크, 보정된 양자화, 메모리 구조 이해가 중요함
    • 공개 가중치 AI의 최전선은 모델 제공자나 유료 장벽 뒤에만 있지 않고, 홈랩의 10년 된 서버 명령줄에서도 접근 가능함
    • Gemma 4 드래프터 양자화 파일을 내려받아 직접 실행할 수 있음
Read Entire Article