Zenn
👻

Llama.cppのデモアプリをCPU-onlyモードでビルドしてiPhoneにデプロイする

2025/02/21に公開
1

この記事ではllama.cppのデモアプリをCPU-onlyモードでビルドし、ローカルのiPhoneにデプロイして任意のモデルでテキストを生成する手順について記述する。

Overview

  • Llama.cppはiPhone上で動作するデモアプリをビルドする手順[1]を公開しているが、GPUでの実行は古いiPhoneのチップに対応していない→CPU-onlyモードでビルドするモンキーパッチを当てた
  • TinySwallow-1.5B-InstructをiPhone XR(Apple A12 Bionic)で動作確認した
  • 一般的なXCode上でのiPhoneアプリのビルド手順についても記載(Appendix A)

環境

  • iPhone: iPhone XR
  • Chip: Apple A12 Bionic
  • OS: iOS 18.3

背景: 古いiPhoneでllama.cppを動作させる場合の問題点

問題: Apple7 familyの命令セットに対応していない

Issue#4998によると、Llama.cppをApple Silicon上で動作させる場合は、MTLGPUFamily.apple7の命令セットに対応した A14, M1以降のデバイス[2, 3]が必要。それより古いデバイスでは以下のようなエラーが出てクラッシュする。

ml_metal_graph_compute_block_invoke: error: unsupported op 'MUL_MAT'
GGML_ASSERT: ggml-metal.m:779: !"unsupported op"

Issue: https://github.com/ggml-org/llama.cpp/issues/4998

確認方法

デバイスがApple7 familyの命令セットに対応しているかどうかはXCodeの画面上でLlama.cppがモデルをロードする時に表示されるログから確認できる。

simdgroup reduction support   = false <-- 未対応

ワークアラウンド

メインコミッターのGGは「これらのsimd_命令を使わないkernelを実装すれば本質的な対処になるが、公式に対応する予定はない」と回答している。

The only way is to implement the respective Metal kernels without using simd_ calls. It's not very difficult, but I don't plan on officially supporting it as it will increase the Metal code by a lot and I'm not convinced it will result in significant gains compared to CPU-only for these machines.

If somebody implements the kernels, we can put them in ggml-metal-intel.metal and have them build as a separate backend for Intel machines

source: https://github.com/ggml-org/llama.cpp/issues/4998#issuecomment-1898421820

従って、本手順ではワークアラウンドとしてCPU-onlyモードで実行させることを目標にする。

アプリのコード修正

以下の1~4のコードを修正してCommand+Rでアプリをビルドする。

1. issue #7085 に対応したcommit hashをチェックアウトする

git clone https://github.com/ggerganov/llama.cpp
git checkout 2c3ffd2944ccfb656d686ccd79edc04c311e6cac

issue: https://github.com/ggml-org/llama.cpp/issues/7085
PR: https://github.com/ggml-org/llama.cpp/pull/4794

2. CPU-onlyモードで動作するようコードを書き換える

CPU-onlyで動作させる。具体的には以下の#if, #endifをコメントアウトしてn_gpu_layers=0に設定する。

https://github.com/ggml-org/llama.cpp/blob/1174def5dce7f76d9ae23b192baa7b294478d8b2/examples/llama.swiftui/llama.cpp.swift/LibLlama.swift#L57-L60

変更後:

//#if targetEnvironment(simulator)
        model_params.n_gpu_layers = 0
        print("Running on simulator, force use n_gpu_layers = 0")
//#endif

3. (Optional)出力テキストのコンテキスト長を延長する

デフォルトだとcontext_len=64なので512に延長する。

https://github.com/ggml-org/llama.cpp/blob/1174def5dce7f76d9ae23b192baa7b294478d8b2/examples/llama.swiftui/llama.cpp.swift/LibLlama.swift#L33

変更後:

    var n_len: Int32 = 512

4. (Optional)モデルを追加する

デフォルトだと使用するモデルが限られているのでコードを編集してTinySwallow-1.5B-Instructを追加する。

https://github.com/ggml-org/llama.cpp/blob/1174def5dce7f76d9ae23b192baa7b294478d8b2/examples/llama.swiftui/llama.swiftui/Models/LlamaState.swift#L66-L102

Modelの定義にTinySwallow-1.5B-Instruct(Q5_K_M)を追加する。

        Model(
            name: "TinySwallow-1.5B-Instruct (Q5_K_M, 1.13 GiB)",
            url: "https://huggingface.co/SakanaAI/TinySwallow-1.5B-Instruct-GGUF/resolve/main/tinyswallow-1.5b-instruct-q5_k_m.gguf?download=true",
            filename: "tinyswallow-1.5b-instruct-q5_k_m.gguf", status: "download"
        )

ref: https://huggingface.co/SakanaAI/TinySwallow-1.5B-Instruct-GGUF

実行時のTips

1. チャットテンプレートの適用

デモアプリではチャットテンプレートの自動付与機能がないため自分で追加する必要がある。
TinySwallowのデモアプリの公式ページに従って、以下のテンプレートを適用する。

[system](あなたは、Sakana AI株式会社が開発したTinySwallowです。小型ながら、誠実で優秀なアシスタントです。)
<|im_start|>user
{{prompt}}<|im_end|>
<|im_start|>assistant

ref: https://github.com/SakanaAI/TinySwallow-ChatUI/blob/main/docs/iphone.md

2. XCodeを落としてiPhoneから実行

公式手順[1]に以下のような説明がある。

Stop Xcode and run the app from the device. This is important because the performance when running through Xcode is significantly slower

具体的には以下のようにする。

  1. Xcode 上で実行を停止
    • Xcode 上部の 停止ボタン (■) をクリック
  2. Xcode を終了
    • Command + Q でXcodeを完全に終了
  3. iPhone のホーム画面からアプリを起動
    • iPhone のホーム画面にアプリアイコン が表示されているので、タップして起動

参考: 生成速度の違い

XCodeありとなしでは実際に生成速度にかなりの差があった。

  • XCodeあり: 5分52秒
  • XCodeなし: 1分22秒

アプリ実行手順

  1. iPhone上からアプリを起動する
  2. View ModelからTinySwallow-1.5B-Instructの量子化モデルをダウンロードする。ダウンロードが終わったらもう一度クリックしてロードする。
  3. Backで元の画面に戻り、テキストボックスにプロンプトを貼り付ける
  4. Sendを押す

実行結果

プロンプト

[system](あなたは、Sakana AI株式会社が開発したTinySwallowです。小型ながら、誠実で優秀なアシスタントです。)
<|im_start|>user
機械学習モデルの正則化にはどのようなアプローチがある?<|im_end|>
<|im_start|>assistant

生成結果

機械学習モデルの正則化には、主に以下のアプローチがあります。

  1. L1正則化 (Lasso):重みの絶対値の合計をペナルティとして加えることで、モデルの複雑さを抑制します。過学習を防ぎ、重要な特徴量を抽出するのに有効です。
  2. L2正則化 (Ridge):重みの二乗の合計をペナルティとして加えることで、モデルの複雑さを抑制します。L1正則化よりも汎化性能が優れている傾向があります。
  3. Dropout:ニューラルネットワークの学習中に、ランダムに一部のニューロンを無効化することで、過学習を防ぎます。
  4. Weight Decay:重みの初期値を制限することで、モデルの複雑さを抑制します。
  5. Early Stopping:検証データの性能が低下し始めたら、学習を停止することで過学習を防ぎます。

これらのアプローチは、単独で使用することも、組み合わせて使用することもできます。最適なアプローチは、問題の性質やデータセットによって異なります。

生成時間: 1分50秒
内容の評価: 「L2正則化がL1正則化より汎化性能が優れている」は一般化しすぎなのと、Weight Decayの説明は誤り。それ以外は概ね的確なことを言っている。

Summary

  • 本記事ではLlama.cppをCPU-only modeで動作させる手順をiPhone XR(Apple A12 bionic)で動作確認した
  • iPhone XR+CPUでの1.5Bモデル(Q5_K_M)の実行速度はあまり実用的でない(簡単な応答に2分程度かかる)
  • Llama.cppをAppleデバイスのGPUで動作するにはA14/M1以降のチップが必要。それより古いチップのGPUで動作させるには自分でKernelを実装する必要がある

Reference

Appendix

A. XCodeからローカルのiPhoneにアプリをデプロイする手順

A-1. 事前にやっておくこと

  1. Apple Developerアカウントの登録
  2. iPhoneの接続(Wi-Fi or USB)
  3. XCodeのインストール

A-2. XCode側の設定

a. Apple IDの登録
  1. Xcodeを起動
  2. メニューから Xcode > Settings (または Preferences) > Accounts を選択
  3. 左下の + ボタンをクリックし、Apple ID を選択してサインインする
b. Bundle Identifier の設定
  1. Project Navigator からプロジェクト名をクリック
  2. TARGETS の下にあるプロジェクトを選択
  3. General タブ内の Bundle Identifier を確認(例: com.example.myapp)
c. チームの設定
  1. Signing & Capabilities タブを開く
  2. Team を設定
    自分のApple IDを選択
    初回のみ、「Provisioning Profile」を自動で作成するため、XcodeがAppleにアクセスする
d. Release Buildの設定
  1. Xcode の上部メニュー から、Product > Scheme > Edit Scheme... を選択
  2. Edit Scheme ウィンドウ が表示される
  3. 左ペインの Run を選択
  4. Info タブを選択
    • Build Configuration: "Release" を選択
    • Debug executable: チェックを外す

A-3. iPhoneのデバイス登録

a. デバイスの信頼設定
  1. iPhoneをUSBケーブルで接続
  2. iPhone上で「このコンピュータを信頼しますか?」と表示されたら「信頼」を選択し、パスコードを入力
  3. Xcode上部の Device選択メニュー から、接続したiPhoneを選択
b. デバイスの信頼確認 (iPhone 側)
  1. 初回デプロイ時、iPhone側で 設定 > 一般 > VPNとデバイス管理 に移動
  2. 自分のApple IDを選択し、「信頼」をタップ

A-4. ビルドとデプロイ

  1. Xcode 上部の 再生ボタン (▶️) をクリック
  2. または、Command + R を押す
  3. ビルドが成功すると、iPhone上でアプリが起動する
GitHubで編集を提案
1

Discussion

ログインするとコメントできます