[메모] Android NDK를 활용하여 llama.cpp 빌드하기: 모바일에서 LLM 구동의 시작

[메모] Android NDK를 활용하여 llama.cpp 빌드하기: 모바일에서 LLM 구동의 시작
📝 Memos에서 자동 발행됨
🕐 작성일: 2025-10-25
✨ AI가 보충 설명을 추가했습니다 🔍 웹 조사 자료를 바탕으로 작성되었습니다

Android NDK를 활용하여 llama.cpp 빌드하기: 모바일에서 LLM 구동의 시작

개요

최근 대규모 언어 모델(LLM) 기술은 우리 삶의 다양한 영역에 혁신을 가져오고 있습니다. 클라우드 기반 서비스가 주를 이루지만, 개인 정보 보호, 지연 시간 최소화, 오프라인 사용 가능성 등의 이유로 기기 내(On-device) LLM 구동에 대한 관심이 높아지고 있습니다. llama.cpp는 Meta의 LLaMA를 비롯한 다양한 LLM을 C/C++ 기반으로 최적화하여 CPU 환경에서도 효율적으로 실행할 수 있게 해주는 경량 라이브러리입니다. 이를 통해 고성능 GPU가 없는 환경에서도 LLM을 활용할 수 있게 되었으며, 특히 모바일 기기에서의 LLM 실행 가능성을 열어주었습니다.

이 블로그 포스트에서는 llama.cpp를 Android 기기에서 구동하기 위한 두 가지 주요 방법, 즉 Termux를 이용한 직접 빌드와 Android NDK를 활용한 크로스 컴파일 방법을 소개합니다. 특히, android ndk 포함한 llama.cpp빌드라는 요청에 맞춰 Android NDK를 이용한 호스트 시스템에서의 크로스 컴파일 방법에 중점을 두어 설명할 것입니다. 이를 통해 개발자는 자신의 Android 애플리케이션에 llama.cpp 기반의 LLM 기능을 통합하거나, 단순히 Android 기기에서 LLM을 테스트하고 싶을 때 유용한 가이드를 얻을 수 있을 것입니다.

Android NDK를 사용하면 데스크톱 환경에서 익숙한 빌드 환경을 유지하면서 Android용 실행 파일을 생성할 수 있습니다. 이는 복잡한 의존성을 관리하거나 특정 하드웨어 아키텍처에 맞춘 최적화된 빌드를 수행할 때 강력한 이점을 제공합니다. 이제 llama.cpp를 Android에서 구동하기 위한 여정을 시작해 보겠습니다.

상세 가이드

llama.cpp를 Android 기기에서 실행하는 방법은 크게 두 가지가 있습니다. 하나는 Android 기기 자체에서 터미널 에뮬레이터 앱인 Termux를 사용하여 직접 빌드하는 것이고, 다른 하나는 개발용 PC(호스트 시스템)에서 Android NDK를 사용하여 크로스 컴파일하는 것입니다. 이 가이드에서는 두 가지 방법을 모두 다루되, NDK 크로스 컴파일에 더 중점을 둡니다.


방법 1: Termux를 사용하여 Android 기기에서 직접 빌드하기

Termux는 안드로이드용 터미널 에뮬레이터이자 리눅스 환경 앱으로, 루팅 없이 리눅스 명령어를 실행할 수 있게 해줍니다. Termux를 사용하면 Android 기기에서 직접 llama.cpp를 빌드하고 실행할 수 있습니다.

1. Termux 설치 및 기본 환경 설정

  • Termux 설치: Google Play 스토어에서 Termux를 검색하거나, 최신 안정 버전을 원한다면 F-Droid 또는 Termux 프로젝트 저장소에서 직접 APK 파일을 다운로드하여 설치합니다. (Play 스토어 버전은 실험적일 수 있습니다.)

필수 도구 설치: llama.cpp 빌드에 필요한 gitcmake를 설치합니다.

apt install git cmake -y

