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 os
|
||||
import shutil
|
||||
import subprocess
|
||||
import uuid
|
||||
from pathlib import Path
|
||||
|
|
@ -7,7 +8,6 @@ from typing import Dict
|
|||
|
||||
import modal
|
||||
|
||||
|
||||
image = ( # build up a Modal Image to run ComfyUI, step by step
|
||||
modal.Image.debian_slim( # start from basic Linux with Python
|
||||
python_version="3.10"
|
||||
|
|
@ -25,7 +25,7 @@ image = ( # build up a Modal Image to run ComfyUI, step by step
|
|||
.pip_install("opencv-python")
|
||||
.run_commands( # use comfy-cli to install ComfyUI and its dependencies
|
||||
"comfy --skip-prompt install --nvidia --version 0.3.10"
|
||||
).add_local_file("snapshot.json","/root/snapshot.json", copy=True)
|
||||
)
|
||||
)
|
||||
|
||||
image = (
|
||||
|
|
@ -60,12 +60,12 @@ image = (
|
|||
"rm -rf /root/comfy/ComfyUI/models"
|
||||
).run_commands(
|
||||
"apt update && apt install -y ffmpeg && ffmpeg -version"
|
||||
).pip_install("av")
|
||||
# Add .run_commands(...) calls for any other custom nodes you want to download
|
||||
).pip_install(
|
||||
"av"
|
||||
).run_commands(
|
||||
"comfy node install https://e.coding.net/g-ldyi2063/dev/ComfyUI-FFmpeg.git"
|
||||
)
|
||||
|
||||
image = image.add_local_file(
|
||||
"highlight_v0.113_api.json", "/root/workflow_api.json"
|
||||
# Add .run_commands(...) calls for any other custom nodes you want to download
|
||||
)
|
||||
|
||||
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
|
||||
output_dir = "/root/comfy/ComfyUI/output"
|
||||
|
||||
|
||||
@app.cls(
|
||||
allow_concurrent_inputs=1, # allow 10 concurrent API calls
|
||||
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,
|
||||
gpu="T4",
|
||||
secrets=[secret],
|
||||
volumes={
|
||||
"/root/comfy/ComfyUI/models": vol,
|
||||
"/root/comfy/ComfyUI/input": modal.CloudBucketMount(
|
||||
"/root/comfy/ComfyUI/input_s3": modal.CloudBucketMount(
|
||||
bucket_name=bucket_input,
|
||||
# bucket_endpoint_url="https://s3.%s.amazonaws.com" % os.environ["AWS_REGION"],
|
||||
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_endpoint_url="https://s3.%s.amazonaws.com" % os.environ["AWS_REGION"],
|
||||
secret=secret,
|
||||
key_prefix="comfyui/"
|
||||
key_prefix="/"
|
||||
),
|
||||
},
|
||||
)
|
||||
|
|
@ -111,14 +113,23 @@ class ComfyUI:
|
|||
def infer(self, workflow_json: str = ""):
|
||||
# runs the comfy run --workflow command as a subprocess
|
||||
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:
|
||||
f.write(workflow_json)
|
||||
f.write(json.dumps(workflow, ensure_ascii=False))
|
||||
cmd = f"comfy run --workflow /root/{session_id}.json --wait --timeout 1200"
|
||||
# TODO 接收返回值
|
||||
subprocess.run(cmd, shell=True, check=True)
|
||||
|
||||
# looks up the name of the output image file based on the workflow
|
||||
workflow = json.loads(workflow_json)
|
||||
file_prefix = [
|
||||
node.get("inputs")
|
||||
for node in workflow.values()
|
||||
|
|
@ -128,10 +139,13 @@ class ComfyUI:
|
|||
# returns the image as bytes
|
||||
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)
|
||||
for f in new_file_list:
|
||||
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
|
||||
|
||||
@modal.web_endpoint(method="POST")
|
||||
|
|
@ -144,7 +158,7 @@ class ComfyUI:
|
|||
# run inference on the currently running container
|
||||
fname = self.infer.local(new_workflow_file)
|
||||
j = {
|
||||
"file_name": os.path.join("comfyui",fname)
|
||||
"file_name": fname
|
||||
}
|
||||
print("json", j)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue