AI公開 データ取得日

スマホで小型 LLM を10分動かし続けると遅くなるのか。この端末では、生成速度に明確な低下は見られなかった(Qwen2.5 0.5B・1.5B)

スマホで小型の言語モデルを動かし続けると、途中から遅くなるのか。この記事では、その問いを自分の端末で確かめた。Qwen2.5 の 0.5B と 1.5B(どちらも Q4_K_M)を llama-bench で10分間連続で動かし、1分ごとの生成速度(tokens/s)と、同じ時間の温度・CPU 周波数の読みを記録した。モデルごとに5セット、計10セットだ。

この端末・この条件では、10分間の連続生成で生成速度が明確に落ちる様子は見られなかった。 0.5B は約20 tokens/s、1.5B は約10 tokens/s で、5セットの中央値は1分目から10分目までほぼ横ばいだった。10分目の中央値を1分目と比べた比は、5セットの中央値で 0.5B が 0.99、1.5B が 0.94 だった。落ちたと言えるのは電池駆動の 0.5B・2 の1セットだけで、そのセットは速度が大きく揺れていた。温度や周波数の読みとの関係は、速度が落ちていないので「同じ時間に落ちた」とは言えない。

測ったのは 2026-10-02 の1台の端末だけで、10分までの話だ。他の端末・他のモデル・もっと長い時間には当てはめられない。

何を確かめたか

最初の問いは次のとおりだ。

  • スマホで小型 LLM を連続で動かし続けると、生成速度は何分ごろからどれだけ落ちるのか。落ちるとして、端末の温度の上昇と同じ時間に起きているのか。

測る前に、編集部は次の予想を記録していた(予備確認の前に、値を見ずに立てたもの)。

  • 生成速度は最初の数分で下がり始め、10分後には最初の1分の中央値より1割以上低くなるのではないか。
  • 大きいモデル(1.5B)の方が落ち幅が大きいのではないか。

この予想がどうなったかは、後の「予想に照らすと」の節に書く。

結果: 速度は10分間ほぼ横ばいだった

次の表は、セットごとの1分目と10分目の生成速度(その分に終わった測定の中央値)と、その比だ。「最後の3分/最初の3分」は、最初の3分間と最後の3分間(8〜10分)の測定をそれぞれまとめた中央値の比で、1分だけの値に左右されにくくするために付けた。「2〜9分の幅」は、途中の分ごとの中央値の最小〜最大だ。

モデル・セット 充電 1分目 10分目 10分目/1分目 最後の3分/最初の3分 2〜9分の幅
0.5B・1 電池 15.2 19.3 1.27 1.11 14.0〜20.4
0.5B・2 電池 22.1 15.2 0.69 0.67 4.7〜21.8
0.5B・3 AC 20.4 19.4 0.95 1.00 20.3〜20.6
0.5B・4 AC 20.3 20.1 0.99 0.99 19.5〜20.3
0.5B・5 AC 21.1 20.8 0.99 1.00 20.7〜21.2
1.5B・1 電池 10.5 9.0 0.85 1.01 9.1〜10.1
1.5B・2 電池 11.0 9.6 0.87 0.95 6.9〜10.5
1.5B・3 AC 10.2 10.0 0.97 1.00 9.9〜10.1
1.5B・4 AC 10.1 9.6 0.96 0.99 10.0〜10.1
1.5B・5 AC 11.2 10.5 0.94 0.99 10.0〜10.5
  • 速度の単位は tokens/s(生成64トークン)。「充電」は各セットの開始時の状態で、どのセットも測定中に変わらなかった。
  • 5セットの中央値(比)は、10分目/1分目が 0.5B で 0.99、1.5B で 0.94。最後の3分/最初の3分が 0.5B で 1.00、1.5B で 0.99。

1分ごとの生成速度を、5セットの中央値で結ぶと次のとおりだ。