패키지 업데이트 및 업그레이드: Termux를 실행한 후, 다음 명령어를 입력하여 시스템 패키지를 최신 상태로 유지합니다.

apt update && apt upgrade -y

2. llama.cpp 저장소 클론 및 빌드

CMake를 이용한 빌드: llama.cpp 프로젝트 디렉토리로 이동한 후, 일반적인 CMake 빌드 절차를 따릅니다.

mkdir build
cd build
cmake ..
make -j$(nproc) # nproc는 사용 가능한 CPU 코어 수를 반환합니다.

저장소 클론: llama.cpp GitHub 저장소를 클론합니다.

git clone https://github.com/ggerganov/llama.cpp.git
cd llama.cpp

3. 모델 다운로드 및 실행

llama-cli 실행: llama.cpp 디렉토리로 돌아가 (cd ../.. 또는 cd ~cd llama.cpp), 빌드된 llama-cli 실행 파일을 사용하여 모델을 구동합니다. context-size는 적절한 값(예: 4096)으로 설정하는 것이 중요합니다.

./build/bin/llama-cli -m ~/{모델-이름}.gguf -c {컨텍스트-크기} -p "{당신의-프롬프트}"

모델 다운로드: 빌드가 완료되면 사용할 GGUF 모델 파일을 다운로드합니다. 모델 파일은 Termux의 ~/ (홈 디렉토리)에 두는 것을 권장합니다. 예를 들어, Hugging Face 등에서 모델 URL을 복사하여 사용합니다.

curl -L {모델-URL} -o ~/{모델-이름}.gguf

방법 2: Android NDK를 사용하여 호스트 시스템에서 크로스 컴파일하기 (권장)

Android NDK(Native Development Kit)를 사용하면 개발용 PC(Linux, macOS, Windows)에서 llama.cpp를 Android용 라이브러리나 실행 파일로 크로스 컴파일할 수 있습니다. 이 방법은 더욱 정교한 제어와 최적화를 가능하게 합니다.

1. Android SDK 및 NDK 설치

  • Android Studio 설치: 가장 쉬운 방법은 Android Studio를 설치하는 것입니다. Android Studio를 설치하면 Android SDK와 NDK를 쉽게 설치하고 관리할 수 있습니다.

NDK 경로 설정: Android Studio 설치 후, SDK Manager를 통해 필요한 NDK 버전을 설치합니다. 환경 변수 $ANDROID_NDK에 NDK 설치 경로를 설정해야 합니다. 예를 들어:

# Linux 또는 macOS
export ANDROID_NDK=/path/to/android-sdk/ndk/{ndk-버전}

# Windows (PowerShell)
$env:ANDROID_NDK = "C:\path\to\android-sdk\ndk\{ndk-버전}"

({ndk-버전}25.2.9519653과 같은 실제 NDK 버전으로 대체해야 합니다.)

2. llama.cpp 저장소 클론

llama.cpp GitHub 저장소를 클론합니다.

git clone https://github.com/ggerganov/llama.cpp.git
cd llama.cpp

3. Android NDK를 사용하여 크로스 컴파일

llama.cpp 프로젝트 디렉토리에서 다음 cmake 명령어를 실행하여 Android용 빌드를 구성합니다.

cmake \
    -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \
    -DANDROID_ABI=arm64-v8a \
    -DANDROID_PLATFORM=android-28 \
    -DCMAKE_C_FLAGS="-march=armv8.7a" \
    -DCMAKE_CXX_FLAGS="-march=armv8.7a" \
    -DGGML_OPENMP=OFF \
    -DGGML_LLAMAFILE=OFF \
    -B build-android

