ETC

갤럭시 S20 Snapdragon LLM

Darfin 2026. 9. 21. 21:46

OpenClaw + Qwen3-4B Q4_K_M 로컬 AI 구축 매뉴얼

1. 목표

이 매뉴얼의 최종 구성은 다음과 같다.

Galaxy S20 Snapdragon 865 / 12GB RAM
→ Termux
→ llama.cpp
→ Qwen3-4B-Q4_K_M
→ llama-server
→ OpenClaw

최종적으로 OpenClaw가 휴대폰 내부에서 실행되는 Qwen3-4B 모델을 호출하도록 구성한다.


2. 준비물

스마트폰

  • Galaxy S20
  • Snapdragon 865 모델
  • RAM 12GB
  • 저장공간 최소 10GB 이상 권장
  • Wi-Fi 권장
  • 배터리 충전 상태 권장

Qwen3-4B Q4_K_M 모델 자체가 약 2.5GB이므로 여유 저장공간이 필요하다.

필요한 앱

  • Termux

Termux는 F-Droid 또는 Termux 공식 GitHub 릴리스에서 설치한다.

Play Store의 오래된 Termux가 설치되어 있다면 제거하고 최신 버전을 사용하는 것이 좋다.


3. Termux 최초 설정

Termux를 실행한다.

먼저 패키지를 업데이트한다.

pkg update -y
pkg upgrade -y

저장공간 접근을 허용한다.

termux-setup-storage

Android 권한 창이 나타나면 허용한다.

기본 도구를 설치한다.

pkg install -y git wget curl cmake clang make

OpenMP 관련 패키지도 설치한다.

pkg install -y libomp

설치 확인:

clang --version
cmake --version

정상적으로 버전이 출력되면 다음 단계로 진행한다.


4. 작업 디렉터리 만들기

모든 작업을 한 곳에 모은다.

mkdir -p ~/ai
mkdir -p ~/ai/models
mkdir -p ~/ai/llama.cpp

실제로 모델은 Android 공유 저장소보다 Termux의 ~/ 아래에 두는 것이 좋다.

llama.cpp 공식 Android 문서도 모델을 ~/ 디렉터리에 두는 것을 권장한다.


5. llama.cpp 다운로드

cd ~/ai
git clone https://github.com/ggml-org/llama.cpp.git

다운로드가 완료되면:

cd ~/ai/llama.cpp

현재 위치 확인:

pwd

다음과 비슷하게 나와야 한다.

/data/data/com.termux/files/home/ai/llama.cpp

6. llama.cpp 빌드

S20에서 먼저 가장 호환성이 높은 기본 ARM64 빌드를 만든다.

cd ~/ai/llama.cpp
cmake -B build \
  -DCMAKE_BUILD_TYPE=Release \
  -DBUILD_SHARED_LIBS=OFF

그 다음 필요한 프로그램만 빌드한다.

cmake --build build --config Release -j6 --target llama-cli llama-server

여기서 -j6은 빌드 작업을 6개 스레드로 실행한다는 의미다.

S20에서 빌드 중 발열이 심하면:

cmake --build build --config Release -j4 --target llama-cli llama-server

로 낮춘다.

llama.cpp 공식 문서에서도 CMake로 llama-server를 빌드할 수 있으며, Android Termux에서 CLI를 직접 빌드하는 방법을 지원한다.

빌드 결과 확인:

ls -lh build/bin/llama-cli
ls -lh build/bin/llama-server

두 파일이 존재하면 성공이다.


7. Qwen3-4B Q4_K_M 다운로드

Qwen3-4B GGUF 공식 모델:

https://huggingface.co/Qwen/Qwen3-4B-GGUF

모델 디렉터리로 이동:

cd ~/ai/models

Q4_K_M 다운로드:

wget -O Qwen3-4B-Q4_K_M.gguf \
"https://huggingface.co/Qwen/Qwen3-4B-GGUF/resolve/main/Qwen3-4B-Q4_K_M.gguf?download=true"

다운로드 확인:

ls -lh ~/ai/models/Qwen3-4B-Q4_K_M.gguf

약 2.5GB 정도의 파일이 있어야 한다.


8. 모델 무결성 확인

파일이 정상적으로 내려받아졌는지 확인한다.

sha256sum ~/ai/models/Qwen3-4B-Q4_K_M.gguf

다운로드한 공식 파일의 SHA256과 비교한다.

값이 다르면 모델을 다시 다운로드한다.


9. Qwen3 단독 실행 테스트

OpenClaw를 설치하기 전에 모델부터 테스트한다.

cd ~/ai/llama.cpp

다음 명령을 실행한다.

