SageMaker HyperPod における LLM 推論のための分離型プリフィルとデコード
AWS は SageMaker HyperPod で vLLM を活用し、GPU リソースを分離する Disaggregated Prefill and Decode (DPD) アーキテクチャを実装することで、長文コンテキストや高同時接続環境における推論性能とレイテンシの最適化を実現した。
キーポイント
Prefill と Decode の分離アーキテクチャ
計算集約型の Prefill(初期 KV キャッシュ生成)とメモリ帯域集約型の Decode(トークン生成)を別々の GPU プールで実行し、EFA RDMA 経由で接続することで相互干渉を排除する。
vLLM と HyperPod Inference Operator の統合
既存の vLLM の連続バッチ処理機能に、マルチノード環境での分散推論を制御する HyperPod Inference Operator を組み合わせることで、スケーラブルな実装を可能にする。
長文・高同時接続ワークロードへの最適化
4,096 トークンを超える長いプロンプトやストリーミング応答が必要なチャットボット、RAG などのユースケースにおいて、TTFT と ITL を独立してチューニングし、テールレイテンシを低減する。
分散推論の適用条件とトレードオフ
EFA RDMA による転送コストがかかるため、短文や低同時接続の場合は従来の集約型アーキテクチャの方が有利であり、ワークロード特性に応じた使い分けが推奨される。
影響分析・編集コメントを表示
影響分析
このアプローチは、大規模言語モデルの推論コストとパフォーマンスのボトルネックを解決する重要な技術的進展であり、特に RAG やエージェント型 AI などの複雑なユースケースにおいて、スケーラビリティと応答速度の両立を可能にします。AWS のインフラストラクチャとオープンソースの vLLM を統合した実装例は、業界全体が直面しているマルチノード分散推論の課題に対する具体的な解決策を示すものとして、クラウド上の LLM 運用標準に影響を与える可能性があります。
編集コメント
LLM 推論のボトルネックである「Prefill と Decode の競合」を物理的に分離する手法は、実運用におけるレイテンシ改善の有力な選択肢となり得ます。特に AWS のハイパフォーマンスネットワーク技術と vLLM を組み合わせた具体的な実装例は、大規模展開を検討しているエンジニアにとって即戦力となる知見です。
GPU でプレフィルとデコードを共有すると、長いプロンプトにより、すべての並行リクエストに対してトークン生成が停止してしまいます。Disaggregated Prefill and Decode (DPD) は、Elastic Fabric Adapter (EFA) を介して接続された別々の GPU プールで各フェーズを実行し、Remote Direct Memory Access (RDMA) を利用することで、この干渉を解消します。
大規模言語モデル(LLM)の推論には、根本的に異なる 2 つのフェーズがあります。プレフィルは計算集約型です。これは、入力プロンプト全体を並列処理して、初期のキーバリュー (KV) キャッシュを生成します。デコードはメモリー集約型です。これは一度に 1 トークンを生成し、モデル重みと成長する KV キャッシュへのアクセスには大量のメモリー帯域幅が必要です。
これらを専門的なエンジンに分離することで、各フェーズに異なる並列戦略を割り当てることができます。この分離により、最初のトークンまでの時間 (TTFT) とトークン間のレイテンシ (ITL) を独立して調整でき、チャンクドプレフィルのチューニングよりも信頼性が高くテールレイテンシを制御し、長いコンテキストを持つプレフィルが進行中のデコードリクエストをブロックすることを防ぐことができます。
vLLM は、連続バッチ処理と PagedAttention によって単一ノードの効率を向上させます。しかし、大規模展開を行う組織は、マルチノード展開のオーケストレーションやルーティングの最適化において依然として課題に直面しています。
本稿では、HyperPod Inference Operator を使用して Amazon SageMaker HyperPod 上で vLLM とともに DPD を実装する方法を示します。

分離型推論の適用タイミング
プレフィルとデコードを分離することで、長文コンテキストや高同時実行ストリーミングワークロードにおいて最大の効果が得られます。具体的には、チャットアシスタント、エージェントパイプライン、ドキュメント分析エンドポイント、および大規模な検索コンテキストを持つ検索拡張生成(RAG)などが該当します。これらのケースでは、単一の長いプロンプトが配置された GPU で処理される際、他のすべてのリクエストに対する実行中のデコードが停止し、トークンごとのレイテンシの急上昇を引き起こします。DPD はこの問題を構造的に解消します。
DPD の適用を検討すべきワークロードとは:
- 4,096 トークンを定期的に超える入力プロンプトを持つ場合。
- 複数の同時実行ユーザーまたはリクエストが存在する場合。
- トークンの一貫した配信が重要なストリーミングレスポンスを必要とする場合。
- 長いプロンプトと短いプロンプトの両方を含む混合トラフィックの場合。
GPU の競合が問題にならない場合は、配置型(colocated)デプロイの方がシンプルです。これは、TTFT(Time To First Token)を最適化するバッチ処理やオフラインワークロード、低同時実行のデプロイメント、または短いプロンプトのみを対象としたトラフィックに適しています。ルーティング閾値以下では、EFA RDMA を介して KV キャッシュを転送する固定コストが、デコードを分離することによるメリットを上回ります。DPD ルーターはこれらのリクエストを直接デコーダーへ送信します。その結果、単一のエンドポイントで長いプロンプトと短いプロンプトの混合トラフィックを自動的に処理でき、手動でのルーティングロジックは不要となります。
DPD には、少なくとも RDMA 対応の EFA ネットワークを備えた 1 つの Prefill ノードと 1 つの Decode ノードが必要です。サポートされているインスタンスタイプについては、「HyperPod クラスターに DPD モデルエンドポイントのデプロイ」セクションをご覧ください。
アーキテクチャ
HyperPod の DPD 実装は、vLLM Production Stack ルーターを基盤として構築されており、NIXL と EFA を介した KV キャッシュ転送層には LMCache が提供されています。このデプロイメントには、3 つのコンポーネントとトランスポートスタックが含まれます。

