ZenML项目教程:如何管理定时调度的机器学习管道
前言
在现代机器学习工程实践中,定时调度(pipeline scheduling)是一个至关重要的功能。它允许我们按照预设的时间计划自动执行数据预处理、模型训练、评估等任务,从而实现端到端的自动化机器学习工作流。本文将详细介绍如何在ZenML中创建、更新和删除定时调度的机器学习管道。
定时调度的工作原理
ZenML本身并不实现调度器功能,而是作为包装层,将调度功能委托给底层编排器(orchestrator)。目前支持的编排器包括Vertex AI、Airflow、Kubeflow等。当您在ZenML中创建定时调度时,系统会执行以下操作:
- 将您的调度定义转换为编排器原生格式
- 在编排器的调度系统中注册该调度
- 在ZenML元数据存储中记录调度信息
之后,编排器将负责按照预定时间执行管道。
准备工作
在开始本教程前,请确保:
- 已安装并配置好ZenML环境
- 已设置支持定时调度的编排器(本教程以Vertex AI为例)
- 了解ZenML管道和步骤的基本概念
创建基础管道
首先,我们需要创建一个将被调度的基础管道。这个管道模拟日常数据处理任务:
from zenml import pipeline, step
from datetime import datetime
@step
def process_data() -> str:
"""模拟数据处理步骤"""
return f"数据已处理于 {datetime.now()}"
@step
def save_results(data: str) -> None:
"""保存处理结果"""
print(f"保存结果: {data}")
@pipeline
def daily_data_pipeline():
"""每日数据处理管道"""
data = process_data()
save_results(data)
创建定时调度
接下来,我们为管道创建定时调度,设置为每天上午9点执行:
from zenml.config.schedule import Schedule
from datetime import datetime
# 创建每天上午9点执行的调度
schedule = Schedule(
name="daily-data-processing",
cron_expression="0 9 * * *" # 每天9点
)
# 将调度附加到管道
scheduled_pipeline = daily_data_pipeline.with_options(schedule=schedule)
# 运行管道以创建调度
scheduled_pipeline()
命名最佳实践
为调度命名时,建议采用一致的命名模式,便于管理:
schedule = Schedule(
name="daily-feature-engineering-prod-v1", # 包含频率、用途、环境和版本
cron_expression="0 4 * * *"
)
验证调度
创建调度后,必须验证其在ZenML和编排器中的存在性。
在ZenML中验证
使用Python代码验证:
from zenml.client import Client
client = Client()
schedules = client.list_schedules()
our_schedule = next((s for s in schedules if s.name == "daily-data-processing"), None)
if our_schedule:
print(f"调度'{our_schedule.name}'创建成功!")
else:
print("未找到调度!")
在编排器中验证
对于Vertex AI,使用Google Cloud SDK验证:
from google.cloud import aiplatform
vertex_schedules = aiplatform.PipelineJobSchedule.list(
filter=f'display_name="{schedule.name}"',
location="us-central1" # 替换为您的实际区域
)
更新调度
当需要修改现有调度时,ZenML不支持直接更新,需要先删除旧调度再创建新调度。
删除现有调度
从ZenML中删除:
client.delete_schedule("daily-data-processing")
从Vertex AI中删除:
vertex_schedules = aiplatform.PipelineJobSchedule.list(
filter=f'display_name="{schedule.name}"',
location="us-central1"
)
for schedule_to_delete in vertex_schedules:
schedule_to_delete.delete()
创建新调度
new_schedule = Schedule(
name="daily-data-processing",
cron_expression="0 10 * * *" # 改为上午10点
)
updated_pipeline = daily_data_pipeline.with_options(schedule=new_schedule)
updated_pipeline()
监控调度执行
检查管道执行历史:
runs = client.list_pipeline_runs(
pipeline_name_or_id="daily_data_pipeline",
sort_by="created",
descending=True,
size=5
)
清理调度
完成调度后,必须从ZenML和编排器中分别删除:
# 从ZenML删除
client.delete_schedule("daily-data-processing")
# 从Vertex AI删除
vertex_schedules = aiplatform.PipelineJobSchedule.list(
filter='display_name="daily-data-processing"',
location="us-central1"
)
for schedule in vertex_schedules:
schedule.delete()
常见问题排查
时区混淆问题
调度运行时区问题很常见。ZenML处理时区的规则:
- 提供带时区的datetime:按原时区使用
- 提供不带时区的datetime:假设为本地时区并转换为UTC
建议明确指定时区:
local_tz = pytz.timezone('Asia/Shanghai') # 替换为您的时区
local_time = local_tz.localize(datetime(2025, 1, 1, 9, 0))
schedule = Schedule(
name="local-time-schedule",
cron_expression="0 9 * * *",
start_time=local_time
)
调度未按预期运行
验证cron表达式:
from croniter import croniter
cron_expression = "0 9 * * *"
is_valid = croniter.is_valid(cron_expression)
总结
通过本教程,您已经掌握了在ZenML中管理定时调度管道的基本技能。定时调度是自动化机器学习工作流的关键组件,合理使用可以显著提高工作效率。建议进一步探索:
- 更复杂的cron表达式配置
- 管道执行监控和告警设置
- 资源分配优化
- 基于数据可用性的触发式调度
定时调度功能为机器学习工程提供了强大的自动化能力,是构建可靠生产级ML系统的重要工具。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考