메인 콘텐츠로 건너뛰기

Unsloth·ExecuTorch로 Qwen3를 휴대폰에 올리는 전체 흐름

wislan
wislan
조회수 26

생성형 AI 도구를 활용하여 작성 및 편집된 노트입니다.

요약

핵심 요약

클라우드가 아닌 스마트폰에서 LLM을 실행하기 위해, Unsloth·TorchAO·ExecuTorch를 조합하여 QAT로 미리 훈련하고, iOS와 Android에 .pte 형식으로 배포하는 전체 과정을 다룬다. 맥 환경에서 iOS 앱(etLLM)을, Java 17·Android SDK 환경에서 Android Llama 데모 앱을 빌드하고, 여기에 Qwen3-0.6B 등의 모델과 토크나이저를 연결해 실제로 채팅까지 동작시키는 것이 목표다.

로컬 LLM 폰 배포 전체 그림

이 내용의 핵심은 "훈련–양자화–모바일 배포"까지 한 번에 이어지는 워크플로우를 이해하는 것이다. 우선 Colab에서 Qwen3 0.6B 같은 모델을 Unsloth로 미세조정하면서 TorchAO의 QAT를 적용하고, 훈련이 끝난 모델을 ExecuTorch 포맷인 .pte 파일로 내보낸다.

그 다음 iOS에서는 etLLM 예제 앱, Android에서는 LlamaDemo 앱을 기반으로 빌드한 후, 이 앱에 .pte 모델과 토크나이저 파일을 연결해 실제로 기기에서 프롬프트를 입력하면 토큰이 생성되도록 만든다. 이 과정을 통해 약 40 tokens/s 수준의 속도로 Pixel 8과 iPhone 15 Pro 같은 기기에서 완전히 오프로딩된 LLM을 사용할 수 있다.

QAT 기반 폰 배포용 모델 훈련 개념

폰 배포의 핵심 기술은 QAT(Quantization-Aware Training)이며, 여기서는 TorchAO를 이용해 적용한다. 훈련 때 qat_scheme = "phone-deployment" 옵션을 주면, 내부적으로는 int8-int4 스킴을 사용하여 Linear 계층의 가중치를 INT4, 활성값을 INT8로 "흉내 내며" 학습한다.

훈련 중 계산은 16비트에서 수행되며, 실제 양자화는 훈련 이후에 진행된다. 이렇게 하면 단순 사후 양자화(PTQ)보다 정확도를 더 잘 보존하면서도, 실제 디바이스에 올렸을 때 모델 크기와 연산량을 크게 줄일 수 있다. 실제 예로 Qwen3-0.6B는 약 472MB 크기의 .pte 파일로 내보낼 수 있고, QAT 덕분에 원래 성능의 상당 부분(예시로 70% 수준)을 유지한 채로 휴대폰에서 빠르게 동작한다.

ExecuTorch와 .pte 포맷 이해하기

ExecuTorch는 Meta와 PyTorch가 만든 온디바이스 추론 런타임으로, Instagram·WhatsApp 같은 대규모 서비스의 휴대폰 내 ML 기능을 담당한다. 이 런타임은 CPU(XNNPACK), 다양한 SoC, Apple·Qualcomm·ARM·Meta Quest와 같은 다양한 하드웨어 백엔드를 지원하여, 동일한 모델을 여러 기기에서 재사용하기 좋은 형태로 추상화한다.

훈련이 끝난 Unsloth 모델은 ExecuTorch용으로 변환되어 .pte 포맷으로 저장된다. 이 파일은 모델 구조, 양자화된 가중치, 실행 그래프 등을 포함한 "배포용 번들"이며, iOS의 etLLM 앱과 Android의 LlamaDemo 앱은 바로 이 .pte를 읽어들여 추론을 수행한다. 따라서 Colab 단계의 최종 목표 산출물은 .pte와 토크나이저 파일 두 가지라고 보면 된다.

Colab에서 Qwen3 0.6B 폰 배포용 미세조정

실제 훈련 환경은 제공된 무료 Colab 노트북을 기반으로 한다. 먼저 Unsloth을 최신 버전으로 업데이트하고 TorchAO·ExecuTorch를 설치한다. 그 다음, 미세조정 스크립트에서 qat_scheme = "phone-deployment" 옵션을 지정하고, 필요한 경우 full_finetuning = True로 전체 파라미터를 업데이트하도록 설정한다.

훈련이 완료되면 모델을 ExecuTorch 포맷으로 내보내는데, 일반적으로 다음과 같은 결과물이 생성된다. 하나는 qwen3_0.6B_model.pte 같은 ExecuTorch 모델 파일이고, 다른 하나는 tokenizer.json(혹은 .bin, .model 등 토크나이저 형식)이다. 이 두 파일을 다음 단계의 iOS·Android 배포에서 공통적으로 사용한다.

