Cómputo, Almacenamiento y GPU en la Nube
GPU Instances para IA
Tipos de GPU en AWS
| Instance | GPU | VRAM | Uso Típico | Costo/hr (on-demand) |
|---|---|---|---|---|
| g5.xlarge | NVIDIA A10G | 24 GB | Inferencia, fine-tuning pequeño | ~$1.00 |
| g5.2xlarge | NVIDIA A10G | 24 GB | Fine-tuning medio, serving | ~$1.20 |
| p4d.24xlarge | 8× A100 | 8×40 GB | Entrenamiento distribuido | ~$32.00 |
| p5.48xlarge | 8× H100 | 8×80 GB | Entrenamiento LLM grande | ~$98.00 |
| inf2.xlarge | AWS Inferentia2 | 32 GB | Inferencia optimizada | ~$0.76 |
Guía de Selección
Inferencia de LLMs (7B-13B params):
→ g5.xlarge o inf2.xlarge
Fine-tuning con LoRA (7B-13B params):
→ g5.2xlarge (1 GPU, 24GB VRAM)
Fine-tuning de modelos medianos (30B-70B params):
→ p4d.24xlarge (8× A100 para model parallelism)
Entrenamiento desde cero:
→ p5.48xlarge × N instancias (distributed training)
Spot Instances para Entrenamiento
import boto3
ec2 = boto3.client("ec2")
# Solicitar spot instance para training (hasta 90% ahorro)
response = ec2.request_spot_instances(
InstanceCount=1,
LaunchSpecification={
"ImageId": "ami-xxx", # Deep Learning AMI
"InstanceType": "g5.2xlarge",
"KeyName": "my-key",
"SecurityGroupIds": ["sg-xxx"],
"IamInstanceProfile": {"Arn": "arn:aws:iam::xxx:instance-profile/ml-role"},
},
SpotPrice="0.50", # Máximo que pagas por hora
)
Tip: Usa checkpointing frecuente cuando entrenes con spot instances (pueden ser interrumpidas).
Almacenamiento para IA
S3: El Almacén Universal
import boto3
s3 = boto3.client("s3")
# Estructura de buckets para IA
"""
s3://company-ai-data/
├── raw/ # Documentos originales
│ ├── pdfs/
│ ├── web-scrapes/
│ └── databases/
├── processed/ # Chunks procesados
│ ├── chunks/
│ └── embeddings/
├── models/ # Modelos y artifacts
│ ├── fine-tuned/
│ ├── adapters/
│ └── onnx/
├── evaluations/ # Resultados de evaluación
│ ├── benchmarks/
│ └── ab-tests/
└── logs/ # Logs de training
"""
# Upload eficiente de datasets grandes
from boto3.s3.transfer import TransferConfig
config = TransferConfig(
multipart_threshold=8 * 1024 * 1024, # 8MB
max_concurrency=10,
multipart_chunksize=8 * 1024 * 1024,
)
s3.upload_file("dataset.parquet", "company-ai-data", "raw/dataset.parquet", Config=config)
S3 Lifecycle para Optimización de Costos
{
"Rules": [
{
"ID": "MoveOldEmbeddings",
"Status": "Enabled",
"Filter": {"Prefix": "processed/embeddings/"},
"Transitions": [
{"Days": 30, "StorageClass": "STANDARD_IA"},
{"Days": 90, "StorageClass": "GLACIER"}
]
},
{
"ID": "DeleteOldLogs",
"Status": "Enabled",
"Filter": {"Prefix": "logs/training/"},
"Expiration": {"Days": 180}
}
]
}
EFS para Shared Storage (GPU Clusters)
# Montar EFS en instancias de training para compartir datos
# Útil cuando múltiples GPUs necesitan acceder al mismo dataset
sudo mount -t efs fs-xxx:/ /mnt/shared-data
# Estructura en EFS:
# /mnt/shared-data/
# ├── datasets/ ← Shared entre instancias
# ├── checkpoints/ ← Checkpoints de entrenamiento
# └── cache/ ← Cache de modelos HuggingFace
Cómputo: Lambda vs ECS vs EKS
Comparativa para IA
| Aspecto | Lambda | ECS Fargate | EKS |
|---|---|---|---|
| Startup | Frío: 1-10s | ~30s | Ya running |
| Timeout | 15 min | Sin límite | Sin límite |
| GPU | No | Sí (g5) | Sí |
| Scaling | Auto (1000 concurrentes) | Auto | Auto + KEDA |
| Costo | Por invocación | Por segundo | Por nodo |
| Ideal para | APIs ligeras, triggers | APIs con estado | Workloads complejas |
Lambda para IA (Casos Ligeros)
# Lambda: ideal para orchestrar (no para inferencia GPU)
import json
import boto3
bedrock = boto3.client("bedrock-runtime")
def handler(event, context):
query = event.get("query", "")
# 1. Embedding
embed_response = bedrock.invoke_model(
modelId="amazon.titan-embed-text-v2:0",
body=json.dumps({"inputText": query, "dimensions": 512}),
)
embedding = json.loads(embed_response["body"].read())["embedding"]
# 2. Vector search (via OpenSearch)
# 3. Generate response (via Bedrock Claude)
return {"statusCode": 200, "body": json.dumps({"answer": response})}
ECS Fargate para Serving de Modelos
# task-definition.json
{
"family": "rag-api",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "4096",
"memory": "8192",
"containerDefinitions": [
{
"name": "rag-service",
"image": "xxx.dkr.ecr.us-east-1.amazonaws.com/rag-api:latest",
"portMappings": [{"containerPort": 8000, "protocol": "tcp"}],
"environment": [
{"name": "AWS_REGION", "value": "us-east-1"},
{"name": "OPENSEARCH_ENDPOINT", "value": "https://xxx.aoss.amazonaws.com"}
],
"secrets": [
{"name": "OPENAI_API_KEY", "valueFrom": "arn:aws:secretsmanager:..."}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/rag-api",
"awslogs-region": "us-east-1",
"awslogs-stream-prefix": "ecs"
}
}
}
]
}
Auto Scaling para IA
# Application Auto Scaling para ECS
autoscaling = boto3.client("application-autoscaling")
# Escalar basado en requests por segundo
autoscaling.put_scaling_policy(
PolicyName="rag-api-scaling",
ServiceNamespace="ecs",
# ResourceId formato ECS: "service/{cluster_name}/{service_name}"
ResourceId="service/ai-cluster/rag-api",
# ScalableDimension: qué ajustar — aquí el número deseado de tasks ECS
ScalableDimension="ecs:service:DesiredCount",
# TargetTrackingScaling funciona como un termostato:
# mide la métrica continuamente y ajusta capacidad para mantener el target
PolicyType="TargetTrackingScaling",
TargetTrackingScalingPolicyConfiguration={
# Mantener CPU promedio al 70% — si sube, agrega tasks; si baja, quita
"TargetValue": 70.0,
"PredefinedMetricSpecification": {
"PredefinedMetricType": "ECSServiceAverageCPUUtilization"
},
# Cooldowns asimétricos:
# ScaleInCooldown=300 (5 min): esperar más antes de REDUCIR — evita
# oscilaciones si el tráfico fluctúa (conservador al quitar capacidad)
"ScaleInCooldown": 300,
# ScaleOutCooldown=60 (1 min): reaccionar RÁPIDO al ESCALAR —
# es más importante responder a picos que ahorrar en sobre-provisión
"ScaleOutCooldown": 60,
},
)
Resumen
La infraestructura cloud para IA se compone de:
- GPU instances (g5, p4d, p5) para inferencia y training
- S3 como almacén universal con lifecycle rules
- Lambda para orquestación ligera y triggers
- ECS/EKS para servicios con estado y GPU
- Auto Scaling para manejar carga variable
🧠 Preguntas de Repaso
1. ¿Cuál es la GPU instance recomendada para inferencia de LLMs de 7B-13B parámetros y cuánto cuesta aproximadamente?
- A) p4d.24xlarge con 8× A100 (~$32/hr)
- B) g5.xlarge con NVIDIA A10G, 24GB VRAM (~$1.00/hr)
- C) p5.48xlarge con 8× H100 (~$98/hr)
- D) inf2.xlarge con Inferentia2 (~$0.76/hr)
Respuesta: B) — La g5.xlarge con GPU A10G y 24GB VRAM es ideal para inferencia de modelos 7B-13B a ~$1.00/hr. Las p4d y p5 son para entrenamiento de modelos grandes. inf2 es alternativa optimizada por AWS pero con menor compatibilidad.
2. ¿Por qué las Spot Instances son especialmente útiles para entrenamiento de modelos de IA?
- A) Son más rápidas que las instancias on-demand
- B) Ofrecen hasta 90% de ahorro, y con checkpointing frecuente se mitiga el riesgo de interrupción
- C) Tienen más VRAM disponible
- D) Son las únicas que soportan GPUs
Respuesta: B) — Las Spot Instances ofrecen hasta 90% de ahorro sobre el precio on-demand. El riesgo es la interrupción, que se mitiga con checkpointing frecuente durante el entrenamiento para poder retomar desde el último checkpoint.
3. ¿Por qué Lambda NO es adecuado para inferencia con GPU pero SÍ es ideal para orquestación?
- A) Lambda es demasiado caro para cualquier uso de IA
- B) Lambda no soporta GPU, tiene timeout de 15 minutos, pero escala automáticamente a 1000 concurrentes — perfecto para orquestar llamadas a Bedrock/APIs
- C) Lambda solo funciona con Python 2
- D) Lambda no puede conectarse a servicios de AWS
Respuesta: B) — Lambda no tiene acceso a GPU y tiene un timeout de 15 minutos, lo que lo descarta para inferencia directa. Sin embargo, su escalado automático (hasta 1000 concurrentes), costo por uso y arranque rápido lo hacen ideal para orquestar llamadas a APIs de IA como Bedrock.
4. En Auto Scaling de ECS, ¿por qué el ScaleInCooldown (300s) es mayor que el ScaleOutCooldown (60s)?
- A) Por una limitación técnica de AWS
- B) Se escala hacia fuera rápido (60s) para responder a demanda, pero se reduce lentamente (300s) para evitar fluctuaciones y no terminar instancias prematuramente
- C) Porque escalar hacia adentro es más caro
- D) No hay razón técnica, es solo convención
Respuesta: B) — Los cooldowns asimétricos son una best practice: ScaleOutCooldown corto (60s) para responder rápidamente a picos de demanda, ScaleInCooldown largo (300s) para ser conservador al reducir y evitar el efecto "ping-pong" de escalar/reducir repetidamente.