
今週もTech Blogの時間がやってまいりました。本日は DX Solution 事業本部 Dev の許が担当いたします。
さて今年はローカルLLMの性能が話題になることが多いですね。
DeepSeek R1 によるDeepSeekショックに始まり、Gemma 3、QwQ、Phi-4、Llama 4など……。
しかもあのOpenAIが、GPT-2以来6年ぶりにオープンウェイトなモデルを公開するとのこと。
TL;DR: we are excited to release a powerful new open-weight language model with reasoning in the coming months, and we want to talk to devs about how to make it maximally useful: https://t.co/XKB4XxjREV
— Sam Altman (@sama) 2025年3月31日
we are excited to make this a very, very good model!
__
we are planning to…
期待していいんだな、アルトマン……!
オープンウェイトなローカルLLMの性能も全体的に上がり、ご家庭のPCでも少し前のGPT-4レベルのLLMが動く時代に。
最近のモデルだと、Gemma 3の27Bモデルがおすすめで、日本語でもかなり自然な対話ができているように感じます。
一昔前のローカルLLMと違い、会話に違和感に覚えることが日に日に少なくなっている、というのが現状です。
PCでローカルLLMがある程度動くようになってきたなら、次に気になるのは普段持ち歩くデバイスで動くかどうか。
そう、スマートフォン上でどれくらい動くかということですね。
ということで、本記事はGemma 3の4B モデルなどの小型モデルを実際にスマートフォン上で動かした記事になります。
スマートフォンで動かせるローカルLLMについて、皆様の解像度が上がれば幸いです。
スマートフォンで動かせるLLMのサイズは?
モデルにもよりますが、おおまかな目安としてパラメーターサイズのBを取った数値の、2倍〜2.5倍程度のメモリがあれば16bitのものが動きます。
量子化するとおおよそ量子化の値に比例して必要メモリが少なくなります。
あるいは、モデルのGGUF自体のファイルサイズ+1GB程度のメモリがあれば最低限動きます。
例えばGemmaやLlamaモデルを読み込むのに必要なメモリの推定値は以下のとおりです。


実機で動かす場合、バックグラウンドで他のアプリも動作していることが考えられるため、数GB程度の余裕がほしいところです。
最新のiPhone16であれば8GBのメモリがあるため、ファイルサイズが4GB程度のGGUFくらいまでなら動く、というのが目安でしょう。
Gemma 3の4Bモデルであれば、8bit量子化がギリギリ動くか動かないかくらいでしょうか。
(直近3年以内に発売されたiPhoneならメモリ6GBのものが多く、その場合Gemma 3の4Bモデルの4bit量子化がギリギリ動くくらいになります。)
サクッと動かしたいならスマホアプリで
ではどうやって動かしていくかというと、オープンソースのスマホアプリが公開されているのでこちらを使うのがおすすめです。*1
2025/4 現在でのおすすめは PocketPal AI と LLMFarm。
どちらもMITライセンスでリポジトリが公開されており、コードの中身まで確認できるため、ユーザーとしては安心、開発者としてはカスタマイズ*2できていいですね。
アプリとしてはPocketPal AI のほうが更新頻度が高いため、最新のモデルを動かしたいだけならこちらがおすすめです。
内部的にはどちらもllama.cppを推論用ライブラリとして使用しています。
llama.cppは初代LLaMAが公開された直後の2023/3からある古参の推論用ライブラリで、かつ今でも更新が活発なライブラリ。
Gemma 3が発表された3/12も、その日のうちにGemma 3のテキスト生成に対応させるPRが出ています。
動かした結果
それでは実際にPocketPal AIを使い、ローカルLLMを動かしてみましょう。
今回動かすのはGemma 3 の4Bを量子化したモデルです。
GGUFへの変換はllama.cppを使って自分で変換してもいいですが、unslothなどがGGUFに変換したものがあるので、こちらをurl指定してダウンロードしましょう。


DLが完了したら、使用したいモデルを選ぶだけです。
それではAIに対する代表的な質問をぶつけてみましょう。
Q. 「3.9 と3.11 はどちらが大きい?」

Q. 「レースで3位の人を抜かしました。今何位?」

Q. 「2キロの羽と1キロのレンガはどちらが重い?」

代表的なひっかけ問題も、惑わされることなく回答できていますね。
数学の問題はどうでしょうか。
Q. 「次の数列の規則性を見つけ、次の数を答えよ:2, 6, 12, 20, 30, ?」

階差数列の問題も解けています。
コーディングはどうでしょう。
Q. 「10番目のフィボナッチ数列を求めるためのpython コードを書いて」
def fibonacci(n): """ n番目のフィボナッチ数列を計算する関数 Args: n: 求めるフィボナッチ数列の項数 (n >= 0) Returns: n番目のフィボナッチ数列の値を返す """ if n <= 1: return n else: a, b = 0, 1 for _ in range(2, n + 1): a, b = b, a + b return b # 10番目のフィボナッチ数列を計算 result = fibonacci(10) print(f"10番目のフィボナッチ数列は: {result}")*コードの説明:
*`fibonacci(n)` 関数:
`n` を引数として受け取ります。これは、求めるフィボナッチ数列の項数を表します。
`n` が 0 または 1 の場合、`n` 自体を返します (0番目、1番目のフィボナッチ数列はそれぞれ0、1です)。
それ以外の場合、`a` と `b` をそれぞれ 0 と 1 で初期化します。これらは、フィボナッチ数列の最初の2つの値を表します。
`for` ループを使用して、2番目から `n` 番目までの項を計算します。
ループ内で、`a` と `b` を更新します。`a` は前の `b` になり、`b` は前の `a` と `b` の合計になります。
ループが完了したら、`b` の値を返します。これは、`n` 番目のフィボナッチ数列の値です。
*`result = fibonacci(10)`:
`fibonacci()` 関数を呼び出し、10番目のフィボナッチ数列を計算します。
結果を `result` 変数に格納します。
*`print(f"10番目のフィボナッチ数列は: {result}")`:
結果を画面に出力します。
*実行結果:10番目のフィボナッチ数列は: 55
簡単なコードなら書けそうです。
動作速度のイメージとしては、長い回答の場合は5トークン/秒、短い回答の場合は10トークン/秒程度です。(今回使用したのはiPhone 15 Pro Max、メモリは8GB)

一方で、日本の地理などの知識問題は苦手なようです。

小型モデルゆえの知識量の制約があるとはいえ、
スマートフォンで動作可能な4Bモデルが、自然な会話を成立させる性能に達しているという状況に技術の進歩を感じますね。