iOS 배포: 개발 환경과 시뮬레이터 동작

iOS 배포의 첫 단계는 macOS 개발 환경을 준비하는 것이다. Xcode 15 이상을 Mac App Store에서 설치한 후, xcode-select --install로 커맨드라인 도구를 설치하고, sudo xcodebuild -license accept로 라이선스 동의까지 완료해야 한다. Xcode를 처음 실행할 때 요청되는 추가 컴포넌트 설치와 iOS 18 시뮬레이터 다운로드도 꼭 진행해야, 이후 빌드 시 에러를 줄일 수 있다.

ExecuTorch 예제 앱은 apple/etLLM.xcodeproj를 Xcode에서 열어 빌드한다. 대상 기기로 iOS 시뮬레이터(iPhone 16 Pro 등)를 선택하고 실행하면, etLLM 앱이 시뮬레이터에서 뜨지만 이 시점에는 모델이 없어 응답은 하지 않는다. 시뮬레이터는 개발자 계정 없이도 사용 가능하므로, 물리 기기가 없다면 이 환경만으로도 동작 확인을 할 수 있다.

iOS에서 모델 파일 연결과 실제 채팅

시뮬레이터에서 모델을 사용하려면 먼저 파일 앱에 공유 폴더를 만들어야 한다. 시뮬레이터 홈 화면에서 Files 앱을 열고, "On My iPhone" 영역에 예를 들어 Qwen3test라는 폴더를 생성한다. 이후 Mac과 시뮬레이터 사이 파일 복사를 위한 명령(예: xcrun simctl addmedia류)이나, 안내된 터미널 스크립트를 이용해 .ptetokenizer.json을 이 폴더로 전송한다.

전송이 끝나면 etLLM 앱을 다시 실행해서, 앱 안에서 파일 선택 인터페이스를 통해 Qwen3test 폴더의 모델과 토크나이저를 지정한다. 모델 로딩이 완료되면 프롬프트를 입력해 바로 채팅을 시작할 수 있으며, 이때 모든 추론은 시뮬레이터에 해당하는 "내장 iPhone 환경"에서 수행된다는 점을 기억하면 된다.

물리 iPhone 배포: 서명, 권한, 모델 전송

실제 iPhone에 앱을 올리려면 몇 가지 추가 단계가 필요하다. 먼저 iPhone을 Mac에 USB로 연결하고 "Trust This Device"를 허용한 뒤, Xcode의 Devices and Simulators 창에서 기기가 인식되는지 확인한다.

물리 기기 배포에는 개발자 서명이 필수이며, 특히 ExecuTorch 기반 앱은 "Increased Memory Limit" capability가 필요해 유료 Apple Developer Program 가입이 요구된다. Xcode 설정에서 Apple ID를 추가하고, 프로젝트의 Signing & Capabilities 탭에서 자동 서명 옵션을 활성화한 뒤, 팀을 선택하고 번들 ID를 고유한 값으로 바꾸어 프로비저닝 프로필 문제를 피한다. 이어서 "Increased Memory Limit" 기능을 추가해야 대형 LLM 모델 로딩 시 메모리 제한에 막히지 않는다.

첫 실행 때는 iPhone에서 Developer Mode를 켜야 하므로, Settings → Privacy & Security → Developer Mode에서 활성화하고 재부팅한다. 앱이 실제 기기에 설치되고 실행된 후, Finder에서 iPhone을 선택하고 Files 탭의 etLLM 항목에 .ptetokenizer.json 파일을 드래그 앤 드롭하여 전송한다. 전송이 끝나면 앱 내에서 해당 파일을 선택하고 모델을 로드해, 이제는 진짜 iPhone의 CPU에서 Qwen3를 실행하게 된다.

Android 배포: 최소 도구 기반 개발 환경

Android에서는 Android Studio 없이도, Java 17과 Android Command Line Tools, Gradle로 앱을 빌드할 수 있도록 안내한다. 먼저 java -version으로 버전을 확인하고, 꼭 17.x가 사용되도록 설정하거나 JAVA_HOME을 Java 17 설치 경로로 지정한다. 그 다음 Android SDK를 위한 디렉터리를 만들고, Command Line Tools를 설치해 필요한 SDK·NDK 컴포넌트를 추가한다.

환경변수로 ANDROID_HOME 혹은 ANDROID_SDK_ROOT, PATHplatform-tools·cmdline-tools 등을 설정한 뒤 쉘 설정 파일(.bashrc 또는 .zshrc)에서 로드한다. ExecuTorch 예제 코드 저장소(executorch-examples)를 클론한 후, 그 안의 Android LlamaDemo 프로젝트 디렉터리로 이동해 Gradle 빌드를 수행한다. 빌드 과정에서 SDK 위치 오류가 발생하면 local.properties 파일에 SDK 경로를 명시하고, 특정 메서드가 deprecated이어서 발생하는 cannot find symbol 오류는 안내된 패치 명령으로 수정할 수 있다.

