데보션앱 소개페이지 바로가기
로그인 선택

신고하기

CLOSE
신고사유 (대표 사유 1개)
상세내용 (선택)
0/200
  • 신고한 게시글은 더 이상 보이지 않습니다.
  • 이용약관과 운영정책에 따라 신고사유에 해당하는지 검토 후 조치됩니다.
  • 허위 신고인 경우, 신고자의 서비스 이용이 제한될 수 있으니 유의하시어 신중하게 신고해 주세요.
(이 회원이 작성한 모든 댓글과 커뮤니티 게시물이 보이지 않고, 알림도 오지 않습니다.)

미리보기

커뮤니티

      1,234

      badge 23.06.15

      글 등록

      카테고리를 선택해주세요.

      DEVOTEE를 활성화 시키면
      지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.

      버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.

      임시저장함에 저장되었습니다. 저장일시 : 2022.5.17 14:29:08

      임시저장함

      제목을 선택하시면 이어서 작성이 가능하며,
      최대 20건까지 저장합니다.
      컨텐츠 유형, 제목, 저장일시, 삭제로 이뤄진 임시저장 목록
      컨텐츠 유형 제목 저장일 삭제

      데보션 블로그 게재 요청

      CLOSE
      • *
      • *

      본인인증

      효율적인 데보션 서비스 이용 및
      고객님의 소중한 개인정보보호를 위해
      본인인증을 진행해주세요. 본인인증 미 진행 시 로그인이 제한됩니다.
      본인인증 실패

      본인인증 로그인에 실패하였습니다.
      회원이 아니시거나 본인인증 등록이
      완료되지 않은 사용자입니다.

      회원정보 연결

      안드로이드에서 On-Device로 Gemma 1 & 2 실행하기

      shkwak 24.09.25
      9,252 11 0
      DEVOTEE 요약
      본 블로그는 기존 글에서 다루지 않은 On-Device에서 Gemma 모델을 실행하는 방법을 안내합니다. Gemma 모델의 장점은 개인정보 보호, 인터넷 연결 없이 사용 가능, 서버 운영 비용 절감 등입니다. MediaPipe와 MLC LLM을 활용하여 안드로이드 디바이스에서 Gemma1, Gemma2 모델을 설정하고 실행하는 방법을 상세히 설명합니다.
      DEVOTEE 추천 블로그

      기존 Gemma 포스팅

      데보션에 이미 여러 분들이 Gemma에 관한 포스팅을 해주셨습니다.

      Gemma에 관해 생소하시다면 아래 포스팅들을 먼저 읽어보시면 좋을 것 같습니다. 여기서는 기존에 다루지 않은 On-Device 상에서 Gemma 모델을 실행하는 방법에 대해서 다루겠습니다.

      On-Device 모델의 장점

      ChatGPT 같이 이미 거대하고 성능이 좋은 모델들이 많이 출시된 상황인데 On-Device로 LLM 모델(LLM를 작게 줄여서 sLLM이라고도 함)을 사용해야 할 필요가 있을까 하는 생각이 들 수도 있습니다.

      하지만 On-Device에서 동작하는 경우엔 다음과 같은 장점들을 갖추고 있습니다.

      • 민감한 개인정보를 서버에 전송할 필요가 없습니다.

      • 인터넷이 연결되지 않은 환경에서도 사용할 수 있습니다.

      • 따로 서버 운영 비용을 감당하지 않아도 됩니다.

      더불어 특정 용도에 맞게 적절히 파인튜닝시키면 거대한 LLM 모델과 비슷하거나 더 좋은 성능을 낼 수 있다고도 합니다.

      디바이스 성능은 지속적으로 향상되고 있고 On-Device로 LLM 모델을 돌리기 위한 노력들도 계속되고 있기 때문에 앞으로 더욱 발전할 것으로 기대되는 분야입니다.


      MediaPipe를 통한 Gemma 모델 실행

      MediaPipe는 구글에서 개발된 AI/ML 관련 라이브러리로 올해 초 생성형 AI 기능들이 추가되었고 Gemma 같은 LLM 모델들을 실행시킬 수 있게 되었습니다.

      여기서는 MediaPipe를 통해 Gemma 모델을 한번 실행해 보겠습니다.

      MediaPipe GenAI의 minSDK는 Android 7.0(API Level 24)이고 디바이스에 대한 최소 요구 사항은 명시되어 있지 않지만 개인적으로 확인했을 때는 Galaxy S10에서도 원활하게 동작하였습니다.


      MediaPipe 환경 셋팅

      샘플 소스 코드를 다운로드합니다.

      git clone https://github.com/google-ai-edge/mediapipe-samples

      Android Studio에서 examples/llm_inference/android 프로젝트를 오픈합니다.

      app/build.gradle.kts에서 com.google.mediapipe:tasks-genai 라이브러리를 확인합니다.

      현시점 최신 버전은 0.10.14 이지만 긴 프롬프트에 대해선 이상한 응답을 생성해내고 있어서 0.10.11 사용을 권장합니다.

      dependencies {
          implementation 'com.google.mediapipe:tasks-genai:0.10.14'   // 최신 버전에서 문제 있을 시 0.10.11 버전 사용 권장
      }

      https://www.kaggle.com/models/google/gemma/tfLite에 접속하여 TensorFlow Lite용으로 변환되어 있는 Gemma 모델을 다운로드 받습니다.

      추천하는 모델은 gemma-1.1-2b-it-gpu-int4.bin 입니다.

      디바이스에 임의의 디렉토리를 생성하고 다운로드 받은 모델을 복사합니다.

      adb shell mkdir -p /data/local/tmp/llm/
      adb push gemma-1.1-2b-it-gpu-int4.bin /data/local/tmp/llm/gemma-1.1-2b-it-gpu-int4.bin

      Inference.kt 파일에 llmInference 생성 부분이 있는데 아래와 같은 형식으로 사용할 수 있습니다.

      val options = LlmInferenceOptions.builder()
              .setModelPath("/data/local/tmp/llm/gemma-1.1-2b-it-gpu-int4.bin")
              .setMaxTokens(1000)
              .setTopK(40)
              .setTemperature(0.8)
              .setRandomSeed(101)
              .setResultListener { partialResult, done ->
                  _partialResults.tryEmit(partialResult to done)
              }
              .build()
       
      llmInference = LlmInference.createFromOptions(context, options)

      modelPath는 모델의 위치입니다.

      maxTokens는 최대 토큰(입력+ 출력) 길이입니다. 만약 maxTokens를 1000으로 설정한 상태에서 입력토큰이 700개 들어오면 최대 300개 토큰을 출력으로 생성해냅니다.

      topK는 토큰을 생성하는 단계에서 사용되는 값으로서 가능성 높은 k개의 토큰중에서 하나를 선택하게 됩니다. setRandomSeed와 함께 사용됩니다.

      temperature는 값이 클 수록 무작위성이 증가하면서 좀 더 창의적인 결과가 나오고 값이 작을 수록 좀 더 일관성 있는 결과들이 나옵니다. setRandomSeed와 함께 사용됩니다.

      randomSeed는 토큰을 선택할 때 사용하는 시드값입니다.

      resultListener는 생성된 결과를 전달 받을 리스너입니다. 비동기적으로 결과를 전달 받을 때 사용되는데 partialResult는 String형으로 새로 추가되는 결과를, done은 boolean형으로 마지막(프롬프트에 대한 응답의 끝)인지 여부를 나타냅니다.


      마지막으로 텍스트 생성 호출은 다음과 같이 수행합니다.

      val result = llmInference.generateResponseAsync(inputPrompt)

      참고로 입력창의 문자열을 전달할때 화면상에서 표시는 안되지만 실제로는 대화형 형식에 맞춰서 앞 뒤에 아래와 같이 토큰들이 덧붙여져서 전달됩니다.

      <start_of_turn>user
      입력메시지<end_of_turn>

      이전 대화 이력이 있다면 아래와 같이 전달됩니다.

      <start_of_turn>user
      입력메시지1<end_of_turn>
      <start_of_turn>model
      응답메시지1<end_of_turn>
      <start_of_turn>user
      입력메시지2<end_of_turn>


      Gemma 모델 실행 & 테스트

      질문을 한번 해 보겠습니다. Gemma 모델은 다국어 데이터셋을 통해 학습되었기 때문에 한글로 질문해도 답변을 곧잘 해냅니다.

      다만, 영어로 질문했을 때보다는 정확도가 떨어지는 답변을 하는 경우가 많습니다.




      MLC LLM을 통한 Gemma2 모델 실행

      최근 기존 Gemma 보다 성능이 더욱 좋아진 Gemma2가 발표되었습니다.

      현재 MediaPipe를 통해서 Gemma2 모델을 실행시킬 수는 없습니다.

      여기선 MLC LLM라는 엔진을 통해서 Gemma2 모델을 안드로이드에서 실행시켜 보겠습니다.

      MLC LLM 샘플 앱의 minSDK는 Android 8.0(API Level 26)이고 Galaxy S23 같은 최신폰에서 테스트되었다고 나와 있습니다.

      개인적으로 Galaxy S10에서 실행해 보니 출력속도가 MediaPipe에서 Gemma1 모델을 실행할때 보다는 많이 느렸습니다. (짧은 질문에도 첫 출력에 20~30초 정도 소요)


      참고: 빌드없이 단순히 실행만 해보고 싶으시면 https://github.com/mlc-ai/binary-mlc-llm-libs/releases/ 에서 apk를 받으셔도 됩니다.


      MLC LLM 환경 셋팅

      아래 명령어로 Rust를 설치합니다.

      curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

      설치 후에는 PATH 환경 변수를 다시 불러오도록 shell을 다시 시작합니다.


      Android Studio의 SDK Manager를 통해 NDK 및 Cmake 최신 버전을 설치하고 아래 환경 변수를 설정합니다.

      export ANDROID_NDK=~/Library/Android/sdk/ndk/27.0.12077973
      export TVM_NDK_CC=$ANDROID_NDK/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android24-clang

      빌드 중 cmake 명령어를 찾지 못하는 경우가 있어서 아래와 같이 cmake 위치를 PATH에 추가해줍니다.

      export PATH=$PATH:~/Library/Android/sdk/cmake/3.22.1/bin

      JAVA_HOME이 설정되어 있지 않은 경우 JDK(17이상) 위치를 JAVA_HOME에 설정합니다

      export JAVA_HOME=/Applications/Android\ Studio.app/Contents/jbr/Contents/Home

      MLC LLM Python 패키지를 설치합니다. (conda 환경에서 설치하는 것을 권장합니다.)

      python -m pip install --pre -U -f https://mlc.ai/wheels mlc-llm-nightly mlc-ai-nightly

      소스 코드를 다운로드합니다.

      git clone https://github.com/mlc-ai/mlc-llm.git
      cd mlc-llm
      git submodule update --init --recursive

      런타임 라이브러리를 빌드합니다.

      cd android/MLCChat
      export MLC_LLM_SOURCE_DIR=$PWD/../../    # mlc-llm에 대한 경로
      export TVM_SOURCE_DIR=$MLC_LLM_SOURCE_DIR/3rdparty/tvm
      mlc_llm package

      dist/lib/mlc4j/output에 tvm4j_core.jar와 arm64-v8a/libtvm4j_runtime_packed.so 파일이 생성된 것을 확인합니다.

      Android Studio에서 android/MLCChat 프로젝트를 열어서 실행을 시킵니다.


      Gemma2 모델 실행 & 테스트

      실행하면 사용할 수 있는 모델 리스트가 나오는데 여기선 gemma-2-2b-it-q4f16_1-MLC 모델을 다운로드 한 후 선택합니다.



      앞에서 했던 질문을 다시 해 보겠습니다. Gemma2 모델은 기본 Gemma 모델보다 더 좋은 품질의 결과가 나오는 것을 확인할 수 있습니다.



      마무리

      지금까지 안드로이드에서 Gemma1 및 Gemma2 모델을 실행하는 법에 대해서 알아 보았습니다.

      파인튜닝과 MediaPipe용 모델변환은 구글에서 제공하는 변환 스크립트의 오류를 좀 더 검토한 뒤에 다음 포스팅에서 추가로 다룰 예정입니다.

      On-Device로 LLM 모델을 실행시킨다는 것이 아직은 부족한 점이 있지만 미리 한번 경험해보셔도 좋을 것 같습니다.


      Reference

      댓글 0

      DEVOTEE를 활성화 시키면
      지금 작성한 댓글에 AI가 댓글을 달아줍니다.

      shkwak 님의 최신 블로그

      더보기

      DEVOTEE 추천 블로그

      동영상 기고하기