バックプレッシャーは、下流のステージにこれ以上処理する余力がないときに上流のステージを遅くしたり停止させたりすることで、複数のステップからなるホームAIパイプラインを安定させます。
パイプラインは、増え続けるキューに過負荷を隠すのではなく、需要を伝播させ、バッファーの上限を設け、稼働中で最も遅いステージが処理できる速度で作業を受け入れます。
下流の処理が追いつかないときにバックプレッシャーが始まる
上流のステージが、下流のステージが一定期間に処理できる量を超えて作業を生成すると、パイプラインは不安定になります。バッファーが増大し、メモリが埋まり、レイテンシーが上昇します。
Akka Streamsは、サブスクライバーが受信できる要素数である下流の需要を使ってバックプレッシャーを説明しています。パブリッシャーは、受け取った需要を超えて要素を発行してはなりません。Reactive Streamsは、ノンブロッキングなバックプレッシャーを備えた非同期ストリーム処理を定義しており、プロデューサーが下流の処理能力を尊重しなければならないという核心的な条件を、Reactive Streamsのバックプレッシャー標準で示しています。
ホームAIサーバーでは、ボトルネックがOCR、埋め込み生成、LLM、ストレージへの書き込み、あるいはツールAPIになることがあります。
バックプレッシャーは、この処理速度の差を隠すのではなく、遅いステージを明らかにします。
需要は処理能力の情報を上流へ伝播する
下流のステージは、あとどれだけ作業を受け入れられるかを通知します。需要がゼロになると、直前のステージは処理能力が戻るまでプッシュを停止します。
Akkaは、下流の処理能力に応じて変化する動的なプッシュ・プルプロトコルについて説明しています。このフィードバックは複数のステージを通じて伝わります。Project Reactorはストリームを通じてサブスクライバーの需要を伝播させ、Project Reactorの需要制御で説明されているように、下流の処理能力の情報が上流へ伝わる仕組みを示しています。
そのため、埋め込み処理のワーカーが遅い場合、ファイルスキャナーがチャンクを送信する速度を落とし、高速なプロデューサーがGPUでまだ処理できない作業でメモリを埋め尽くすのを防げます。
上限付きバッファーは、継続的な過負荷を隠さずにバーストを吸収する
ワークロードは突発的に増えるため、小さなバッファーは役立ちます。複数の写真が同時に届いたり、音声アシスタントが短時間に複数のタスクをキューに追加したりすることがあります。
Akka Streamsは、バックプレッシャーのあるストリーム内で、明示的なバッファーとオーバーフロー戦略をサポートしています。バッファーは一時的なバーストを吸収しますが、下流の処理能力そのものを増やすわけではありません。Apache Flinkは、下流のオペレーターが十分な速度でデータを消費できない場合にバックプレッシャーを表示し、Apache Flinkのバックプレッシャー監視によって、短時間のバーストと継続的な過負荷を区別できるようにしています。
平均到着率が処理速度を上回り続けると、最終的にバッファーは満杯になります。バッファーを大きくしても、プロデューサーが減速、拒否、または処理を延期しなければならなくなる時点を遅らせるだけです。
制御された並列処理は、別のボトルネックが現れるまで処理能力を高める
ハードウェアと下流のサービスが対応できる場合、複数の埋め込み生成、OCRジョブ、I/O呼び出しを並行して実行できます。
目標は、すべてのステージを無制限にすることなく、処理速度を高めることです。
Akkaのアクター連携ドキュメントは、設定された並列度を超える作業をメールボックスが受け取らないように、バックプレッシャーで制御する仕組みを示しています。処理が完了すると、追加の需要が発生します。Akka Streamsは、上限付きの非同期処理と需要制御を使用して、プロデューサーからの無制限な負荷を防ぎます。これは、別のステージがボトルネックになるまでしか制御された並行処理が役立たない理由を、Akka Streamsのバックプレッシャーで示しています。
ローカルモデルの並列度を高めすぎると、メモリへの負荷や競合が増える可能性があります。そのため、処理能力はCPUコア数から推測するのではなく、実際のボトルネックで測定する必要があります。
バックプレッシャーはキューの分離やデッドレター処理とは異なる
分離されたキューはワークロードの種類を隔離し、DLQは失敗したイベントを隔離します。
バックプレッシャーは、下流の処理能力が上流の生成速度を下回る場合に、正常な作業の処理速度を制御します。
ZimaSpaceのインタラクティブ処理とバックグラウンド処理のキュー分離では、優先度とワークロードの隔離について説明しています。Java Flowでは、サブスクライバーが項目を要求し、需要を超える項目を受け取らないようにする仕様が定められています。これは、Java Flowの需要セマンティクスで、真のバックプレッシャーと、単に作業を別々のキューへ振り分けることを区別するのに役立ちます。
関連するホームAIのバッチ処理とレイテンシー・スループットのトレードオフは、スループット向上のために作業をどのようにまとめるかを変えます。一方、バックプレッシャーは、そもそも下流が受け入れられる作業量を決定します。
安定したパイプラインは、ユーザーが障害に気づく前に負荷を明らかにする
健全なパイプラインでは、キューの深さ、最古の項目の経過時間、処理速度、アクティブな並列度、拒否数、バックプレッシャー状態に費やした時間を確認できるようにする必要があります。
AkkaのReactive Streamsガイドは、バックプレッシャーを、システムが負荷に対応し、負荷によって崩壊するのを防ぐフィードバック機構として説明しています。gRPCは、フロー制御によって高速な送信者が受信者を圧倒するのを防ぐと説明しています。これは、gRPCのフロー制御において、複数のステップからなるパイプラインが崩壊する前に負荷を明らかにし、伝播させることを支えます。
ホームサーバーで目指すべきなのは、緩やかな減速です。バックグラウンドのRAG再インデックス処理を一時停止し、その間もインタラクティブな音声処理とストレージを応答可能な状態に保つことで、すべてのワークロードが競合してマシン全体が使えなくなる事態を防げます。
テック&AIハブ
もっと読む

ホームカメラはクラウドの時刻サービスなしでイベントを同期できますか?
クラウドを使わないカメラ時刻の仕組みを優先した説明、共有リソースに伴うトレードオフ、クエリのファンアウトに関する3つのFAQ、そして実践的な検証手順。

ローカルAIサービスは推論前に破損したモデルレイヤーを検出できますか?
破損したモデル層の検出について、メカニズムを優先して説明し、共有リソースのトレードオフ、クエリのファンアウトに関する3つのFAQ、実践的な検証プロトコルを取り上げます。

すべての埋め込みを再生成せずにRAGシステムを復元できますか?
再埋め込みなしでRAGを復元する仕組み優先の説明、共有リソースのトレードオフ、クエリファンアウトに関する3つのFAQ、そして実践的な検証プロトコル。