Qwen2.5 の 0.5B と 1.5B(どちらも Q4_K_M)を llama-bench で10分連続で回したときの、1分ごとの生成速度(tokens/s)。5セットの1分ごとの中央値を結んだ線。0.5B は 19.4〜20.5 の間で、1.5B は 9.6〜10.5 の間で動き、どちらも右下がりの傾向は見えない。1.5B は10分目が 9.6 で、ほかの分より少し低い。
単位: tokens/s(生成64トークン)。横軸は経過時間(分)。各点は、その分に終わった測定(1セットあたり 0.5B で5〜16回、1.5B で6〜9回)の中央値を5セットで取り、さらにその中央値を取った値。10分連続で回した2026-10-02の1台の端末の結果で、1・2セット目は電池駆動、3〜5セット目は AC 接続だった。セット別の値は表にある。出典: 筆者が Android スマホの Termux/PRoot(Ubuntu 26.04)上の llama.cpp 8681 で測定

線はどちらも右下がりになっていない。1.5B は1分目がやや高く(10.5)、2分目以降は 9.9〜10.1 で動き、10分目が 9.6 だった。10分目が9分目より低いのは、5セットのうち4セット(1〜4)だったが、10分目の測定は1セットあたり6〜8回で、これ以上は確かめていない。11分目以降は測っていないので、この低下が続くのかどうかは分からない。

「落ちた」と言える線

個々の測定は同じ条件でも揺れる。AC 接続のセットで、測定ごとの値のばらつき(標準偏差÷中央値)は 5〜12% あった。「1割」という線は1回の測定の揺れと同じ大きさなので、分ごとの中央値(1分あたり 5〜16回)で比べた。さらに、1分だけの値は揺れやすいので、次の両方を満たすときだけ「落ちた」と書くことにした(測定のあとに決めた線で、一般的な基準ではない)。

  1. 10分目の中央値が、1分目の 0.90 倍以下。
  2. 最後の3分の中央値が、最初の3分の 0.90 倍以下。

この線で見ると、落ちたと言えるのは 0.5B の2セット目だけだった(0.69 と 0.67)。ほかの9セットは、どちらか、または両方が 0.90 を超えている。AC 接続だった3〜5セットは、途中(2〜9分)の分ごとの中央値の幅が 0.1〜0.8 tokens/s と狭く、10分目の比は 0.94〜0.99 だった。

落ちたと言えるのは1セットだけ: 電池駆動の 0.5B・2

10分目が1分目より1割以上低かったのは、10セット中3セットだ(0.5B・2、1.5B・1、1.5B・2)。3つとも、電池駆動で測った1・2セット目に当たる。AC 接続のセットは6つとも1割未満だった。そのうち上の線(両方の比が 0.90 以下)を満たしたのは 0.5B・2 だけだ。

  • 0.5B・2: 1分目 22.1 から10分目 15.2 へ下がった。3分目(16.6)までに下がり、5分目に 4.7 まで落ちたあとは 12.9〜15.2 で動いた。落ちたと言えるが、途中の分ごとの中央値は 4.7〜21.8 と大きく揺れていて、「一定の速さで落ち続けた」形ではない。このセットは測定中にプロセスが約 154MiB スワップ(メモリの退避先)に出ていた。揺れや低下の原因は確かめていない。
  • 1.5B・1(0.85)・1.5B・2(0.87): 1分目が高いために比が下がっている。1.5B は5セットとも、1分目が全体の最大だった(1.5B・4 は途中の最大と同じ値)。最初の3分と最後の3分の比は 1.01 と 0.95 で、線を満たさない。1.5B・2 は4〜5分目に 6.9・7.6 まで落ちた分があり、6分目以降は 9.6〜10.5 で動いている。

0.5B・1 は逆に、1分目(15.2)が低く10分目(19.3)が高い(比 1.27)。電池駆動の2セットは、AC の3セットより速度の揺れが大きかった。セット内の測定ごとのばらつき(標準偏差÷中央値)は、0.5B で 1・2セット目が 19%・36%、3〜5セット目が 9〜11%。1.5B では 1・2セット目が 18%・20%、3〜5セット目が 5〜12%だった。ただし、電池駆動か AC かだけが違ったわけではない。1・2セット目は 03:26〜04:09 の測定で、3〜5セット目は 05:57 以降の測定だった(0.5B・2 は 05:42 の再測定で電池駆動)。測定中のスワップや、端末の他のプロセスの状況も同じではない(付録の表)。何が揺れを大きくしたのかは、このデータでは切り分けられない。

温度と周波数は、同じ時間に何をしていたか

速度が落ちていないので、「落ちた時刻と温度上昇の時刻が合うか」は確かめようがない。代わりに、速度が横ばいだった10分間に、読めた温度と周波数がどう動いたかを書く。

経過(分) 0.5B 電池ゾーン(℃) 0.5B CPU 系ゾーンの最大(℃) 0.5B 周波数(MHz) 1.5B 電池ゾーン(℃) 1.5B CPU 系ゾーンの最大(℃) 1.5B 周波数(MHz)
1 36.9 53.9 1667 37.7 58.0 1773
2 37.0 54.8 1628 38.0 55.9 1488
3 37.3 53.8 1445 38.2 56.4 1505
4 37.5 54.5 1452 38.4 56.2 1504
5 37.7 54.0 1436 38.5 56.6 1536
6 37.9 54.9 1460 38.7 56.2 1478
7 38.0 54.3 1441 38.8 56.3 1535
8 38.0 55.0 1415 38.8 56.4 1468
9 38.1 54.3 1386 38.9 56.3 1504
10 38.1 54.4 1403 39.0 56.5 1475
  • 各値は、その分の間に5秒ごとに読んだ値の平均を、5セットで平均したもの。電池ゾーンは /sys/class/thermal の battery。「CPU 系ゾーンの最大」は、名前が cpu-0-・cpu-1- で始まる16個のゾーンのうち、各時点で最も高い読み。周波数は CPU 0・1・4・5(この端末で使える4コア)の scaling_cur_freq の平均。

読み取れることは次のとおりだ。

  • 電池ゾーンは、10分間で約1.2〜1.3℃上がった(0.5B: 36.9→38.1、1.5B: 37.7→39.0)。速度は横ばいだった。
  • CPU 系ゾーンの最大は、ほぼ横ばいだった(0.5B: 53.9→54.4、1.5B: 58.0→56.5)。5秒ごとの読みの最大は、0.5B で 67.8℃、1.5B で 93.0℃(1.5B・1 の測定開始13秒後に1回だけ。5秒ごとの読みなので、その間の最大は分からない)。次に高かったのは 1.5B・5 の開始12.5秒後の 84.9℃ で、1.5B・2 にも 70.9℃・70.5℃ の読みがあった。中断線の 95℃ に近い読みは、93.0℃ と 84.9℃ の2回あったことになる。そのあとの分ごとの平均は54〜58℃前後だった。
  • 周波数の平均は、1分目から10分目にかけて下がった(0.5B: 1667→1403、1.5B: 1773→1475)。ただし、30秒ごとの区間に分けて5セットを合わせた中央値は、10分間の20区間のうち、0.5B で19区間、1.5B で18区間が 1325 MHz だった。平均を押し上げていたと見られる 2.5GHz 超の読み(5秒ごとの読みのうち、10分までで0.5B が8回、1.5B が4回、いずれも5セットの合計)は、最初の2分に集中していて、3分目から10分までは0回だった。10分を過ぎた測定の終わり際には、1.5B のセット1に開始602秒後の読みが1回だけあった。

周波数の読みが下がっても速度は下がっていない。周波数の低下が熱によるものかどうか(サーマルスロットリングかどうか)は、この測定では確かめられていない。確かめられるのは、周波数の読みが最初の1〜2分で下がり、そのあと速度も温度の読みも大きく動かなかった、という並びだけだ。

