volume work

This commit is contained in:
Nicholas Koben Kao 2024-01-20 19:54:35 -08:00
parent 60471a8e01
commit 7b61fea849
6 changed files with 108 additions and 27 deletions

View File

@ -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))

View File

@ -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():

View File

@ -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"
}

View File

@ -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

View File

@ -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)

View 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}