Zenn
📱

iPad で、LLM を動作させる手順詳細(Deep Seek R1, Qwen , MLX)、オンデバイスAIに向けて

に公開

オートロ株式会社の代表をしております福田です。オートロとオープンでLLMの研究開発を行っております。前回の、Jetson Orin で LLM を動作させてみたことに引き続き、iPad で実行してみましたので、共有いたします。エッジデバイス、オンデバイスLLMをテーマに、現場で役に立つAIを開発していますので、今後ともよろしくお願いいたします。

さて、記事の方をご覧いただければと思います。詳細に手順を記述しているのでどなたでも再現できるようになっていると思います。いってらっしゃい。

概要

今回は、MLX形式のローカルLLMをiPadのアプリ内で動作させたときのトークン生成速度やRAM使用量を調査するために、サンプルアプリ「LLMEval」を使用して、簡単なプロンプトを実行する検証を行った。検証結果として、「Qwen2.5」と「DeepSeek-R1」については、パラメータ数7B以下のモデルであれば、11インチ iPad Pro (M4) Wi-Fiモデルで問題なく動作することが分かった。一方で、パラメータ数14Bのモデルについては、「Qwen2.5」は動作したものの、「DeepSeek-R1」使用時にアプリがクラッシュしてしまったため、安定して動作させることが難しいと考えられる。

また、開発用MacBook Pro(M2搭載、メモリ16GB)で実行したときと比べて、トークン生成速度(トークン/秒)はiPadの方が速く、RAM使用量(GB)については、ほとんど変わらないことが分かった。

簡単な質問への回答精度については、パラメータ数1.5Bのモデルでは不安定な回答が多いのに対し、7B, 14Bのモデルでは納得感のある回答が得られることが多いことが分かった。

動作の様子

フォーマットの都合上、GIF での共有となるが動作は以下のようになった。体感では GIF よりもスムーズに動作している。録画の都合上、WiFiのマークが表示されているが、外部のネットワークにアクセスしているものではなく、デバイス上で実行されていることを強調したい。

Deep Seek R1

推論過程もそのまま、 <think>...</think> で出力されるので結果までは時間がかかる。

deepseek ipad

Qwen 2.5

Qwen ipad

今回使用した端末について

端末情報

今回は、検証用端末として「11インチ iPad Pro (M4) Wi-Fiモデル」を使用した。以下にその詳細を示す。

iPad

公式サイトより引用

項目 スペック
機種 11インチ iPad Pro (M4) Wi-Fiモデル
容量 1TB
CPU 4つの高性能コアと6つの高効率コアを搭載した10コアCPU
GPU 10コアGPU
AI処理 16コアNeural Engine
RAM 16GB
サイズ 幅: 177.5 mm
高さ 249.7 mm
厚さ 5.3 mm
重量 444 g

Xcodeの環境構築

Xcodeとは

xcode

Xcodeとは、Appleが提供するmacOS向けの統合開発環境(IDE)である。開発したiOSアプリをiPhoneで動作させる主な方法として用いられている「App Storeへの公開」と「有線接続で端末へ直接インストール」のどちらでもXcodeが必要となるため、iOSアプリ開発には欠かせないツールとなっている。主な機能として、コードエディタ、インターフェースビルダー、シミュレーター、デバッガ、パフォーマンス解析ツールなどがあり、開発からテスト、デバッグまで一貫して行うことができる。XcodeはmacOS専用のアプリケーションであるため、Windows PCではそのまま使用することはできず、仮想マシンやクラウドベースのMac環境など、追加の環境構築が必要となる。

環境構築手順

MacOSのアップデート

Xcodeのインストールには、MacOSのアップデートを要求される場合がある。開発時点(2025/03/19)では、XcodeのインストールにmacOS14.5以降が必要である。

MacのPC画面左上のAppleマーク → システム設定 → ソフトウェアアップデート → 今すぐアップデートの順で選択することで、最新のバージョンにアップデートを行うことができる。

※ アップデートによっては、かなり時間がかかる場合がある。

Screenshot

Xcodeのインストール

Xcodeは、Apple Storeからもインストールが可能だが、今回は公式サイトからダウンロードしたため、その手順について説明する。

