기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.
HyperPod 추론을 위한 분해된 사전 채우기 및 디코딩
DPD(Disaggregated Prefill and Decode)는 LLM 추론의 두 단계인 사전 채우기 및 디코딩을 전용 GPU 풀로 분리하고 GPU-Direct Remote Direct Memory Access(RDMA)를 사용하여 EFA(Elastic Fabric Adapter)를 통해 키-값(KV) 캐시를 전송합니다.
동일한 GPU(콜로케이션)에서 사전 채우기 및 디코딩을 실행할 때 단일 긴 컨텍스트 요청이 다른 클라이언트의 진행 중인 토큰 스트림을 중지하여 로드 시 토큰당 지연 시간을 팽창시킬 수 있습니다. DPD는 한 GPU 세트에서 컴퓨팅 바운드 프리필을 실행하고 다른 GPUs 세트에서 memory-bandwidth-bound운드 디코딩을 실행하여 혼합 트래픽에서 더 예측 가능한 지연 시간을 생성하고 각 단계를 독립적으로 확장할 수 있으므로 이러한 간섭을 제거합니다.
추론 연산자는 라우터 프로비저닝, LMCache 및 NIXL을 통해 포드 사전 채우기 및 디코딩 연결, HyperPod 관찰성과의 통합을 포함하는 오케스트레이션을 처리합니다. 추론 엔드포인트에 이미 사용하는 것과 동일한 InferenceEndpointConfig 리소스에 pdSpec 섹션을 추가하여 DPD를 활성화할 수 있습니다.
DPD가 도움이 되는 경우
DPD는 다음 조건이 모두 존재할 때 가장 큰 이점을 제공합니다.
-
고밀도 대형 모델 - 70B 이상의 파라미터(예: Llama 3.3 70B).
-
긴 입력 - 4,000개 이상의 입력 토큰. 토큰 간 지연 시간(ITL) 개선은 입력 길이에 따라 확장됩니다. 사전 채우기가 길수록 공동 배치 시 디코딩 간섭이 더 많이 발생하기 때문입니다.
-
지속적인 동시성 - 초당 2개 이상의 요청. 동일한 GPU에 대해 경쟁하는 동시 요청이 없으면 분해할 필요가 없습니다.
-
중간 또는 긴 출력 - 256개 이상의 출력 토큰. 출력 토큰이 많을수록 안정적인 토큰당 지연 시간의 누적 이점이 커집니다.
워크로드에 짧은 입력이 있거나 동시성이 낮거나 작은 모델을 사용하는 경우 표준 공동 배치 배포가 더 간단하고 성능이 좋습니다.
사전 조건
분해된 사전 채우기 및 디코딩을 사용하는 추론 엔드포인트를 배포하기 전에 로컬 개발 환경에 다음 구성 요소를 설정해야 합니다.
-
kubectl
을 통해 HyperPod Amazon EKS 클러스터에 액세스 -
각 모델 체크포인트에 대한 읽기 액세스를 허용하는 Hugging Face
토큰입니다. 모델 체크포인트가 이미 Amazon S3 버킷에 있는 경우에는 필요하지 않습니다. -
vLLM, LMCache, NVIDIA NIXL 및 EFA libfabric 공급자가 포함된 작업자 이미지입니다. 지원되는 이미지 옵션은 다음과 같습니다.
-
DLC:
public.ecr.aws/deep-learning-containers/vllm:server-hyperpod-cuda-v1.1 -
LMCache:
lmcache/vllm-openai:v0.4.3
두 이미지 모두 LMCache 0.4.3, vLLM 0.19.0 및 NIXL 1.0.0을 포함합니다.
-
-
HyperPod 추론 연산자 버전 3.2 이상이 설치되었습니다. 이전 버전에서는 DPD가 지원되지 않습니다. 연산자는 새로 생성된 HyperPod Amazon EKS 클러스터에 기본적으로 설치됩니다. 기존 클러스터를 사용하려는 경우의 설치 지침을 따릅니다모델 배포를 위한 HyperPod 클러스터 설정. 버전 확인:
kubectl get deployment hyperpod-inference-operator-controller-manager \ -n hyperpod-inference-system \ -o jsonpath='{.spec.template.spec.containers[?(@.name=="manager")].image}{"\n"}'
중요
분해된 사전 채우기 및 디코딩에는 GPU-Direct RDMA를 지원하는 EFA 지원 인스턴스가 필요합니다. 지원되는 인스턴스 유형은 ml.p5.48xlarge, , ml.p5e.48xlarge, ml.p5en.48xlargeml.p6-b200.48xlarge, 입니다ml.p6-b300.48xlarge. DPD에는 다른 인스턴스 유형이 지원되지 않습니다.
DPD 엔드포인트 배포
대부분의 InferenceEndpointConfig 필드는 비 DPD 엔드포인트와 공유되며에 문서화됩니다파운데이션 모델 및 사용자 지정 미세 조정 모델 배포. DPD를 활성화하려면 매니페스트에 다음 섹션을 추가합니다.
사전 채우기 디코딩 사양: pdSpec
사전 채우기/디코딩 토폴로지를 선언하고 인수를 지정합니다. 이 필드가 있으면 엔드포인트가 분해됩니다. 운영자는 사전 채우기 및 디코딩을 위해 별도의 배포를 생성하고 라우터 및 LMCache PD 백엔드를 통해 함께 연결합니다.
pdSpec: prefillSpec: replicas: 1 resources: limits: nvidia.com/gpu: ${GPUS_PER_NODE} requests: nvidia.com/gpu: ${GPUS_PER_NODE} args: - "--gpu-memory-utilization" - "0.75" decodingSpec: replicas: 1 resources: limits: nvidia.com/gpu: ${GPUS_PER_NODE} requests: nvidia.com/gpu: ${GPUS_PER_NODE} routingThreshold: 4096
replicas-
사전 채우기 및 디코딩을 독립적으로 조정합니다.
resources-
역할의 포드 사양에 적용됩니다. DPD 포드의 경우 최상위는 무시
worker.resources되고 역할별 값은 재정의됩니다. routingThreshold-
요청을 분해된 경로로 라우팅하는 토큰 길이 임계값입니다. 이 임계값을 충족하지 않는 요청은 프리필러를 우회하고 디코더로 직접 이동합니다.
args-
해당 역할에 특정한 vLLM 플래그입니다. 시작
worker.args시에 병합됨: 이미에 있는 플래그worker.args가 역할당 값으로 대체되고 존재하지 않는 플래그가 추가됩니다.
DPD 환경 변수: environmentVariables
이러한 환경 변수는 프리필러 및 디코더 컨테이너 모두에 동일하게 적용되며, 역할별 env-var 필드는 없습니다. 역할별 동작의 경우 pdSpec.{prefillSpec,decodingSpec}.args 대신를 사용합니다.
environmentVariables: - name: PD_BUFFER_SIZE value: "8589934592" - name: LMCACHE_SAVE_DECODE_CACHE value: "False" - name: PYTHONHASHSEED value: "0"
PD_BUFFER_SIZE(8GiB)-
들어오는 KV 캐시 전송을 위해 디코더에 예약된 GPU 버퍼로, 순위별로 크기가 조정됩니다. TP=8의 Llama 70B의 경우 각 토큰의 KV 캐시는 순위당 약 40KB이므로 6000토큰 프롬프트는 순위당 약 0.23GB를 차지하고 8GiB는 이러한 전송 중 전송을 약 35개 보유합니다. 버퍼가 용량을 초과하면 디코더 로그
Failed to allocate memory object, retrying...와 클라이언트에 지연 시간이 급증합니다. 16/32GiB로 늘리거나 필요한decodingSpec.replicas경우 확장합니다. LMCACHE_SAVE_DECODE_CACHE:"False"-
디코더에서 중복 L1 캐싱을 비활성화합니다. 프리필러는 캐시 적중의 정확한 소스입니다.
PYTHONHASHSEED:"0"-
LMCache는 Python의 내장 기능을
hash()사용하여 프롬프트 토큰 캐시 키를 계산합니다. Python은 기본적으로 프로세스당 해당 해시 시드를 무작위화하므로 동일한 프롬프트가 프리필러 및 디코더에서 다른 키를 생성하고 조회가 누락됩니다. 시드를 고정하면 포드 간에 키가 일치합니다.
라우팅 전략 구성
이 intelligentRoutingSpec 섹션에서는 DPD 라우터가 각 요청에 대한 프리필러를 선택하는 데 사용하는 라우팅 전략을 설정합니다. 이 pdSpec 있으면 라우터가 자동으로 생성됩니다.이 섹션은 선택 사항이며 기본값은 입니다prefixaware.
intelligentRoutingSpec: enabled: true routingStrategy: prefixaware
DPD를 지능형 라우팅 및 KV 캐싱과 통합할 수도 있습니다. 자세한 내용은 KV 캐싱 및 지능형 라우팅 구성 단원을 참조하십시오.
단일 사전 채우기 복제본을 사용하면 모든 전략이 해당 복제본으로 라우팅됩니다. 선택 사항은 prefillSpec.replicas > 1다음과 같은 경우에만 동작에 영향을 줍니다.
-
단일 사전 채우기 복제본의 경우 프롬프트가 시스템 프롬프트 또는 채팅 기록과 같은 공통 접두사를 공유할 때
prefixaware(기본값)을 사용하여 KV 캐시 적중을 극대화합니다. -
여러 사전 채우기 복제본의 경우
roundrobin를 사용하여 복제본 간에 로드를 균등하게 분산하고 단일 사전 채우기 도구의 핫스팟을 방지합니다.
전체 예제
다음 매니페스트는 2개의 ml.p5.48xlarge 인스턴스(프리필러 1개, 디코더 1개)에 Llama 3.3 70B를 배포합니다.
apiVersion: inference.sagemaker.aws.amazon.com/v1 kind: InferenceEndpointConfig metadata: name: dpd-test namespace: default spec: endpointName: dpd-test instanceType: ml.p5.48xlarge invocationEndpoint: v1/chat/completions modelName: Llama-3.3-70B-Instruct modelSourceConfig: modelSourceType: s3 modelLocation: Llama-3.3-70B-Instruct s3Storage: bucketName: <YOUR_BUCKET> region: <YOUR_REGION> loadBalancer: healthCheckPath: /health metrics: enabled: true kvCacheSpec: enableL1Cache: true intelligentRoutingSpec: enabled: true routingStrategy: prefixaware pdSpec: prefillSpec: replicas: 1 resources: requests: nvidia.com/gpu: "8" limits: nvidia.com/gpu: "8" decodingSpec: replicas: 1 resources: requests: nvidia.com/gpu: "8" limits: nvidia.com/gpu: "8" routingThreshold: 4096 worker: image: public.ecr.aws/deep-learning-containers/vllm:server-hyperpod-cuda-v1.1 args: - "--model" - "/opt/ml/model" - "--host" - "0.0.0.0" - "--port" - "8000" - "--tensor-parallel-size" - "8" - "--max-model-len" - "16384" - "--gpu-memory-utilization" - "0.75" modelInvocationPort: name: http containerPort: 8000 modelVolumeMount: name: model-weights mountPath: /opt/ml/model resources: requests: cpu: "96" memory: 1024Gi nvidia.com/gpu: "8" limits: cpu: "96" memory: 1024Gi nvidia.com/gpu: "8" environmentVariables: - name: HF_HOME value: /tmp/hf_home - name: PD_BUFFER_SIZE value: "8589934592" - name: LMCACHE_SAVE_DECODE_CACHE value: "False" - name: PYTHONHASHSEED value: "0"
매니페스트를 적용합니다.
kubectl apply -f inference_endpoint_dpd_config.yaml
배포 확인
이미지 가져오기 및 모델 로드에는 몇 분 정도 걸립니다. 포드 상태 모니터링:
kubectl get pods -A \ | grep -E "prefill-|decode-|router"
정상 배포는 다음을 보여줍니다.
NAMESPACE NAME READY STATUS RESTARTS AGE default prefill-dpd-test-XXXX 3/3 Running 0 7m default decode-dpd-test-XXXX 3/3 Running 0 7m hyperpod-inference-system dpd-test-router-XXXX 2/2 Running 0 7m
각 모델 포드에는 3개의 컨테이너(vLLM 작업자, Nginx 역방향 프록시, OpenTelemetry 수집기)가 있습니다. 라우터 포드에는 2개의 컨테이너(라우터, OpenTelemetry 수집기)가 있습니다. InferenceEndpointConfig 상태를 확인합니다.
kubectl get inferenceendpointconfig dpd-test -n default \ -o jsonpath='{.status.conditions[0].message}{"\n"}'
예상 결과: DPD prefill and decode deployments are
ready
DPD 역할 확인
프리필러 보고서sender와 디코더 보고서를 확인합니다receiver. 이는 가장 구별되는 단일 시작 신호입니다. 두 포드가 동일한 역할을 보고하거나 둘 다 줄을 인쇄하지 않으면 연산자가 DPD를 올바르게 연결하지 않은 것입니다.
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}') kubectl logs $PREFILL_POD -n ${NAMESPACE} -c prefill-${DEPLOYMENT_NAME} \ | grep -oE "'pd_role': '[a-z]+'" | sort -u kubectl logs $DECODE_POD -n ${NAMESPACE} -c decode-${DEPLOYMENT_NAME} \ | grep -oE "'pd_role': '[a-z]+'" | sort -u
예상 결과:
'pd_role': 'sender' 'pd_role': 'receiver'
API 엔드포인트 호출
엔드포인트가 준비되면 짧고 긴 프롬프트를 보내 두 라우팅 경로를 모두 연습한 다음 로그를 확인하여 EFA를 통한 KV 전송을 확인합니다.
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
짧은 프롬프트(임계값 미만, 디코더로 직접)
프리필러를 routingThreshold 우회하고 디코더로 직접 이동하는 것보다 토큰이 적은 요청:
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 }'
긴 프롬프트(임계값 초과, DPD 경로)
KV 캐시 계산을 위한 프리필러를 통해 임곗값을 초과하는 요청은 토큰 생성을 위해 디코더로 라우팅됩니다.
kubectl run curl-long --rm -it --image=curlimages/curl --restart=Never -- sh -c ' LONG="" i=0; while [ $i -lt 600 ]; do LONG="${LONG}The quick brown fox jumps over the lazy dog. "; i=$((i+1)); done curl -s -k -X POST "'"$ROUTER_URL"'" \ -H "Content-Type: application/json" \ -d "{\"model\":\"/opt/ml/model\",\"messages\":[{\"role\":\"user\",\"content\":\"${LONG}\"}],\"max_tokens\":30,\"temperature\":0.0}" '
KV 전송 확인
긴 프롬프트를 전송한 후 디코더 로그를 확인하여 KV 캐시가 전송되었는지 확인합니다.
kubectl logs $DECODE_POD -n ${NAMESPACE} -c decode-${DEPLOYMENT_NAME} \ | grep -E "Retrieved.*tokens.*throughput" | tail -2
예상 출력(TP 순위당 한 줄):
[Worker_TP5] [LMCache INFO] [req_id=cmpl-...] Retrieved 6035 out of 6035 required tokens (from 6035 total tokens). size: 0.2344 gb, cost 1.3304 ms, throughput: 176.1686 GB/s
Retrieved N out of N required tokens N > 0이면 KV 캐시가 NIXL 채널을 성공적으로 통과했음을 확인합니다. 가 표시되면 디코더Retrieved 0 out of N가 로컬 다시 계산으로 떨어졌습니다. 단원을 참조하십시오분해된 사전 채우기 및 디코딩(DPD) 배포 문제.
라우터 로그에서 라우팅 결정을 확인할 수도 있습니다.
kubectl logs $ROUTER_POD -n hyperpod-inference-system -c router-container --tail=20 \ | grep -E "Conditional routing"
긴 프롬프트의 경우 다음이 표시되어야 합니다.
[INFO] Conditional routing: estimated_tokens=6750, threshold=4096, disaggregate=True
짧은 프롬프트의 경우:
[INFO] Conditional routing: estimated_tokens=12, threshold=4096, disaggregate=False
참고
SageMaker AI AI 엔드포인트를 통해 호출하려면 endpointName에서를 설정합니다InferenceEndpointConfig. endpointName를 설정하지 않으면 SageMaker AI 엔드포인트가 생성되지 않으며 직접 ALB 간접 호출만 사용할 수 있습니다.
관찰성
metrics.enabled: true에서를 설정하여 지표를 활성화합니다InferenceEndpointConfig. DPD 지표는 HyperPod 추론 대시보드에서 사용할 수 있습니다. 자세한 내용은 HyperPod 클러스터에서 추론 관찰성 구현 단원을 참조하십시오.
다음과 같은 DPD별 지표를 사용할 수 있습니다.
| 지표 | 설명 |
|---|---|
| E2E TTFT | 첫 번째 토큰까지의 전체 시간(미리 채우기 + KV 전송 + 라우팅) |
| TTFT 미리 채우기 | 프리필러 전용 지연 시간 |
| 대기열 미리 채우기 | 사전 채우기를 기다리는 요청 수 |
| 대기열 디코딩 | 디코더에서 대기 중인 요청 수 |
| 사전 채우기 시간 | 사전 채우기 계산에 소요된 시간 |
| 디코딩 지연 시간 | 토큰당 출력 지연 시간(TPOT) |
| KV 전송 시간 | 프리필러에서 디코더로 KV 캐시를 전송하는 시간 |
| DPD 라우팅 수 | 분리된 요청과 폴백(임계값 미만) 요청 비교 |
DPD 배포 조정
다음 표는 지표 대시보드에서 관찰한 증상을 기반으로 DPD를 튜닝하기 위한 빠른 참조를 제공합니다.
| 구성 | 하는 일 | 기본값 | 튜닝 시기 |
|---|---|---|---|
pdSpec.routingThreshold |
프리필러를 통해 라우팅할 최소 입력 토큰입니다. 이 임계값 미만의 요청은 디코더로 직접 이동합니다. | 4096 |
기본값은 대부분의 워크로드에 적합합니다. 너무 낮게 설정하면 짧은 프롬프트에서 불필요한 KV 전송으로 인해 TTFT가 증가하지만, 너무 높게 설정하면 DPD 경로를 사용하는 요청이 적기 때문에 TPOT 개선이 제한됩니다. |
pdSpec.prefillSpec.replicas |
사전 채우기 포드 수입니다. | 1 |
사전 채우기 대기열 깊이가 높으면 사전 채우기 TTFT를 개선하기 위해 스케일 업합니다. |
PD_BUFFER_SIZE |
수신 KV 전송을 위한 GPU 버퍼를 디코더합니다(순위별). 8GiB는 TP=8에서 70B에 대해 약 35회의 진행 중인 6K-token 전송을 보유합니다. | "8589934592" (8GiB) |
더 많은 동시 KV 전송을 처리하려면를 늘립니다. 메모리 문제가 발생하면를 줄입니다. 늘릴 때 더 큰 버퍼에 대한 GPU 메모리를 확보하려면 디코더--gpu-memory-utilization를 낮춰야 할 수 있습니다. |
--gpu-memory-utilization |
GPU 메모리 vLLM이 가중치, 활성화 및 KV 캐시에 사용하는 비율입니다. | 0.75 |
긴 입력에서 더 많은 KV 캐시 헤드룸을 늘리세요. 위험: 프리필링에는 활성화를 위한 메모리도 필요하기 때문에 프리필러 OOM. 실제 입력 길이 분포로 테스트합니다. |
--max-num-seqs |
작업자 배치당 최대 동시 시퀀스 수입니다. | 16 (프리필러), 32 (디코더) |
로드 시 배치 처리를 개선하려면를 높입니다. 프리필러에서 OOM에 도달하면를 낮춥니다. 를 통해 역할별로 설정합니다pdSpec.{prefillSpec,decodingSpec}.args. |
intelligentRoutingSpec.routingStrategy |
복제본이 여러 개 있는 경우 라우터가 프리필러를 선택하는 방법. | prefixaware |
roundrobin를 사용하여 여러 프리필러 복제본에 로드를 균등하게 분산합니다. prefixaware 또는를 단일 프리필러와 kvaware 함께 사용하거나 프롬프트가 공통 접두사(시스템 프롬프트, 채팅 기록)를 공유하여 캐시 적중을 극대화할 때 사용합니다. |
실제 워크로드 및 입력 길이 분포로 테스트합니다.
구성 변경 사항을 적용하려면 배포 YAML을 편집하고 다시 적용합니다.
kubectl apply -f inference_endpoint_dpd_config.yaml
알려진 제한 사항
-
DPD는 파라미터가 70B 이상인 밀집 모델에 권장됩니다. 소형 모델과 Mixture-of-Experts 모델은 일반적으로 분해의 이점을 얻지 못합니다.
-
현재 릴리스는 엔드포인트당 단일 디코딩 배포를 지원합니다. 향후 릴리스에서는 여러 디코딩 배포에 대한 지원이 계획되어 있습니다.
-
성능은 Llama 3.3 70B를 사용하는 ml.p5.48xlarge에서 최대 64개의 동시 요청으로 검증됩니다.
-
DPD 배포에서 표준 공동 배치 배포로 되돌리려면
InferenceEndpointConfig없이 새를 적용합니다pdSpec.
DPD 배포 문제 해결은 섹션을 참조하세요분해된 사전 채우기 및 디코딩(DPD) 배포 문제.