インテリジェントルーター
ルーターは制御プレーンです。各プロンプトをトークン化し、設定可能なトークン閾値を適用して、リクエストが分離パスを経由するか、デコーダー上でエンドツーエンドで実行されるかを決定します。長文コンテキストのプロンプトは、まず Prefiller を経由してから Decoder へ送られます。短いプロンプトは Prefiller をスキップし、有益ではないクロス GPU の KV キャッシュ転送を回避します。分離リクエストの場合、Prefiller に計算と KV キャッシュのデコーダーへのプッシュを指示し、その後生成のためにそのデコーダーへリクエストを転送します。また、replica 間でのキャッシュ局所性を最大化するために、intelligentRoutingSpec.routingStrategy を介して per-prefiller ルーティング戦略(prefixaware, kvaware, session, roundrobin)もサポートしています。
Prefiller pod
Prefiller は、LMCacheConnectorV1 を介して LMCache を KV コネクタとして使用する vLLM ワーカーです。長いプロンプトに対する KV キャッシュを計算し、LMCache の PD 送信者バックエンドレイヤーを通じて層ごとに選択されたデコーダへプッシュします。これにより、計算と転送が重なることで GPU を飽和状態に保ちます。また、LMCache は各 Prefiller に L1 CPU キャッシュも提供します。プレフィックスが再出現する場合(システムプロンプト、多回対話の履歴、検索コンテキストなど)、GPU の再計算を行わずに CPU メモリからサービスを提供するため、TTFT(Time To First Token)の大幅な向上を実現します。InferenceEndpointConfig で DPD を有効化すると、コネクタとキャッシュが自動的にプロビジョニングされます。
Decoder pod
デコーダは、LMCache を受信側として使用する vLLM ワーカーです。着信する KV 転送のために GPU メモリ(PD バッファ)を確保します。このバッファサイズは PD_BUFFER_SIZE によって決定されます。デコードカーネルには完全な CUDA グラフを実行し、転送が完了した瞬間に生成を開始します。デコーダはプレフィルを実行しないため、並列処理下でもデコードレイテンシは安定しており、長文コンテキストのリクエストを追加しても、すでにストリーミング中のトークンを妨げることはありません。
KV transfer
KV キャッシュ転送は、HyperPod がエンドツーエンドで構築する 4 レイヤーのスタック(LMCache PD → NIXL → libfabric → EFA)を使用します。LMCache の PD バックエンドが、prefiller 側のプット処理と decoder 側の取得処理をオーケストレーションします。NIXL は GPU、CPU、およびリモートピア間における統一されたメモリ抽象化を提供し、適切な RDMA オペレーションを選択します。libfabric プロバイダは EFA をカーネルバイパスかつ GPU-Direct RDMA として公開し、ホスト CPU をデータパスから除外します。これにより、転送コストは prefill 計算に対して無視できるほど小さくなります。具体的には、3,200 Gbps の EFA を備えた ml.p5.48xlarge インスタンスにおいて、Llama 3.3 70B の 8,000 トークンの転送は単一桁のミリ秒で完了します。HyperPod はこのスタックを事前統合した状態で提供するため、DPD サポート対応のワーカーイメージを選択するだけで、オペレーターが各ポッド上でコネクタ、NIXL、および EFA の接続を自動的に設定します。
Deployment overview
Disaggregated Prefill and Decode (DPD) は、HyperPod Inference Operator によって実装される機能です。本セクションでは、前提条件、推論オペレーターのインストール方法、および DPD を活用して Llama 70B モデルを効率的にサーブするための推論エンドポイントのデプロイ手順について解説します。
前提条件と HyperPod Inference Operator のインストール
AWS Command Line Interface (AWS CLI)、HyperPod クラスターへの kubectl アクセス、HuggingFace トークン、および十分なサービスクォータがあることを確認してください。ローカルの kubectl 設定を設定して、HyperPod クラスターに接続できるようにします。詳細については、Disaggregated Prefill and Decode for HyperPod inference を参照してください。
DPD (Disaggregated Prefill and Decode: 分離型プリフィルおよびデコード) には、HyperPod Inference Operator のバージョン 3.2 以降が必要です。このオペレーターは、新しい HyperPod EKS クラスターではデフォルトでインストールされています。インストール、セットアップ、アップグレードの手順については、Unlock efficient model deployment: simplified Inference Operator setup on Amazon SageMaker HyperPod を参照してください。
以下のコマンドを実行して、オペレーターのバージョンを確認してください:
kubectl get deployment hyperpod-inference-operator-controller-manager \
-n hyperpod-inference-system \
-o jsonpath='{.spec.template.spec.containers[?(@.name=="manager")].image}{"\n"}'
出力には、完全なコンテナイメージの参照が表示されます。末尾のタグにバージョン情報が含まれており、例えば以下のようになります:
XXXXXXXXXXXXXXX.dkr.ecr.us-east-2.amazonaws.com/hyperpod-inference-operator:v3.2
オペレーターバージョンが最新でない場合は、HyperPod Inference Operator リリースノート のアップグレード手順に従って、続行する前にアップグレードしてください。
HyperPod クラスターに DPD モデルエンドポイントをデプロイする
この例では、Meta Llama 3.3 70B モデルを 2 つの ml.p5.48xlarge インスタンス上でデプロイします。続行する前に、HyperPod クラスター内のインスタンスグループにこれらのインスタンスが利用可能であることを確認してください。DPD(Disaggregated Prefill and Decode)推論デプロイメントでは、NVLink と EFA(Elastic Fabric Adapter)の両方をサポートするインスタンスタイプを選択してください。EFA は読み取りおよび書き込みモードでの RDMA(Remote Direct Memory Access)をサポートしている必要があります。これには AWS 上の P5 および P6 インスタンスタイプファミリーが含まれます。なお、EFA の高帯域幅通信のためには、インスタンスは同じアベイラビリティゾーン(AZ)内に配置されている必要があります。G6、G6e、G7e インスタンスタイプファミリーも RDMA 読み取り/書き込みを備えた EFA をサポートしていますが、マルチ GPU インスタンスにおけるパフォーマンスは、PCI を介した GPU から GPU への通信によってボトルネックになります。
推論デプロイメント用のワーカーイメージには、vLLM、LMCache、NVIDIA NIXL、および EFA libfabric プロバイダーが含まれている必要があります。執筆時点では、2 つのイメージオプションをサポートしています:
- オープンソース LMCache: lmcache/vllm-openai v0.4.3。
- SageMaker Deep Learning Container (DLC): vllm:server-hyperpod-cuda-v1.1。
モデルチェックポイントの場所
HyperPod Inference Operator は、Amazon Simple Storage Service (Amazon S3) バケット、Amazon FSx ファイルシステム、HuggingFace からの直接プル、および インスタンスの NVMe ストレージ を含む、幅広いチェックポイント読み込みソースをサポートしています。本記事では、モデルチェックポイントを Amazon S3 バケットからロードします。
HyperPod クラスターと同じリージョンにある S3 バケットに、お好みのモデルチェックポイントがダウンロードされていることを確認してください。まだ行っていない場合は、バケット名と HuggingFace トークンを設定し、HuggingFace から Meta Llama 3.3 70B Instruct をダウンロードして Amazon S3 に同期してください。Amazon S3 への高帯域幅ネットワークを実現するためには、Amazon Elastic Compute Cloud (Amazon EC2) インスタンスからこの操作を実行することを推奨します。
export MODEL_BUCKET=
export MODEL_PREFIX=Llama-3.3-70B-Instruct
export AWS_REGION=
export HF_TOKEN=
pip install -U "huggingface_hub[cli]" "huggingface_hub[hf-transfer]"
HF_HUB_ENABLE_HF_TRANSFER=1 hf download meta-llama/Llama-3.3-70B-Instruct \
--local-dir ./$MODEL_PREFIX \
--token "$HF_TOKEN"
aws s3 sync ./$MODEL_PREFIX \
s3://$MODEL_BUCKET/$MODEL_PREFIX/ \
--region "$AWS_REGION"モデルデプロイマニフェストを準備し、必要に応じて環境変数を変更してください。
export DEPLOYMENT_NAME="dpd-test-deployment"
export ENDPOINT_NAME="dpd-test"
export MODEL_NAME="meta-llama-3-3-70b"
export NAMESPACE="default"
export INSTANCE_TYPE="ml.p5.48xlarge"
export GPUS_PER_NODE="8"
export MODEL_IMAGE="lmcache/vllm-openai:v0.4.3"
完全なデプロイ YAML は、DPD エンドポイントのデプロイを参照してください。
DPD 関連のデプロイマニフェスト内のフィールド
InferenceEndpointConfig のほとんどのフィールドは、非 DPD エンドポイントと共有されており、Inference Operator ドキュメントで文書化されています。以下のフィールドは、DPD において必須であるか、または異なる意味を持ちます。
spec.pdSpec: プリフィル/デコードのトポロジを宣言し、引数を指定します。このフィールドが存在することが、エンドポイントを非集約型にする要因となります。オペレーターは、プリフィルとデコードのために個別の Deployment オブジェクトを作成し、ルーターおよび LMCache PD バックエンドを通じてこれらを接続します。
- replicas: プリフィルとデコードを独立してスケールします。
- resources: ロールのポッド仕様に適用されます。DPD ポッドではトップレベルの worker.resources は無視され、ロールごとの値が優先されます。
- routingThreshold: リクエストが非集約パスを使用するトークン長のしきい値です。このしきい値以下の場合、リクエストはプリフィルラーをバイパスして直接デコーダーへ送られます。
- args: そのロール固有の vLLM フラグで、起動時に worker.args にマージされます。worker.args に既に存在するフラグはロールごとの値に置き換えられ、存在しないフラグは追加されます。
spec.worker.environmentVariables: これらの環境変数はプリフィルラーとデコーダーのコンテナの両方に同一の方法で適用されます。現時点ではロールごとの環境変数フィールドはありません。ロールごとの動作については、代わりに pdSpec.{prefillSpec,decodingSpec}.args を使用してください。
環境変数に関する詳細は DPD エンドポイントのデプロイ をご覧ください。
マニフェストを適用してデプロイメントを検証する
kubectl apply -f inference_endpoint_dpd_config.yaml
オペレーターは、名前空間内に 2 つの Deployment オブジェクトと hyperpod-inference-system にルーター用の Deployment を作成します。イメージのプルとモデルの読み込みには数分かかります。ポッドはまず ContainerCreating 状態に入り、その後コンテナが起動すると Running 状態になります。両方の名前空間にわたってポッドを一覧表示してください:
kubectl get pods -A \
| grep -E "prefill-${DEPLOYMENT_NAME}|decode-${DEPLOYMENT_NAME}|${DEPLOYMENT_NAME}-${NAMESPACE}-router"
NAMESPACE NAME READY STATUS RESTARTS AGE
default prefill-dpd-test-deployment-XXXX 3/3 Running 0 7m
default decode-dpd-test-deployment-XXXX 3/3 Running 0 7m
hyperpod-inference-system dpd-test-deployment-default-router-XXXX 2/2 Running 0 7m
各モデルポッドには 3 つのコンテナが含まれています:vLLM ワーカー、Nginx リバースプロキシ(reverse proxy)、および OpenTelemetry カレータです。ルーターポッドには 2 つのコンテナ(router, otel)があります。IEC 条件は準備完了を報告します:
kubectl get inferenceendpointconfig ${DEPLOYMENT_NAME} -n ${NAMESPACE} \
-o jsonpath='{.status.conditions[0].message}{"\n"}'
DPD prefill および decode デプロイメントが準備完了しました
エンドポイントの呼び出しと KV 転送の確認
エンドポイントが準備できたら、短いプロンプトと長いプロンプトを送信して両方のルーティングパスを動作させます。prefiller と decoder のログを確認し、KV キャッシュ(key-value cache)が EFA を介して転送されていることを確認します。以下のコマンドは、IEC が前述のマニフェストと同じ ${NAMESPACE}、${ENDPOINT_NAME}、および ${DEPLOYMENT_NAME} でデプロイされたことを前提としています。
必要なポッド名とルーター URL を取得します:
PREFILL_POD=$(kubectl get pod -n ${NAMESPACE} \
-l 'inference.sagemaker.aws.amazon.com/dpd-role=prefill' \
-o jsonpath='{.items[0].metadata.name}')
DECODE_POD=$(kubectl get pod -n ${NAMESPACE} \
-l 'inference.sagemaker.aws.amazon.com/dpd-role=decode' \
-o jsonpath='{.items[0].metadata.name}')
ROUTER_POD=$(kubectl get pods -n hyperpod-inference-system -o name \
| grep -- "${DEPLOYMENT_NAME}-${NAMESPACE}-router" | head -1)
ROUTER_URL=http://${DEPLOYMENT_NAME}-${NAMESPACE}-routing-service.hyperpod-inference-system.svc.cluster.local:443/v1/chat/completions
ショートプロンプト(閾値未満、デコーダへの直接パス)
クラスター内のポッドでエンドポイントを呼び出すショートプロンプトを実行します:
kubectl run curl-short --rm -it --image=curlimages/curl --restart=Never -- \
curl -s -k -X POST "$ROUTER_URL" \
-H "Content-Type: application/json" \
-d '{
"model": "/opt/ml/model",
"messages": [{"role": "user", "content": "What is disaggregated prefill-decode in one sentence?"}],
"max_tokens": 80,
"temperature": 0.0
}'{
"id": "chatcmpl-7-...",
"object": "chat.completion",
"model": "/opt/ml/model",
"choices": [{
"index": 0,
"message": {"role": "assistant", "content": "Disaggregated prefill-decode is an inference architecture that ..."},
"finish_reason": "stop"
}]
}
Long prompt (above threshold, DPD path)
4,096 トクンのルーティング閾値を超えるプロンプトは、まずプリフェッチャ(prefiller)を経由し、その後トークン生成のためにデコーダーへルーティングされます。以下の例では、ある文を繰り返し追加して約 6,000 トクンのプロンプトを構築しています:
kubectl run curl-long --rm -it --image=curlimages/curl --restart=Never -- sh -c '
ROUTER="'$ROUTER_URL'"
LONG=""
i=0; while [ $i -lt 600 ]; do LONG="${LONG}The quick brown
原文を表示
When prefill and decode share a GPU, long prompts stall token generation for every concurrent request. Disaggregated Prefill and Decode (DPD) removes this interference by running each phase on separate GPU pools connected through Elastic Fabric Adapter (EFA) with Remote Direct Memory Access (RDMA). Large language model (LLM) inference has two fundamentally different phases. Prefill is compute-bound. It processes the entire input prompt in parallel to generate the initial key-value (KV) cache. Decode is memory-bound. It generates one token at a time and requires substantial memory bandwidth to access model weights and the growing KV cache. By disaggregating these into specialized engines, you can assign different parallel strategies to each phase. With this separation, you can tune time to first token (TTFT) and inter-token latency (ITL) independently, control tail latency more reliably than chunked prefill tuning, and keep long-context prefills from blocking ongoing decode requests. vLLM improves single-node efficiency through continuous batching and PagedAttention. However, organizations that deploy at scale still face challenges when they orchestrate multi-node deployments and optimize routing.
In this post, we show how to implement DPD with vLLM on Amazon SageMaker HyperPod using the HyperPod Inference Operator.

