

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# Rellene previamente y decodifique de forma desagregada para hacer inferencias HyperPod
<a name="sagemaker-hyperpod-model-deployment-dpd"></a>

El prellenado y la decodificación desagregados (DPD) separan las dos fases de la inferencia LLM, prellenado y decodificación, en grupos de GPU dedicados y transfiere la caché clave-valor (KV) entre ellas a través del Elastic Fabric Adapter (EFA) mediante el acceso remoto directo a la memoria (RDMA). GPU-Direct 

Cuando la precarga y la decodificación se ejecutan en la misma GPU (colocadas), una sola solicitud de contexto prolongado puede detener las transmisiones de tokens en movimiento para otros clientes, lo que aumenta la latencia por token en caso de carga. DPD elimina esta interferencia al ejecutar el rellenado previo vinculado al procesamiento en un conjunto de GPU y la decodificación vinculada al ancho de banda de la memoria en otro, lo que produce una latencia más predecible en caso de tráfico mixto y permite escalar cada fase de forma independiente.

El operador de inferencia se encarga de la organización, que incluye el aprovisionamiento del router, el cableado de los módulos de prellenado y decodificación mediante LMCache y NIXL, y la integración con la observabilidad. HyperPod Para habilitar DPD, agrega una `pdSpec` sección al mismo recurso que ya utilizas para los puntos finales de inferencia. `InferenceEndpointConfig`

## Cuando DPD ayuda
<a name="sagemaker-hyperpod-model-deployment-dpd-when"></a>

El DPD ofrece el mayor beneficio cuando se presentan todas las siguientes condiciones:
+ **Modelos de gran densidad**: más de 70 000 millones de parámetros (por ejemplo, Llama 3.3 70B).
+ **Entradas largas: más de 4000 fichas de entrada**. Inter-token La mejora de la latencia (ITL) se amplía con la longitud de entrada, ya que los prerellenos más largos provocan más interferencias de decodificación cuando se colocan en un mismo lugar.
+ **Simultaneidad sostenida**: más de 2 solicitudes por segundo. Si las solicitudes simultáneas no compiten por la misma GPU, no hay nada que desglosar.
+ **Salidas moderadas o largas**: más de 256 fichas de salida. Más fichas de salida se traducen en más beneficios acumulativos gracias a una latencia estable por ficha.

Si su carga de trabajo tiene entradas cortas, poca simultaneidad o utiliza modelos pequeños, un despliegue compartido estándar es más sencillo y tiene un buen rendimiento.

## Requisitos previos
<a name="sagemaker-hyperpod-model-deployment-dpd-prereqs"></a>

