RTX 3060 12GB와 16GB DDR4 RAM만으로 Qwen 3.8 Flash Next-GSQ-RCO-IQ2_XS를 테스트한 결과
요약
본 글은 RTX 3060 12GB와 16GB DDR4 RAM 환경에서 대규모 MoE 모델(Qwen 3.8 Flash Next)을 구동하는 성능 테스트 결과를 다룹니다. 기존의 메모리 부족 문제로 인해 발생하는 페이지 폴트 문제를 해결하기 위해, llama.cpp에 --moe-direct-io 기능을 구현하여 기본 버전과 비교했을 때 비트 단위 정확도를 유지하며 약 20 tok/s의 높은 디코드 속도를 달성했음을 보여줍니다.
핵심 포인트
- 16GB RAM 환경에서 대규모 MoE 모델 구동 시 메모리 부족(OOM) 문제가 발생하기 쉽습니다.
- 기존 방식은 페이지 폴트와 SSD I/O에 의존하여 성능 저하가 심각했습니다.
- llama.cpp의 --moe-direct-io 기능을 통해 정확도를 유지하며 속도 향상을 이뤘습니다.
- 이 방법은 메모리 제약 환경에서 MoE 모델을 효율적으로 구동하는 방법을 제시합니다.
(스크린샷만 보고 판단하지 마세요, 캐시가 차갑습니다. 따뜻한 캐시에서는 24+ tok/s에 도달합니다!) 약 두 달 전, 저는 다음 토큰에 어떤 MoE(Mixture-of-Experts) 전문가가 사용될지 예측하는 것이 CPU/GPU 오프로딩 속도를 실제로 높일 수 있는지 여부를 질문하며 게시물을 올렸습니다. 원본 게시물: 다음 토큰에 사용되는 MoE 전문가를 예측하여 CPU/GPU 오프로드를 가속화하는 방법
우선 솔직하게 고백하자면, 저는 그 프로젝트를 곧바로 보류했습니다. 이유는 무엇일까요? 당시 제가 얻었던 속도가 일종의 허상이었기 때문입니다. 제 엔진은 라우터(router) 가중치에 기반하여 전문가들을 공격적으로 가지치기(pruning)했고, 기본적으로 사용하지 않는 전문가들(cold experts)을 제거하여 더 나은 성능을 얻으려고 했습니다. 물론 수치는 훌륭해 보였지만, 이미 양자화된 모델에서 그렇게 하는 것은 출력 품질과 일관성을 해쳤습니다. 저는 그 트레이드오프가 마음에 들지 않아 포기했고, 공개하지 않았습니다.
시간이 흘러 최근에 Qwen 3.8 Flash Next (125B MoE, 512 experts, top-10 routing)가 출시되었습니다. 저는 이 모델의 68GB GSQ-RCO IQ2_XS 빌드를 다운로드하여 일상적으로 사용하는 컴퓨터에서 실행해보고 싶었습니다. 그때 저는 그 아이디어를 다시 검토하기로 결정했지만, 이번에는 대충 넘기는 법이 없었습니다.
제 환경:
GPU: RTX 3060 12GB
RAM: 16GB DDR4, 싱글 채널(~19 GB/s 대역폭)
OS: CachyOS / Arch Linux
저장 장치: 중급 NVMe SSD (~2.1 GB/s 읽기)
소프트웨어: llama.cpp (CUDA로 빌드됨)
만약 16GB RAM 기계에서 기본 llama.cpp를 사용하여 68GB MoE를 실행해 본 적이 있다면, 얼마나 고통스러운지 아실 겁니다. 저는 토큰당 1.4–2.1 tok/s에 불과했고, 일부 실행에서는 수천 개의 주요 페이지 폴트(major page faults)가 발생했습니다. 메모리에 작업 집합(working set)을 유지할 만큼 충분한 메모리가 없기 때문에 리눅스는 지속적으로 SSD에서 모델 데이터를 끌어오게 됩니다. 그러다가 Strata 같은 엔진들이 소비자용 하드웨어에서 약 40 tok/s에 도달한다는 주장을 내세우며 등장했습니다. 매우 인상적이지만, RAM이 적은 사람들에게는 함정이 있습니다. 이러한 접근 방식 중 일부는 mlock을 사용하여 전문가 24 GiB를 메모리에 고정(pin) 상태로 유지하는 것에 의존합니다. 만약 여러분의 RAM이 16GB에 불과하다면, 당연히 그렇게 할 수는 없습니다.
설정에 따라 OOM(Out Of Memory) 문제가 발생하거나 성능이 매우 나쁜 결과로 끝납니다. 그래서 저는 원래 아이디어로 돌아가서 llama.cpp 내부에 선택적 기능으로 제대로 구현하기 시작했습니다: --moe-direct-io 이번 목표는 간단했습니다. 전문가를 드롭하지 않고, 출력 품질을 희생시키지 않으며, 기본(stock) 버전과 비트 단위로 정확한 출력을 얻는 것이었습니다. 아래 모든 테스트는 cgroup을 사용하여 MemoryMax=6G로 실행되었습니다. 모델: Qwen 3.8 Flash Next IQ2_XS (68GB) 하드웨어: RTX 3060 12GB + 16GB DDR4 RAM 엔진/모드 디코드 속도 토큰당 주요 페이지 폴트 SSD I/O 출력 기본(stock) llama.cpp (mmap) 1.41–2.12 tok/s 1,140–1,565 208–312 MB/token 일관성 유지(Coherent) 저희 엔진 (블로킹, 온디맨드 전용) 0.73 tok/s 0 ~206 MB/token 비트 단위 정확도(--moe-direct-io + prefetch) 20.14–21.13 tok/s ~0 (+32 토큰에 걸쳐!!) 순차 스트리밍 비트 단위 정확도로 기본(stock)과 비교 블로킹 버전은 실제로 기본보다 느립니다. 이는 당연합니다. 레이턴시를 숨기기 위해 많은 작업을 하지 않고 디스크 읽기를 기다리는 것에 불과하기 때문입니다. 프리페칭 버전이 흥미로운 부분입니다. 캐시가 따뜻해지면 20–21 tok/s를 유지하며, 일부 실행에서는 24+ tok/s에 도달합니다. 이는 동일한 장치에서 기본 llama.cpp 대비 약 10–15배의 속도 향상입니다. 그리고 아닙니다. 저희는 전문가를 드롭해서 이 수치를 얻은 것이 아닙니다. 출력은 기본 버전과 비트 단위로 정확합니다. 솔직히 제가 가장 기대하는 부분입니다. 평소의 페이지 폴트 악몽 없이 16GB 장치에서 이렇게 큰 모델을 실행할 수 있다는 것이 원래 프로젝트로 달성하고 싶었던 것입니다. 여전히 미흡한 점이 있습니다. 아직 완벽하지는 않습니다. 저희가 여전히 작업 중인 몇 가지 사항이 있습니다. 1. 콜드 스타트(Cold starts) 속도가 눈에 띄게 느립니다 현재 슬롯은 비어있는 상태(-1)로 시작하므로, 새로운 주제에 대한 첫 요청은 온 워킹 세트가 안정화되면서 20+ tok/s까지 올라가기 전에 약 3.5–4.5 tok/s에서 시작할 수 있습니다. 저희는 오프라인 핫 프로파일 시딩(offline hot-profile seeding)을 작업하여 모든 것을 처음부터 학습하는 대신 유용한 워킹 세트로 시작할 수 있도록 하고 있습니다. 2.
프롬프트 처리 속도가 느립니다. 512개 이상의 토큰으로 프롬프트를 공급하면 짧은 시간 동안 엄청난 수의 전문가(experts)를 건드릴 수 있습니다. 이는 레이어당 72개의 슬롯에 많은 부담을 주어 프리필(prefill) 단계가 어려움을 겪게 합니다. 저희는 이를 해결하기 위해 프롬프트 청크 마이크로 배치 처리(-ub 32) 작업을 진행하고 있습니다. 3. SSD 오프로딩 시 추론 디코딩이 이상하게 작동합니다. 표준 MTP 추측(speculation) 방식은 오히려 속도를 늦출 수 있다는 것을 발견했습니다. 2~3개의 토큰을 검증하려면 해당 토큰들에 필요한 전문가들의 조합 세트를 디스크에서 로드해야 하는데, 이 과정이 얻는 성능 향상을 잠식합니다. 현재로서는 신뢰도 게이트 추측(confidence-gated speculation) (min-p 0.8) 또는 접미사 프롬프트 조회(suffix prompt lookup)가 이러한 환경에 더 유망해 보입니다. 어쨌든, 이것이 프로젝트의 현재 상황입니다. 개선할 부분이 여전히 많습니다. 특히 프리필과 콜드 스타트(cold starts) 부분에서요. 하지만 전문가 가지치기(pruning experts) 없이 이 설정으로 20+ tok/s를 달성한 것은 저에게는 상당히 큰 성과입니다. 관심 있는 분이 계시면 질문에 답하거나 io_uring 및 슬롯 재매핑 구현 세부 사항에 대해 논의할 준비가 되어 있습니다. (이 게시물의 후반부는 Claude의 도움을 받아 작성되었습니다.) /u/zyxciss 제출 [링크] [댓글]
AI 자동 생성 콘텐츠
본 콘텐츠는 r/LocalLLaMA의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기