각 옵션에 대한 설명은 다음과 같습니다:

  • -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake: CMake에게 Android NDK 툴체인 파일을 사용하여 빌드하도록 지시합니다. $ANDROID_NDK는 이전에 설정한 환경 변수입니다.
  • -DANDROID_ABI=arm64-v8a: 타겟 Android 아키텍처를 arm64-v8a로 지정합니다. 이는 대부분의 최신 Android 기기에 적합합니다. armeabi-v7a 등 다른 ABI도 선택할 수 있습니다.
  • -DANDROID_PLATFORM=android-28: 타겟 Android API 레벨을 28로 지정합니다 (Android 9.0 Pie). 이는 앱이 지원해야 하는 최소 API 레벨에 따라 조정할 수 있습니다. developer.android.com/ndk/guides/stable_apis에서 안정적인 API 레벨을 확인할 수 있습니다.
  • -DCMAKE_C_FLAGS="-march=armv8.7a"-DCMAKE_CXX_FLAGS="-march=armv8.7a": C 및 C++ 컴파일러 플래그를 설정하여 ARMv8.7a 아키텍처에 최적화된 코드를 생성하도록 합니다. 이는 성능 향상에 기여할 수 있습니다.
  • -DGGML_OPENMP=OFF: GGML(llama.cpp의 내부 라이브러리)에서 OpenMP를 끄도록 설정합니다. Android 환경에서는 OpenMP 지원이 제한적이거나 성능 문제가 발생할 수 있으므로, 종종 이 옵션을 끕니다. 대신 자체 스레딩 모델을 사용하거나 특정 하드웨어 가속기를 활용할 수 있습니다.
  • -DGGML_LLAMAFILE=OFF: llamafile 지원을 끄도록 설정합니다.
  • -B build-android: 빌드 결과물이 저장될 디렉토리(여기서는 build-android)를 지정합니다.

4. 빌드 실행

cmake 명령어가 성공적으로 실행되면, build-android 디렉토리로 이동하여 make 명령어를 실행합니다.

cd build-android
make -j$(nproc) # 호스트 시스템의 CPU 코어 수에 따라 병렬 빌드

빌드가 완료되면 build-android/bin 디렉토리 내에서 Android용으로 컴파일된 llama-cli와 같은 실행 파일들을 찾을 수 있습니다. 이 파일들을 Android 기기로 전송한 후 Termux와 같은 환경에서 실행하거나, Android 앱에 통합하여 사용할 수 있습니다.

실제 사용 예시

앞서 Termux 가이드에서 보여드렸던 llama-cli 실행 예시는 llama.cpp가 Android 기기에서 어떻게 구동될 수 있는지를 잘 보여줍니다. NDK를 통해 빌드된 실행 파일도 마찬가지 방식으로 Android 기기에서 실행할 수 있습니다.

1. GGUF 모델 다운로드 (Termux 환경 기준)

Termux 내에서 curl 명령어를 사용하여 Hugging Face 또는 다른 소스에서 GGUF 모델 파일을 다운로드하고 ~/ 디렉토리에 저장합니다. 예를 들어, mistral-7b-instruct-v0.2.Q4_K_M.gguf 모델을 다운로드하는 경우:

# Termux 셸 내에서
curl -L https://huggingface.co/TheBloke/Mistral-7B-Instruct-v0.2-GGUF/resolve/main/mistral-7b-instruct-v0.2.Q4_K_M.gguf -o ~/mistral-7b-instruct-v0.2.Q4_K_M.gguf

2. llama-cli를 이용한 대화형 세션 시작

다운로드한 모델을 사용하여 llama-cli를 실행하고 프롬프트를 입력합니다. 이때 context-size는 모델과 기기의 메모리 용량에 맞춰 적절하게 조절해야 합니다.

# Termux 셸 내에서, llama.cpp 저장소 루트 디렉토리에서 실행
./build/bin/llama-cli -m ~/mistral-7b-instruct-v0.2.Q4_K_M.gguf -c 4096 -p "안드로이드에서 LLM을 실행하는 방법에 대해 알려줘."

