parent
24b3b021ee
commit
05ff0a42d5
|
|
@ -0,0 +1,8 @@
|
||||||
|
# 默认忽略的文件
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# 基于编辑器的 HTTP 客户端请求
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="PyPep8NamingInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<option name="ignoredErrors">
|
||||||
|
<list>
|
||||||
|
<option value="N802" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</inspection_tool>
|
||||||
|
</profile>
|
||||||
|
</component>
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<settings>
|
||||||
|
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||||
|
<version value="1.0" />
|
||||||
|
</settings>
|
||||||
|
</component>
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Black">
|
||||||
|
<option name="sdkName" value="Python 3.9 (pythonProject)" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9 (modalDeploy)" project-jdk-type="Python SDK" />
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="PYTHON_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/.venv" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="jdk" jdkName="Python 3.9 (modalDeploy)" jdkType="Python SDK" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/modalDeploy.iml" filepath="$PROJECT_DIR$/.idea/modalDeploy.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import uuid
|
import uuid
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -7,7 +8,6 @@ from typing import Dict
|
||||||
|
|
||||||
import modal
|
import modal
|
||||||
|
|
||||||
|
|
||||||
image = ( # build up a Modal Image to run ComfyUI, step by step
|
image = ( # build up a Modal Image to run ComfyUI, step by step
|
||||||
modal.Image.debian_slim( # start from basic Linux with Python
|
modal.Image.debian_slim( # start from basic Linux with Python
|
||||||
python_version="3.10"
|
python_version="3.10"
|
||||||
|
|
@ -25,7 +25,7 @@ image = ( # build up a Modal Image to run ComfyUI, step by step
|
||||||
.pip_install("opencv-python")
|
.pip_install("opencv-python")
|
||||||
.run_commands( # use comfy-cli to install ComfyUI and its dependencies
|
.run_commands( # use comfy-cli to install ComfyUI and its dependencies
|
||||||
"comfy --skip-prompt install --nvidia --version 0.3.10"
|
"comfy --skip-prompt install --nvidia --version 0.3.10"
|
||||||
).add_local_file("snapshot.json","/root/snapshot.json", copy=True)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
image = (
|
image = (
|
||||||
|
|
@ -60,12 +60,12 @@ image = (
|
||||||
"rm -rf /root/comfy/ComfyUI/models"
|
"rm -rf /root/comfy/ComfyUI/models"
|
||||||
).run_commands(
|
).run_commands(
|
||||||
"apt update && apt install -y ffmpeg && ffmpeg -version"
|
"apt update && apt install -y ffmpeg && ffmpeg -version"
|
||||||
).pip_install("av")
|
).pip_install(
|
||||||
# Add .run_commands(...) calls for any other custom nodes you want to download
|
"av"
|
||||||
|
).run_commands(
|
||||||
|
"comfy node install https://e.coding.net/g-ldyi2063/dev/ComfyUI-FFmpeg.git"
|
||||||
)
|
)
|
||||||
|
# Add .run_commands(...) calls for any other custom nodes you want to download
|
||||||
image = image.add_local_file(
|
|
||||||
"highlight_v0.113_api.json", "/root/workflow_api.json"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
app = modal.App(name="highlight-comfyui-s3", image=image)
|
app = modal.App(name="highlight-comfyui-s3", image=image)
|
||||||
|
|
@ -77,26 +77,28 @@ secret = modal.Secret.from_name("aws-s3-secret")
|
||||||
# completed workflows write output images to this directory
|
# completed workflows write output images to this directory
|
||||||
output_dir = "/root/comfy/ComfyUI/output"
|
output_dir = "/root/comfy/ComfyUI/output"
|
||||||
|
|
||||||
|
|
||||||
@app.cls(
|
@app.cls(
|
||||||
allow_concurrent_inputs=1, # allow 10 concurrent API calls
|
allow_concurrent_inputs=1, # allow 10 concurrent API calls
|
||||||
concurrency_limit=50,
|
concurrency_limit=50,
|
||||||
container_idle_timeout=120, # 5 minute container keep alive after it processes an input; increasing this value is a great way to reduce ComfyUI cold start times
|
container_idle_timeout=120,
|
||||||
|
# 5 minute container keep alive after it processes an input; increasing this value is a great way to reduce ComfyUI cold start times
|
||||||
timeout=800,
|
timeout=800,
|
||||||
gpu="T4",
|
gpu="T4",
|
||||||
secrets=[secret],
|
secrets=[secret],
|
||||||
volumes={
|
volumes={
|
||||||
"/root/comfy/ComfyUI/models": vol,
|
"/root/comfy/ComfyUI/models": vol,
|
||||||
"/root/comfy/ComfyUI/input": modal.CloudBucketMount(
|
"/root/comfy/ComfyUI/input_s3": modal.CloudBucketMount(
|
||||||
bucket_name=bucket_input,
|
bucket_name=bucket_input,
|
||||||
# bucket_endpoint_url="https://s3.%s.amazonaws.com" % os.environ["AWS_REGION"],
|
# bucket_endpoint_url="https://s3.%s.amazonaws.com" % os.environ["AWS_REGION"],
|
||||||
secret=secret,
|
secret=secret,
|
||||||
key_prefix="comfyui/"
|
key_prefix="/"
|
||||||
),
|
),
|
||||||
"/root/comfy/ComfyUI/output": modal.CloudBucketMount(
|
"/root/comfy/ComfyUI/output_s3": modal.CloudBucketMount(
|
||||||
bucket_name=bucket_output,
|
bucket_name=bucket_output,
|
||||||
# bucket_endpoint_url="https://s3.%s.amazonaws.com" % os.environ["AWS_REGION"],
|
# bucket_endpoint_url="https://s3.%s.amazonaws.com" % os.environ["AWS_REGION"],
|
||||||
secret=secret,
|
secret=secret,
|
||||||
key_prefix="comfyui/"
|
key_prefix="/"
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
@ -111,14 +113,23 @@ class ComfyUI:
|
||||||
def infer(self, workflow_json: str = ""):
|
def infer(self, workflow_json: str = ""):
|
||||||
# runs the comfy run --workflow command as a subprocess
|
# runs the comfy run --workflow command as a subprocess
|
||||||
session_id = str(uuid.uuid4())
|
session_id = str(uuid.uuid4())
|
||||||
|
workflow = json.loads(workflow_json)
|
||||||
|
file_to_move = None
|
||||||
|
for node in workflow.values():
|
||||||
|
if node.get("class_type") == "ComfyUIDeployExternalText":
|
||||||
|
if node.get("inputs").get("input_id") == "file_path":
|
||||||
|
file_to_move = node.get("inputs").get("default_value")
|
||||||
|
if file_to_move:
|
||||||
|
os.makedirs(os.path.dirname(file_to_move.replace("input_s3", "input")), exist_ok=True)
|
||||||
|
shutil.copy(file_to_move, file_to_move.replace("input_s3", "input"))
|
||||||
|
node["inputs"]["default_value"] = node["inputs"]["default_value"].replace("input_s3", "input")
|
||||||
with open(f"/root/{session_id}.json", "w", encoding="utf-8") as f:
|
with open(f"/root/{session_id}.json", "w", encoding="utf-8") as f:
|
||||||
f.write(workflow_json)
|
f.write(json.dumps(workflow, ensure_ascii=False))
|
||||||
cmd = f"comfy run --workflow /root/{session_id}.json --wait --timeout 1200"
|
cmd = f"comfy run --workflow /root/{session_id}.json --wait --timeout 1200"
|
||||||
# TODO 接收返回值
|
# TODO 接收返回值
|
||||||
subprocess.run(cmd, shell=True, check=True)
|
subprocess.run(cmd, shell=True, check=True)
|
||||||
|
|
||||||
# looks up the name of the output image file based on the workflow
|
# looks up the name of the output image file based on the workflow
|
||||||
workflow = json.loads(workflow_json)
|
|
||||||
file_prefix = [
|
file_prefix = [
|
||||||
node.get("inputs")
|
node.get("inputs")
|
||||||
for node in workflow.values()
|
for node in workflow.values()
|
||||||
|
|
@ -128,10 +139,13 @@ class ComfyUI:
|
||||||
# returns the image as bytes
|
# returns the image as bytes
|
||||||
file_list = os.listdir(output_dir)
|
file_list = os.listdir(output_dir)
|
||||||
# 获取按照文件时间创建排序的列表,默认是按时间升序
|
# 获取按照文件时间创建排序的列表,默认是按时间升序
|
||||||
new_file_list = sorted(file_list, key=lambda file: os.path.getctime(os.path.join(output_dir, file)), reverse=True)
|
new_file_list = sorted(file_list, key=lambda file: os.path.getctime(os.path.join(output_dir, file)),
|
||||||
|
reverse=True)
|
||||||
# print("file_list", new_file_list)
|
# print("file_list", new_file_list)
|
||||||
for f in new_file_list:
|
for f in new_file_list:
|
||||||
if f.startswith(file_prefix):
|
if f.startswith(file_prefix):
|
||||||
|
os.makedirs(os.path.dirname(os.path.join(output_dir.replace("output","output_s3"), f)), exist_ok=True)
|
||||||
|
shutil.copy(os.path.join(output_dir, f), os.path.join(output_dir.replace("output","output_s3"), f))
|
||||||
return f
|
return f
|
||||||
|
|
||||||
@modal.web_endpoint(method="POST")
|
@modal.web_endpoint(method="POST")
|
||||||
|
|
@ -144,7 +158,7 @@ class ComfyUI:
|
||||||
# run inference on the currently running container
|
# run inference on the currently running container
|
||||||
fname = self.infer.local(new_workflow_file)
|
fname = self.infer.local(new_workflow_file)
|
||||||
j = {
|
j = {
|
||||||
"file_name": os.path.join("comfyui",fname)
|
"file_name": fname
|
||||||
}
|
}
|
||||||
print("json", j)
|
print("json", j)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue