核心摘要
- 基于AWS Auto Scaling和SQS构建的ComfyUI轻量级管理方案,支持从0到20实例的弹性伸缩,空闲时实现真正的零成本待机
- 提供S3 Mount Point、本地复制、EFS三种存储策略,可根据模型加载性能需求和成本预算灵活选择
- 一键部署脚本支持快速创建和销毁多套隔离环境,AMI镜像自动化确保开发与生产环境的高度一致性
- 优雅退出机制保障缩容时任务完整性,日志集中存储至S3便于问题排查和审计追踪
ComfyUI在AWS上的弹性部署与成本优化实战指南
AI图像生成技术正在经历前所未有的发展速度,ComfyUI作为Stable Diffusion生态中最具影响力的工作流工具之一,凭借其节点式可视化界面和高度灵活的工作流编排能力,已成为众多创意工作者和AI开发团队的首选。在AWS云平台上,已有多个成熟的大规模Stable Diffusion部署方案可供选择,包括异步图像生成指南和弹性插件解决方案等。
然而,实际业务场景往往更加复杂多变。特别是在产品验证阶段、可行性分析过程中,团队需要频繁进行工作流微调、问题排查和快速迭代。这种场景下,既要保持生产环境的稳定性,又希望实现更激进的成本控制和资源利用率优化。针对这一痛点,本文介绍一套基于AWS云服务的ComfyUI轻量级管理解决方案,通过灵活配置和智能弹性伸缩,构建高效、经济且易于扩展的AI图像生成系统。值得注意的是,这套架构设计思路同样适用于其他需要弹性处理能力的异步任务场景。
典型业务场景与技术挑战
在与客户的深入交流中,我们发现以下几类问题具有相当的普遍性:
工作流管理复杂度
客户通常维护着超过50个图片处理工作流,并计划扩展至100个以上。设计师团队习惯在Ubuntu环境下进行工作流编写,需要频繁试验、添加和调整各类组件。核心诉求是所见即所得——在开发环境中完成的工作流能够直接部署到生产弹性环境,且行为和效果保持高度一致。
传统的容器化方案需要频繁修改Dockerfile,并在容器环境中进行验证测试。对于运维资源有限的团队而言,这种模式难以支撑快速迭代的业务节奏。此外,部分模型依赖系统底层库,在不同Linux发行版之间存在兼容性问题,进一步增加了维护成本。
差异化弹性策略需求
业务上需要区分常用工作流和长尾工作流,两者在响应时效性和成本预算方面存在显著差异。这要求系统支持快速调整弹性策略,为不同业务场景提供差异化的响应能力。更重要的是,在完全空闲时能够停止所有实例,实现真正意义上的零成本无服务器架构。
系统集成简洁性
客户希望将工作流能力集成到现有业务系统中,期望逻辑尽量简单清晰,便于快速开发和对接。通过SQS队列进行逻辑解耦,实现任务的异步处理和快速响应。
解决方案架构设计
这是一个设计简洁但功能强大的ComfyUI任务管理和弹性扩展方案,充分利用AWS多项托管服务构建了可根据任务负载灵活配置和自动扩展的系统。
核心工作流程
用户通过send_job.py将ComfyUI工作流任务提交至SQS队列。系统检测到队列中存在待处理任务且无运行中实例时,会自动触发Auto Scaling扩展组启动EC2实例。运行中的EC2实例通过parse_job.py持续从队列获取并处理任务,生成的图像存储到S3中。
系统具备智能的动态伸缩能力,根据队列深度和预设的单实例任务处理上限自动调整实例数量。缩减实例规模时采取优雅退出策略,确保当前任务完成并妥善保存相关日志后再关闭实例。这种设计既保证了资源的高效利用,又确保了任务处理的可靠性。
存储策略选型
方案提供三种存储策略,可根据实际需求灵活选择:
方案一:S3 Mount Point直接加载模型(默认推荐)
这种方案的优势在于灵活性高且维护简单。系统根据需求从S3自动加载所需模型,S3可存储大量模型文件,未使用的模型不会被加载,从而提高资源利用效率。S3 Mount Point在文件顺序读取时可充分利用机器带宽,例如g5.2xlarge实例可达到Burst模式下的10Gbps速度。
需要注意的是,当某些模型在加载过程中需要进行随机读取操作时,从S3加载可能出现性能瓶颈。例如SafeTensors格式设计时考虑了内存映射(memory mapping)功能,文件头部包含描述各张量位置和大小的元数据,这可能引起文件的随机读取。由于S3通过HTTP方式获取数据,在大量随机读取场景下性能不如本地磁盘。
方案二:初始化时复制模型到本地
通过初始化时使用顺序加载或多线程方式将模型复制到本地磁盘,特别是使用带有实例存储的机型时(如g5.2xlarge配备450GB NVMe存储),能够实现最优的性能和成本效益。在需要频繁切换模型或进行随机读取操作时,由于模型已在本地,无需重复从S3加载。
这种方案的限制在于需要复制目录中的所有模型,因此需要仔细管理不同工作流使用的模型集合。模型更新后需要重新下载数据或进行机器替换,增加了一定的维护复杂性。
方案三:使用EFS加载模型
EFS方案具有较高的灵活性和简单的维护性,在处理随机读取场景时表现出色。缺点是需要承担相对更高的存储成本。适合对模型加载性能要求较高且预算充足的场景。
方案核心优势分析
成本优化与资源高效利用
- 零实例待机成本:空闲时弹性伸缩组可将实例数量缩减至0,完全消除无任务时的计算资源成本
- 按需扩展:系统根据SQS队列中的任务数量自动调整实例数量,确保资源与工作负载精确匹配
- 优雅退出机制:缩容时实现优雅退出流程,确保任务完成并保存日志,避免工作丢失
简化的部署与管理
- 一键部署:通过脚本可一键创建完整运行环境,支持随时创建或销毁多套相互独立的隔离环境
- AMI镜像自动化:环境配置完成后自动创建AMI镜像,简化配置过程,实现所见即所得
- 最小化依赖:整个系统仅依赖SQS队列实现异步任务分发,架构简洁明了,便于扩展和维护
优化的存储策略
- S3/EFS挂载:通过挂载S3或EFS存储,频繁更新配置无需重新创建AMI镜像,大量模型按需读取共享使用,节省磁盘空间,减少冗余,加快系统启动过程
- 日志集中管理:任务执行日志可直接在服务日志中查看,机器释放前统一存储到S3,便于问题排查和审计
完整部署指南
先决条件准备
准备基础环境Comfy Base,该环境用于平时直接使用ComfyUI,也作为部署生产环境时的原始镜像。
启动EC2实例时需赋予实例角色以提供创建资源的权限,涉及的权限包括:EC2、S3、EFS、SQS、AutoScaling、CloudWatch的创建权限,以及IAM的PassRole权限。
选择预装显卡驱动的AMI或在启动时安装Nvidia显卡驱动。安装AWS CLI、S3 Mount Point或EFS驱动,也可安装s5cmd加速S3复制操作。
ComfyUI安装步骤
参照官方安装方法,运行以下命令:
sudo apt install -y python3.12-venv
python3 -m venv venv
. venv/bin/activate
pip install comfy-cli
# 一路y即可,comfy会安装在/home/ubuntu/comfy下
comfy install
配置管理脚本
wget https://github.com/aws-samples/aws-global-accelerator-custom-routing-workshop/raw/refs/heads/main/stack/comfy-on-ec2/scripts.zip \
-O /home/ubuntu/comfy/scripts.zip
cd /home/ubuntu/comfy/
unzip scripts.zip
# 注意应该在venv环境中执行
. /home/ubuntu/venv/bin/activate
pip install boto3 dotenv
生成环境配置文件
生成配置文件/home/ubuntu/comfy/env,不同环境和配置都唯一依赖这个配置文件:
ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)
TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" \
-H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
INSTANCE_ID=$(curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \
http://169.254.169.254/latest/meta-data/instance-id)
REGION=$(aws ec2 describe-instances --instance-ids $INSTANCE_ID \
--query 'Reservations[0].Instances[0].Placement.AvailabilityZone' \
--output text | sed 's/[a-z]$//')
echo "ENV=base" > /home/ubuntu/comfy/env
echo "PREFIX=simple-comfy" >> /home/ubuntu/comfy/env
echo "ACCOUNT_ID=${ACCOUNT_ID}" >> /home/ubuntu/comfy/env
echo "REGION=${REGION}" >> /home/ubuntu/comfy/env
echo "S3_BUCKET=\${PREFIX}-\${ACCOUNT_ID}-\${REGION}-\${ENV}" >> /home/ubuntu/comfy/env
echo "SQS_NAME=\${PREFIX}-\${ENV}-queue" >> /home/ubuntu/comfy/env
echo "ASG_NAME=\${PREFIX}-\${ENV}-asg" >> /home/ubuntu/comfy/env
echo "INSTANCE_TYPE=g5.2xlarge" >> /home/ubuntu/comfy/env
echo "MIN_INSTANCES=0" >> /home/ubuntu/comfy/env
echo "MAX_INSTANCES=20" >> /home/ubuntu/comfy/env
echo "BACKLOGSIZE_PER_INSTANCE=3" >> /home/ubuntu/comfy/env
echo "SCALE_COOLDOWN=180" >> /home/ubuntu/comfy/env
可选:存储方案配置
使用S3或EFS只需将对应目录进行软链接映射。如选择生产环境机器初始化时将模型复制到本地,可添加以下配置:
# 使用aws cli进行模型复制
echo "COPY_MODEL_TO_LOCAL=awscli" >> /home/ubuntu/comfy/env
# 或使用s5cmd进行模型复制
echo "COPY_MODEL_TO_LOCAL=s5cmd" >> /home/ubuntu/comfy/env
标准环境配置
标准环境供测试开发使用,不需要配置弹性伸缩,只需配置SQS和S3桶:
source /home/ubuntu/comfy/env
# 创建标准环境的queue
aws sqs create-queue --queue-name "${SQS_NAME}" --region ${REGION}
# 创建S3桶(兼容us-east-1区域)
([ "$REGION" == "us-east-1" ] && aws s3api create-bucket --bucket "$S3_BUCKET" \
--region "$REGION" || aws s3api create-bucket --bucket "$S3_BUCKET" \
--region "$REGION" --create-bucket-configuration LocationConstraint="$REGION")
# 挂载S3桶
mkdir /home/ubuntu/comfy/s3
mount-s3 ${S3_BUCKET} /home/ubuntu/comfy/s3 --allow-delete --allow-overwrite
S3桶内容初始化
注意:以下操作会与S3保持完全一致的同步,如果S3本身有数据会被删除:
aws s3 sync /home/ubuntu/comfy/ComfyUI/models s3://${S3_BUCKET}/models --delete
aws s3 sync /home/ubuntu/comfy/ComfyUI/input s3://${S3_BUCKET}/input --delete
aws s3 sync /home/ubuntu/comfy/ComfyUI/output s3://${S3_BUCKET}/output --delete
# 清空本地目录以节省磁盘空间
rm -rf /home/ubuntu/comfy/ComfyUI/models /home/ubuntu/comfy/ComfyUI/input /home/ubuntu/comfy/ComfyUI/output
# 创建软链接使用S3桶数据
ln -s /home/ubuntu/comfy/s3/input /home/ubuntu/comfy/ComfyUI/
ln -s /home/ubuntu/comfy/s3/output /home/ubuntu/comfy/ComfyUI/
ln -s /home/ubuntu/comfy/s3/models /home/ubuntu/comfy/ComfyUI/
配置系统服务
配置两个系统自启动服务(comfyui是ComfyUI本身的服务,comfy-manage是任务调度服务):
cat << EOF | sudo tee /etc/systemd/system/comfyui.service
[Unit]
Description=ComfyUI Service
After=network-online.target
Requires=network-online.target
[Service]
User=ubuntu
WorkingDirectory=/home/ubuntu/comfy/ComfyUI
ExecStart=/home/ubuntu/comfy/start_service.sh comfyui
Restart=always
[Install]
WantedBy=multi-user.target
EOF
cat << EOF | sudo tee /etc/systemd/system/comfy-manage.service
[Unit]
Description=ComfyUI Service
After=network-online.target
Requires=network-online.target
[Service]
User=ubuntu
WorkingDirectory=/home/ubuntu/comfy
ExecStart=/home/ubuntu/comfy/start_service.sh comfy-manage
Restart=always
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable comfyui.service
sudo systemctl start comfyui.service
sudo systemctl enable comfy-manage.service
sudo systemctl start comfy-manage.service
日志查看与问题排查
# 系统启动后所有服务的运行情况
sudo journalctl -b
# 查看上一次启动的日志
sudo journalctl -b -1
# 查看具体服务状态和日志
systemctl status comfyui
journalctl -f -u comfyui
systemctl status comfy-manage
journalctl -f -u comfy-manage
# 查看parse_job.py的日志
tail -F /home/ubuntu/comfy/logs/*
# 如果弹性实例已销毁,可直接查看S3桶上的日志
source <(sed 's/^ENV=.*$/ENV=pro/' /home/ubuntu/comfy/env)
# 列出所有实例id
aws s3 ls s3://${S3_BUCKET}/output/ | grep "i-"
# 打印日志
aws s3 cp s3://${S3_BUCKET}/output/i-xxxxx/parse_job.log -
环境管理
在comfy文件夹中,通过./create_env.sh <环境名>一键创建环境,./delete_env.sh <环境名>一键删除环境。脚本会执行以下操作:
- 通过Comfy Base制作AMI镜像
- 配置弹性伸缩环境(开发环境使用公网IP,生产环境使用私有子网增加安全性)
- 复制S3环境,实现各生产环境和开发环境的隔离
- 配置SQS用于任务队列收发
业务集成与任务分发
测试示例
下载演示工作流所需的相关模型:
wget "https://huggingface.co/linsg/AWPainting_v1.5.safetensors/resolve/main/AWPainting_v1.5.safetensors?download=true" -O /home/ubuntu/comfy/ComfyUI/models/checkpoints/AWPainting_v1.5.safetensors
wget "https://huggingface.co/hakurei/waifu-diffusion-v1-4/resolve/main/vae/kl-f8-anime2.ckpt?download=true" -O /home/ubuntu/comfy/ComfyUI/models/vae/kl-f8-anime2.ckpt
wget "https://huggingface.co/ac-pill/upscale_models/resolve/main/RealESRGAN_x4plus_anime_6B.pth?download=true" -O /home/ubuntu/comfy/ComfyUI/models/upscale_models/RealESRGAN_x4plus_anime_6B.pth
wget "https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11f1e_sd15_tile.pth?download=true" -O /home/ubuntu/comfy/ComfyUI/models/controlnet/control_v11f1e_sd15_tile.pth
wget "https://huggingface.co/Comfy-Org/stable-diffusion-v1-5-archive/resolve/main/v1-5-pruned-emaonly-fp16.safetensors?download=true" -O /home/ubuntu/comfy/ComfyUI/models/checkpoints/v1-5-pruned-emaonly-fp16.safetensors
发送任务
send_job.py中提供了演示代码供参考,该文件可独立部署并按需集成到业务代码中。注意环境依赖env、comfy_utils.py文件和演示工作流simple_workflow.json:
python send_job.py
# 输出示例:
# Message sent successfully: c29f8168-8e7e-428a-a936-f76a6d287567
# Job submitted successfully
# Current queue size: 1
# Current instance count: 0
# Starting first instance...
# Adjusted ASG capacity to 1
示例中还提供了便捷指令,例如通过exec_cmd在base环境中执行下载模型任务:
execute_data = {
"exec_cmd": "wget 'https://huggingface.co/linsg/AWPainting_v1.5.safetensors/resolve/main/AWPainting_v1.5.safetensors?download=true' -O /home/ubuntu/comfy/ComfyUI/models/checkpoints/AWPainting_v1.5.safetensors",
}
弹性环境运行流程
弹性环境启动后,内置的parse_job.py将执行以下流程:
- 实例正常运行后,从SQS获取任务
- 获取任务并执行,根据队列深度控制弹性伸缩
- 完成后可对业务逻辑进行回调
- 判断队列深度,控制实例的缩放,通过生命周期钩子触发优雅退出
自定义业务逻辑扩展
- 任务完成后进行回调操作:在parse_job.py中查找关键字”# 这里可以添加自定义任务的业务回调处理”
- 机器缩容时进行退出前的善后工作:在parse_job.py中查找关键字”# 这里可以添加自定义善后工作逻辑”
直接调整弹性伸缩组设置
如修改了min/max size,需要在env文件里做对应修改:
# --min-size 0 --max-size 5
aws autoscaling update-auto-scaling-group --auto-scaling-group-name --desired-capacity 1
实施要点与注意事项
性能优化建议
- 对于模型加载时间敏感的场景,建议将高频使用的模型预先复制到本地实例存储
- BACKLOGSIZE_PER_INSTANCE参数决定了每个实例处理的任务积压上限,需根据单任务处理时间合理设置
- SCALE_COOLDOWN冷却时间设置过短可能导致频繁扩缩容,建议根据任务特性调整
成本控制策略
- 充分利用MIN_INSTANCES=0配置实现空闲时零成本
- 对于可预测的批量任务,可考虑使用Spot实例进一步降低成本
- 定期清理S3中的历史输出文件和日志,避免存储成本累积
安全性考量
- 生产环境建议部署在私有子网,通过NAT Gateway访问外部资源
- IAM角色权限应遵循最小权限原则,仅授予必要的资源访问权限
- 敏感的模型文件和输出结果建议启用S3服务端加密
方案价值与适用场景
该解决方案通过结合AWS的Auto Scaling、SQS消息队列和S3存储服务,为ComfyUI提供了一个高效、经济且可扩展的运行环境。方案不仅解决了传统部署方式中的环境兼容性、资源精细化管理和扩展性问题,还提供了简单易用的管理接口,使AI图像生成服务的运维变得更加简单。
无论是个人创作者还是企业级应用,