When to use disaggregated inference
Disaggregating prefill and decode delivers the strongest gains for long-context, high-concurrency streaming workloads: chat assistants, agentic pipelines, document-analysis endpoints, and Retrieval Augmented Generation (RAG) with large retrieved contexts. In these cases, a single long prompt on a colocated GPU stalls in-flight decode for every other request, causing per-token latency spikes that DPD removes by construction.
Consider DPD when your workload has:
- Input prompts that regularly exceed 4,096 tokens.
- Multiple concurrent users or requests.
- Streaming responses where consistent token delivery matters.
- Mixed traffic with both long and short prompts.
A colocated deployment is the simpler choice when GPU contention is not a real concern: batch or offline workloads optimizing for TTFT, low-concurrency deployments, or short-prompt-only traffic. Below the routing threshold, the fixed cost of transferring KV cache over EFA RDMA outweighs the benefit of isolating decode. The DPD router sends those requests straight to a decoder. A single endpoint therefore handles mixed long and short traffic automatically, without manual routing logic.
DPD requires at minimum one prefill node and one decode node with RDMA-capable EFA networking. For supported instance types, see the Deploy a DPD model endpoint to your HyperPod cluster section.
Architecture
The HyperPod DPD implementation is built on the vLLM Production Stack router, with LMCache providing the KV cache transfer layer over NIXL and EFA. The deployment has three components plus a transport stack.