이 명령어를 실행하면 llama-cli가 모델을 로드하고 프롬프트에 대한 응답을 생성하기 시작합니다. llama-cli 외에도 examples 디렉토리의 다른 실행 파일들도 유사한 방식으로 활용할 수 있습니다. 예를 들어, 웹 서버 형태로 LLM을 구동하는 server 예제 등 다양한 활용이 가능합니다.

실제 구동 시각 자료: llama.cpp 개발팀에서 Pixel 5 폰에서 인터랙티브 세션이 실행되는 모습을 담은 데모 영상을 참고하면, Android 기기에서 LLM이 어떻게 동작하는지 시각적으로 이해하는 데 도움이 될 것입니다. https://user-images.githubusercontent.com/271616/225014776-1d567049-ad71-4ef2-b050-55b0b3b9274c.mp4

💡 유용한 팁

  1. Termux 설치 소스 고려: Google Play 스토어의 Termux는 업데이트가 느리거나 실험적인 버전일 수 있습니다. 최신 기능과 안정적인 버전을 원한다면 F-Droid 또는 Termux 프로젝트의 GitHub 저장소에서 직접 다운로드하는 것을 권장합니다.
  2. 모델 파일 위치 최적화: Termux 환경에서 모델 파일을 다운로드할 때는 ~/ (사용자 홈 디렉토리)에 저장하는 것이 일반적이며, 권한 문제나 경로 설정 없이 쉽게 접근할 수 있어 편리합니다.
  3. 적절한 컨텍스트 크기 설정: llama.cpp 실행 시 -c {context-size} 옵션은 매우 중요합니다. 너무 큰 컨텍스트 크기는 모바일 기기의 제한된 메모리를 급격히 소모하여 터미널 앱이 강제 종료될 수 있습니다. 4096과 같은 적절한 값으로 시작하여 기기의 성능에 맞춰 조절하는 것이 좋습니다.
  4. NDK 환경 준비의 중요성: Android NDK를 통한 크로스 컴파일 경로를 선택했다면, Android SDK가 제대로 설치되어 있고 $ANDROID_NDK 환경 변수가 올바른 NDK 경로를 가리키도록 설정하는 것이 가장 중요합니다. 환경 설정 오류는 빌드 실패로 이어질 수 있습니다.
  5. NDK 빌드 시 라이브러리 제한 인지: Android 환경은 데스크톱 환경과 달리 기본적으로 제공되는 네이티브 라이브러리 세트가 제한적입니다. llama.cpp 빌드 시 NDK 툴체인을 사용하면, Android가 제공하는 안정적인 API(stable_apis)만 사용할 수 있음을 인지해야 합니다. 필요한 경우 추가 라이브러리를 직접 빌드하여 포함해야 할 수도 있습니다.

⚠️ 주의사항

  1. Termux 버전 문제: Termux의 Google Play 스토어 버전은 최신 업데이트가 적용되지 않거나 호환성 문제가 있을 수 있습니다. 따라서 빌드 실패 등의 문제가 발생할 경우, F-Droid 또는 공식 GitHub 저장소에서 최신 버전을 다운로드하여 시도해 보는 것이 좋습니다.
  2. 메모리 부족으로 인한 강제 종료: llama.cpp는 모델 크기와 context-size 설정에 따라 상당한 메모리를 소비할 수 있습니다. 특히 구형 또는 저사양 Android 기기에서는 메모리 부족으로 인해 앱이 예기치 않게 종료될 수 있으므로, 작은 모델과 적절한 컨텍스트 크기로 시작하는 것이 안전합니다.
  3. Android NDK의 라이브러리 제한: Android NDK를 사용하여 빌드할 때는 Android가 기본적으로 제공하는 네이티브 라이브러리만 사용할 수 있습니다. 데스크톱 환경에서 흔히 사용되는 특정 라이브러리나 기능이 Android NDK 환경에서는 제공되지 않거나 제한적으로만 지원될 수 있습니다. 따라서, 복잡한 의존성을 가진 프로젝트를 빌드할 때는 이 점을 고려해야 합니다.

🔗 참고 자료

개인정보보호링크