对于许多AI应用场景,例如定时报告分析、夜间批处理或用户量波动巨大的内部工具,模型的流量往往呈现出低频且突发性的特点。如果为此类任务部署传统的常驻GPU服务,将导致高昂的闲置成本。Serverless架构,尤其是AWS Lambda,正是解决这一问题的理想方案。
Contents
1. 为什么Serverless适合突发性AI任务?
Serverless(如Lambda)的核心优势在于其按需付费和极速弹性。当请求到来时,Lambda可以在几秒内启动数十个甚至数百个执行环境来处理并发请求。任务完成后,资源立即释放,不产生任何闲置费用。
然而,传统的Lambda限制(部署包最大250MB)难以容纳大型AI模型(如PyTorch、TensorFlow等库及其模型权重)。幸运的是,AWS推出了Lambda容器镜像支持,允许我们将整个运行环境(包括模型和所有依赖)打包成一个最大10GB的容器镜像,完美解决了AI工作负载的部署难题。
2. 构建Lambda容器镜像环境
我们将演示如何构建一个包含PyTorch依赖的容器镜像,用于模拟一个AI推理服务。
2.1 准备环境文件
首先,创建requirements.txt和模拟的模型文件。我们使用torch作为示例中的重型依赖。
****requirements.txt:
1
2
3 requests
pillow
torch
2.2 编写Dockerfile
使用AWS官方提供的Lambda Python基础镜像,确保最佳兼容性。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 # Dockerfile for Lambda AI Inference
# 使用 AWS Lambda Python 3.9 基础镜像
FROM public.ecr.aws/lambda/python:3.9
# 设置工作目录
WORKDIR /var/task
# 复制文件
COPY requirements.txt .
COPY app.py .
# 假设模型权重较大,放在/tmp目录下(Lambda运行时可写)
# 实际操作中,大模型可以存储在S3中,然后在冷启动时下载到 /tmp
# 为了简化示例,我们直接在镜像中放置一个占位符
RUN mkdir -p /tmp/model
RUN echo "model_data" > /tmp/model/weights.pth
# 安装 Python 依赖,使用 --target /var/task 确保路径正确
RUN pip install -r requirements.txt
# 设置 CMD 为 Lambda Handler
CMD ["app.handler"]
2.3 编写推理 Handler (app.py)
为了优化冷启动(Cold Start)时间,我们必须将模型的加载逻辑放在Handler函数外部,确保模型仅在容器启动时加载一次,并在后续的“热调用”中复用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59 import json
import time
import os
# 导入大型依赖库 (示例)
import torch
# --- 关键:模型全局加载区 (冷启动时执行) ---
# 模拟模型加载
try:
MODEL = None
model_path = '/tmp/model/weights.pth'
# 实际中可能是 MODEL = torch.load(model_path)
if os.path.exists(model_path):
MODEL = f"Model loaded from {model_path}"
print("--- Model Cold Loaded Successfully ---")
else:
print("Model weights not found.")
except Exception as e:
print(f"Error during model cold load: {e}")
# -----------------------------------------------
def handler(event, context):
"""
Lambda主处理函数,负责处理单个突发性推理请求。
"""
start_time = time.time()
if MODEL is None:
return {
"statusCode": 503,
"body": json.dumps({"message": "Model service initializing..."})
}
# 假设输入来自 API Gateway
try:
input_data = json.loads(event.get('body', '{}'))
# --- 推理逻辑 ---
# 模拟耗时操作
time.sleep(0.1)
# result = MODEL.infer(input_data)
result = f"Inference result for input ID: {input_data.get('id', 'N/A')}"
inference_duration = time.time() - start_time
return {
"statusCode": 200,
"body": json.dumps({
"result": result,
"duration_ms": int(inference_duration * 1000),
"model_status": "hot" if context.get_remaining_time_in_millis() > 0 else "cold"
})
}
except Exception as e:
return {
"statusCode": 400,
"body": json.dumps({"error": str(e)})
}
3. 部署和配置
部署过程涉及将镜像推送到ECR(Elastic Container Registry),然后配置Lambda函数。
3.1 构建并推送镜像 (Bash)
1
2
3
4
5
6
7
8
9
10 # 1. 登录 ECR
aws ecr get-login-password --region <your-region> | docker login --username AWS --password-stdin <aws_account_id>.dkr.ecr.<your-region>.amazonaws.com
# 2. 标记并构建镜像
IMAGE_URI=<aws_account_id>.dkr.ecr.<your-region>.amazonaws.com/ai-serverless-inference:latest
docker build -t ai-serverless-inference .
docker tag ai-serverless-inference:latest $IMAGE_URI
# 3. 推送镜像
docker push $IMAGE_URI
3.2 Lambda 函数配置要点
在AWS控制台或使用CloudFormation/Terraform配置Lambda时,需要注意以下几点:
- 选择镜像包: 选择刚刚推送到ECR的镜像作为部署包。
- 内存配置: AI任务通常需要更高的内存。建议配置 2048MB 到 4096MB 的内存,这也会间接提升分配到的CPU性能。
- 超时设置: 根据推理任务的复杂性,设置合适的超时时间(例如30秒)。
- 预留并发(Provisioned Concurrency): 如果需要极低的延迟启动,可以为Serverless函数预留一些并发实例,以消除冷启动延迟。对于低频突发性任务,通常只需少量或不预留,以最大化成本效益。
通过Serverless容器,您可以在需要时以极低成本运行高性能AI推理任务,实现真正的弹性部署和成本优化。
汤不热吧