Intelligent router
The router is the control plane. It tokenizes each prompt and applies a configurable token threshold to decide whether the request takes the disaggregated path or runs end-to-end on a decoder. Long-context prompts go through a prefiller then a decoder. Short prompts skip the prefiller, avoiding cross-GPU KV transfer that isn’t worthwhile. For disaggregated requests, it directs the prefiller to compute and push KV cache to a decoder, then forwards the request to that decoder for generation. It also supports per-prefiller routing strategies (prefixaware, kvaware, session, roundrobin) through intelligentRoutingSpec.routingStrategy to maximize cache locality across replicas.
Prefiller pod
The prefiller is a vLLM worker with LMCache as its KV connector through LMCacheConnectorV1. It computes KV cache for long prompts and pushes it to the chosen decoder via LMCache’s PD sender backend layer-by-layer, overlapping compute and transfer to keep its GPUs saturated. LMCache also gives each prefiller an L1 CPU cache. When a prefix recurs (system prompts, multi-turn history, retrieval contexts), it serves from CPU memory without GPU recomputation. This produces significant TTFT gains. Activating DPD on an InferenceEndpointConfig provisions both the connector and the cache automatically.
Decoder pod
The decoder is a vLLM worker with LMCache as its receiver. It reserves GPU memory (the PD buffer, sized by PD_BUFFER_SIZE) for incoming KV transfers. It runs full CUDA graphs for the decode kernel and starts generation as soon as the transfer completes. Because it never executes prefill, decode latency stays stable under concurrency and adding a long-context request never disturbs tokens already streaming.
KV transfer
KV cache transfer uses a four-layer stack (LMCache PD → NIXL → libfabric → EFA) that HyperPod composes end-to-end. LMCache’s PD backend orchestrates the prefiller-side put and decoder-side retrieval. NIXL provides a unified memory abstraction across GPU, CPU, and remote peers and selects the right RDMA operation. The libfabric provider exposes EFA as kernel-bypass, GPU-Direct RDMA, keeping the host CPU off the data path. This makes transfer cost negligible relative to prefill compute: on ml.p5.48xlarge with 3,200 Gbps of EFA, an 8,000-token transfer for Llama 3.3 70B takes single-digit milliseconds. HyperPod ships the stack pre-integrated, so you select a DPD-supported worker image and the operator wires up the connector, NIXL, and EFA on every pod.
Deployment overview
Disaggregated Prefill and Decode (DPD) is a functionality implemented by the HyperPod Inference Operator. This section covers prerequisites, installation of the inference operator and deployment of an inference endpoint that uses DPD for efficiently serving a Llama 70B model.
Prerequisites and HyperPod Inference Operator installation
Make sure you have the AWS Command Line Interface (AWS CLI), kubectl access to your HyperPod cluster, a HuggingFace token, and sufficient service quota. Set up your local kubectl configuration to connect to your HyperPod cluster. For more information, see Disaggregated Prefill and Decode for HyperPod inference.
DPD requires HyperPod Inference Operator version 3.2 or later. The operator is installed by default on new HyperPod EKS clusters. For installation, setup, and upgrade instructions, see Unlock efficient model deployment: simplified Inference Operator setup on Amazon SageMaker HyperPod.
Verify your operator version by running:
kubectl get deployment hyperpod-inference-operator-controller-manager \
-n hyperpod-inference-system \
-o jsonpath='{.spec.template.spec.containers[?(@.name=="manager")].image}{"\n"}'The output is the full container image reference. The tag at the end encodes the version, for example:
XXXXXXXXXXX.dkr.ecr.us-east-2.amazonaws.com/hyperpod-inference-operator:v3.2If your operator version is not up-to-date, upgrade before continuing by following the upgrade instructions in the HyperPod Inference Operator Release Notes.
Deploy a DPD model endpoint to your HyperPod cluster
In this example, we deploy the Meta Llama 3.3 70B model on two ml.p5.48xlarge instances. Verify that the instances are available in an instance group within the HyperPod cluster before proceeding. For DPD inference deployments, choose instance types that support both NVLink and EFA. EFA needs to support RDMA in read and write mode. This includes the P5 and P6 instance families on AWS. Note that instances are required to be located within the same Availability Zone (AZ) for EFA high-bandwidth communication. Although G6, G6e, and G7e instance families do support EFA with RDMA read/write, performance on multi-GPU instances is bottlenecked by GPU-to-GPU communication over PCIe.
The worker image for the inference deployment must include vLLM, LMCache, NVIDIA NIXL, and the EFA libfabric provider. At the time of writing, we support two image options:
- Open source LMCache: lmcache/vllm-openai v0.4.3.
- SageMaker Deep Learning Container (DLC): vllm:server-hyperpod-cuda-v1.1.
Model checkpoint location
The HyperPod Inference Operator supports a broad range of checkpoint loading sources, including Amazon Simple Storage Service (Amazon S3) buckets, Amazon FSx file systems, and direct pulling from HuggingFace and the instance NVMe storage. For this post, we load the model checkpoint from an Amazon S3 bucket.
Verify that you have downloaded your preferred model checkpoint to an S3 bucket in the same Region as your HyperPod cluster. If you haven’t done so yet, set up your bucket name and HuggingFace token, then download Meta Llama 3.3 70B Instruct from HuggingFace and sync it to Amazon S3. To achieve high-bandwidth networking to Amazon S3, we recommend that you run this from an Amazon Elastic Compute Cloud (Amazon EC2) instance.
export MODEL_BUCKET=
export MODEL_PREFIX=Llama-3.3-70B-Instruct
export AWS_REGION=
export HF_TOKEN=
pip install -U "huggingface_hub[cli]" "huggingface_hub[hf-transfer]"
HF_HUB_ENABLE_HF_TRANSFER=1 hf download meta-llama/Llama-3.3-70B-Instruct \
--local-dir ./$MODEL_PREFIX \
--token "$HF_TOKEN"
aws s3 sync ./$MODEL_PREFIX \
s3://$MODEL_BUCKET/$MODEL_PREFIX/ \
--region "$AWS_REGION"Prepare the model deployment manifest and change the environment variables as needed:
export DEPLOYMENT_NAME="dpd-test-deployment"
export ENDPOINT_NAME="dpd-test"
export MODEL_NAME="meta-llama-3-3-70b"
export NAMESPACE="default"
export INSTANCE_TYPE="ml.p5.48xlarge"
export GPUS_PER_NODE="8"
export MODEL_IMAGE="lmcache/vllm-openai:v0.4.3"For the full deployment YAML, see Deploy a DPD endpoint.
DPD-relevant fields in the deployment manifest
Most InferenceEndpointConfig fields are shared with non-DPD endpoints and documented in the Inference Operator documentation. The fields below are required or have different semantics for DPD.
spec.pdSpec: Declares the prefill/decode topology and specifies arguments. Presence of this field is what makes the endpoint disaggregated: the operator creates separate Deployment objects for prefill and decode and wires them together through the router and LMCache PD backend.
- replicas: Scale prefill and decode independently.
- resources: Applied to the role’s pod spec. Top-level worker.resources is ignored for DPD pods. Per-role values override.
- routingThreshold: Token length threshold above which requests use the disaggregated path. Below the threshold, requests bypass the prefiller and go directly to the decoder.
- args: vLLM flags specific to that role, merged into worker.args at startup. Flags already in worker.args are replaced with the per-role value, and flags not present are appended.
spec.worker.environmentVariables: These environment variables are applied identically to both the prefiller and decoder containers. There is no per-role environment-variable field today. For per-role behavior, use pdSpec.{prefillSpec,decodingSpec}.args instead.
More details about environment variables are in Deploy a DPD endpoint.
Apply the manifest and validate the deployment
kubectl apply -f inference_endpoint_dpd_config.yamlThe operator creates two Deployment objects in your namespace and a router Deployment in hyperpod-inference-system. Image pull and model load take a few minutes. The pods first enter ContainerCreating, then become Running as containers come up. List the pods across both namespaces:
kubectl get pods -A \
| grep -E "prefill-${DEPLOYMENT_NAME}|decode-${DEPLOYMENT_NAME}|${DEPLOYMENT_NAME}-${NAMESPACE}-router"NAMESPACE NAME READY STATUS RESTARTS AGE
default prefill-dpd-test-deployment-XXXX 3/3 Running 0 7m
default decode-dpd-test-deployment-XXXX 3/3 Running 0 7m
hyperpod-inference-system dpd-test-deployment-default-router-XXXX 2/2 Running 0 7mEach model pod has 3 containers: the vLLM worker, an Nginx reverse proxy, and an OpenTelemetry collector. The router pod has 2 containers (router, otel). The IEC condition reports readiness:
kubectl get inferenceendpointconfig ${DEPLOYMENT_NAME} -n ${NAMESPACE} \
-o jsonpath='{.status.conditions[0].message}{"\n"}'DPD prefill and decode deployments are readyInvoke the endpoint and verify KV transfer
Once the endpoint is ready, send a short and a long prompt to exercise both routing paths. Check the prefiller and decoder logs to confirm KV cache is being transferred over EFA. The following commands assume the IEC was deployed with ${NAMESPACE}, ${ENDPOINT_NAME}, and ${DEPLOYMENT_NAME} set as in the preceding manifest.
Get the required pod names and router url:
PREFILL_POD=$(kubectl get pod -n ${NAMESPACE} \
-l 'inference.sagemaker.aws.amazon.com/dpd-role=prefill' \
-o jsonpath='{.items[0].metadata.name}')
DECODE_POD=$(kubectl get pod -n ${NAMESPACE} \
-l 'inference.sagemaker.aws.amazon.com/dpd-role=decode' \
-o jsonpath='{.items[0].metadata.name}')
ROUTER_POD=$(kubectl get pods -n hyperpod-inference-system -o name \
| grep -- "${DEPLOYMENT_NAME}-${NAMESPACE}-router" | head -1)
ROUTER_URL=http://${DEPLOYMENT_NAME}-${NAMESPACE}-routing-service.hyperpod-inference-system.svc.cluster.local:443/v1/chat/completionsShort prompt (below threshold, direct-to-decoder path)
Run a short prompt through a pod within the cluster that invokes the endpoint:
kubectl run curl-short --rm -it --image=curlimages/curl --restart=Never -- \
curl -s -k -X POST "$ROUTER_URL" \
-H "Content-Type: application/json" \
-d '{
"model": "/opt/ml/model",
"messages": [{"role": "user", "content": "What is disaggregated prefill-decode in one sentence?"}],
"max_tokens": 80,
"temperature": 0.0
}'{
"id": "chatcmpl-7-...",
"object": "chat.completion",
"model": "/opt/ml/model",
"choices": [{
"index": 0,
"message": {"role": "assistant", "content": "Disaggregated prefill-decode is an inference architecture that ..."},
"finish_reason": "stop"
}]
}Long prompt (above threshold, DPD path)
A prompt above the 4,096-token routing threshold is routed through the prefiller, then to the decoder for token generation. The following example builds a roughly 6,000-token prompt by repeating a sentence:
kubectl run curl-long --rm -it --image=curlimages/curl --restart=Never -- sh -c '
ROUTER="'"$ROUTER_URL"'"
LONG=""
i=0; while [ $i -lt 600 ]; do LONG="${LONG}The quick brown
関連記事
今日のまとめ
AI日報で今日の重要ニュースをまとめ読み