Apple Developerアカウントの作成

公式サイトページ下部のXcodeをダウンロードするを選択して、Apple IDでログインすると、Apple Developerへの登録を要求されるため、指示に従って登録する。

※ 今回は、公式サイトからXcodeをダウンロードするためにアカウントを作成しているため、Apple Developer Programへの登録は不要。

Xcodeのダウンロード

登録が完了したら、こちらのページからXcode(今回は16.2)をダウンロードする。

Xcodeの起動

ダウンロードからXcodeを展開する。その後、ApplicationにXcodeアプリを移動し、起動する。起動したら以下の画面が表示されるため、Agreeを選択後、パスワードを入力する。

Screen

次に、開発に必要な項目にチェックを入れて、インストールする。今回は、コード補完 2.51GB, iOSシミュレーター 8.72GBをインストールした。

xcode

インストールが完了すると、以下のような画面が表示される。

xcode startup

Xcodeの動作確認

プロジェクトの作成

Create New Project → Appの順で選択し、Nextを押下する。

image

以下のように入力後、Nextを押下して、テスト用プロジェクトを作成する。com.test というところは、自社で持っているドメインなどを利用すると良い。autoro.io の場合は、io.autoro.ios.xxxx のようにしている。

image

任意のフォルダ(今回はXcodeTest)にプロジェクトを保存する。

image

サンプルの実行

以下のような画面になったら、右下再生ボタンであらかじめ用意されたコードを実行する。Hello, World!とかかれたウィンドウが表示されたら正常に動作している。

sample app

iOSシミュレーターをインストールした場合、右下にある端末変更ボタン(初期時点ではMy Macと記載あり)でiPad等を選択し、シミュレーションも可能である。

hello world

プログラムの変更

以下のサンプルコードのように、ContentViewを書き換えることで別のコードも動作することを確認。

サンプルコード

import SwiftUI

struct ContentView: View {
    var body: some View {
        Text("Hello, World!")
            .font(.largeTitle)
            .padding()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

実行結果

MLX形式LLMモデルの実装

MLXとは

MLX Logo

MLXは、Appleシリコン向けに特別に設計された効率的な機械学習用配列フレームワークである。ローカルLLM実装において主流であるllama.cppと比較して対応モデル数が少ないものの、Apple製ハードウェアとの親和性が高く、高速・省メモリ・省電力でローカルLLMの推論が期待できる。huggingfaceのMLX Communityでは、MLX形式のモデルが公開されているため、今回は形式変換は行わず公開済みモデルをダウンロードして使用する。

実装手順(Mac)

今回は、iPadでローカルLLMを動作させるために、サンプルアプリ(LLMEval)をXcodeでビルドしiPadへ直接インストールする。そのため、まずはMac上でサンプルアプリをビルドし、MLX形式のLLMモデルが正常に動作することを確認する。

サンプルアプリ(LLMEval)の導入

サンプルアプリのダウンロード

以下のコマンドで、任意のフォルダにサンプルアプリを含むリポジトリをクローンする。

git clone https://github.com/ml-explore/mlx-swift-examples

Xcodeプロジェクトの起動

クローンできたら、mlx-swift-examples.xcodeproj を開く。

image

開発者アカウントの登録

次に、開発者アカウントの登録を行う。画面左から mlx-swift-example を選択後、画面中央のTARGETSでLLMEval を選択。Teamが None となっている部分をクリックすると、Add an account という項目があるので、そちらから自分の開発用アカウントでサインインする。

screen

開発者アカウントを未登録の状態で実行しようとすると、以下のようにエラーになるため注意。

screen

LLMEvalの実行

画面上部バー内でLLMEval → My Macを選択する。

screen

画面左上から再生ボタンを押下し、ビルドと実行が成功すると、以下のように新しいWindowが表示される。generateボタンを押して、プロンプトに対してテキストが生成されると、正常に動作している。

screen

エラーと対応方法

ファイルにアクセスできない

ContentView .swiftなどのファイルにアクセスできない場合は、Xcodeからのアクセスを許可する必要がある。

システム設定 → プライバシーとセキュリティ → フルディスクアクセス → +マークからXcodeを追加で対応する。

screen

iOSシミュレーターのビルドエラー

iOSシミュレーターでiPadを実行端末として選択して実行したところ、以下のようなエラーが発生した。

#endif
  return __builtin_strlen(__str); ///EXC_BAD_ACCESS A bad access to memory terminated the process
}

このエラーは、シミュレーターでのみ発生する事象と考えられるため、実機での評価が目的である今回は対応を見送る。

モデルの変更

デフォルトではQwen2.5の1.5Bモデルが設定されているが、ライブラリにすでに登録されているものは、簡単に変更することができる。

初めから登録されているモデル一覧

codeLlama13b4bit,
deepSeekR1_7B_4bit,
gemma2bQuantized,
gemma_2_2b_it_4bit,
gemma_2_9b_it_4bit,
llama3_1_8B_4bit,
llama3_2_1B_4bit,
llama3_2_3B_4bit,
llama3_8B_4bit,
mistral7B4bit,
mistralNeMo4bit,
openelm270m4bit,
phi3_5MoE,
phi3_5_4bit,
phi4bit,
qwen205b4bit,
qwen2_5_7b,
qwen2_5_1_5b,
smolLM_135M_4bit,

モデルの変更手順

今回は、DeepSeek-R1(deepSeekR1_7B_4bit)に変更する手順を説明する。

LLMEval > ContentView.swift の変数 modelConfiguration を以下のように変更する。

let modelConfiguration = ModelRegistry.deepSeekR1_7B_4bit

再度ビルドして実行すると、DeepSeek-R1にモデルが変更されている。

deepseek

モデルの追加

モデルの追加手順

ここでは、deepSeekR1_14B_4bitをライブラリに追加する手順について説明する。

以下のように、Libraries > MLXLLM > LLMModelFactory.swift にあるLLMRegistriy というクラスで新しい定数 deepSeekR1_14B_4bit を宣言する。

具体的には、deepSeekR1_7B_4bit の宣言部分をコピーし、定数名を deepSeekR1_14B_4bit 、idを “mlx-community/DeepSeek-R1-Distill-Qwen-14B-4bit” (hugging faceのモデル名)に変更する。

追加後、上述した手順でモデルの変更を行えば、ライブラリに追加したモデルを利用することができる。

screen
追加できないモデルもある

今回、gemma3を追加して実行したところ、ビルドは成功した一方で、モデルのタイプがサポートされていないと表示され、テキスト生成には失敗した。

 こちらの記事によると、内部パラメータ調整して読み込むためのコードを定義する必要があるようなので、今回は対応を見送る。

screen

モデルの設定変更

出力トークン制限の変更

デフォルトでは、LLMEval > ContentView.swift の定数 maxTokens で出力トークン制限が240に設定されている。今回は、DeepSeekR1の出力が長いことを考慮して、1000に変更した。

let maxTokens = 1000

実装手順(iPad)

LLMEvalのインストール

ここからは、iPadにLLMEvalをインストールする手順について説明する。

iPadとMacを接続

はじめに、有線(今回はUSB C to USB C)を用いてiPadとMacを接続する。

【Mac】接続すると画面上に以下のメッセージが表示されるので、接続を許可する。

screen

【iPad】以下のメッセージが表示されるので、コンピュータを信頼を選択し、パスワードを入力する。

ipad

LLMEvalのビルド

【Mac】Xcodeで利用する端末をMy Macから接続したiPadに変更する。

【iPad】iPadが認識されていない場合はiPadを再起動する。

screen

再起動後、端末が認識されるとエラーが解消される。

screen

【Mac】Xcode画面左上の再生ボタン押下しビルドを試みると、iPadでデベロッパーモードを有効化するように要求される。

ipad

【iPad】設定 → プライバシーとセキュリティ → デベロッパモード →でデベロッパーモードをチェックする。その後、画面の指示に従い再起動を行う。

ipad

再起動後には、デベロッパモードを有効にしてよいか確認されるので、「有効にする」を選択してパスワードを入力する。

※ デベロッパモードはセキュリティが低下するリスクがあるため、検証が終わったらオフにすることを推奨。

【Mac】再度LLMEvalを再生ボタンから実行すると、iPadへのLLMEvalのインストールが開始する

ipad

【iPad】画面上に信頼されていないデベロッパのため、デバイスを許可することを要求されるため、デバイス管理から設定する。

設定 → 一般 → VPNとデバイス管理 → デベロッパアプリの順で選択すると、Xcodeの開発者アカウントのメールアドレスが表示されているので、そちらを選択する。その後、青字で書かれている「”メールアドレス”を信頼」を選択する。これにより、LLMEvalが起動できるようになる。

※ 起動後はモデルのダウンロードによりテキスト生成が可能になるまで時間を要するため注意。また、モデル変更のボタン等は実装されていないため、新しいモデルを利用したい場合は、Xcode上でモデルを変更して再度実行 → インストールして上書きすることで対応を行った。一度iPad上で利用したモデルは、iPad内に保存されているようなので、次回からはロード時間なく使用することができる。

起動後の画面

ipad app

有効期限の確認

ビルドしたアプリには有効期限があり、Apple Developer Programに登録していないアカウントの場合は7日間、登録している場合は1年間となっている。有効期限については、Xcode上で確認ができる。
 サイドバーから、mlx-swift-exmaples を選択後、team でビルド用のチームを選択する。

screen

すると、以下のようにiOSの Provisioning Profilei のマークが表示されるので、クリックする。

screen

以下のように Expires in 〇〇 と有効期限が表示される。有効期限が切れた場合は、Xcodeで再度ビルドしてインストールし直す必要がある。

screen

検証

評価指標

今回は、サンプルアプリ上で表示されている「トークン生成速度(トークン/秒)」と「RAM使用量(GB)」評価指標を集計した。

使用モデル

今回の検証では、「Deepseek-R1」と「Qwen2.5」の2種類 × 各3サイズ(1.5B, 7B, 14B)の計6つのモデルを使用した。また、今回使用したモデルは、すべて4bit量子化されたモデルである。

  • Deepseek-R1
    • DeepSeek-R1は、中国のAI企業DeepSeekが2025年1月に発表した大規模言語モデルである。強化学習を活用した独自のトレーニング手法により、複雑な問題解決に優れた推論能力を持ち、回答だけでなく思考の過程も出力する特徴がある。
  • Qwen2.5
    • Qwen2.5は、Alibaba CloudのAI研究チームであるQwenが2024年9月に発表した大規模言語モデルである。すべてのモデルが最大18 兆トークンを網羅する最新の大規模データセットで事前トレーニングされており、日本語を含む29以上の言語に対応している。

検証方法

プロンプト一覧

今回は、以下に示す4つの簡単なプロンプトを実行し、評価指標であるトークン生成速度とRAM使用量、回答精度について評価を行った。

プロンプト 言語 内容
Hello. 英語 挨拶
List the days of the week. 英語 指示
こんにちは! 日本語 挨拶
りんごの色は何ですか? 日本語 質問

結果

評価指標

各モデルの評価指標の平均値を以下に示す。

Model Parameters
(B)
Output Speed
(tokens/sec)
RAM Usage
(GB)
DeepSeek-R1 1.5 90.01 0.97
DeepSeek-R1 7 23.66 4.01
DeepSeek-R1 14 強制終了 強制終了
Qwen2.5 1.5 88.12 0.83
Qwen2.5 7 23.54 4.00
Qwen2.5 14 12.16 7.79

検証によって、以下のことが分かった。

