volume work
This commit is contained in:
parent
60471a8e01
commit
7b61fea849
@ -312,7 +312,9 @@ async def build_logic(item: Item):
|
|||||||
config = {
|
config = {
|
||||||
"name": item.name,
|
"name": item.name,
|
||||||
"deploy_test": os.environ.get("DEPLOY_TEST_FLAG", "False"),
|
"deploy_test": os.environ.get("DEPLOY_TEST_FLAG", "False"),
|
||||||
"gpu": item.gpu
|
"gpu": item.gpu,
|
||||||
|
"public_checkpoint_volume": "model-store",
|
||||||
|
"private_checkpoint_volume": "private-model-store"
|
||||||
}
|
}
|
||||||
with open(f"{folder_path}/config.py", "w") as f:
|
with open(f"{folder_path}/config.py", "w") as f:
|
||||||
f.write("config = " + json.dumps(config))
|
f.write("config = " + json.dumps(config))
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import urllib.parse
|
|||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from fastapi import FastAPI, Request
|
from fastapi import FastAPI, Request
|
||||||
from fastapi.responses import HTMLResponse
|
from fastapi.responses import HTMLResponse
|
||||||
|
from volume import volumes
|
||||||
|
|
||||||
# deploy_test = False
|
# deploy_test = False
|
||||||
|
|
||||||
@ -28,9 +29,6 @@ web_app = FastAPI()
|
|||||||
print(config)
|
print(config)
|
||||||
print("deploy_test ", deploy_test)
|
print("deploy_test ", deploy_test)
|
||||||
stub = Stub(name=config["name"])
|
stub = Stub(name=config["name"])
|
||||||
volume = modal.Volume.persisted("model-store")
|
|
||||||
MODEL_DIR = "/comfyui/models/checkpoints/"
|
|
||||||
# print(stub.app_id)
|
|
||||||
|
|
||||||
if not deploy_test:
|
if not deploy_test:
|
||||||
# dockerfile_image = Image.from_dockerfile(f"{current_directory}/Dockerfile", context_mount=Mount.from_local_dir(f"{current_directory}/data", remote_path="/data"))
|
# dockerfile_image = Image.from_dockerfile(f"{current_directory}/Dockerfile", context_mount=Mount.from_local_dir(f"{current_directory}/data", remote_path="/data"))
|
||||||
@ -58,7 +56,7 @@ if not deploy_test:
|
|||||||
# # Install comfy deploy
|
# # Install comfy deploy
|
||||||
# "cd /comfyui/custom_nodes && git clone https://github.com/BennyKok/comfyui-deploy.git",
|
# "cd /comfyui/custom_nodes && git clone https://github.com/BennyKok/comfyui-deploy.git",
|
||||||
# )
|
# )
|
||||||
# .copy_local_file(f"{current_directory}/data/extra_model_paths.yaml", "/comfyui")
|
.copy_local_file(f"{current_directory}/data/extra_model_paths.yaml", "/comfyui")
|
||||||
|
|
||||||
.copy_local_file(f"{current_directory}/data/start.sh", "/start.sh")
|
.copy_local_file(f"{current_directory}/data/start.sh", "/start.sh")
|
||||||
.run_commands("chmod +x /start.sh")
|
.run_commands("chmod +x /start.sh")
|
||||||
@ -74,7 +72,6 @@ if not deploy_test:
|
|||||||
.copy_local_file(f"{current_directory}/data/deps.json", "/")
|
.copy_local_file(f"{current_directory}/data/deps.json", "/")
|
||||||
|
|
||||||
.run_commands("python install_deps.py")
|
.run_commands("python install_deps.py")
|
||||||
.run_commands(f"rm -rf {MODEL_DIR}") # clear model dir so volume can mount, NOTE: could instead use the extra_model_paths
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Time to wait between API check attempts in milliseconds
|
# Time to wait between API check attempts in milliseconds
|
||||||
@ -156,10 +153,9 @@ image = Image.debian_slim()
|
|||||||
|
|
||||||
target_image = image if deploy_test else dockerfile_image
|
target_image = image if deploy_test else dockerfile_image
|
||||||
|
|
||||||
|
|
||||||
@stub.function(image=target_image, gpu=config["gpu"]
|
@stub.function(image=target_image, gpu=config["gpu"]
|
||||||
, volumes={MODEL_DIR: volume}
|
,volumes=volumes
|
||||||
)
|
)
|
||||||
def run(input: Input):
|
def run(input: Input):
|
||||||
import subprocess
|
import subprocess
|
||||||
import time
|
import time
|
||||||
@ -168,6 +164,7 @@ def run(input: Input):
|
|||||||
|
|
||||||
command = ["python", "main.py",
|
command = ["python", "main.py",
|
||||||
"--disable-auto-launch", "--disable-metadata"]
|
"--disable-auto-launch", "--disable-metadata"]
|
||||||
|
|
||||||
server_process = subprocess.Popen(command, cwd="/comfyui")
|
server_process = subprocess.Popen(command, cwd="/comfyui")
|
||||||
|
|
||||||
check_server(
|
check_server(
|
||||||
@ -241,8 +238,8 @@ async def bar(request_input: RequestInput):
|
|||||||
|
|
||||||
|
|
||||||
@stub.function(image=image
|
@stub.function(image=image
|
||||||
, volumes={MODEL_DIR: volume}
|
,volumes=volumes
|
||||||
)
|
)
|
||||||
@asgi_app()
|
@asgi_app()
|
||||||
def comfyui_api():
|
def comfyui_api():
|
||||||
return web_app
|
return web_app
|
||||||
@ -292,7 +289,7 @@ def spawn_comfyui_in_background():
|
|||||||
# to be on a single container.
|
# to be on a single container.
|
||||||
concurrency_limit=1,
|
concurrency_limit=1,
|
||||||
timeout=10 * 60,
|
timeout=10 * 60,
|
||||||
volumes={MODEL_DIR: volume}
|
volumes=volumes,
|
||||||
)
|
)
|
||||||
@asgi_app()
|
@asgi_app()
|
||||||
def comfyui_app():
|
def comfyui_app():
|
||||||
|
|||||||
@ -1 +1,7 @@
|
|||||||
config = {"name": "my-app", "deploy_test": "True", "gpu": "T4"}
|
config = {
|
||||||
|
"name": "my-app",
|
||||||
|
"deploy_test": "True",
|
||||||
|
"gpu": "T4",
|
||||||
|
"public_checkpoint_volume": "model-store",
|
||||||
|
"private_checkpoint_volume": "private-model-store"
|
||||||
|
}
|
||||||
|
|||||||
@ -1,11 +1,30 @@
|
|||||||
comfyui:
|
comfyui:
|
||||||
base_path: /runpod-volume/ComfyUI/
|
base_path: /extra_models/
|
||||||
checkpoints: models/checkpoints/
|
checkpoints: |
|
||||||
clip: models/clip/
|
checkpoints
|
||||||
clip_vision: models/clip_vision/
|
private_checkpoints
|
||||||
configs: models/configs/
|
clip: |
|
||||||
controlnet: models/controlnet/
|
clip
|
||||||
embeddings: models/embeddings/
|
private_clip
|
||||||
loras: models/loras/
|
clip_vision: |
|
||||||
upscale_models: models/upscale_models/
|
clip_vision
|
||||||
vae: models/vae/
|
private_clip_vision
|
||||||
|
configs: |
|
||||||
|
configs
|
||||||
|
private_configs
|
||||||
|
controlnet: |
|
||||||
|
controlnet
|
||||||
|
private_controlnet
|
||||||
|
embeddings: |
|
||||||
|
embeddings
|
||||||
|
private_embeddings
|
||||||
|
loras: |
|
||||||
|
loras
|
||||||
|
private_loras
|
||||||
|
upscale_models: |
|
||||||
|
upscale_models
|
||||||
|
private_upscale_models
|
||||||
|
vae: |
|
||||||
|
vae
|
||||||
|
private_vae
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,15 @@
|
|||||||
|
"""
|
||||||
|
This is a standalone script to download models into a modal Volume using civitai
|
||||||
|
|
||||||
|
Example Usage
|
||||||
|
`modal run insert_models::insert_model --civitai-url https://civitai.com/models/36520/ghostmix`
|
||||||
|
This inserts an individual model from a civitai url (public not API url)
|
||||||
|
|
||||||
|
`modal run insert_models::insert_models`
|
||||||
|
This inserts a bunch of models based on the models retrieved by civitai
|
||||||
|
|
||||||
|
civitai's API reference https://github.com/civitai/civitai/wiki/REST-API-Reference
|
||||||
|
"""
|
||||||
import modal
|
import modal
|
||||||
import subprocess
|
import subprocess
|
||||||
import requests
|
import requests
|
||||||
@ -5,7 +17,7 @@ import requests
|
|||||||
stub = modal.Stub()
|
stub = modal.Stub()
|
||||||
|
|
||||||
# NOTE: volume name can be variable
|
# NOTE: volume name can be variable
|
||||||
volume = modal.Volume.persisted("model-store")
|
volume = modal.Volume.persisted("private-model-store")
|
||||||
model_store_path = "/vol/models"
|
model_store_path = "/vol/models"
|
||||||
MODEL_ROUTE = "models"
|
MODEL_ROUTE = "models"
|
||||||
image = (
|
image = (
|
||||||
@ -15,8 +27,10 @@ image = (
|
|||||||
@stub.function(volumes={model_store_path: volume}, gpu="any", image=image, timeout=600)
|
@stub.function(volumes={model_store_path: volume}, gpu="any", image=image, timeout=600)
|
||||||
def download_model(model):
|
def download_model(model):
|
||||||
# wget https://civitai.com/api/download/models/{modelVersionId} --content-disposition
|
# wget https://civitai.com/api/download/models/{modelVersionId} --content-disposition
|
||||||
model_id = model['modelVersions'][0]['id']
|
# model_id = model['modelVersions'][0]['id']
|
||||||
download_url = f"https://civitai.com/api/download/models/{model_id}"
|
# download_url = f"https://civitai.com/api/download/models/{model_id}"
|
||||||
|
|
||||||
|
download_url = model['modelVersions'][0]['downloadUrl']
|
||||||
subprocess.run(["wget", download_url, "--content-disposition", "-P", model_store_path])
|
subprocess.run(["wget", download_url, "--content-disposition", "-P", model_store_path])
|
||||||
subprocess.run(["ls", "-la", model_store_path])
|
subprocess.run(["ls", "-la", model_store_path])
|
||||||
volume.commit()
|
volume.commit()
|
||||||
@ -34,11 +48,44 @@ def get_civitai_models(model_type: str, sort: str = "Highest Rated", page: int =
|
|||||||
print(f"Error fetching models: {e}")
|
print(f"Error fetching models: {e}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
@stub.function()
|
||||||
|
def get_civitai_model_url(civitai_url: str):
|
||||||
|
# Validate the URL
|
||||||
|
if not civitai_url.startswith("https://civitai.com/models/"):
|
||||||
|
return "Error: URL must be from civitai.com and contain /models/"
|
||||||
|
|
||||||
|
# Extract the model ID
|
||||||
|
try:
|
||||||
|
model_id = civitai_url.split("/")[4]
|
||||||
|
int(model_id) # Check if the ID is an integer
|
||||||
|
except (IndexError, ValueError):
|
||||||
|
return None #Error: Invalid model ID in URL
|
||||||
|
|
||||||
|
# Make the API request
|
||||||
|
api_url = f"https://civitai.com/api/v1/models/{model_id}"
|
||||||
|
response = requests.get(api_url)
|
||||||
|
|
||||||
|
# Check for successful response
|
||||||
|
if response.status_code != 200:
|
||||||
|
return f"Error: Unable to fetch data from {api_url}"
|
||||||
|
|
||||||
|
# Return the response data
|
||||||
|
return response.json()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@stub.local_entrypoint()
|
@stub.local_entrypoint()
|
||||||
def insert_model(type: str = "Checkpoint", sort = "Highest Rated", page: int = 1):
|
def insert_models(type: str = "Checkpoint", sort = "Highest Rated", page: int = 1):
|
||||||
civitai_models = get_civitai_models.local(type, sort, page)
|
civitai_models = get_civitai_models.local(type, sort, page)
|
||||||
if civitai_models:
|
if civitai_models:
|
||||||
for _ in download_model.map(civitai_models['items'][1:]):
|
for _ in download_model.map(civitai_models['items'][1:]):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
print("Failed to retrieve models.")
|
print("Failed to retrieve models.")
|
||||||
|
|
||||||
|
@stub.local_entrypoint()
|
||||||
|
def insert_model(civitai_url: str):
|
||||||
|
civitai_model = get_civitai_model_url.local(civitai_url)
|
||||||
|
if civitai_model:
|
||||||
|
download_model.remote(civitai_model)
|
||||||
|
|||||||
10
builder/modal-builder/src/template/volume.py
Normal file
10
builder/modal-builder/src/template/volume.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import modal
|
||||||
|
from config import config
|
||||||
|
|
||||||
|
public_model_volume = modal.Volume.persisted(config["public_checkpoint_volume"])
|
||||||
|
private_volume = modal.Volume.persisted(config["private_checkpoint_volume"])
|
||||||
|
|
||||||
|
BASEMODEL_DIR = "/extra_models/"
|
||||||
|
MODEL_DIR = BASEMODEL_DIR + "checkpoints"
|
||||||
|
PRIVATE_MODEL_DIR = BASEMODEL_DIR + "private_checkpoints"
|
||||||
|
volumes = {MODEL_DIR: public_model_volume, PRIVATE_MODEL_DIR: private_volume}
|
||||||
Loading…
x
Reference in New Issue
Block a user