
안드로이드 폰에서 1~5 tok/s 속도로 구동되는 GPT-OSS-120B, Qwen 30B 및 Gemma 26B: 60GB 모델, 11GB
요약
안드로이드 스마트폰의 제한된 RAM 환경에서 MoE 모델을 스트리밍 방식으로 실행하여 120B 규모의 대형 모델을 구동하는 기술을 소개합니다. O_DIRECT를 통해 플래시 메모리에서 필요한 전문가 가중치만 직접 읽어와 CPU만으로도 유의미한 추론 속도를 확보했습니다.
핵심 포인트
- MoE 구조를 활용해 필요한 전문가 가중치만 플래시 메모리에서 스트리밍 방식으로 로드
- GPU/NPU 없이 4개의 CPU 코어와 플래시 메모리만으로 120B 모델 구동 성공
- llama.cpp의 API를 활용하여 모델의 수학적 정확도(bit-for-bit lossless)를 완벽히 유지
- Qwen 30B 및 Gemma 26B 모델을 통해 모바일 환경에서의 실용적인 성능 입증
이 기기는 약 11GB의 사용 가능한 RAM을 가진 OnePlus 15R입니다. 가장 무거운 모델은 gpt-oss-120b로, Q4_K_M 양자화 방식이며 디스크 용량은 60GB입니다. 따라서 실행 중인 메모리보다 대략 5배 더 큽니다. 이는 모델을 메모리에 상주시키는 것이 튜닝의 문제가 아니라, 물리적으로 불가능함을 의미합니다. 그럼에도 불구하고 작동합니다. 모델 자체의 라우팅 너비(기본 전문가(experts), adb를 통해)에서 1.3 tok/s의 속도로 실행됩니다. 클립(clip) 영상은 전문가 수가 더 적기 때문에 약 1.8 tok/s로 약간 더 빠릅니다. Qwen과 Gemma 클립도 마찬가지로 레이어당 8개가 아닌 6개의 전문가를 사용합니다. 모든 모드는 GitHub에 있습니다. 참고로 동일한 파일에 대해 일반적인 mmap 로드를 수행하면 0.089 tok/s가 나오는데, 따라서 스트리밍(streaming)을 통해 약 14배의 성능 이득을 얻고 있습니다. GPU도, NPU도, 그 어떤 것도 없습니다. 오직 4개의 CPU 코어와 휴대폰의 플래시 메모리뿐입니다. 아이디어 자체는 오래되었고 다소 지루할 수 있습니다. MoE(Mixture of Experts) 레이어는 많은 전문가를 가지고 있지만, 각 토큰은 오직 몇 개만을 사용합니다(gpt-oss는 레이어당 128개 중 4개를 선택합니다). 그래서 저는 항상 필요한 가중치(weights)는 메모리에 유지하고, 토큰이 요청하는 전문가들만 해당 레이어가 실행되기 직전에 O_DIRECT를 통해 플래시 메모리에서 직접 읽어옵니다. 자주 사용되는(hot) 전문가들은 작은 캐시(cache)에 유지되며, 읽기 작업은 CPU가 이전 레이어를 처리하는 동안 발생합니다. 솔직히 120B 모델이 주목을 받지만, 저에게는 다른 두 가지가 더 중요합니다. 첫째, 출력 결과는 모델을 전체 RAM에서 실행하는 것과 정확히 동일합니다. "거의 같다"가 아니라 동일합니다. CI(지속적 통합) 테스트에서 스트리밍 방식과 상주 방식의 토큰을 하나씩 비교하여 조금이라도 차이가 나면 실패하도록 검증하고 있습니다. 스트리밍은 가중치가 나타날 때만 영향을 줄 뿐, 수학적 계산 자체를 바꾸지는 않습니다. (속도를 높이기 위해 전문가 수를 줄여 GPT에서 2.2 tok/s를 구현하는 선택적 옵션이 하나 있지만, 이는 모델이 계산하는 내용을 변경하므로 명확하게 표시해 두었습니다.) 둘째, 내부적으로는 순수한 llama.cpp를 사용합니다. 포크(fork)가 아니며, 저는 그들의 코드를 전혀 건드리지 않습니다. 모든 것은 공개된 콜백(callback) 및 gguf API를 통해 이루어지며, llama.cpp는 단순한 서브모듈(submodule)로 포함되어 있습니다. 따라서 업스트림(upstream)을 따라가는 작업은 병합(merge) 전쟁 대신 버전 업데이트만으로 충분합니다.
새로운 MoE (Mixture of Experts) 모델을 추가하는 것은 레지스트리(registry)에 한 줄만 추가하면 됩니다. 로드 시 파일에서 전문가(expert) 크기를 읽어오기 때문이며, MXFP4와 Q4_K_M 모두 동일한 경로를 따르므로 모든 양자화(quantization) 형식을 무료로 사용할 수 있습니다. 현재 qwen3moe, qwen2moe, gemma4 및 gpt-oss가 작동합니다. 실제로 사용해보고 싶다면 더 작은 모델들이 적합합니다. 동일한 휴대폰에서 Qwen3-30B는 5.2 tok/s, Gemma-4-26B는 약 4.1 tok/s의 속도로 작동하며, 두 모델 모두 비트 단위로 손실이 없는(bit-for-bit lossless) 상태입니다. 스트리밍(streaming) 자체가 어려운 부분은 아니었습니다. 진짜 어려운 부분은 안드로이드(Android)가 메모리를 다시 회수해가는 것이었습니다. RAM 용량을 넘어서게 되면, 커널(kernel)은 모델이 문장 중간에 있는 동안 상주하는 가중치(resident weights)를 계속 회수하며, 이로 인해 생성 과정 내내 가중치를 다시 페이징(paging)하여 불러오는 데 시간을 허비하게 됩니다. macOS는 스트리머에게 수십 기가바이트의 페이지 캐시(page cache)를 기꺼이 제공하지만, 압박을 받는 안드로이드는 거의 아무것도 제공하지 않습니다. 솔직히 이 싸움이 작업의 대부분이었습니다. 이 프로젝트는 Apache-2.0 라이선스이며, 직접 시도해보고 싶다면 릴리스(releases) 페이지에서 빌드된 APK를 받을 수 있습니다. 일반적인 주의사항은 다음과 같습니다: 단일 기기 테스트 결과이며, 구성별로 제가 확인한 최상의 성능이고, 휴대폰의 수치는 발열과 여유 메모리에 따라 변동되므로 단순히 수치를 주장하기보다는 방법론을 기술하는 데 중점을 두었습니다. https://github.com/Helldez/BigMoeOnEdge /u/dai_app [link] [comments] 에 의해 제출된 내용을 다루게 되어 기쁩니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 r/LocalLLaMA의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기