弹性Job服务
EAS弹性Job服务支持训练和推理场景。在训练场景中,支持一个实例(Job)内循环执行任务,根据队列长度自动扩缩容。在推理场景中,能感知每个请求的执行进度,做到更公平的任务调度。本文为您介绍如何使用弹性Job服务。
使用场景
训练场景
弹性Job服务用于训练场景:
功能实现:前后端分离架构,支持部署常驻的前端服务与弹性Job服务。
架构优势:前端服务通常资源需求低,价格低廉,常驻前端服务可避免频繁创建前端服务,减少等待时间。后端弹性Job服务支持在一个实例(Job)内循环执行训练任务,避免实例(Job)被反复拉起和释放,提升吞吐效率。同时,后端弹性Job服务会在队列长度过长或过短时自动进行扩缩容,保证资源高效利用。
推理场景
弹性Job服务在模型推理场景中,能感知每个请求的执行进度,实现更公平的任务调度。
对于响应时间较长的推理服务,建议使用EAS异步推理服务,但异步服务存在以下问题:
队列服务推送请求时不能保证优先推送给空闲的实例,导致资源利用不足。
服务实例缩容时不能保证当前实例退出时内部请求已处理完毕,可能导致请求中断重新调度。
针对这些问题,弹性Job服务进行了优化:
优化订阅逻辑,优先推送请求到空闲实例。实例退出前阻塞等待当前请求处理完毕。
提高扩缩容效率,不同于定期上报机制,队列服务内置监控服务,快速触发扩容,将扩缩容的响应时间从分钟级降低到10秒左右。
基本架构
整体框架由队列服务、HPA控制器和弹性Job服务三部分组成,如下图所示。
实现逻辑如下:
队列服务解耦请求和任务的下发与执行,使一个弹性Job服务可以处理多个不同请求或任务。
HPA控制器监听队列服务中待执行的训练任务和请求的数量,实现弹性Job服务实例的弹性伸缩。弹性Job服务自动扩缩容的默认配置如下,更多参数说明,请参见水平自动扩缩容功能。
{ "behavior":{ "onZero":{ "scaleDownGracePeriodSeconds":60 # 缩容到0的生效时间(秒)。 }, "scaleDown":{ "stabilizationWindowSeconds":1 # 缩容的生效时间(秒)。 } }, "max":10, # 实例(Job)的最大个数。 "min":1, # 实例(Job)的最小个数。 "strategies":{ "avg_waiting_length":2 # 每个实例(Job)的平均负载阈值。 } }
服务部署
部署推理服务
类似于创建异步推理服务,参照以下示例内容准备服务配置文件:
{
"containers": [
{
"image": "registry-vpc.cn-shanghai.aliyuncs.com/eas/eas-container-deploy-test:202010091755",
"command": "/data/eas/ENV/bin/python /data/eas/app.py",
"port": 8000,
}
],
"metadata": {
"name": "scalablejob",
"type": "ScalableJob",
"rpc.worker_threads": 4,
"instance": 1,
}
}
其中,type配置为ScalableJob,推理服务就会以弹性Job服务的形式部署。其他参数配置详情,请参见服务模型所有相关参数说明。关于如何部署推理服务,请参见部署写真相机在线推理服务。
服务部署成功后,会自动创建队列服务和弹性Job服务,同时默认启用Autoscaler(水平自动扩缩容)的功能。
部署训练服务
支持集成部署与独立部署两种方式。具体的实现逻辑和配置详情说明如下,具体部署方法,请参见部署弹性伸缩的Kohya训练服务。
实现逻辑
集成部署:EAS除了创建队列服务和弹性Job服务外,还会创建一个前端服务。前端服务主要负责接收用户请求,并将用户请求转发到队列服务中。您可以将前端服务理解成弹性Job服务的客户端。在此模式下,弹性Job服务会被绑定到唯一的前端服务上,此时弹性Job服务只能执行当前前端服务下发的训练任务。
独立部署:独立部署适用于多用户场景,在此模式下弹性Job服务作为公共的后端服务,可以和多个前端服务绑定,每个用户都可以在自己的前端服务下发训练任务,后端Job服务会创建对应的Job实例来执行训练任务,并且每个Job实例可以依次执行不同的训练任务,实现多个用户共享训练资源。不用多次创建训练任务,有效降低使用成本。
配置说明
在部署弹性Job服务时,您需要提供一个自定义镜像环境(kohya场景可直接使用EAS预置的kohya_ss镜像)。该镜像需包含执行训练任务的所有依赖,只是作为训练任务的执行环境,因此不需要配置启动命令和端口号。如果您需要在训练任务开始前执行一些初始化任务,可以配置初始化命令,EAS会在实例(Job)内部单独创建一个进程来执行初始化任务。如何准备自定义镜像,请参见服务部署:自定义镜像。EAS的预置镜像地址为:eas-registry-vpc.cn-shanghai.cr.aliyuncs.com/pai-eas/kohya_ss:2.2。
集成部署
参照下方示例准备服务配置文件,以EAS提供的预置镜像(kohya_ss)为例:
{ "containers": [ { "image": "eas-registry-vpc.cn-shanghai.cr.aliyuncs.com/pai-eas/kohya_ss:2.2" } ], "metadata": { "cpu": 4, "enable_webservice": true, "gpu": 1, "instance": 1, "memory": 15000, "name": "kohya_job", "type": "ScalableJobService" }, "front_end": { "image": "eas-registry-vpc.cn-shanghai.cr.aliyuncs.com/pai-eas/kohya_ss:2.2", "port": 8001, "script": "python -u kohya_gui.py --listen 0.0.0.0 --server_port 8001 --data-dir /workspace --headless --just-ui --job-service" } }
其中关键配置说明如下,其他参数配置说明,请参见服务模型所有相关参数说明。
将type配置为ScalableJobService。
前端服务使用的资源组默认和弹性Job服务相同,系统默认分配的资源为2核CPU和8 GB内存。
参考以下示例自定义配置资源组或资源:
{ "front_end": { "resource": "", # 修改前端服务使用专属资源组。 "cpu": 4, "memory": 8000 } }
参考以下示例自定义配置部署的机型:
{ "front_end": { "instance_type": "ecs.c6.large" } }
独立部署
参照下方示例准备服务配置文件,以EAS提供的预置镜像(kohya_ss)为例:
{ "containers": [ { "image": "eas-registry-vpc.cn-shanghai.cr.aliyuncs.com/pai-eas/kohya_ss:2.2" } ], "metadata": { "cpu": 4, "enable_webservice": true, "gpu": 1, "instance": 1, "memory": 15000, "name": "kohya_job", "type": "ScalableJob" } }
其中,type需要配置为ScalableJob,其他参数配置说明,请参见服务模型所有相关参数说明。
在此模式下,需要用户手动部署前端服务,并在前端服务内部实现请求的代理,将接收到的请求转发到弹性Job服务的队列内部,完成前端服务和后端Job服务的绑定,详情请参见向队列服务发送数据。
服务调用
为了区分训练场景和推理场景,在调用弹性Job服务时,需设置taskType
为command
或query
来标识。其中:
command:用来标识训练服务。
query:用来标识推理服务。
调用服务时需显式地指定taskType,示例如下:
HTTP调用: 如果是推理服务,Wanted_TaskType替换为query。
curl http://166233998075****.cn-shanghai.pai-eas.aliyuncs.com/api/predict/scalablejob?taskType={Wanted_TaskType} -H 'Authorization: xxx' -D 'xxx'
SDK调用时需要指定tags,通过该参数来配置taskType。下面示例中,如果是推理服务,将 wanted_task_type替换为query。
# 创建输入队列,用于发送任务或请求。 queue_client = QueueClient('166233998075****.cn-shanghai.pai-eas.aliyuncs.com', 'scalabejob') queue_client.set_token('xxx') queue_client.init() tags = {"taskType": "wanted_task_type"} # 向输入队列发送任务或请求。 index, request_id = inputQueue.put(cmd, tags)
获取结果:
推理服务:通过EAS队列服务的SDK来获取输出队列的结果,详情请参见队列服务订阅推送。
训练服务:建议部署服务时配置OSS挂载,将训练结果直接保存到OSS路径中做持久化存储,详情请参见部署弹性伸缩的Kohya训练服务。
配置日志收集
EAS弹性Job服务提供了enable_write_log_to_queue
配置,通过该配置可以将实时日志写入队列。
{
"scalable_job": {
"enable_write_log_to_queue": true
}
}
训练场景:默认开启,实时日志回写到输出队列,您可通过EAS队列服务SDK实时获取训练日志。详情请参见自定义前端服务镜像调用弹性Job服务。
推理场景:默认关闭,日志只能通过stdout输出。
相关文档
关于EAS弹性Job服务更详细的使用场景介绍,请参见: