OCRの電力予算を1桁下げた——速くするのではなく、呼ぶ回数を減らして
OCRを速くするより、呼ばないほうが効いた——常時起動の極小レイヤー「Awake Layer」に、いつ起こすかを任せる
端末の上でOCRを速くした。検出1回は 40→20ms、エネルギーは −58%。それでも電池の持ちは、体感が変わるほど伸びなかった。1回を半分にしても、回している回数がそのままだったからだ。
測ると、OCRの稼働率は 10%。9割は、何も無い画面を読み続けていた。そこで「どう速くするか」をやめて「そもそも呼ぶか」を判定する層を置いた——70倍安い常時起動の Awake Layer だ。検出まわりの電力予算は、おおよそ1桁下がった。
ただし、きれいな話ではない。ゲート自体を4.5倍安くしても、総電力は -22% しか動かなかった。電力を支配していたのはゲートのコストではなく、ゲートが出した呼び出しの回数(理想の6.9倍)だった。
字幕翻訳は、画面の文字を読むところから始まる。端末の上でOCRを回す以上、その電力はユーザーの電池から出ていく。クラウドの請求書と違って、こちらは目に見えない請求書だ。だが確実に届く——バッテリーの減りとして。
だから最初にやったのは、当然のように「OCRを速くする」だった。
速くはなった。桁は変わらなかった
打ち手はまっとうだった。フル画面を読むのをやめ、文字がありそうな帯だけを見る。処理する画素を減らせば、当然速くなる。
実測で、検出1回の時間は 40ms → 20ms(-51%)、エネルギーは 146mJ → 61mJ(-58%) になった。悪くない。実際これは今も入っている。
しかし電池の持ちは、体感が変わるほどには伸びなかった。理由は簡単で、1回を半分にしても、回している回数がそのままだったからだ。この処理は毎周期・秒5回、字幕があろうがなかろうが走り続けていた。半分の重さのものを、同じ回数だけ持ち上げていた。
測ったら、9割は空振りだった
そこで、回数のほうを測った。
| 指標 | 実測 |
|---|---|
| OCRの処理能力(容量) | 4.2 blocks/s |
| 実際に来る需要 | 0.45 blocks/s |
| 稼働率 | 約10% |
能力の9割は、何も無い画面を読み続けることに使われていた。 字幕は出っぱなしではない。喋っていない間は消えるし、出ている間も同じ文字が静止している。読む価値のある瞬間は、実はごく短い。
ここで問いが変わった。「この処理をどう速くするか」ではなく、「この処理は本当に要るのか」。
Awake Layer — 眠らせておいて、必要な瞬間だけ起こす
答えとして置いたのが Awake Layer だ。考え方はひどく単純で、
高価な処理の手前に、桁違いに安い常時起動の層を置き、「今、起こす必要があるか」だけを判定させる。
注:「1桁」は実測した構成要素からの積み上げ試算で、端末全体のODPM実測ではない。
この層が見るのは2つだけ。いま画面に読むべき文字があるか(presence)、そしてそれが変わったか(change)。文字を読むわけではない。中身も分からない。「起こすべきか、寝かせておくか」しか答えない。
なぜ成立するかは、コストの桁を並べれば分かる。
| 1回あたり | 役割 | |
|---|---|---|
| 高価な検出 | 15ms / 40.8mJ | 文字を実際に見つける |
| Awake Layer | 0.5ms / 0.59mJ | 起こすかどうかを決める |
約70倍。この比なら、安いほうを常時回して高いほうを止めるほうが、圧倒的に得になる。門番の給料が、中で働く職人の70分の1なら、門番を24時間立たせておいたほうが安い。
もう一つ、設計として効いたのが変化の内訳だった。字幕の変化イベントを分解すると、出現45% + 消失45% = 90%が「有る/無い」の遷移で、これは安い層でも見分けられる。難しいのは残り10%——presenceが途切れないまま中身だけ差し替わる場合だけだ。9割は、安い層で拾える。
結果、検出の常時電力は
- 高価な検出を毎周期(秒5回)走らせる: 204mW
- Awake Layer 常時 + 検出は字幕の変わり目だけ(秒0.5回): 約32mW(-84%)
ここに前述の「1回あたり-58%」が乗る。積み上げると、検出まわりの電力予算は 204mW → 20mW前後=おおよそ1桁。Live翻訳全体が約2000mWなので、電池寿命でおよそ+9%に相当する。
(この1桁は、実測した構成要素——検出1回の実測エネルギー、常時層の実測電力、実測した発火頻度——を積み上げた試算であって、端末全体を通した一発のODPM実測ではない。正直に書いておく。)
ついでに副産物があった。この層は文字を「読んで」いない。文字らしい視覚構造があるかを見ているだけだ。結果として、日本語で学んだものが、そのままラテン文字にもハングルにも効いた(4作品・4スクリプト横断で確認)。言語ごとに作り込む処理が、丸ごと要らなくなった。消した処理は、多言語対応のコストごと消える。
ここからが本題——ゲートを安くしても、電力は落ちなかった
きれいな話に見えるが、実際にはここで一度、完全に外した。
門番の役をもっと安いモデルに置き換えたとき、ゲート単体では4.5倍の省電力になった。当然、全体も大きく落ちると思った。落ちなかった。総電力は-22%。
原因を分解して、目を疑った。
33個の字幕に対して、高価な処理を約228回呼んでいた。理想(1字幕につき1回)の6.9倍。
門番を安くしても、その門番が用も無いのに職人を叩き起こし続けていたなら、電気代は職人が食う。電力を支配していたのは門番のコストではなく、門番が出した呼び出しの回数だった。
つまり——「安くする」では足りず、「呼ぶ回数を減らす」まで到達して初めて電力は動く。 ゲートを入れた時点で満足していたら、この6.9倍には気づかないままだった。
減らしすぎると、今度は体験が壊れる
では呼び出しを絞ればいい、と発火の条件を「立ち上がりの1回だけ」に厳しくした。呼び出しは 274回 → 69回(-75%)、電力指標は -48%。狙いどおり落ちた。
代わりに字幕の捕捉率が 82% → 61% に落ちた。横向きの画面ではもっとひどく、71% → 32%——字幕の3分の2を取りこぼした。電力は半分になったが、翻訳アプリとして失格だ。
ここで分かったのは、「減らす」は「雑に減らす」ではないということだった。呼び出しを1回に絞れる前提は、「起こすべき瞬間を、その層が正確に当てられる」こと。それができていないうちに回数だけ削ると、削った分がそのまま取りこぼしになる。判定の質と、呼ぶ回数は、分離できない。 現在はここ——判定側を正すほうに投資している。
教訓
- 1回のコストより、回数を見る。 1回を半分にしても、無駄な回数が10倍あるなら電力は動かない。最初に測るべきは処理時間ではなく稼働率だった(実測10%)。
- 桁の違う安い層は常時回しても得になる。ただしゲートを入れただけでは終わらない。 70倍安い判定器なら24時間起こしておくほうが安い。だがゲートを安くすること(4.5倍)と、無駄な呼び出しを減らすこと(6.9倍の過剰発火)は別問題で、効いたのは後者だった。
- 消した処理は付随コストも一緒に消える。ただし、減らす権利は精度で買う。 言語ごとの作り込みも評価も保守も、処理と一緒に消えた——高速化ではこれは起きない。一方で呼び出しを絞る前提は「起こすべき瞬間を外さない」ことで、そこが甘いまま削れば、電力の勝ちを体験の負けで払う。
これは マニフェストの4番目の原則——処理を高速化するより、処理自体を減らす——の、いちばん素直な現れだ。速くしたときの利益は-51%だった。呼ばないことにしたときの利益は、桁だった。
付録:生データ
| 項目 | 実測 | 条件・留保 |
|---|---|---|
| 検出1回のエネルギー | フル 960×448 = 86.8ms / 330mJ、フル 736×320 = 40.1ms / 146mJ、帯 960×128 = 19.6ms / 61mJ、帯 448×320 = 23.9ms / 70mJ | Pixel 10 / 放電+電流サンプリング、3ラウンド interleave |
| 電力の性質 | 検出中の瞬時電力はおおむね一定(約3.0〜3.8W) | エネルギーは処理時間で決まる=省エネの実体は「短くする」か「やらない」かの二択 |
| コスト比 | 高価な検出 15ms / 40.8mJ 対 Awake Layer 0.5ms / 0.59mJ = 約69倍 | 常時稼働時の消費は 12mW(50ms周期) |
| 稼働率 | 容量 4.2 blocks/s に対し需要 0.45 blocks/s = 約10% | 9割は何も無い画面を読んでいた |
| 検出の常時電力 | 毎周期5Hz = 204mW → 変わり目のみ+常時層 = 約32mW(-84%) | Live全体 約2000mW に対し -172mW ≒ 電池 +9% |
| 変化イベントの内訳 | 出現45% / 消失45% / 中身の差し替え10% | 90%は presence の遷移=安い層で拾える |
| スクリプト横断 | 日本語で学習 → ラテン文字 AUC 0.989 / ハングル 0.950、混合時 0.996〜0.998 | 既存の高価な検出器 0.994〜0.997 と同等 |
| ゲート置換の逆説 | ゲート単体 4.5倍省電力 → 総電力は -22% のみ | 33字幕に対し呼び出し 約228回 = 理想の6.9倍 |
| 呼び出しの過剰な絞り込み | 縦画面 274→69(-75%)、横画面 297→44(-85%)、電力指標 -48% / -66% | 代償に捕捉率 82→61% / 71→32%=減らしすぎは体験を壊す |
注記: 電力指標の一部(発火数×コストの相対値)はハーネス上の積算であって ODPM 実測ではない。上記の「1桁」も、実測した構成要素からの積み上げ試算。