AIアプリは、CPUとRAMで考えるとうまくいく
借りるCPU、自社設計のRAM——1つのメタファーが設計全体を組織化する
辞書を何件持たせるか。履歴を何件さかのぼるか。ジャンルのタグを渡すか。別々に見えたこれらの判断は、全部「記憶をどう持つか」の話だった。
そこで語彙を1つ決めた。LLMは借り物のCPU、context(文脈・データ)は自社設計のRAM。 これだけで、迷いは「これはどの段のキャッシュか」という1つの問いに畳まれた。
そして投資先も決まる。CPUは他社も同じものを借りられるうえ、退役する。載せ替えても生き残るのはRAM側の設計だ。ただし文脈は多いほど良いわけではない——履歴を+120%積んでコスト+42%、品質は頭打ちで差し戻した。
しばらくの間、私は同じ種類の判断を、毎回ゼロから迷っていた。用語辞書(glossary)をどれだけ持たせるか。字幕の履歴を何件さかのぼるか。作品ジャンルのタグをプロンプトに足すか。シーン境界の情報を渡すか。どれも「LLMに何を渡すか」の話なのに、別々の問題として、そのつど手探りしていた。
ある日、それらを並べて眺めていて、手が止まった。これは全部、「記憶をどう持つか」の話だ。どの情報を、どれだけ近くに、どれだけの間、置いておくか——コンピュータが何十年も前に解いた、あの問題とまったく同じ形をしている。
そこで語彙を1つ決めた。LLMは借り物のCPU。context(文脈・データ)は自社設計のRAM。 これだけで、迷いの多くが消えた。行き着いた答えは、context を4段のキャッシュ階層として設計することだった。この記事は、その1つのメタファーが設計全体をどう組織化したか、という話だ。
LLMは、借りているCPUだ
LLMは、演算装置だ。文脈(入力)を受け取り、翻訳(出力)を計算して返す。CPUが命令とデータを受け取って結果を返すのと、役割は同じだ。
そして決定的なのは——それは借り物だ、ということ。基盤モデルを自分で設計しているわけではない。外部から借りて、世代交代のたびに載せ替える。事実、第4回で書いたとおり、頼っていたモデルは退役し、値上げされ、こちらの都合とは無関係に消えていった。借り物のCPUは、いつか返さなければならない。
CPUだと思えば、性質もそのまま当てはまる。演算は速いに越したことはないが(レイテンシは重みのバイト数で決まる)、どのCPUに載せ替えても、渡す仕事の中身は変わらない。qwenでもllamaでも、字幕を訳すという仕事は同じだ。だからCPUそのものは、突き詰めれば交換可能な部品にすぎない。(ただしここで言う「仕事の中身」は、“字幕を訳す”という抽象的な役割のこと。それをCPUに渡す具体的なプロンプトの書式はモデルごとに違い、そこは載せ替えのたびに書き直しになる——この境界の話は最後に戻ってくる。)
では、交換できないものは何か。
では、RAMは誰のものか
CPUに仕事をさせるには、その手元にデータを置いてやらねばならない。翻訳で言えば、いま画面に何が映っているか、この作品の固有名詞をどう訳すと決めたか、直前のセリフは何だったか——これらを構造化して、CPUの手が届く場所に並べる。これがRAMの仕事だ。
そして、このRAMは自分で設計できる。どの情報を拾い、どう並べ、どれだけ持ち、いつ捨てるか。ここは借り物ではなく、100%自社の設計判断だ。
| ハードウェア | LYRでの対応 |
|---|---|
| CPU | LLM(借り物・世代交代する演算装置) |
| RAM容量 | context window(8k〜128kトークン=一度に渡せる文脈の量) |
| RAM帯域 | 入力トークンの読み込み速度(8Bで約750 tok/s) |
| キャッシュ階層 | context配信の階層(後述のC1/C2/C3/Cold) |
(プリフェッチ=先読み、キャッシュ追い出し、メモリコントローラ、専用ASIC=専用回路といった細部も同じ語彙で1対1に写せる。対応表は付録にまとめた。)
CPUを速くする(=良いモデルを借りる)のは、たしかに効く。だが、それは他社も同じ手が打てる。差がつくのは、CPUの外側——どんなデータを、どれだけ的確に、その手元に用意できるかだ。これはマニフェスト第2原則「まだ、安く・速くできる」——律速は、たいていモデルの外側にある——そのものだった。モデルは全体のごく一部。勝ち筋は、たいていモデルの外側に眠っている。
キャッシュ階層で考える
RAMだと分かれば、次の問いは自動的に決まる。メモリ階層をどう切るかだ。CPUに近いほど速いが小さく高価、遠いほど遅いが大きく安い——この古典的なトレードオフを、そのまま文脈設計に持ち込む。
- C1(プロンプト直挿し)=L1キャッシュ。1リクエストの間だけ生きる、CPUに直結した最速の場所。画面のテキストブロック、用語辞書の該当項、口調の指示——全トークンがそのままLLMの入力になる。ここが一番速いが、一番狭い。
- C2(セッション内メモリ)=メインメモリ。アプリが起動している間だけ生きる。用語辞書のキャッシュ(LRU=最近使われていないものから捨てる方式・上限200件)、字幕モードの直近履歴(3件)。引き当てるとC1へ昇格する。
- C3(永続結果キャッシュ)=ディスクキャッシュ。端末の再起動をまたいで残る。入力のMD5(内容の指紋=短い固定長ハッシュ)をキーに、過去の訳文をそのまま引く。ヒットすれば、CPU(LLM)を叩かずに答えが返る。ここは正直に言うと、RAMの比喩が少し軋む——データを”近くに置く”のではなく、同じ計算を二度やらない(メモ化)という別の節約だからだ。それでも「遠い層に貯めておき、要れば最速層へ引き上げる」という階層の骨格は同じなので、C3として扱う。あえて”KVキャッシュ”と呼ばないのは、これがtransformer内部のKVキャッシュ(注意機構の中間状態)とはまったく無関係な、結果そのもののキャッシュだからだ。
- Cold(評価データ・ユーザーログ)=アーカイブ。GB級の資産だが、LLMには直接届かない。回帰テスト、将来の自前モデルの学習、そして検索してC2/C3へ引き上げる元ネタになる。
この4段が決まると、新しい文脈のアイデアが来たとき、最初に問う質問が1つに固定される——「これはC1か、C2か、C3か、Coldか?」。以前は毎回ゼロから迷っていた判断が、置き場所を決めるだけの作業になった。1つの語彙が、意思決定のブレを消したのだ。
「もっと文脈を」が、裏目に出た
RAMのメタファーが本当に役立ったのは、ある失敗を正しく説明できたときだった。
ページ翻訳で、文脈として渡す履歴を増やしたことがある。もっと文脈を与えれば訳は良くなるはず、という素直な発想だった。入力トークンは521→1212と+120%に膨らみ、コストは平均+42%(記事により+21〜62%)増えた。重課金ユーザー(200ページ/日)では、サブスク粗利の27%を浸食する規模だった。prefill(入力読み込み)は+約50msだった。
見返りは、これに見合わなかった。履歴を積んで得たかったのは固有名詞の訳の一貫性だが、その便益は——のちに分かるとおり——固有名詞だけを抜き出す小さな辞書キャッシュ(注入は10項目まで)で、桁違いに安く取れた。全履歴を毎リクエスト積むのは、コストばかりが線形に増え、品質の伸びはとうに頭打ちだった。だから元に戻した(revert)。
最初、私はこれをメモリの壁(memory wall=CPUの演算速度の伸びにメモリ帯域が追いつかず、両者の性能差が開いていくハードの現象)になぞらえたくなった。だが、それは正確ではない——そう書けば、ハードを知るCTOにはすぐ見抜かれる。memory wall は容量を”増やす”と遅くなる話ではない。RAMを足しても遅延は増えない。ここで起きていたのは別の力学だ。入力トークン数に比例してprefillコストが線形に増える一方、品質の見返りは逓減していく。壁ではなく、傾きの違う2本の線——伸び続けるコストと、頭打ちになる品質——が交わる、その交点の問題だった。
「もっと文脈を」は無条件の善ではない。1リクエストに載せてよい量には上限(計算機でいうワーキングセット=処理に同時に必要なデータの実働範囲)があり、それを意識的に設計しなければならない。LYRでは、辞書は10項目まで、履歴は3件まで、と上限を明示的に決めている。この上限は「ケチっている」のではなく、コストと品質の交点の手前に線を引いている。メモリ階層の語彙がなければ、私はこの失敗を「なぜか文脈を足すと悪くなった」と、原因不明のまま片付けていただろう。
(ページ翻訳と字幕翻訳で、この交点の位置が違うのも同じ語彙で腑に落ちる。ページは入力が支配的、字幕は出力が支配的で、コストと文脈量の上限が別物になる。同じ「RAM設計」でも、CPUの使われ方が違えば最適な階層構成も変わる。)
CPUは買う、RAMは自社設計する
ここまで来ると、投資の原則が1行になる。CPUは買う。RAMは自社設計する。
LLM(CPU)は外部委託でいい。世代交代は速く、自前で追いかける価値は薄い(追いかけるにしても、それは経済が逆転してからの話だ)。一方、キャッシュ階層・プリフェッチ・追い出し・ワーキングセット管理は、すべて内部資産として積み上がる。
この非対称が効く。借り物のCPUは、退役すれば消える——積み上げた最適化ごと、次のモデルへ引き継げないこともある。だがRAM側の資産、つまり「環境からどの文脈を、どう構造化して、どの階層に置くか」という設計は、CPUを載せ替えてもそのまま生き残る。用語辞書も、翻訳キャッシュも、評価データセットも、モデルが何であろうと価値を保つ。
ただし、資産の境界は正直に引いておきたい。生き残るのは「どの文脈を選び、どう優先順位をつけ、何段に置くか」という構造化の設計であって、それを実際にモデルへ渡す具体的なプロンプトの書式そのものは、CPU(モデル)に強く結びつく。事実、第4回でモデルが消えたとき、作り直す羽目になったのは、まさにこの書式レイヤーだった。失うのは翻訳(=モデル依存の形式)で、設計(=どの記憶をどう持つかという意味)は残る——境界はそこにある。それどころか、いつか自前のCPU(専用モデル)を作る日が来たとき、このCold層に貯めたデータが、そのまま学習の燃料になる。
だから、投資はRAM側に寄せる。派手なのはCPU(新しいモデル)だが、返さなくていいのはRAM(自社の文脈・データ階層)のほうだ。
教訓
-
1つの良いメタファーが、設計全体を組織化する。 バラバラに迷っていた判断(辞書の件数、履歴の深さ、タグの有無)が、「LLM=CPU、context=RAM」という1語彙で1つの問いに畳まれた——「これはC1/C2/C3/Coldのどれか?」。良い比喩は、装飾ではなく意思決定の道具だ。
-
CPU(借り物LLM)は交換可能、RAM(自社の文脈・データ階層)が競争優位。 モデルは他社も同じものを借りられる。差がつくのはモデルの外側——どの文脈を、どれだけ的確に、CPUの手元へ用意できるか。マニフェスト第2原則「まだ、安く・速くできる」の、設計版だ。
-
文脈は多いほど良いわけではない。借り物は返り、資産は残る。 入力トークンに比例してコストは線形に増えるが、品質の見返りは逓減する(履歴+120%でコスト+42%・prefill+50ms、品質は頭打ちで差し戻した)。ワーキングセットはケチではなく設計だ。そしてCPUは退役するが、RAM側に積んだ設計とデータは載せ替えても生き残る——だから投資はRAM側へ寄せる。
付録:実測値/生データ
| 項目 | 実測 | 条件・留保 |
|---|---|---|
| 文脈を積んだ失敗 | 入力 521→1212トークン(+120%)/コスト平均 +42%/prefill +約50ms/粗利の 27% を浸食 → 差し戻し | Page context history、Llama 8B。狙った固有名詞の一貫性は、上限10件の辞書キャッシュで桁違いに安く取れた |
| 事前見積もりの誤り | 「Page=出力支配、cost +5-8%」→ 実測は input:output≈2:1(入力支配) | 見積もりを1桁外した |
| C3(永続結果キャッシュ) | Live translate段の cache hit 86% | その割合はLLM呼び出しを丸ごとスキップ。キーは入力のハッシュ→訳文(transformer内部のKVキャッシュとは無関係) |
| プリフェッチ(投機的OCRキャッシュ) | hit cycle 226ms vs miss 646ms、hit率 9.2%→19.4%(2.1×) | det+capture をスキップ |
| ワーキングセット上限 | 辞書10項目・履歴N=3 | 壁ではなく「コスト線形増×品質逓減」の交点の手前に引いた設計値。交点はモード依存(ページ=入力支配/字幕=出力支配) |
| 資産境界 | 生き残るのは「どの文脈をどう構造化し、何段に置くか」の設計 | 載せ替えで失うのはプロンプト書式(モデル依存・第4回で実際に失った層) |
メタファー対応: CPU=LLM(借り物・世代交代)/RAM容量=context window(8k〜128kトークン)/RAM帯域=入力読み込み速度(8B約750 tok/s)/プリフェッチ=投機的OCRキャッシュ/追い出し=辞書LRU上限200・履歴スライディング窓/専用ASIC=自前OCR/将来のcustom CPU=自前字幕基盤モデル。関連: 自前化の経済/CPUを速くする量子化。