./build/bin/llama-cli \
  -m ~/ai/models/Qwen3-4B-Q4_K_M.gguf \
  -c 4096 \
  -t 8 \
  -ngl 0 \
  -p "안녕하세요. 당신은 누구인가요? 한국어로 간단히 답해주세요."

여기서 중요한 옵션:

-m
모델 파일

-c 4096
컨텍스트 길이

-t 8
CPU 스레드

-ngl 0
GPU offload 사용 안 함

처음에는 -c 4096을 권장한다.

llama.cpp 공식 Android 문서도 처음에는 4096 정도의 합리적인 context size를 사용하라고 안내한다. context가 너무 크면 메모리 사용량이 증가할 수 있다.

정상적으로 한국어 답변이 출력되면 모델 실행은 성공이다.


10. S20에서 성능 측정

모델이 실행된다면 응답 마지막 부분에서 llama.cpp의 timing 정보를 확인한다.

예:

eval time
tokens per second

여기서 중요한 것은 tokens/sec이다.

S20에서 다음 세 가지를 시험해볼 수 있다.

테스트 A

-t 4

테스트 B

-t 6

테스트 C

-t 8

예:

./build/bin/llama-cli \
  -m ~/ai/models/Qwen3-4B-Q4_K_M.gguf \
  -c 4096 \
  -t 6 \
  -ngl 0 \
  -p "1부터 100까지의 숫자를 간단하게 설명해주세요."

S20은 발열 때문에 무조건 스레드를 많이 사용하는 것이 좋은 것은 아니다.

실사용에서는 4~8 threads부터 비교하는 것을 권장한다.


11. llama-server 실행

이제 OpenClaw가 접근할 API 서버를 실행한다.

cd ~/ai/llama.cpp
./build/bin/llama-server \
  -m ~/ai/models/Qwen3-4B-Q4_K_M.gguf \
  --host 127.0.0.1 \
  --port 8080 \
  -c 4096 \
  -t 8 \
  -ngl 0

정상적으로 시작되면 서버는:

http://127.0.0.1:8080

에서 동작한다.

llama.cpp의 기본 서버 포트는 8080이며 OpenAI-compatible API를 제공한다.

이 Termux 세션은 닫지 않는다.


12. 새로운 Termux 세션 열기

Termux의 메뉴에서:

새 세션

을 만든다.

첫 번째 세션:

llama-server

두 번째 세션:

OpenClaw

용도로 사용한다.


13. llama-server 작동 확인

두 번째 Termux 세션에서:

curl http://127.0.0.1:8080/health

정상이라면 서버 상태가 정상임을 나타내는 응답이 나온다.

모델 API 확인:

curl http://127.0.0.1:8080/v1/models

모델 정보가 JSON으로 나오면 성공이다.


14. Chat API 테스트

OpenClaw를 연결하기 전에 OpenAI-compatible API를 직접 테스트한다.

curl http://127.0.0.1:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      {
        "role": "user",
        "content": "한국의 수도는 어디인가요?"
      }
    ],
    "max_tokens": 100
  }'

JSON 형태의 답변이 나오면:

Qwen3
 ↓
llama.cpp
 ↓
llama-server
 ↓
OpenAI-compatible API

구성이 정상이다.

이 단계에서 문제가 있으면 OpenClaw를 설치하지 말고 먼저 llama.cpp 문제를 해결한다.


15. OpenClaw 설치

두 번째 Termux 세션에서 실행한다.

pkg update -y
pkg install -y curl

그 다음 openclaw-android 공식 설치 명령을 사용한다.

curl -sL myopenclawhub.com/install | bash && source ~/.bashrc

현재 openclaw-android 공식 README에서도 이 방법을 사용한다. 설치 프로그램은 Android ARM64에서 사용할 수 있는 환경을 구성하고 OpenClaw를 설치한다.

설치 확인:

openclaw --version

버전이 출력되면 성공이다.


16. OpenClaw 초기 설정

openclaw onboard

화면의 안내에 따라 기본 설정을 완료한다.

OpenClaw 자체는 클라우드 LLM을 사용할 수도 있고 로컬 LLM을 사용할 수도 있다.

이번 매뉴얼에서는 로컬 Qwen3를 연결한다.


17. OpenClaw에서 llama-server 연결

llama-server는 OpenAI-compatible API를 제공하므로 OpenClaw에서 기존 llama.cpp 서버를 연결하는 구조를 사용할 수 있다.

API 주소:

http://127.0.0.1:8080/v1

모델 ID는 먼저 확인한다.

curl http://127.0.0.1:8080/v1/models

응답에 표시되는 id를 확인한다.

그 값을 OpenClaw의 custom model ID로 사용한다.