読めた範囲と、読めなかったこと

  • 温度: /sys/class/thermal の zone 名は端末が出したままで、どのコア・部品に対応するかはメーカーの資料で確かめていない。電池ゾーンは、termux-battery-status の temperature と、同じ時刻に両方を読めた全組で比べると、差は平均0.2℃、最大1.0℃だった。cpu-hw-trip-* という名前のゾーンは常に 105000(105℃ 相当)を返す。cpu-hw-trip-0(zone58)の trip_point_0_temp も 105000(測定後に読み直して確認)だったので、温度ではなくしきい値の表示と見て使わなかった(Linux カーネルの文書では、trip point は「The temperature above which trip point will be fired」)。
  • 周波数: scaling_cur_freq は、読んだ瞬間の値を5秒ごとに拾っただけだ。5秒の間の変化は見えていない。
  • 端末の保護の仕組み: この端末の保護閾値は確かめていない。測定前に決めた中断条件(電池ゾーン 45℃ 以上、CPU 系ゾーン 95℃ 以上、電池残量 15% 未満)には、10セットとも当たらなかった。

予想に照らすと

記録しておいた予想と、測った結果を並べる。

  • 「10分後には最初の1分の中央値より1割以上低くなる」: 全体としては支持されなかった。10分目/1分目の比は、5セットの中央値で 0.5B が 0.99、1.5B が 0.94。1割以上低かったのは10セット中3セットで、いずれも電池駆動のセットだった。AC のセットでは0.5B・1.5B とも1割未満だった。最初の3分と最後の3分の比も合わせて見ると、落ちたと言えるのは 0.5B・2 の1セットだけだった。
  • 「最初の数分で下がり始める」: 1.5B は1分目(10.5)から2分目(10.1)にかけて少し下がり、そのあとは 9.9〜10.1 で動いた。0.5B の中央値は 19.4〜20.5 の間で、下がり始める分は見えなかった。
  • 「1.5B の方が落ち幅が大きい」: 比の中央値は 1.5B が 0.94、0.5B が 0.99 で、向きは予想と同じだった。ただし、最初の3分と最後の3分の比では 1.5B が 0.99、0.5B が 1.00 でほとんど差がなく、1.5B は1分目が5セットとも最大で、その分だけ比が小さく出ている。「1.5B の方が大きく落ちる」とは言えない。

つまり、予想した「10分で1割以上落ちる」は、この端末の AC 接続の測定では起きなかった。電池駆動のセットでは落ちて見えたものがあるが、速度の揺れが大きく、スワップや時間帯も違うため、この測定だけでは原因を分けられない。

考察と、この結果の限界

ここからは測定結果をもとにした編集部の考えで、確認した事実とは分けて読んでほしい。

  • この端末・この条件では、小さなモデルの生成速度は10分の連続使用の間、ほぼ一定だったと読める。a00012(短い測定)で測った 0.5B の約 19〜20 tokens/s(Q4_K_M・4スレッド)と、今回の1分目の値(約 20)は近く、10分たっても同じ水準だった。ただし a00012 は prompt の処理も含めた測定で、有効だった条件は少なく、直接の比較ではない。
  • 速度が落ちない理由は確かめていない。周波数の読みが 1325 MHz の付近で動かなかったことと関係があるのかもしれないが、これは推測で、この測定では確かめられない。
  • 電池駆動のセットで速度が大きく揺れたことと、充電状態の関係も確かめていない。充電状態のほかにも時間帯・スワップ・他のプロセスが違っており、因果は言えない。

限界は次のとおりだ。

  • 1台の端末、10分までの結果。11分以降は測っていない。他の端末・他のモデル・他の量子化・他のスレッド数には当てはめられない。
  • 測ったのは生成の速度だけ。-p 0(prompt の処理なし)、生成64トークンを繰り返す条件で、実際に長い文章を生成し続けたときの速度ではない。1回あたりの測定は約2〜23秒(中央値は 0.5B で 3.2秒、1.5B で 6.4秒)で、測定の間にモデルの読み込みがある(測った生成は各セットの約83〜87%の時間)。
  • 条件を制御できていない。室温は記録していない(電池ゾーンの開始時の温度は 34.1〜39.1℃)。充電状態は1・2セット目が電池駆動、3〜5セット目が AC 接続で、途中で充電器につながれた(つないだ時刻の記録は無い)。ほかのプロセスの負荷も制御できていない。
  • 測定の中断があった。最初のスクリプトは 04:16 ごろ(0.5B の2セット目の途中)に止まったので、その分のログは使わず、残りを同じ条件・順序で 05:37 から回し直した(0.5B の2セット目は 05:42 に最初からやり直し)。測定した順序は、付録の表の開始時刻のとおりだ。
  • 測定中も、測定を動かしている AI エージェントの実行環境と、30秒ごとの電池状態の取得が端末で動いていた。