Gradle 빌드가 성공하면 app-debug.apk 같은 디버그 APK가 생성된다. 이 APK는 ADB를 통해 바로 설치하거나, 원격 서버에서 빌드한 경우 폰으로 옮겨 "알 수 없는 출처 앱 설치"를 허용한 뒤 직접 설치할 수 있다.

Android에서 모델·토크나이저 연결과 ADB 활용

LlamaDemo 앱은 ExecuTorch .pte 파일과 토크나이저 파일을 필요로 하며, 이를 폰 저장소에 옮긴 뒤 앱 내에서 선택해야 한다. 간단한 방법은 .ptetokenizer.bin 혹은 tokenizer.model 파일을 PC에서 폰의 Downloads 폴더로 복사하고, 앱에서 파일 선택 화면을 열어 둘 다 지정하는 것이다. 모델과 토크나이저를 모두 선택해야 로딩이 정상적으로 이루어지며, 둘 중 하나라도 빠지면 로딩 실패나 앱 크래시가 발생할 수 있다.

다만 어떤 ExecuTorch 데모 앱 버전은 특정 내부 디렉터리에서만 모델을 읽을 수 있는데, 이 경로는 일반 파일 관리자에서 접근할 수 없다. 이 경우 ADB를 사용해 해당 디렉터리를 생성하고, adb push 명령으로 .ptetokenizer.json을 그 위치로 전달해야 한다. ADB 연결 시 폰에서 "이 컴퓨터를 신뢰할 것인지" 묻는 팝업이 반드시 뜨며, 이를 허용하지 않으면 디렉터리 생성·파일 푸시가 작동하지 않는다.

모델과 토크나이저가 올바른 위치에 올라갔다면, 앱 설정 화면의 Model·Tokenizer 선택 메뉴에서 파일명을 선택하고 모델 유형(Qwen3 등)을 맞춰준 뒤 "Load Model"을 눌러 모델을 메모리에 로드한다. "Successfully loaded model" 같은 메시지가 뜨면 채팅 화면에서 바로 프롬프트를 입력해 대화할 수 있고, 응답 생성 속도는 폰의 CPU·스토리지 성능에 따라 달라진다.

다른 지원 모델과 확장 가능성

이 워크플로우는 Qwen3-0.6B에 특화된 예시로 설명되지만, Unsloth와 TorchAO, ExecuTorch 조합 자체는 여러 모델에 확장 가능하다. Qwen3, Qwen2.5, Gemma3, Llama3, Phi4(특히 Mini 계열) 등 여러 아키텍처를 동일한 Colab 구조 안에서 QAT 스킴만 맞추어 사용하면 된다.

핵심은 두 가지다. 하나는 훈련 단계에서 "폰 배포를 염두에 둔 QAT 설정"을 사용하는 것이고, 다른 하나는 "ExecuTorch가 이해할 수 있는 .pte 포맷과 지원되는 백엔드(XNNPACK 등)로 내보내는 것"이다. 이 두 가지를 만족하면, 예제에서 사용하는 etLLM·LlamaDemo 앱을 약간만 수정해 다양한 모델을 비슷한 방식으로 iOS와 Android에서 실행할 수 있다.

인사이트

온디바이스 LLM 배포는 단순히 모델을 가볍게 만드는 문제가 아니라, 훈련, 양자화, 런타임, OS 권한과 개발자 서명까지 이어지는 "엔드 투 엔드 파이프라인"을 이해하는 과정이다. 실무에서 이 흐름을 재사용하려면, 먼저 Colab에서 QAT 스킴을 정확히 맞추어 .pte를 안정적으로 생성하는 것을 목표로 하고, 그 다음 iOS·Android 중 한 플랫폼에만이라도 예제 앱을 성공적으로 올려보는 것이 좋다.

처음에는 환경 설정과 빌드 오류가 가장 큰 장벽이 되지만, 한 번 셋업을 성공해 두면 이후에는 모델만 바꾸어 빠르게 다양한 온디바이스 LLM 실험을 반복할 수 있다. 특히 프라이버시, 지연 시간, 오프라인 사용성이 중요한 서비스라면, ExecuTorch 기반 폰 배포는 "클라우드만으로는 어려운 사용자 경험"을 구현하는 좋은 출발점이 될 수 있다.

출처 및 참고:

https://docs.unsloth.ai/new/deploy-llms-phone

이 노트는 요약·비평·학습 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.