OpenClaw의 현재 CLI에는 기존 llama.cpp 서버를 연결하기 위한 llama-cpp-existing-server 인증 방식이 제공된다.

예:

openclaw onboard --non-interactive \
  --accept-risk \
  --auth-choice llama-cpp-existing-server \
  --custom-base-url "http://127.0.0.1:8080/v1" \
  --custom-model-id "Qwen3-4B-Q4_K_M.gguf"

단, --custom-model-id에는 /v1/models에서 실제로 출력된 모델 ID를 사용하는 것이 가장 안전하다.


18. OpenClaw 로컬 모델 테스트

llama-server가 실행 중인 상태에서 새로운 Termux 세션을 만든다.

openclaw agent --local --agent main --message "안녕하세요. 자기소개를 간단하게 해주세요."

정상적으로 Qwen3의 응답이 나오면:

Galaxy S20
   ↓
Termux
   ↓
OpenClaw
   ↓
llama-server
   ↓
Qwen3-4B-Q4_K_M

구축이 완료된 것이다.

Qwen 공식 GGUF 모델에서도 llama.cpp 기반 OpenClaw 연결 방법을 안내하고 있다.


19. OpenClaw Gateway 실행

OpenClaw를 실제로 상시 실행하려면:

openclaw gateway

를 실행한다.

중요:

openclaw gateway는 SSH 세션보다는 휴대폰의 Termux에서 직접 실행하는 것이 권장된다. SSH 연결이 끊기면 Gateway도 종료될 수 있기 때문이다. openclaw-android 공식 README에서도 이 점을 명시하고 있다.

Gateway가 실행되는 Termux 세션은 계속 유지한다.


20. 최종 Termux 구성

실제 사용 시에는 대략 다음처럼 사용한다.

Termux 세션 1

cd ~/ai/llama.cpp

./build/bin/llama-server \
  -m ~/ai/models/Qwen3-4B-Q4_K_M.gguf \
  --host 127.0.0.1 \
  --port 8080 \
  -c 4096 \
  -t 8 \
  -ngl 0

Termux 세션 2

openclaw gateway

Termux 세션 3

필요할 때 테스트:

curl http://127.0.0.1:8080/health

또는:

openclaw agent --local --agent main --message "현재 상태를 간단히 설명해줘."

21. S20 권장 초기 설정

처음에는 다음 설정을 사용한다.

설정권장값

모델 Qwen3-4B
양자화 Q4_K_M
모델 크기 약 2.5GB
Context 4096
CPU threads 6~8
GPU layers 0
서버 주소 127.0.0.1
포트 8080
OpenClaw 로컬 llama-server

22. 성능을 높이고 싶을 때

처음부터 성능 옵션을 많이 넣지 않는다.

먼저:

Qwen3-4B
Q4_K_M
4096 context
6~8 threads
GPU offload 0

으로 안정성을 확인한다.

그 다음 하나씩 변경한다.

CPU thread 테스트

-t 4
-t 6
-t 8

각각의 tokens/sec를 비교한다.

Context 테스트

-c 4096

에서 안정적으로 작동하면:

-c 8192

를 테스트할 수 있다.

단, context가 증가하면 메모리 사용량도 증가한다. llama.cpp 공식 Android 문서 역시 처음에는 4096 정도로 시작할 것을 권장한다.


23. 중요한 발열 관리

S20은 성능보다 지속적인 발열이 문제가 될 가능성이 크다.

Qwen3-4B를 장시간 실행할 경우:

CPU 100% 근처
↓
발열 증가
↓
스로틀링
↓
tokens/sec 감소

가 발생할 수 있다.

따라서 장시간 OpenClaw를 사용할 경우:

  • 케이스 제거
  • 충전 중 고부하 작업 최소화
  • 화면 밝기 감소
  • 백그라운드 앱 종료
  • Termux 배터리 최적화 예외 설정

등을 고려한다.


24. Android 배터리 최적화 해제

OpenClaw와 Termux가 백그라운드에서 종료되지 않도록 Android 설정에서 Termux의 배터리 사용 제한을 확인한다.

일반적으로:

설정
→ 애플리케이션
→ Termux
→ 배터리
→ 제한 없음

형태의 설정을 선택한다.

메뉴 이름은 One UI 버전에 따라 다를 수 있다.


25. 문제가 발생했을 때 확인 순서

문제가 생기면 한꺼번에 여러 부분을 수정하지 않는다.

1단계

./build/bin/llama-cli \
  -m ~/ai/models/Qwen3-4B-Q4_K_M.gguf \
  -c 4096 \
  -t 6 \
  -ngl 0 \
  -p "안녕하세요"