Antes de implementar puntos finales de inferencia que utilicen el prellenado y la decodificación desagregados, debe configurar los siguientes componentes en su entorno de desarrollo local:
+ [AWS Interfaz de línea de comandos (AWS CLI)](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html)
+ Acceda a su clúster de HyperPod Amazon EKS a través de [kubectl](https://kubernetes.io/docs/tasks/tools/)
+ Token [Hugging](https://huggingface.co/) Face que permite el acceso de lectura al punto de control del modelo respectivo. Esto no es obligatorio si el punto de control del modelo ya está ubicado en un bucket de Amazon S3.
+ Una imagen de trabajo que incluye vLLM, LMCache, NVIDIA NIXL y el proveedor libfabric de EFA. Se admiten las siguientes opciones de imagen:
  + DLC: `public.ecr.aws/deep-learning-containers/vllm:server-hyperpod-cuda-v1.1`
  + Caché de LMC: `lmcache/vllm-openai:v0.4.3`

  Ambas imágenes incluyen LMCache 0.4.3, vLLm 0.19.0 y NIXL 1.0.0.
+ HyperPod Se **ha instalado la versión 3.2** o posterior de Inference Operator. Las versiones anteriores no admiten DPD. El operador se instala de forma predeterminada en los clústeres de HyperPod Amazon EKS recién creados. Si piensa utilizar un clúster existente, siga las instrucciones de instalación que se indican en[Configuración de los HyperPod clústeres para la implementación de modelos](sagemaker-hyperpod-model-deployment-setup.md). Compruebe su versión:

  ```
  kubectl get deployment hyperpod-inference-operator-controller-manager \
    -n hyperpod-inference-system \
    -o jsonpath='{.spec.template.spec.containers[?(@.name=="manager")].image}{"\n"}'
  ```

**importante**  
El prellenado y la decodificación desagregados requieren EFA-capable instancias compatibles con GPU-Direct RDMA. Se admiten los siguientes tipos de instancias:`ml.p5.48xlarge`,,,,`ml.p5e.48xlarge`. `ml.p5en.48xlarge` `ml.p6-b200.48xlarge` `ml.p6-b300.48xlarge` DPD no admite otros tipos de instancias.

## Implementa un punto final de DPD
<a name="sagemaker-hyperpod-model-deployment-dpd-deploy"></a>

La mayoría de `InferenceEndpointConfig` los campos se comparten con puntos finales ajenos a DPD y se documentan en ellos. [Implementación de modelos fundacionales y modelos de ajuste fino personalizados](sagemaker-hyperpod-model-deployment-deploy.md) Para habilitar DPD, agrega las siguientes secciones a tu manifiesto.

### Prefill-Decode `Especificación: PDSpec`
<a name="sagemaker-hyperpod-model-deployment-dpd-fields-pdspec"></a>

Declara la prefill/decode topología y especifica los argumentos. La presencia de este campo es lo que hace que el punto final se desagregue: el operador crea despliegues independientes para prerellenar y decodificar y los conecta mediante el router y el backend PD de LMCache.

```
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`  
Escale el prellenado y la decodificación de forma independiente.

`resources`  
Se aplica a las especificaciones del módulo del rol. Top-level`worker.resources`se omite en los pods de DPD; se anulan los valores por rol.

`routingThreshold`  
Umbral de longitud del token que enruta las solicitudes a la ruta desagregada. Las solicitudes que no cumplen con este umbral pasan por alto el prellenado y van directamente al decodificador.

`args`  
Indicadores vLLM específicos para esa función. Combinados `worker.args` al inicio: los indicadores que ya estaban incluidos `worker.args` se sustituyen por el valor de cada rol; los indicadores que no están presentes se añaden.

### `Variables de entorno de DPD: variables de entorno`
<a name="sagemaker-hyperpod-model-deployment-dpd-fields-env"></a>

Estas variables de entorno se aplican de forma idéntica a los contenedores de prerelleno y decodificador; no hay ningún campo env-var por rol. Para conocer el comportamiento por rol, utilícelo en su lugar. `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`(8 GiB)  
Búfer de GPU reservado en el decodificador para las transferencias de caché KV entrantes, dimensionado por rango. Para Llama 70B con TP=8, la caché en KV de cada token es de aproximadamente 40 KB por rango, por lo que un indicador de 6000 fichas ocupa aproximadamente 0,23 GB por rango y 8 GiB contienen aproximadamente 35 transferencias en vuelo de este tipo. Cuando el búfer supera su capacidad, el decodificador registra picos de latencia y los clientes registran picos de latencia. `Failed to allocate memory object, retrying...` Aumente a 16/32 GiB o escale `decodingSpec.replicas` si es necesario.

`LMCACHE_SAVE_DECODE_CACHE`: `"False"`  
Desactiva el almacenamiento en caché L1 redundante en el decodificador. El prerelleno es la fuente verdadera de las visitas a la caché.

`PYTHONHASHSEED`: `"0"`  
LMCache utiliza la tecnología integrada de Python `hash()` para calcular las claves de caché de los símbolos de solicitud. Python aleatoriza esa semilla de hash por proceso de forma predeterminada, por lo que las solicitudes idénticas producen claves diferentes en el prerelleno y el decodificador y las búsquedas fallan. Al fijar la semilla, las claves coinciden en todos los módulos.

### Configure la estrategia de enrutamiento
<a name="sagemaker-hyperpod-model-deployment-dpd-fields-routing"></a>

La `intelligentRoutingSpec` sección establece la estrategia de enrutamiento que el router DPD utiliza para seleccionar un relleno previo para cada solicitud. El router se crea automáticamente cuando `pdSpec` está presente; esta sección es opcional y su valor predeterminado es. `prefixaware`

```
intelligentRoutingSpec:
  enabled: true
  routingStrategy: prefixaware
```

DPD también se puede integrar con el enrutamiento inteligente y el almacenamiento en caché de KV. Para obtener más información, consulte [Configure el almacenamiento en caché KV y el enrutamiento inteligente](sagemaker-hyperpod-model-deployment-caching-routing.md#sagemaker-hyperpod-model-deployment-deploy-ftm-cache-route).

Con una única réplica precargada, todas las estrategias se dirigen a esa réplica. La elección solo afecta al comportamiento cuando`prefillSpec.replicas > 1`:
+ En el caso de una única réplica precargada, `prefixaware` utilícela (opción predeterminada) para maximizar las visitas a la caché de KV cuando las solicitudes comparten prefijos comunes, como las del sistema o el historial de chats.
+ En el caso de varias réplicas de prellenado, utilícelas `roundrobin` para distribuir la carga de manera uniforme entre las réplicas y evitar que se acumule una sola precarga.

### Ejemplo completo
<a name="sagemaker-hyperpod-model-deployment-dpd-deploy-example"></a>

El siguiente manifiesto despliega Llama 3.3 70B en dos instancias ml.p5.48xlarge (una prellenadora y un decodificador):

```
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"
```

Aplique el manifiesto:

```
kubectl apply -f inference_endpoint_dpd_config.yaml
```

## Verifique la implementación
<a name="sagemaker-hyperpod-model-deployment-dpd-verify"></a>

La extracción de la imagen y la carga del modelo tardan varios minutos. Supervise el estado del módulo:

```
kubectl get pods -A \
  | grep -E "prefill-|decode-|router"
```

Una implementación en buen estado muestra:

```
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
```

Cada módulo modelo tiene 3 contenedores (vLLM worker, proxy inverso de Nginx y recopilador). OpenTelemetry El módulo del router tiene 2 contenedores (router y colector). OpenTelemetry Compruebe el `InferenceEndpointConfig` estado:

```
kubectl get inferenceendpointconfig dpd-test -n default \
  -o jsonpath='{.status.conditions[0].message}{"\n"}'
```

Resultado esperado: `DPD prefill and decode deployments are ready`

### Verifica las funciones de DPD
<a name="sagemaker-hyperpod-model-deployment-dpd-verify-roles"></a>

Confirme los informes de prellenado `sender` y los informes del decodificador. `receiver` Esta es la señal de arranque más exigente: si ambos módulos cumplen la misma función o ninguno imprime la línea, el operador no conectó DPD correctamente.

```
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
```

Resultado previsto:

```
'pd_role': 'sender'
'pd_role': 'receiver'
```

## Invocar al punto de conexión
<a name="sagemaker-hyperpod-model-deployment-dpd-invoke"></a>

Una vez que el terminal esté listo, envía un mensaje corto y uno largo para utilizar ambas rutas de enrutamiento y, a continuación, comprueba los registros para confirmar la transferencia de KV a través de EFA.

```
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
```

### Mensaje breve (por debajo del umbral, directo al decodificador)
<a name="sagemaker-hyperpod-model-deployment-dpd-invoke-short"></a>

Las solicitudes con menos fichas que las que se `routingThreshold` envían no tienen que rellenar previamente y van directamente al decodificador:

```
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
    }'
```

### Solicitud larga (supera el umbral, ruta DPD)
<a name="sagemaker-hyperpod-model-deployment-dpd-invoke-long"></a>

Las solicitudes que superan el umbral pasan por el prerelleno para el cálculo de la caché en KV y, luego, al decodificador para la generación del token:

```
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}"
'
```

### Verifica la transferencia en KV
<a name="sagemaker-hyperpod-model-deployment-dpd-invoke-verify-kv"></a>

Tras enviar un mensaje largo, confirme que la caché KV se ha transferido comprobando los registros del decodificador:

```
kubectl logs $DECODE_POD -n ${NAMESPACE} -c decode-${DEPLOYMENT_NAME} \
  | grep -E "Retrieved.*tokens.*throughput" | tail -2
```

Salida esperada (una línea por rango de 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`con N > 0 confirma que la caché KV cruzó el canal NIXL correctamente. Si lo ve`Retrieved 0 out of N`, el decodificador recurrió al recálculo local, consulte. [Problemas de implementación desagregados de prellenado y decodificación (DPD)](sagemaker-hyperpod-model-deployment-ts-dpd.md)

También puede verificar la decisión de enrutamiento en los registros del router:

```
kubectl logs $ROUTER_POD -n hyperpod-inference-system -c router-container --tail=20 \
  | grep -E "Conditional routing"
```

Para el mensaje largo, deberías ver:

```
[INFO] Conditional routing: estimated_tokens=6750, threshold=4096, disaggregate=True
```

Para el mensaje corto:

```
[INFO] Conditional routing: estimated_tokens=12, threshold=4096, disaggregate=False
```

**nota**  
Para invocar a través de un punto final de SageMaker IA, configure `endpointName` su`InferenceEndpointConfig`. Si no `endpointName` está configurado, no se crea ningún punto final de SageMaker IA y solo está disponible la invocación directa de ALB.

## Observabilidad
<a name="sagemaker-hyperpod-model-deployment-dpd-observability"></a>

Habilite las métricas `metrics.enabled: true` configurando su. `InferenceEndpointConfig` Las métricas de DPD están disponibles en el panel de HyperPod inferencias. Para obtener más información, consulte [Implementar la observabilidad de inferencias en clústeres HyperPod](sagemaker-hyperpod-model-deployment-observability.md).

Están disponibles las siguientes DPD-specific métricas:


**DPD-specific métricas**  

| Métrica | Description (Descripción) | 
| --- | --- | 
| E2E TTFT | Tiempo total hasta el primer token (prellenado \+ transferencia KV \+ enrutamiento) | 
| Rellene previamente el TTFT | Prefiller-only latencia | 
| Cola de prellenado | Número de solicitudes pendientes de prellenado | 
| Cola de decodificación | Número de solicitudes en espera en el decodificador | 
| Tiempo de prellenado | Tiempo dedicado al cálculo previo | 
| Decodifique la latencia | Per-token latencia de salida (TPOT) | 
| Tiempo de transferencia en KV | Es hora de transferir la caché KV del prellenador al decodificador | 
| El enrutamiento DPD cuenta | Solicitudes desagregadas frente a solicitudes alternativas (por debajo del umbral) | 

## Ajuste su implementación de DPD
<a name="sagemaker-hyperpod-model-deployment-dpd-tuning"></a>

La siguiente tabla proporciona una referencia rápida para ajustar el DPD en función de los síntomas que observe en su panel de métricas.


**Referencia de ajuste del DPD**  

| Config | ¿Qué hace? | Predeterminado | ¿Cuándo afinar | 
| --- | --- | --- | --- | 
| pdSpec.routingThreshold | Número mínimo de fichas de entrada para pasar por el prerelleno. Las solicitudes por debajo de este umbral van directamente al decodificador. | 4096 | El valor predeterminado funciona bien para la mayoría de las cargas de trabajo. Si se establece un valor demasiado bajo, se aumenta el TTFT debido a las transferencias innecesarias de KV en las solicitudes cortas, mientras que si se establece un valor demasiado alto, se limita la mejora del TPOT, ya que hay menos solicitudes que siguen la ruta de DPD. | 
| pdSpec.prefillSpec.replicas | Número de cápsulas precargadas. | 1 | Aumente la escala si la profundidad de la cola de prellenado es alta para mejorar la TTFT de prellenado. | 
| PD\_BUFFER\_SIZE | Decodificador: búfer de GPU para las transferencias KV entrantes (por rango). 8 GiB contienen aproximadamente 35 K-token transferencias en vuelo, 6 para 70 B a TP=8. | "8589934592"(8 GiB) | Aumente para gestionar más transferencias KV simultáneas. Disminuya si observa problemas de memoria. Al aumentar, es posible que tengas que colocar el decodificador a una --gpu-memory-utilization posición inferior para liberar memoria de la GPU y poder utilizarla en el búfer más grande. | 
| --gpu-memory-utilization | Fracción de la memoria de la GPU que VLLM utiliza para pesos, activaciones y caché de KV. | 0.75 | Aumente para obtener más espacio de caché en KV en entradas largas. Riesgo: rellenar previamente el OOM, ya que el prellenado también necesita memoria para las activaciones. Pruébelo con su distribución de longitud de entrada real. | 
| --max-num-seqs | Máximo de secuencias simultáneas por lote de trabajadores. | 16(prerelleno), (decodificador32) | Levántelo para un mejor procesamiento por lotes bajo carga. Baje si pulsa OOM en la prellenadora. Se establece por rol a través de. pdSpec.{prefillSpec,decodingSpec}.args | 
| intelligentRoutingSpec.routingStrategy | Cómo selecciona el router un prerelleno cuando existen varias réplicas. | prefixaware | roundrobinUtilícelo para distribuir uniformemente la carga entre varias réplicas de prellenado. prefixawareÚsalo kvaware con un solo relleno previo o cuando los mensajes compartan prefijos comunes (mensajes del sistema, historial de chat) para maximizar las visitas a la memoria caché. | 

Realice pruebas con su carga de trabajo real y la distribución de la longitud de entrada.

Para aplicar los cambios de configuración, edita el YAML de tu implementación y vuelve a aplicarlo:

```
kubectl apply -f inference_endpoint_dpd_config.yaml
```

## Limitaciones conocidas
<a name="sagemaker-hyperpod-model-deployment-dpd-limitations"></a>
+ Se recomienda el uso de DPD para modelos densos con 70 B o más parámetros. Los modelos y Mixture-of-Experts modelos más pequeños no suelen beneficiarse de la desagregación.
+ La versión actual admite un único despliegue de decodificación por punto final. El soporte para múltiples despliegues de decodificación está previsto para una futura versión.
+ El rendimiento se valida hasta en 64 solicitudes simultáneas en ml.p5.48xlarge con Llama 3.3 70B.
+ Para pasar de una implementación de DPD a una implementación conjunta estándar, aplica una nueva implementación sin ella. `InferenceEndpointConfig` `pdSpec`

Para solucionar problemas de las implementaciones de DPD, consulte. [Problemas de implementación desagregados de prellenado y decodificación (DPD)](sagemaker-hyperpod-model-deployment-ts-dpd.md)