  • パラメータ数が7B以下のモデルは、問題なく動作した。
    • 開発用のMacBook Pro(M2搭載、メモリ16GB)上で実行させたときと比較すると、トークン生成速度はiPadの方が速く、RAM使用量はほとんど変わらなかった。
  • DeepSeek-R1_14B_4bitモデルは、11インチ iPad Pro (M4) Wi-Fiモデルで動作させることが難しい。
    • 原因は不明だが、回答生成中に端末がかなり熱くなったことやLLMEvalで使用できるメモリの上限に達したことなどが考えられる。

また、1.5Bにおいては、トークン生成速度が90→70(トークン/秒)程度に一時的に低下する現象が発生した。原因は不明だが、一度アプリを終了して再起動することで解消した。

回答精度

以下に、「りんごの色は何ですか?」に対する出力例を示す。

DeepSeek-R1:1.5B

嗯,用户问的是“りんごの色是什么?”我需要先理解这句话的意思。看起来用户可能在问“utsun”这个词,或者可能是在问“りんご”的颜色。但“utsun”通常是指utsun语,和中文无关,所以不太可能。再看看“りんご”的颜色,可能是指颜色,或者颜色对应的颜色。比如红色、黄色、蓝色等。或者“utsun”对应的颜色,比如红色。可能用户想了解utsun是什么,但utsun在中文里是utsun语,和颜色无关。或者用户可能在询问utsun的颜色,但utsun不是颜色。可能需要进一步确认用户的意思,或者提供一个常见的颜色,比如红色,因为utsun在中文里常常被描述为红色。或者可能用户在问utsun的颜色,但utsun不是颜色,而是汉字,所以可能需要解释。或者用户可能在问utsun的颜色,但utsun是汉字,不能有颜色。可能需要更多的信息,或者直接回答utsun是什么,但utsun在中文里是utsun语,不是颜色。可能需要确认用户的问题,或者提供一个常见的颜色,比如红色。
</think>

“utsun”(utsun语)在中文中是汉字,不是颜色。如果您的意思是“utsun的颜色”,那么“utsun”通常被描述为红色。如果你有其他问题,可以进一步说明!

DeepSeek-R1:7B

Okay, so I need to figure out what the color of the word "りんご" is. I know that "りんご" is the Japanese word for "plum." I've seen pictures of plums before, and I think they're usually red, but I'm not entirely sure. Maybe I should think about other languages or contexts where "りんご" is used. In some cases, I've heard people refer to plums as being a certain color, but I can't remember exactly. I should also consider if the color changes based on the type of plum, like whether it's a fruit from a tree or a different kind. Maybe I can recall seeing red plums in fall, which makes me think that's the common color. I don't think they're usually green or yellow. So, putting it all together, I'm pretty confident that "りんご" refers to a red fruit.
</think>

The color of "りんご" (plum) is red.

DeepSeek-R1:14B

クラッシュしたため、今回は未確認。

Qwen2.5:1.5B

りんごの色は、一般的に黄色い果物です。特に、その果皮の表面は薄い黄色に見えますが、果肉の中には白い部分があります。この白い部分は、りんごの果肉の中核(果核)の部分です。また、りんごの果皮が熟すと青色から黄色に変わり、さらに熟すと黄色が明るくなり、果肉が白くなります。ただし、果皮が薄い部分に黄みが入るりんごも見られ、この果皮は一般的に果肉と同色です。

Qwen2.5:7B

りんごの色は様々な種類によって異なりますが、一般的には赤や緑、黄などの色が考えられます。赤みがかった色のりんごや緑色のりんご、黄緑色のりんごなどがあります。また、熟れ具合によっても色が変化します。完全に熟したりんごはより深みのある赤色を示すことが多いです。

Qwen2.5:14B

りんごの色は主に赤や緑、黄などの色があります。しかし、品種によって様々な色や色の組み合わせがあります。例えば、ジョナゴールドは橙黄色を帯びた黄色いりんごで、フジは赤とグリーンの組み合わせが特徴です。

上記の結果から、パラメータ数が7B以上のモデルからは一般的な回答である「赤」を含めた正常な回答が得られたことが分かる。

まとめ

今回は、MLX形式に変換した「DeepSeek-R1」「Qwen2.5」の2種類のモデル(パラメーター数:14b↓, 4bit量子化)を「11インチ iPad Pro (M4) Wi-Fiモデル」にインストールしたアプリ上で動作させ、トークン生成速度やVRAM使用量について検証を行った。検証では、以下のことが分かった。

  • パラメータ数が7B以下のモデルは、問題なく動作する。
  • DeepSeek-R1_14B_4bitモデルは、11インチ iPad Pro (M4) Wi-Fiモデルで動作させることが難しい。

参考文献

Discussion

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