0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

自前でAIを持って、E2Eを約500ms→120ms・コストを1/3〜1/10にした

0
Posted at

この記事は、自社ブログの LYR Performance Note #005 に掲載したものの転載です。

待ち行列と距離を同時に消す——ただし、同じ落とし穴つき

自前でAIを持つと、E2Eは 約500ms → 約120ms になった。消えたのは待ち行列(専有)と距離(近接)、そして最後に生成(量子化)だ。

ただし、途中に落とし穴がある。待ちと距離を消した瞬間、それまで最小だった生成が新しい律速になり、素のままでは約190msで止まる。3点セットで、はじめて勝てる。

経済も反転する。使うほど払う変動費が固定費になり、DAUあたりの単価はおよそ 1/3〜1/10 へ。数千DAUを超えれば自前が安い。速さ・コスト・供給の主権が、同じ一手で揃う。

E2Eを待ち行列・距離・生成の3項に分解したBefore/After。外部APIは待ち行列167ms+距離275ms+生成50msで約500ms、うち待ちと距離が89%。自前に移すと待ち行列は専有で0、距離は近接で約25msになるが、素の汎用GPUでは生成が50msから168msへ増え、E2Eは約190msで止まる。量子化で生成を95msに縮めると、E2Eは約120msになり、外部APIの約4分の1になる。

図1:E2Eの3項が、自前化でどう変わるか。外部API(上)は待ち行列167ms + 距離275ms + 生成50ms = 約500msで、待ちと距離が89%を占める。自前に移すと待ち行列は専有で0、距離は近接で約25msになるが、素の汎用GPUでは生成が50→168msへ増え、E2Eは約190msで止まる。量子化で生成を95msに縮めて初めて、E2Eは約120ms=外部APIの約1/4になる。
注:距離25msは近接時 14〜36ms の代表値。生成50msは外部API側の専用チップ(LPU)の値で、素の汎用GPUとは前提が異なる。

この二重コストは、外部APIのままでは消せない

第4回では、自前でAIを持つ理由として供給の主権——退役や値上げから自由になること——を書いた。だが、動機はもうひとつあった。それは第2回で行き詰まった問題の、正面からの答えでもある。

第2回で、遅さの支配項は待ち行列と距離に移っていた。E2Eレイテンシ約500msの内訳は、生成わずか10%に対して、距離(往復)275ms + 待ち行列167ms = 約89%。しかもこの二重コストは、外部APIを使い続けるかぎりこちらの手では消せない。待ち行列は他人の都合で決まり、距離はサーバーの置き場所が決める——どちらも、コードを磨いても動かない。

自前で持つと、これを両方消せる。ただし——同じ落とし穴が待っている

待ち行列と距離を、同時に消す

セルフホストは、外部APIではできない2つのことを可能にする。

  • 専有する → 共有インフラの待ち行列が消える。自分専用なら、並ぶ相手がいない。もちろん、需要が急増すれば自前でも待ちは生じ得る。だが決定的に違うのは、その待ち行列を自分でコントロールできることだ。GPUを最適化し、モデルを量子化してさばける量を増やし、サーバーを増やせばいい(このあと順に触れる)。外部の共有APIでは、待ち行列は他人の都合で決まる。第2回で見た、待ち時間が異様に長くなるロングテールのリスクを、こちらはただ受け入れるしかなかった。
  • 近くに置く → 物理的な距離(往復275ms)が消える。ユーザーに近い地域にサーバーを置けば、往復は数十ミリ秒だ。

実測すると、こうなった。

区間 外部API(遠い・共有) 自前(近い・専有・素)
待ち行列 167 ms ほぼ0 ms(専有)
距離(往復) 275 ms 14〜36 ms(近接)
生成(compute) 50 ms 168 ms
E2E ~500 ms ~190 ms

前提として——この比較は同じモデルどうしではない。外部API側は、はるかに高品質な大型モデルを専用チップで動かしている(第4回)。自前側は、安価なGPUに載る小型モデルだ。だからこれは品質を揃えた正式な比較ではなく、あくまでレイテンシとコストの比較である。小型モデルの品質を大型に近づける仕込みは専門特化シリーズで扱う。ここでの主張は「同じ品質を安く」ではなく、「主権を持ちつつ、体感に十分な速さとコストを実現できる」ことだ。

しかも、この待ち行列の167msは中央値にすぎない。第2回で見たとおり、混雑時にはp99で約5秒まで跳ねることがあった。専有が消すのは、167msという中央値だけではない——いつ来るか読めない"最悪のテール"ごとだ。だから体感への効きは、表の数字が見せる以上に大きい。

E2Eは約500ms → 約190ms。89%を占めていた待ち行列と距離が、丸ごと崩れた。……が、表をもう一度見てほしい。

だが、生成が"重くなっている"ことに気づく

生成(compute)が、50ms → 168ms と、3倍以上に重くなっている

外部APIが使っていたのは、翻訳のような処理に特化した超高速チップ(LPU)で、生成はわずか50msだった。一方、自前で借りる安価な汎用GPU(RTX 4090)は、素のままだと生成が168ms——3倍以上かかる。そうなると——第2回とまったく同じ罠だ。待ち行列と距離を消したのに、今度はその生成(compute)が新しいボトルネックになる。E2E 約190msのうち168msが生成——「待ち行列と距離の問題を、今度はcompute問題に付け替える」だけになりかねない。

部分最適の罠は、ここでもう一度顔を出す。3つのうち2つを消しても、3つ目が残れば勝てない

3つ目を、量子化で潰す

これを解いたのが量子化(INT4)だった。モデルの重みを圧縮して、安価な汎用GPUのさばける量と速度を大きく引き上げる。生成を168ms → 95msまで縮められた。(なぜ圧縮するだけで速くなり、しかも品質がほぼ落ちないのか——その仕組みは専門特化シリーズ・量子化編で分解した。)

  • 生成 compute 168ms → 95ms(高価なデータセンター級GPUに匹敵する速度)
  • さばける量 2,200 → 9,600 リクエスト/分(4倍)
  • 品質 −1pt(ほぼ無劣化、n=100)

この95msは、外部の専用チップ(LPUの50ms)にこそ及ばない。だが、そこまで速くなくていい。待ち行列(0)と距離(14〜36ms)がすでに消えているから、生成が50msでなく95msでも、E2Eは約120ms——外部APIの500msに圧勝する。こうして、待ち行列(専有)・距離(近接)・生成(量子化)の3つを同時に潰せた——冒頭の図1でいえば、3段目にたどり着いたことになる。専用チップより生成が遅くても、全体では勝てるのだ。

コストは、変動費から固定費に裏返る

速さと同じくらい大きいのが、コスト構造の反転だ。

外部APIは変動費——使うほど払う。しかも混雑時には全体の上限(429エラー)に頭を打つ。自前は固定費——GPUを1枚借りたら、あとは何回叩いても値段は変わらない。

月間インフラ費用の形の比較(軸の数値は省略): 従量の外部APIはユーザー数に比例して直線的に急増、自前ホストは固定費に近く低いまま。ユーザーが増えるほど差が青天井に開く。

図2:月間インフラ費用の形。従量(外部API)はユーザー数に比例して直線的に増え、自前ホストは固定費に近く横ばいのまま。ユーザーが増えるほど差は開く。
注:形の比較が目的のため軸の数値は省略。損益分岐の実額は本文の表を参照。

外部API(変動費) 自前(4090+INT4, 固定費)
コスト(DAUあたり・月) 変動費(使うほど増える)+ 混雑時の上限(429)あり 固定費。変動費の 1/3〜1/10(GPUが埋まった規模で)
損益分岐 数千DAU で逆転(以降ずっと自前が安い)

コンシューマ向けGPUの月額は、同等クラスのデータセンターGPUの約1/8で、INT4を載せればその高級GPUに並ぶ性能が出る。外部APIのDAU単価でこの固定費を割り戻すと、ユーザーが数千人を超えたあたりから、自前のほうが安くなる(使用強度が高いほど早く逆転する)。それ未満ならGPUが遊ぶので外部APIが合理的、それ以上なら自前がコストでもレイテンシでも勝つ。なお表の「変動費の1/3〜1/10」は、GPUが十分埋まった規模での単価だ(損益分岐の直後はGPUに余りがあるぶん、1人あたりは割高になる)。

そして、この「固定費」という性質が、事業の判断そのものを変えた。変動費のときは、使われるほどコストが膨らむので「無料機能はほどほどに」という発想になる。固定費なら、追加の1回はほぼタダ。だから「無料でどこまで開放するか」の答えが反転する。

ただし、"固定費"にはタダの顔をした手間がある

もっとも、自前化は「GPUを借りて終わり」ではない。外部APIが肩代わりしてくれていた運用——障害対応、監視、モデルの更新、需要変動に備えた冗長化(N+1)、GPUの調達——が、そっくり自分の仕事になる。ここまでのコストは"GPU代"だけを見たもので、人手と運用の固定費は別に乗る。だから自前化は、規模(損益分岐)と、この運用を背負える体制の両方が揃って初めて合理的になる。安さと主権は、タダでは手に入らない。

まとめ — 速さとコストは、どう変わったか

専有(待ち行列)・近接(距離)・量子化(生成)の3つを同時に潰した結果を、2つに分けて置いておく。速さは中央値だけでなく分布ごと、コストは金額でなく費用の"形"そのものが変わった——効いたのはこの2点で、どちらも「外部APIのままでは手が届かない」ものだった。

端末で計った翻訳1回の所要時間の分布比較。外部API時代は中央値502msで上側の分位は未記録、混雑時は青天井に伸びる。自前・近接後は実測でp10 231ms、中央値252ms、p90 460ms、p99 977msと、テールまで1秒以内に収まる。

図3:翻訳1回の所要時間の分布。どちらも端末で計った同じ量。外部APIは中央値 502ms で、混雑時にどこまで伸びるかが読めなかった(別モデルの実測では、待ち行列だけで p99 4.9秒)。自前・近接に移すと 中央値252ms・p90 460ms・p99 977ms と、テールまで1秒以内に収まる。専有が消すのは中央値だけでなく、読めないテールのほうだ。
注:外部API側は中央値のみの記録で、上側の分位(p90・p99)は残していない(n=38)。自前側の分位は第9回の端末実測。

コストの比較。外部APIは変動費で使うほど増える。自前は固定費で、DAUあたりの単価は外部APIの3分の1から10分の1。損益分岐は数千DAU。

図4:コストの比較。変わったのは金額の大小ではなく費用の形だ。使うほど増える変動費が固定費になり、DAUあたりの単価は 1/3〜1/10。損益分岐は数千DAUで、以降はずっと自前が安い。

教訓

  1. セルフホストは、待ち行列と距離を"自分で"潰せる。 共有・遠隔の外部APIでは、どちらも他人任せだった。専有・近接・スケールアウトで E2E 約500ms → 約120ms。
  2. ただし"3つ目"を残すと成立しない。 安い汎用GPUで素にやると、消したはずのボトルネックがcomputeへ移るだけだ(第2回の罠の再来)。専有+近接+量子化の3点セットで初めて勝つ。
  3. コストは変動費→固定費に反転し、供給の主権まで同じ一手で揃う。 ある規模を超えれば安くなり、混雑上限も消え、無料開放の判断まで変わる。ただしそれは、正しく測って「3つ目」を潰したときだけだ。

付録:生データ

項目 実測 条件・留保
外部API(日本リージョン)E2E内訳 往復 275ms / 待ち行列 167ms / 生成 50ms 生成は10%、待ち+距離が89%
自前・近接(主役=安価な RTX 4090) 台湾4090+INT4 → RTT ~36ms + compute 95ms = E2E 131ms 国内近接なら RTT ~14ms で E2E ~110ms 圏(本文の「約120ms」)。〔参考〕H100 福島は RTT 13.6ms + compute 90ms = 97ms
部分最適の罠 汎用GPU素の生成 168〜230ms 待ち+距離の問題を、computeの問題に付け替えただけ
INT4(GPTQ-Marlin)の効果 生成 168→95ms、throughput 2,200→9,600 req/分 品質 −1pt(n=100)
コスト 外部API 変動費(最悪ケースは平均の約2.7倍)→ 自前 固定費。DAU単価で 1/3〜1/10 損益分岐 数千DAU。データセンターGPUは約8倍のDAUが必要(コンシューマGPU=1/8コスト)
遠隔自前(cross-Pacific) E2E 340ms 外部API(~500ms)より速いが体感の壁は超過=近接が要る

シリーズ「計測が導いた旅」第5回の記事です。原文と続きは LYR Performance Note #005 / 記事一覧 にあります。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?