Cargas de trabajo de IA/ML
Versiones compatibles: Kubernetes 1.31, 1.32, 1.33 Última actualización: February 23, 2026
Kubernetes es una plataforma potente para ejecutar cargas de trabajo de IA/ML. En este capítulo, aprenderemos cómo ejecutar cargas de trabajo de IA/ML en EKS y exploraremos las mejores prácticas.
Características de las cargas de trabajo de IA/ML
Las cargas de trabajo de IA/ML tienen características diferentes en comparación con las cargas de trabajo de aplicaciones típicas:
- Intensivas en recursos: Requieren recursos de cómputo significativos, incluidos GPU, CPU de alto rendimiento y mucha memoria.
- Intensivas en datos: Requieren acceso rápido a grandes conjuntos de datos.
- Procesamiento distribuido: Requieren procesamiento distribuido en múltiples nodes para el entrenamiento de modelos a gran escala.
- Diversidad de cargas de trabajo: Incluyen varios tipos de cargas de trabajo, como entrenamiento, inferencia y preprocesamiento de datos.
Tendencias más recientes de IA/ML (2025)
Las tendencias más recientes para ejecutar cargas de trabajo de IA/ML en Kubernetes incluyen:
1. Despliegue de modelos de lenguaje grandes (LLM)
Los modelos de lenguaje grandes (LLM) son una de las tecnologías más destacadas recientemente en IA. Consideraciones clave para desplegar LLMs de manera eficiente en Kubernetes:
- Model Sharding: Distribución de modelos grandes entre múltiples GPU
- Quantization: Reducción del uso de memoria al disminuir la precisión del modelo (INT8, FP16, etc.)
- Inference Optimization: Mejora del rendimiento de inferencia mediante vLLM, TensorRT, ONNX Runtime, etc.
- Scaling Strategy: Aumento del throughput mediante escalado horizontal
2. Frameworks de orquestación de IA
Frameworks de orquestación especializados para gestionar cargas de trabajo de IA/ML en Kubernetes:
- Kubeflow: Plataforma integral para workflows de machine learning
- Ray on Kubernetes: Framework de cómputo distribuido
- KServe: Servicio de inferencia serverless
- Seldon Core: Serving y monitoreo de modelos
3. Uso compartido y optimización de GPU
Tecnologías para utilizar recursos de GPU de manera eficiente:
- MIG (Multi-Instance GPU): Particionamiento de GPU NVIDIA A100/H100
- Time-Sharing Scheduling: NVIDIA MPS, segmentación temporal de GPU
- Dynamic Allocation: Asignación dinámica de recursos de GPU según sea necesario
- GPU Operator: Automatización de la gestión de GPU en Kubernetes
4. Integración de MLOps y GitOps
Aplicación de principios DevOps para la gestión del ciclo de vida de IA/ML:
- Model Version Control: Versionado de modelos integrado con Git
- CI/CD Pipelines: Automatización del entrenamiento y despliegue de modelos
- A/B Testing: Despliegue gradual de nuevas versiones de modelos
- Monitoring and Feedback Loops: Monitoreo del rendimiento del modelo y reentrenamiento
5. Integración de bases de datos vectoriales
Integración de bases de datos vectoriales para embeddings y búsqueda semántica:
- Pinecone: Búsqueda vectorial gestionada
- Milvus: Base de datos vectorial open-source
- Faiss: Biblioteca de búsqueda de similitud eficiente de Facebook AI
- OpenSearch: Motor de búsqueda con capacidades de búsqueda vectorial
- Procesamiento batch y en tiempo real: Se requieren tanto procesamiento batch como inferencia en tiempo real.
Configuración de infraestructura de IA/ML en EKS
Selección del tipo de node
Los tipos de instancia EC2 adecuados para cargas de trabajo de IA/ML incluyen:
Instancias GPU:
- p4d.24xlarge: 8 GPU NVIDIA A100, 320 GB de memoria GPU
- p3.16xlarge: 8 GPU NVIDIA V100, 128 GB de memoria GPU
- g5.xlarge~g5.48xlarge: GPU NVIDIA A10G, hasta 8 GPU
- g4dn.xlarge~g4dn.16xlarge: GPU NVIDIA T4, hasta 4 GPU
Instancias optimizadas para CPU:
- c6i.32xlarge: 128 vCPU, 256 GB de memoria
- c7g.16xlarge: 64 vCPU (AWS Graviton3), 128 GB de memoria
Instancias optimizadas para memoria:
- r6i.32xlarge: 128 vCPU, 1024 GB de memoria
- x2gd.16xlarge: 64 vCPU, 1024 GB de memoria
Instancias Inferentia:
- inf1.24xlarge: 16 chips AWS Inferentia, 96 vCPU, 192 GB de memoria
Instancias Trainium:
- trn1.32xlarge: 16 chips AWS Trainium, 128 vCPU, 512 GB de memoria
Configuración de almacenamiento
Las cargas de trabajo de IA/ML requieren almacenamiento de alto rendimiento:
Amazon EBS:
- gp3: Almacenamiento SSD de propósito general predeterminado
- io2: Almacenamiento SSD de alto rendimiento
- st1: Almacenamiento HDD optimizado para throughput
Amazon EFS:
- Útil cuando múltiples nodes necesitan acceder a datos compartidos
- Modo de rendimiento: General purpose o Max I/O
- Modo de throughput: Bursting o Provisioned throughput
Amazon FSx for Lustre:
- Sistema de archivos paralelo de alto rendimiento
- Proporciona acceso rápido a grandes conjuntos de datos
- Simplifica la importación y exportación de datos mediante la integración con S3
Amazon S3:
- Almacena grandes conjuntos de datos
- Almacena datos de entrenamiento y artefactos de modelos
Configuración de red
Configuración de red para entrenamiento distribuido:
Cluster Placement Groups:
- Minimiza la latencia entre nodes
- Coloca los nodes dentro de la misma zona de disponibilidad
Enhanced Networking:
- Elastic Network Adapter (ENA)
- ENA Express
- Elastic Fabric Adapter (EFA)
Configuración de VPC CNI:
- Gestión de direcciones IP para despliegues de pods a gran escala
- Configuración de rango de direcciones IP secundarias
Despliegue de cargas de trabajo de IA/ML
NVIDIA GPU Operator
NVIDIA GPU Operator es una herramienta para gestionar GPU NVIDIA en clusters de Kubernetes:
# Installation using Helm
helm repo add nvidia https://helm.ngc.nvidia.com/nvidia
helm repo update
helm install --wait --generate-name \
-n gpu-operator --create-namespace \
nvidia/gpu-operatorGPU Operator despliega los siguientes componentes:
- NVIDIA Driver: Instalación automática del driver de GPU
- NVIDIA Container Toolkit: Habilita el uso de GPU en contenedores
- NVIDIA Device Plugin: Expone recursos de GPU a Kubernetes
- NVIDIA DCGM Exporter: Proporciona métricas de monitoreo de GPU
Kubeflow
Kubeflow es una plataforma para ejecutar workflows de ML en Kubernetes:
# Kubeflow installation
kustomize build https://github.com/kubeflow/manifests/tree/master/example | kubectl apply -f -Kubeflow proporciona los siguientes componentes:
- Jupyter Notebooks: Entorno de desarrollo interactivo
- TensorFlow/PyTorch Training Jobs: Ejecución de jobs de entrenamiento distribuido
- KFServing: Serving de modelos
- Pipelines: Workflows de ML de extremo a extremo
- Katib: Ajuste de hiperparámetros
Entrenamiento distribuido
Recursos de Kubernetes para entrenamiento distribuido:
- MPI Operator:
apiVersion: kubeflow.org/v1
kind: MPIJob
metadata:
name: tensorflow-benchmarks
spec:
slotsPerWorker: 8
cleanPodPolicy: Running
mpiReplicaSpecs:
Launcher:
replicas: 1
template:
spec:
containers:
- image: mpioperator/tensorflow-benchmarks:latest
name: tensorflow-benchmarks
command:
- mpirun
- --allow-run-as-root
- -np
- "16"
- -bind-to
- none
- -map-by
- slot
- -x
- NCCL_DEBUG=INFO
- python
- scripts/tf_cnn_benchmarks/tf_cnn_benchmarks.py
- --model=resnet50
- --batch_size=64
- --variable_update=horovod
Worker:
replicas: 2
template:
spec:
containers:
- image: mpioperator/tensorflow-benchmarks:latest
name: tensorflow-benchmarks
resources:
limits:
nvidia.com/gpu: 8- PyTorch Elastic:
apiVersion: batch/v1
kind: Job
metadata:
name: pytorch-elastic-job
spec:
completions: 1
parallelism: 1
template:
spec:
containers:
- name: pytorch-elastic
image: pytorch/pytorch:1.9.0-cuda10.2-cudnn7-runtime
command:
- torchrun
- --nnodes=2
- --nproc_per_node=8
- --rdzv_id=job1
- --rdzv_backend=c10d
- --rdzv_endpoint=$(MASTER_ADDR):$(MASTER_PORT)
- train.py
env:
- name: MASTER_ADDR
value: pytorch-elastic-job-0
- name: MASTER_PORT
value: "29500"
resources:
limits:
nvidia.com/gpu: 8
restartPolicy: NeverServing de modelos
Opciones para serving de modelos:
- KServe:
apiVersion: serving.kserve.io/v1beta1
kind: InferenceService
metadata:
name: bert-model
spec:
predictor:
model:
modelFormat:
name: pytorch
storageUri: s3://my-bucket/bert-model
resources:
limits:
nvidia.com/gpu: 1- TorchServe:
apiVersion: apps/v1
kind: Deployment
metadata:
name: torchserve
spec:
replicas: 3
selector:
matchLabels:
app: torchserve
template:
metadata:
labels:
app: torchserve
spec:
containers:
- name: torchserve
image: pytorch/torchserve:latest
ports:
- containerPort: 8080
- containerPort: 8081
volumeMounts:
- name: model-store
mountPath: /home/model-server/model-store
resources:
limits:
nvidia.com/gpu: 1
volumes:
- name: model-store
persistentVolumeClaim:
claimName: model-store-pvc
---
apiVersion: v1
kind: Service
metadata:
name: torchserve
spec:
selector:
app: torchserve
ports:
- port: 8080
targetPort: 8080
name: inference
- port: 8081
targetPort: 8081
name: management
type: LoadBalancer- Triton Inference Server:
apiVersion: apps/v1
kind: Deployment
metadata:
name: triton-server
spec:
replicas: 3
selector:
matchLabels:
app: triton-server
template:
metadata:
labels:
app: triton-server
spec:
containers:
- name: triton-server
image: nvcr.io/nvidia/tritonserver:21.08-py3
command:
- tritonserver
- --model-repository=/models
ports:
- containerPort: 8000
- containerPort: 8001
- containerPort: 8002
volumeMounts:
- name: model-repository
mountPath: /models
resources:
limits:
nvidia.com/gpu: 1
volumes:
- name: model-repository
persistentVolumeClaim:
claimName: model-repository-pvc
---
apiVersion: v1
kind: Service
metadata:
name: triton-server
spec:
selector:
app: triton-server
ports:
- port: 8000
targetPort: 8000
name: http
- port: 8001
targetPort: 8001
name: grpc
- port: 8002
targetPort: 8002
name: metrics
type: LoadBalancerOptimización de cargas de trabajo de IA/ML
Optimización de memoria GPU
- GPU Memory Overcommit:
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: nvidia-mps
handler: nvidia-container-runtime
---
apiVersion: v1
kind: Pod
metadata:
name: cuda-mps
spec:
runtimeClassName: nvidia-mps
containers:
- name: cuda-mps
image: nvidia/cuda:11.6.0-base-ubuntu20.04
command: ["nvidia-cuda-mps-control", "-d"]
securityContext:
privileged: true
resources:
limits:
nvidia.com/gpu: 1- GPU Sharing:
apiVersion: v1
kind: Pod
metadata:
name: gpu-pod-1
spec:
containers:
- name: gpu-container
image: nvidia/cuda:11.6.0-base-ubuntu20.04
resources:
limits:
nvidia.com/gpu: 0.5Optimización de entrenamiento distribuido
- Node Affinity:
apiVersion: v1
kind: Pod
metadata:
name: gpu-pod
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node.kubernetes.io/instance-type
operator: In
values:
- p3.16xlarge
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- gpu-intensive
topologyKey: kubernetes.io/hostname
containers:
- name: gpu-container
image: nvidia/cuda:11.6.0-base-ubuntu20.04
resources:
limits:
nvidia.com/gpu: 8- Topology-Aware Scheduling:
apiVersion: v1
kind: Pod
metadata:
name: gpu-pod
annotations:
topology.kubernetes.io/region: us-west-2
topology.kubernetes.io/zone: us-west-2a
spec:
containers:
- name: gpu-container
image: nvidia/cuda:11.6.0-base-ubuntu20.04
resources:
limits:
nvidia.com/gpu: 8Optimización de almacenamiento
- FSx for Lustre Configuration:
apiVersion: fsx.aws.k8s.io/v1beta1
kind: Lustre
metadata:
name: lustre-fs
spec:
deploymentType: SCRATCH_2
storageCapacity: 1200
subnetIds:
- subnet-0123456789abcdef0
securityGroupIds:
- sg-0123456789abcdef0
perUnitStorageThroughput: 200
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fsx-lustre
provisioner: fsx.csi.aws.com
parameters:
fileSystemId: fs-0123456789abcdef0
mountName: lustre-fs
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: lustre-pvc
spec:
accessModes:
- ReadWriteMany
storageClassName: fsx-lustre
resources:
requests:
storage: 1200Gi- Data Caching:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: alluxio-worker
spec:
selector:
matchLabels:
app: alluxio-worker
template:
metadata:
labels:
app: alluxio-worker
spec:
containers:
- name: alluxio-worker
image: alluxio/alluxio:2.7.3
resources:
limits:
memory: 8Gi
volumeMounts:
- name: alluxio-domain
mountPath: /opt/domain
volumes:
- name: alluxio-domain
hostPath:
path: /mnt/alluxio
type: DirectoryOrCreateMonitoreo y logging
Prometheus y Grafana
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: gpu-metrics
namespace: monitoring
spec:
selector:
matchLabels:
app: dcgm-exporter
endpoints:
- port: metrics
interval: 15s
---
apiVersion: v1
kind: ConfigMap
metadata:
name: gpu-dashboard
namespace: monitoring
labels:
grafana_dashboard: "1"
data:
gpu-dashboard.json: |
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": "-- Grafana --",
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"gnetId": null,
"graphTooltip": 0,
"id": 1,
"links": [],
"panels": [
{
"aliasColors": {},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": null,
"fieldConfig": {
"defaults": {
"custom": {}
},
"overrides": []
},
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 0
},
"hiddenSeries": false,
"id": 2,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"nullPointMode": "null",
"options": {
"alertThreshold": true
},
"percentage": false,
"pluginVersion": "7.2.0",
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"expr": "DCGM_FI_DEV_GPU_UTIL",
"interval": "",
"legendFormat": "GPU {{gpu}}",
"refId": "A"
}
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "GPU Utilization",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"buckets": null,
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "percent",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
],
"yaxis": {
"align": false,
"alignLevel": null
}
}
],
"schemaVersion": 26,
"style": "dark",
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "GPU Dashboard",
"uid": "gpu-dashboard",
"version": 1
}Recolección de logs
apiVersion: v1
kind: ConfigMap
metadata:
name: fluentd-config
namespace: logging
data:
fluent.conf: |
<source>
@type tail
path /var/log/containers/*.log
pos_file /var/log/fluentd-containers.log.pos
tag kubernetes.*
read_from_head true
<parse>
@type json
time_format %Y-%m-%dT%H:%M:%S.%NZ
</parse>
</source>
<filter kubernetes.**>
@type kubernetes_metadata
@id filter_kube_metadata
</filter>
<match kubernetes.var.log.containers.**>
@type cloudwatch_logs
log_group_name /eks/ml-cluster/pods
log_stream_name_key $.kubernetes.pod_name
remove_log_stream_name_key true
auto_create_stream true
region us-west-2
</match>Optimización de costos
Uso de Spot Instances
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: gpu-spot
spec:
template:
spec:
requirements:
- key: node.kubernetes.io/instance-type
operator: In
values:
- g4dn.xlarge
- g4dn.2xlarge
- g4dn.4xlarge
- key: karpenter.sh/capacity-type
operator: In
values:
- spot
- key: kubernetes.io/arch
operator: In
values:
- amd64
nodeClassRef:
name: gpu-spot-class
limits:
nvidia.com/gpu: 10
disruption:
consolidationPolicy: WhenEmpty
consolidateAfter: 30s
---
apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
metadata:
name: gpu-spot-class
spec:
subnetSelector:
karpenter.sh/discovery: gpu-cluster
securityGroupSelector:
karpenter.sh/discovery: gpu-clusterAuto Scaling
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: inference-service
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: inference-service
minReplicas: 1
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: nvidia.com/gpu
target:
type: Utilization
averageUtilization: 80
- type: Pods
pods:
metric:
name: inference_requests_per_second
target:
type: AverageValue
averageValue: 100Uso de Hybrid Nodes
apiVersion: v1
kind: Pod
metadata:
name: training-pod
spec:
nodeSelector:
node.kubernetes.io/instance-type: p3.16xlarge
containers:
- name: training-container
image: tensorflow/tensorflow:latest-gpu
resources:
limits:
nvidia.com/gpu: 8
---
apiVersion: v1
kind: Pod
metadata:
name: inference-pod
spec:
nodeSelector:
node.kubernetes.io/instance-type: g4dn.xlarge
containers:
- name: inference-container
image: tensorflow/tensorflow:latest-gpu
resources:
limits:
nvidia.com/gpu: 1Conclusión
Ejecutar cargas de trabajo de IA/ML en EKS proporciona una infraestructura robusta, escalado flexible y varias opciones de optimización. Es importante seleccionar tipos de node, configuraciones de almacenamiento y ajustes de red adecuados, aprovechar herramientas como Kubeflow para gestionar workflows de ML, y optimizar la memoria GPU y el entrenamiento distribuido. Además, puedes hacer seguimiento del rendimiento de las cargas de trabajo mediante monitoreo y logging, y optimizar costos utilizando Spot Instances y auto scaling.
Referencias
- IA en EKS - Guía y ejemplos de AWS para desplegar cargas de trabajo de IA/ML en EKS
Quiz
Para comprobar lo que has aprendido en este capítulo, prueba el quiz del tema.