모델 자체가 실행되는지 확인한다.

2단계

curl http://127.0.0.1:8080/health

llama-server가 살아있는지 확인한다.

3단계

curl http://127.0.0.1:8080/v1/models

API가 정상인지 확인한다.

4단계

OpenClaw를 테스트한다.

openclaw agent --local --agent main --message "안녕하세요"

이렇게 하면 문제가:

모델
↓
llama.cpp
↓
API
↓
OpenClaw

중 어디에 있는지 구분하기 쉽다.


26. 만약 llama.cpp 빌드가 실패한다면

Android/Termux에서 llama.cpp 직접 빌드는 기기와 Android 버전에 따라 문제가 발생할 수 있다.

특히 Android 15/Termux 환경에서는 특정 linker 문제가 보고되어 있으며, 일부 환경에서는 전체 target을 빌드하지 않고 llama-cli와 llama-server만 빌드하는 방법이 사용된다.

다음처럼 다시 시도한다.

cd ~/ai/llama.cpp
rm -rf build
cmake -B build \
  -DCMAKE_BUILD_TYPE=Release \
  -DBUILD_SHARED_LIBS=OFF
cmake --build build \
  --config Release \
  -j4 \
  --target llama-cli llama-server

그래도 실패하면 오류 메시지 마지막 30~50줄을 확인한다.

임의로 Android NDK를 설치하거나 -march 옵션을 추가하지 않는다.

현재 llama.cpp 공식 Android 문서에서도 Android 대상 cross-compile에서는 GGML_NATIVE=OFF가 필요하다고 명시하고 있으며, 전역 -march 사용도 주의하도록 안내한다.


27. OpenClaw 설치와 llama.cpp 빌드는 서로 독립적으로 생각한다

중요한 구조적 차이가 있다.

OpenClaw 자체:

Termux
 ↓
openclaw-android installer
 ↓
OpenClaw

로 설치한다.

로컬 AI:

llama.cpp
 ↓
llama-server
 ↓
Qwen3 GGUF

로 별도로 구성한다.

그 다음:

OpenClaw
    ↓
http://127.0.0.1:8080/v1
    ↓
llama-server
    ↓
Qwen3

로 연결한다.

openclaw-android 자체도 Android에서 로컬 LLM을 지원하지만, 공식 README는 모바일 CPU 추론이 느리고 GPU offload에 제한이 있기 때문에 로컬 모델을 보조적인 용도로 보는 것이 현실적이라고 설명한다.


28. 최종 체크리스트

다음 항목이 모두 성공하면 구축 완료다.

[ ] Termux 설치
[ ] termux-setup-storage
[ ] git / cmake / clang 설치
[ ] llama.cpp 다운로드
[ ] llama-cli 빌드 성공
[ ] llama-server 빌드 성공
[ ] Qwen3-4B-Q4_K_M 다운로드
[ ] llama-cli에서 Qwen3 실행
[ ] llama-server 실행
[ ] /health 정상
[ ] /v1/models 정상
[ ] /v1/chat/completions 정상
[ ] OpenClaw 설치
[ ] openclaw onboard 완료
[ ] OpenClaw → llama-server 연결
[ ] openclaw agent 테스트 성공
[ ] openclaw gateway 실행

29. 최종 실행 구조

구축이 끝난 S20은 다음과 같이 동작한다.

                    Galaxy S20
              Snapdragon 865 / 12GB
                         │
                  ┌──────┴──────┐
                  │   Termux    │
                  └──────┬──────┘
                         │
             ┌───────────┴───────────┐
             │                       │
       OpenClaw Gateway         llama-server
             │                       │
             │                  port 8080
             │                       │
             │                Qwen3-4B Q4_K_M
             │                       │
             └───────────┬───────────┘
                         │
                    Local AI Agent

이 구성을 먼저 안정적으로 만든 다음, S20 Snapdragon 865에서 실제 tokens/sec를 측정하고 threads, context, batch 등을 조정하는 것이 다음 단계다.

특히 S20에서는 RAM이 부족해서라기보다 Snapdragon 865의 지속적인 CPU 추론 성능과 발열이 핵심 변수다. 따라서 4B Q4_K_M을 기준으로 실제 속도를 측정한 후 7B/8B로 올릴지 결정하는 것이 좋다.

:::񎟧
참고 자료

다음 단계: 이 매뉴얼대로 설치한 뒤 llama-cli에서 나오는 eval time / tokens per second 결과를 보내주시면, S20 Snapdragon 865에 맞춰 -t, context, batch 값을 조정하는 성능 최적화 매뉴얼을 이어서 만들 수 있습니다.