測り方

  • 端末・環境: a00012 と同じ。Android の Termux に PRoot で入れた Ubuntu 26.04、使える CPU は4コア(0・1・4・5)、llama.cpp 8681(Ubuntu のパッケージ、llama-bench の表示は version 8681 (Debian))。
  • モデル: Hugging Face の Qwen 公式 GGUF のうち、qwen2.5-0.5b-instruct-q4_k_m.gguf と qwen2.5-1.5b-instruct-q4_k_m.gguf(a00012 で取得し、ファイルサイズと sha256 を API と照合したもの)。
  • コマンド: llama-bench -m <モデル> -t 4 -r 4 -p 0 -n 64 -mmp 0 -o json を、経過時間が10分になるまで繰り返し起動した。1回の起動で、モデルの読み込み、慣らし1回(llama-bench の既定)、測定4回が走る。a00012 の条件のうち、スレッド数は 4、生成は64トークン、-mmp 0(モデルをプロセスのメモリに読み込む)に合わせ、prompt の処理は測らない(-p 0)。
  • 1分ごとの値: 測定ごとの終了時刻を、起動の終了時刻から測定の所要時間を引いて求め、その分に終わった測定の中央値を取った。1分あたりの測定回数は 0.5B で 5〜16回、1.5B で 6〜9回。セットの最後の起動は10分を少し過ぎて終わるので(セット全体で606〜646秒)、10分を超えた測定は1分ごとの値に入れていない。
  • セット: モデルごとに5セット。0.5B→1.5B と 1.5B→0.5B を交互に並べた。セット間は最低5分の冷却を置き、電池ゾーンが測定前の基準(38.1℃)+1.5℃ 以内に戻るのを待った(上限15分)。
  • モニタ: 5秒ごとに温度ゾーン・CPU 周波数・llama-bench の VmSwap・VmRSS・VmHWM を、30秒ごとに termux-battery-status を記録した。
  • 「落ちた」の判定: 上の「「落ちた」と言える線」のとおり。

付録: セットごとの測定条件

セット 開始(JST) 充電 電池残量(開始→終了) 開始時の電池ゾーン(℃) プロセスのスワップ最大(MiB) 開始時の空きメモリ(GB) 1分あたりの測定回数
0.5B・1 03:26 電池 71→68% 38.0 0 2.77 11〜15
1.5B・1 03:41 電池 67→64% 39.1 170 2.69 6〜8
1.5B・2 03:59 電池 63→60% 37.0 207 2.66 6〜9
0.5B・2 05:42(再測定) 電池 46→42% 34.1 154 2.46 5〜16
0.5B・3 05:57 AC 43→49% 36.3 0 3.97 15〜16
1.5B・3 06:12 AC 54→60% 37.9 163 2.70 7〜8
1.5B・4 06:28 AC 64→70% 38.7 0 3.53 7〜8
0.5B・4 06:43 AC 74→80% 38.8 0 3.66 14〜16
0.5B・5 07:03 AC 79→79% 37.4 0 2.90 16
1.5B・5 07:18 AC 79→79% 35.9 164 3.04 8〜9
  • 空きメモリは、各セットの開始時の MemAvailable(1GB は10億バイト)。端末全体では、測定前からスワップが使われていた(1・2セット目の前の使用量は約7.5GB。全体は約12.9GB)。
  • スワップは llama-bench のプロセスの VmSwap の最大。a00012 では、スワップに出た条件を無効にした。今回は無効にせず、全セットを表に載せた。スワップに出なかったセットだけに絞ると、0.5B は 1・3・4・5 の4セット(10分目/1分目は 1.27・0.95・0.99・0.99)で、落ちたセットは無い。1.5B は 1.5B・4 の1セットだけになる(比 0.96、最後の3分/最初の3分 0.99)。
  • 測定は2026-10-02、03:26〜07:28(JST)。

出典