

 **Ayude a mejorar esta página** 

Para contribuir a esta guía del usuario, elija el enlace **Edit this page on GitHub** que se encuentra en el panel derecho de cada página.

# Aceleración de la carga de modelos en Amazon EKS
<a name="ml-inference-fast-model-loading"></a>

Al implementar modelos de lenguaje de gran tamaño (LLM) en Amazon EKS, el tiempo de carga de los modelos afecta directamente a la rapidez con la que los pods pueden comenzar a atender las solicitudes de inferencia. Esto es especialmente cierto durante los eventos de escalado vertical, cuando los nuevos pods o nodos deben cargar el modelo antes de gestionar el tráfico. El inicio del modelo consta de dos fases que puede mejorar al ajustar y almacenar en caché los artefactos de compilación:
+  **Carga de pesos:** transmisión de archivos de pesos del modelo desde Amazon S3 a la memoria de la GPU mediante [Run:ai Model Streamer](https://github.com/run-ai/runai-model-streamer).
+  **torch.compile:** compilación del gráfico de computación del modelo en kernels de CUDA o Triton fusionados optimizados. Esta compilación se ejecuta en el primer inicio y puede afectar significativamente al tiempo de inicio en función del tamaño del modelo.

En este tema, se muestra cómo optimizar el rendimiento de Run:ai Model Streamer y el almacenamiento en caché de torch.compile para reducir ambas fases del proceso de carga del modelo. Para ver el procedimiento completo de implementación de vLLM en Amazon EKS para inferencia, consulte [Modelos de carga y servicio en Amazon EKS](ml-inference-load-serve-model.md).

## Optimización de la ruta de red de S3 en el modo automático de EKS
<a name="model-loading-auto-mode-s3"></a>

Si utiliza el modo automático de EKS con nodos de GPU en subredes privadas, le recomendamos que utilice un [punto de conexión de VPC de puerta de enlace para S3]({aws-docs-url}/vpc/latest/privatelink/vpc-endpoints-s3.html) a fin de optimizar la ruta de red entre los nodos y S3. Con el punto de conexión de VPC de puerta de enlace, el tráfico a S3 permanece en la red de AWS y evita por completo la puerta de enlace de NAT, por lo que no hay un límite de ancho de banda compartido ni ningún cargo por procesamiento de datos de NAT por GB. Sin el punto de conexión de VPC de puerta de enlace, cuando el tráfico atraviesa una puerta de enlace de NAT, esta se convierte en un cuello de botella compartido durante el escalado vertical, cuando varios nodos extraen el modelo al mismo tiempo.

El modo automático de EKS suele colocar los nodos en subredes privadas, por lo que el tráfico a S3 fluye a través de una puerta de enlace de NAT de forma predeterminada. Una puerta de enlace de NAT proporciona hasta 100 Gbps de ancho de banda y 55 000 conexiones simultáneas por destino. Sin embargo, ese ancho de banda se comparte entre todos los nodos de la subred privada. Durante un evento de escalado vertical, varios nodos que descargan el modelo completo a la vez compiten por el mismo ancho de banda de la puerta de enlace de NAT, lo que puede ralentizar la carga de los pesos del modelo en todos ellos.

## Ajuste del rendimiento de Run:ai Model Streamer
<a name="model-loading-runai-model-streamer"></a>

Los motores de inferencia como vLLM y SGLang utilizan Run:ai Model Streamer como mecanismo alternativo para cargar los pesos durante el inicio de la inferencia.

De forma predeterminada, Run:ai Model Streamer utiliza una configuración de simultaneidad conservadora al descargar los archivos de peso del modelo desde S3. Al aumentar la simultaneidad de descarga y el tamaño de los fragmentos, se reduce el tiempo de carga de los pesos del modelo al descargar más datos en paralelo.

### Cálculo de la simultaneidad óptima
<a name="model-loading-calculate-concurrency"></a>

Calcule el valor de simultaneidad óptimo de la siguiente manera:

```
concurrency = ceil(total_model_size_gb / chunk_size_gb)
```

Sustituya el valor `concurrency` que utiliza en función del tamaño del modelo y del fragmento. Consulte la siguiente tabla para ver algunos ejemplos. Por ejemplo, con un modelo de 67 GB y un tamaño de fragmento de 4 GB: `ceil(67 / 4) = 17`.


| Tamaño del modelo | Tamaño del fragmento | Simultaneidad | 
| --- | --- | --- | 
| 10 GB | 4 GB | 3 | 
| 67 GB | 4 GB | 17 | 
| 140 GB | 4 GB | 35 | 

### Aplicación de la configuración
<a name="model-loading-apply-configuration"></a>

Agregue los siguientes argumentos y variables de entorno a la especificación del contenedor de inferencia:
+  `--tensor-parallel-size`: el grado de paralelismo de tensores (TP) suele ser la cantidad mínima de GPU necesarias para que quepa el modelo en la memoria de la GPU en función del tamaño del modelo. Por ejemplo, un modelo de 67 GB en un tipo de instancia `p5.48xlarge` requiere al menos 2 GPU, así que debe establecerlo en `2`.
+  `concurrency` y `distributed` (en `--model-loader-extra-config`): establezca `concurrency` en el valor calculado para el modelo. Establezca `distributed` en `true` solo cuando se utilice el paralelismo de tensores (TP > 1). Cuando está habilitado, cada clasificación de paralelismo de tensores transmite su propia partición de peso directamente desde Amazon S3, en lugar de cargar todos los pesos en la clasificación 0 y transmitirlos a las demás clasificaciones. Esto mejora considerablemente el rendimiento de carga en las implementaciones de varias GPU. Déjelo sin establecer (o `false`) si TP = 1, donde no proporciona ningún beneficio. Esta opción requiere la arquitectura vLLM V1. Es incompatible con `--enforce-eager`, lo que fuerza la ruta V0; si se utilizan ambas juntas, se producirá un error o se regresará silenciosamente a una carga no distribuida.
+  `RUNAI_STREAMER_CHUNK_BYTESIZE`: tamaño de fragmento de 4 GB. Este valor muestra de forma coherente el mejor rendimiento en todos los puntos de referencia. Los fragmentos más grandes reducen el número de solicitudes de S3 y mejoran el rendimiento en las instancias con un gran ancho de banda.
+  `RUNAI_STREAMER_S3_REQUEST_TIMEOUT_MS`: tiempo de espera por solicitud en milisegundos. Permite un reintento más rápido en respuestas lentas de S3.
+  `RUNAI_STREAMER_S3_LOW_SPEED_LIMIT`: velocidad de transferencia mínima en bytes por segundo antes de que una solicitud se considere lenta y se vuelva a intentar.

```
containers:
- name: vllm-inference
  image: vllm/vllm-openai:v0.21.0
  command:
    - python3
    - -m
    - vllm.entrypoints.openai.api_server
  args:
  # ... your existing args ...
  - --model=s3://<MODEL_PATH>
  - --tensor-parallel-size={{2}}
  - --load-format=runai_streamer
  - --model-loader-extra-config={"concurrency":{{17}},"distributed":{{true}}}
  env:
  - name: RUNAI_STREAMER_CHUNK_BYTESIZE
    value: {{"4294967296"}}
  - name: RUNAI_STREAMER_S3_REQUEST_TIMEOUT_MS
    value: {{"3000"}}
  - name: RUNAI_STREAMER_S3_LOW_SPEED_LIMIT
    value: {{"1048576"}}
```

## Optimización del arranque en frío de torch.compile
<a name="model-loading-torch-compile-cold-start"></a>

El paso `torch.compile` del proceso de procesamiento de inferencias traza el gráfico de computación de un modelo (la secuencia de operaciones matemáticas) y lo compila en kernels de CUDA o Triton fusionados optimizados. No compila los pesos del modelo, solo las operaciones que los transforman.

Los motores de inferencia utilizan torch.compile porque proporciona mejoras significativas en el rendimiento de forma automática, sin necesidad de una ingeniería de kernels personalizada para cada arquitectura de modelo:
+  **Fusión de kernels:** varias operaciones pequeñas (adición residual, layernorm, activación) se fusionan en un solo kernel, lo que reduce los viajes de ida y vuelta de la memoria de la GPU.
+  **Menos lanzamientos de kernels:** una capa de transformador pasa de entre 15 y 30 kernels de CUDA independientes a unos 10 fusionados, lo que reduce la sobrecarga de la CPU por lanzamiento.
+  **Eliminación de Python de la ruta crítica:** toda la fase de avance se convierte en un plan de ejecución de C\+\+, lo que elimina la sobrecarga del intérprete de Python entre las operaciones.
+  **Mejor compatibilidad con los gráficos de CUDA:** los gráficos estáticos compilados se capturan y reproducen con una sobrecarga de la CPU prácticamente nula.
+  **Optimización automática:** funciona con cualquier arquitectura de modelo. El rendimiento mejora entre un 5 % y un 30 % en comparación con el modo Eager.

En la siguiente tabla, se muestran los motores de inferencia más comunes que utilizan torch.compile.


| Motor | Uso de torch.compile | 
| --- | --- | 
|  [vLLM](https://docs.vllm.ai/en/latest/)  | Habilitado de forma predeterminada (arquitectura V1) | 
|  [SGLang](https://github.com/sgl-project/sglang)  | Opcional a través de `--enable-torch-compile`  | 
| TensorRT-LLM | La nueva ruta lo admite junto con la versión anterior del motor | 

### Problema de arranque en frío de torch.compile
<a name="model-loading-cold-start-problem"></a>

La desventaja de torch.compile es que el primer pod de inferencia se debe compilar antes de poder atender las solicitudes. Esta compilación puede tardar varios minutos, en función del tamaño del modelo. Los artefactos compilados son pequeños (aproximadamente 15 MB para un modelo de 60 GB), pero aumentan considerablemente el tiempo de arranque en frío. Como los artefactos son pequeños y deterministas para una configuración determinada, puede almacenarlos en caché y reutilizarlos para evitar la penalización de arranque en frío al iniciar el pod y el nodo posteriormente.

Los artefactos constan de:
+ Archivos de origen del kernel de Triton generados
+ Archivos binarios del kernel compilados (`.cubin`)
+ Estructura de gráficos que secuencia las llamadas del kernel

### La compensación de --enforce-eager
<a name="model-loading-enforce-eager-tradeoff"></a>

vLLM habilita `torch.compile` y la captura de gráficos de CUDA de forma predeterminada. El indicador `--enforce-eager` los desactiva ambos y ejecuta el modelo en modo Eager, donde cada operación se ejecuta inmediatamente a través del intérprete de Python. Como el modo Eager omite tanto la compilación como la captura de gráficos, algunas guías de inicio rápido (incluida la implementación básica en [Modelos de carga y servicio en Amazon EKS](ml-inference-load-serve-model.md)) utilizan `--enforce-eager` para iniciar los pods más rápido.

 `--enforce-eager` es una opción válida para la depuración, las implementaciones con limitaciones de memoria o las arquitecturas de modelo que no se compilan de forma limpia, y puede usarlo en producción por esos motivos. Si bien puede mitigar la penalización por arranque en frío de `torch.compile`, recomendamos otros enfoques, como los que se detallan en las siguientes secciones de esta página, para mantener el rendimiento en tiempo de ejecución en producción.

Comprenda la relación entre el tiempo de inicio y el rendimiento en tiempo de ejecución de `--enforce-eager` antes de la implementación en producción.


| Aspecto | Con `--enforce-eager` (modo Eager) | Predeterminado (torch.compile \+ gráficos de CUDA) | 
| --- | --- | --- | 
| Tiempo de inicio | Rápido: sin pasos de compilación ni captura de gráficos | Arranque en frío lento (el problema que resuelven [Almacenamiento de artefactos de torch.compile en el mismo nodo](#model-loading-torch-compile-same-node) y [Precalentamiento de la caché de torch.compile en nodos nuevos](#model-loading-torch-compile-new-nodes)) | 
| Rendimiento en estado estable | Referencia | Entre un 5 % y un 30 % más gracias a la fusión de kernels | 
| Latencia por token (lote pequeño) | Mayor sobrecarga de lanzamiento de la CPU | Mucho más bajo: los gráficos de CUDA reproducen los lanzamientos del kernel como una sola unidad | 
| Memoria de GPU | Más bajo y más predecible | Más alto: la captura de gráficos preasigna los grupos de búferes | 
| Depurabilidad | Seguimientos de pila limpios por operación | Los errores aparecen dentro de los kernels generados | 

## Almacenamiento de artefactos de torch.compile en el mismo nodo
<a name="model-loading-torch-compile-same-node"></a>

Esta técnica se aplica cuando se utiliza un motor de inferencia compatible con `torch.compile`, como vLLM (activado de forma predeterminada) o SGLang (activado mediante `--enable-torch-compile`). Solo funciona cuando `torch.compile` está activo, es decir, cuando `--enforce-eager` **no** se ha configurado.

**importante**  
Esta mejora no tiene ningún efecto si `torch.compile` está deshabilitado. En vLLM, el indicador `--enforce-eager` desactiva `torch.compile` por completo, por lo que no se compila ni almacena en caché ningún artefacto. Si ha seguido la implementación base en [Modelos de carga y servicio en Amazon EKS](ml-inference-load-serve-model.md) con `--enforce-eager`, vLLM crea el directorio de caché, pero nunca escribe en él. Elimine `--enforce-eager` antes de aplicar esta técnica.

Cuando un motor de inferencia compila el gráfico de computación del modelo en el primer inicio, puede almacenar en caché los kernels optimizados resultantes en el almacenamiento local del nodo. Los pods posteriores del mismo nodo reutilizan los artefactos almacenados en caché y omiten por completo el paso de compilación, lo que puede reducir considerablemente el tiempo de inicio.

### Adición de variables de entorno de caché
<a name="model-loading-add-cache-env-vars"></a>

Agregue las siguientes variables de entorno a la especificación del contenedor de inferencia para dirigir la caché de torch.compile y Triton a una ruta de host persistente. Recomendamos utilizar el almacén de instancias de NVMe local del nodo y no el volumen raíz de Amazon Elastic Block Store (Amazon EBS) para `hostPath`. Para obtener ejemplos, consulte la siguiente sección.

```
containers:
- name: vllm-inference
  env:
  # torch.compile cache
  - name: XDG_CACHE_HOME
    value: {{"/compile-cache"}}
  - name: TORCHINDUCTOR_CACHE_DIR
    value: {{"/compile-cache/inductor"}}
  - name: TRITON_CACHE_DIR
    value: {{"/compile-cache/triton"}}
  volumeMounts:
  - name: compile-cache
    mountPath: /compile-cache
volumes:
- name: compile-cache
  hostPath:
    path: {{/mnt/k8s-disks/0/compile-cache}}
    type: DirectoryOrCreate
```

### Establecimiento de la ruta de la caché al almacén de instancias de NVMe
<a name="model-loading-nvme-instance-store"></a>

Los artefactos compilados y los pesos transmitidos se benefician de un almacenamiento local rápido. En las instancias de GPU con almacén de instancias de NVMe (como las instancias de las familias G y P), el almacén de instancias ofrece aproximadamente 30 GB/s, en comparación con aproximadamente 1 GB/s del volumen raíz de Amazon EBS. Dirija `hostPath` de la caché al punto de montaje de NVMe para optimizar el rendimiento.

**importante**  
El volumen `hostPath` utiliza `type: DirectoryOrCreate`. Si dirige a una ruta que no está respaldada por el almacén de instancias de NVMe, Kubernetes crea el directorio de forma silenciosa en el volumen raíz de Amazon EBS. La caché continúa funcionando, pero se pierde el beneficio de rendimiento de NVMe sin errores ni advertencias.

El punto de montaje de NVMe y la forma de habilitarlo difieren entre el modo automático de EKS y los nodos autoadministrados:


| Computación | Punto de montaje de NVMe | Cómo habilitar el almacén de instancias de NVMe | 
| --- | --- | --- | 
| Modo automático de EKS |  `/mnt/.ephemeral`  | Se habilita de forma dinámica en función del almacenamiento efímero solicitado. El modo automático de EKS formatea y monta el almacén de instancias de NVMe como una matriz RAID 0 cuando la instancia tiene varias unidades de NVMe, solo cuando el `ephemeralStorage.size` solicitado en la NodeClass es menor que la capacidad de NVMe disponible de la instancia. Si el `ephemeralStorage.size` solicitado es igual o superior a la capacidad de NVMe, el modo automático de EKS no utiliza el almacén de instancias y, en su lugar, la ruta está respaldada por el volumen raíz de EBS. | 
| Karpenter autoadministrado |  `/mnt/k8s-disks/0`  | Establezca `instanceStorePolicy: RAID0` en la `EC2NodeClass` de Karpenter. Sin esta opción, Karpenter ignora los volúmenes del almacén de instancias y la ruta no está respaldada por NVMe. | 

Para el modo automático de EKS, establezca `hostPath` en `/mnt/.ephemeral/compile-cache` en las especificaciones del contenedor:

```
volumes:
- name: compile-cache
  hostPath:
    path: /mnt/.ephemeral/compile-cache
    type: DirectoryOrCreate
```

Para Karpenter autoadministrado, establezca `hostPath` en `/mnt/k8s-disks/0/compile-cache` en las especificaciones del contenedor:

```
volumes:
- name: compile-cache
  hostPath:
    path: /mnt/k8s-disks/0/compile-cache
    type: DirectoryOrCreate
```

### Resultados de ejemplo
<a name="model-loading-same-node-results"></a>

1. El primer pod de un nodo ejecuta torch.compile y escribe los kernels compilados en `/compile-cache` en el host.

1. Los pods posteriores del mismo nodo montan la caché existente y omiten la compilación por completo, lo que reduce el tiempo de arranque en frío de torch.compile de aproximadamente entre 50 y 80 s a aproximadamente entre 4 y 6 s.

En la siguiente tabla, se muestra la mejora del almacenamiento en caché en el mismo nodo para modelos de diferentes tamaños:


| Tamaño del modelo | Primer pod de torch.compile (sin caché) | Pods posteriores de torch.compile (mismo nodo) | 
| --- | --- | --- | 
| 60 GB | Aproximadamente 53 s | Aproximadamente 6 s | 
| 140 GB | Aproximadamente 60 s | Aproximadamente 6 s | 
| 640 GB | Aproximadamente 80 s | Aproximadamente 6 s | 

## Precalentamiento de la caché de torch.compile en nodos nuevos
<a name="model-loading-torch-compile-new-nodes"></a>

Esta técnica se aplica cuando se ejecuta una inferencia de varios nodos con GPU homogéneas, paralelismo de tensores, modelos y versiones de PyTorch entre nodos. La técnica de [Almacenamiento de artefactos de torch.compile en el mismo nodo](#model-loading-torch-compile-same-node) se centra en el caso de un solo nodo, pero los nuevos nodos que se agregan durante los eventos de escalado vertical comienzan con una caché de torch.compile vacía. Para reducir aún más el tiempo de arranque en frío en los nodos recién inicializados, puede implementar un mecanismo de almacenamiento en caché que almacene los artefactos de torch.compile compilados en S3 y los predescargue en los nodos nuevos cuando se unan al clúster.

El enfoque general es el siguiente:

1. Cuando el primer pod compile el modelo en el primer nodo, cargue los artefactos de torch.compile (aproximadamente 15 MB) a un bucket de S3.

1. Cuando se unan nuevos nodos al clúster, descargue los artefactos en caché al almacenamiento local del nodo antes de programar los pods de inferencia.

Por ejemplo, puede implementar un DaemonSet que se ejecute en nodos de GPU y que empaquete y cargue la caché de torch.compile en S3. También puede sincronizar esa caché con el almacenamiento local del nodo antes de programar los pods de inferencia en los nodos nuevos.

### Consideraciones sobre el almacenamiento en caché entre nodos
<a name="model-loading-cross-node-considerations"></a>

Al almacenar en caché los artefactos de torch.compile entre nodos, los kernels compilados solo son válidos cuando estos parámetros coinciden entre el nodo que generó la caché y el nodo que la consume. El mecanismo de almacenamiento en caché debe tener en cuenta todos estos aspectos. Una discrepancia en algún parámetro produce una caché no válida que fuerza la recompilación o provoca errores en tiempo de ejecución. La herramienta de almacenamiento en caché debe diferenciar los artefactos según estos parámetros, por ejemplo, al incorporarlos a la clave de objeto de S3 o a la estructura de directorios de caché.


| Parámetro | ¿Por qué importa? | 
| --- | --- | 
| Tipo de GPU | Los kernels compilados son específicos de la arquitectura de la GPU (por ejemplo, sm\_90 para H100 frente a sm\_89 para L4). | 
| Paralelismo de tensores (TP) | Los diferentes grados de TP producen diferentes particiones de gráficos de computación. | 
| Modelo | La arquitectura y el tamaño de cada modelo se compilan en diferentes kernels. | 
| Versión PyTorch | Los componentes internos del compilador de Triton y torch.compile pueden introducir cambios bruscos entre las versiones. | 

### Resultados de ejemplo
<a name="model-loading-cross-node-results"></a>

En las pruebas direccionales con el precalentamiento de la caché entre nodos (Qwen3-6-35B-A3B, 67 GB, 2 GPU con TP = 2 en p5.48xlarge), el primer pod en nodos recién escalados alcanzó el mismo tiempo de inicio que los pods posteriores en un nodo ya caliente:


| Escenario | Primer pod | Segundo pod | 
| --- | --- | --- | 
| Sin almacenamiento en caché entre nodos (nuevo nodo) | 65 s | 16 s | 
| Con almacenamiento en caché entre nodos (nuevo nodo) | 16 s | 16 s | 

## Ejemplo de implementación
<a name="model-loading-deployment-example"></a>

En el siguiente ejemplo, se combina el ajuste de rendimiento de Run:ai Model Streamer y una caché de torch.compile en un solo manifiesto de implementación de vLLM. Reemplace los valores de marcador de posición por su propia configuración:
+  `serviceAccountName`: cuenta de servicio con un rol de IAM que tiene acceso de lectura de Amazon S3 al bucket del modelo.
+  `nodeSelector` (`karpenter.sh/nodepool`): nombre del grupo de nodos de la GPU (por ejemplo, `gpu-nodepool-g6e-12xlarge`).
+  `--model`: ruta de Amazon S3 a los pesos del modelo.
+  `--model-loader-extra-config`: establezca `concurrency` en función del tamaño del modelo: `ceil(total_model_size_gb / chunk_size_gb)`. Por ejemplo, un modelo de 67 GB con un tamaño de fragmento de 4 GB da como resultado `ceil(67 / 4) = 17`.
+  `--tensor-parallel-size`: establezca el grado de paralelismo de tensores (TP) a la cantidad mínima de GPU necesarias para que quepa el modelo en la memoria.
+  `path` `hostPath`: punto de montaje del almacén de instancias de NVMe para nodos autoadministrados con Karpenter. En el modo automático de EKS, use `/mnt/.ephemeral/compile-cache` en su lugar. Para obtener más información, consulte [Almacenamiento de artefactos de torch.compile en el mismo nodo](#model-loading-torch-compile-same-node).

```
apiVersion: apps/v1
kind: Deployment
metadata:
  name: vllm-inference
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: vllm-inference
  template:
    metadata:
      labels:
        app: vllm-inference
    spec:
      serviceAccountName: <SERVICE_ACCOUNT_NAME>
      nodeSelector:
        karpenter.sh/nodepool: <GPU_NODEPOOL>
      tolerations:
        - key: nvidia.com/gpu
          operator: Exists
          effect: NoSchedule
      containers:
        - name: vllm
          image: vllm/vllm-openai:v0.21.0
          command:
            - python3
            - -m
            - vllm.entrypoints.openai.api_server
          args:
            - --model=s3://<BUCKET_NAME>/<MODEL_PATH>
            - --load-format=runai_streamer
            - --model-loader-extra-config={"concurrency":{{17}},"distributed":{{true}}}
            - --tensor-parallel-size={{2}}
            - --max-model-len=8192
            - --host=0.0.0.0
            - --port=8000
          ports:
            - containerPort: 8000
              name: http
          env:
            # Run:ai streamer tuning
            - name: RUNAI_STREAMER_CHUNK_BYTESIZE
              value: {{"4294967296"}}
            - name: RUNAI_STREAMER_S3_REQUEST_TIMEOUT_MS
              value: {{"3000"}}
            - name: RUNAI_STREAMER_S3_LOW_SPEED_LIMIT
              value: {{"1048576"}}
            # torch.compile cache
            - name: XDG_CACHE_HOME
              value: {{"/compile-cache"}}
            - name: TORCHINDUCTOR_CACHE_DIR
              value: {{"/compile-cache/inductor"}}
            - name: TRITON_CACHE_DIR
              value: {{"/compile-cache/triton"}}
          resources:
            requests:
              cpu: "12"
              memory: 80Gi
              nvidia.com/gpu: "2"
            limits:
              nvidia.com/gpu: "2"
          volumeMounts:
            - name: compile-cache
              mountPath: /compile-cache
          startupProbe:
            httpGet:
              path: /health
              port: 8000
            periodSeconds: 10
            failureThreshold: 60
            initialDelaySeconds: 30
          readinessProbe:
            httpGet:
              path: /health
              port: 8000
            periodSeconds: 5
            timeoutSeconds: 3
      volumes:
        - name: compile-cache
          hostPath:
            path: {{/mnt/k8s-disks/0/compile-cache}}
            type: DirectoryOrCreate
```