Squashed commit of the following:
commit 33c0ad7d14a85f22c57f943dab58610c13d2ac07
Author: Nicholas Koben Kao <[email protected]>
Date: Tue Jan 30 21:56:00 2024 -0800
revert custom form change
commit d2905ad045ad7856156e3647a81d642999352de7
Merge: 654423d e3a1d24
Author: Nicholas Koben Kao <[email protected]>
Date: Tue Jan 30 20:50:06 2024 -0800
merge schema
commit 654423d597e019a5ebf1ab6568c9942fcb9181c5
Author: Nicholas Koben Kao <[email protected]>
Date: Tue Jan 30 20:49:34 2024 -0800
merge confl.ict
commit 641724c11346319674fbb329e8e29b362117c242
Author: Nicholas Koben Kao <[email protected]>
Date: Tue Jan 30 20:47:34 2024 -0800
model reload on create
commit eb4dfe8e3f39a0a98eab0fcf1affe7096c12f33b
Author: Nicholas Koben Kao <[email protected]>
Date: Tue Jan 30 17:00:03 2024 -0800
delete models
commit 0bea9583fada102396c4e08fe6da971c94d404df
Author: Nicholas Koben Kao <[email protected]>
Date: Tue Jan 30 14:35:15 2024 -0800
deploy volume uploader to have timeouts only be modal related
This commit is contained in:
@@ -13,4 +13,4 @@ RUN mkdir builds
|
||||
# CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "80", "--lifespan", "on"]
|
||||
CMD ["python", "src/main.py"]
|
||||
# If running behind a proxy like Nginx or Traefik add --proxy-headers
|
||||
# CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80", "--proxy-headers"]
|
||||
# CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80", "--proxy-headers"]
|
||||
|
||||
@@ -19,7 +19,7 @@ import requests
|
||||
from urllib.parse import parse_qs
|
||||
from starlette.middleware.base import BaseHTTPMiddleware
|
||||
from starlette.types import ASGIApp, Scope, Receive, Send
|
||||
|
||||
import modal
|
||||
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
|
||||
@@ -236,6 +236,14 @@ class UploadType(str, Enum):
|
||||
checkpoint = "checkpoint"
|
||||
lora = "lora"
|
||||
embedding = "embedding"
|
||||
clip = "clip"
|
||||
clip_vision = "clip_vision"
|
||||
configs = "configs"
|
||||
controlnet = "controlnet"
|
||||
upscale_models = "upscale_models"
|
||||
vae = "vae"
|
||||
ipadapter = "ipadapter"
|
||||
other = "other"
|
||||
|
||||
class UploadBody(BaseModel):
|
||||
download_url: str
|
||||
@@ -251,8 +259,46 @@ UPLOAD_TYPE_DIR_MAP = {
|
||||
UploadType.checkpoint: "checkpoints",
|
||||
UploadType.lora: "loras",
|
||||
UploadType.embedding: "embeddings",
|
||||
UploadType.clip: "clip",
|
||||
UploadType.clip_vision: "clip_vision",
|
||||
UploadType.configs: "configs",
|
||||
UploadType.controlnet: "controlnet",
|
||||
UploadType.upscale_models: "upscale_models",
|
||||
UploadType.vae: "vae",
|
||||
UploadType.ipadapter: "ipadapter",
|
||||
UploadType.other: "",
|
||||
}
|
||||
|
||||
class DeleteBody(BaseModel):
|
||||
volume_name: str
|
||||
path: str
|
||||
file_name: str
|
||||
|
||||
|
||||
@app.post("/delete-volume-model")
|
||||
async def delete_model(body: DeleteBody):
|
||||
global last_activity_time
|
||||
last_activity_time = time.time()
|
||||
logger.info(f"Extended inactivity time to {global_timeout}")
|
||||
|
||||
full_path = f"{body.path.rstrip('/')}/{body.file_name}"
|
||||
|
||||
rm_process = await asyncio.subprocess.create_subprocess_exec("modal", "volume", "rm", body.volume_name, full_path,
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE,)
|
||||
await rm_process.wait()
|
||||
|
||||
logger.info(f"Successfully deleted: {full_path} from volume: {body.volume_name}")
|
||||
stdout, stderr = await rm_process.communicate()
|
||||
if stdout:
|
||||
logger.info(f"cp_process stdout: {stdout.decode()}")
|
||||
if stderr:
|
||||
logger.info(f"cp_process stderr: {stderr.decode()}")
|
||||
|
||||
if rm_process.returncode == 0:
|
||||
return JSONResponse(status_code=200, content={"status":f"Successfully deleted {full_path} from volume {body.volume_name}"})
|
||||
else:
|
||||
return JSONResponse(status_code=500, content={"status": "error", "error": stderr.decode()})
|
||||
|
||||
@app.post("/upload-volume")
|
||||
async def upload_model(body: UploadBody):
|
||||
@@ -267,12 +313,16 @@ async def upload_model(body: UploadBody):
|
||||
|
||||
|
||||
async def upload_logic(body: UploadBody):
|
||||
folder_path = f"/app/builds/{body.volume_id}"
|
||||
folder_path = f"/app/builds/{body.volume_id}-{uuid4()}"
|
||||
|
||||
cp_process = await asyncio.subprocess.create_subprocess_exec("cp", "-r", "/app/src/volume-builder", folder_path)
|
||||
cp_process = await asyncio.subprocess.create_subprocess_exec("cp", "-r", "/app/src/volume_builder", folder_path)
|
||||
await cp_process.wait()
|
||||
|
||||
upload_path = UPLOAD_TYPE_DIR_MAP[body.upload_type]
|
||||
if upload_path == "":
|
||||
# TODO: deal with custom paths
|
||||
pass
|
||||
|
||||
config = {
|
||||
"volume_names": {
|
||||
body.volume_name: {"download_url": body.download_url, "folder_path": upload_path}
|
||||
@@ -286,16 +336,22 @@ async def upload_logic(body: UploadBody):
|
||||
"volume_id": body.volume_id,
|
||||
"folder_path": upload_path,
|
||||
},
|
||||
"civitai_api_key": os.environ.get('CIVITAI_API_KEY')
|
||||
"civitai_api_key": os.environ.get('CIVITAI_API_KEY'),
|
||||
"app_name": f"vol_name_{uuid4()}"
|
||||
}
|
||||
with open(f"{folder_path}/config.py", "w") as f:
|
||||
f.write("config = " + json.dumps(config))
|
||||
|
||||
await asyncio.subprocess.create_subprocess_shell(
|
||||
f"modal run app.py",
|
||||
process = await asyncio.subprocess.create_subprocess_shell(
|
||||
f"python runner.py",
|
||||
cwd=folder_path,
|
||||
env={**os.environ, "COLUMNS": "10000"}
|
||||
)
|
||||
await process.wait()
|
||||
|
||||
# import modal
|
||||
# modal.deploy_stub(stub)
|
||||
# stub["download_model"].web_url
|
||||
|
||||
@app.post("/create")
|
||||
async def create_machine(item: Item):
|
||||
|
||||
@@ -9,6 +9,8 @@ public:
|
||||
loras: loras
|
||||
upscale_models: upscale_models
|
||||
vae: vae
|
||||
ipadapter: ipadapter
|
||||
|
||||
|
||||
private:
|
||||
base_path: /private_models/
|
||||
@@ -21,3 +23,4 @@ private:
|
||||
loras: loras
|
||||
upscale_models: upscale_models
|
||||
vae: vae
|
||||
ipadapter: ipadapter
|
||||
|
||||
+13
-11
@@ -1,10 +1,18 @@
|
||||
from fastapi import FastAPI, Request
|
||||
from fastapi.responses import HTMLResponse
|
||||
import modal
|
||||
from config import config
|
||||
import os
|
||||
import subprocess
|
||||
from pprint import pprint
|
||||
|
||||
stub = modal.Stub()
|
||||
stub = modal.Stub(config["app_name"])
|
||||
vol_name_to_links = config["volume_names"]
|
||||
vol_name_to_path = config["volume_paths"]
|
||||
callback_url = config["callback_url"]
|
||||
callback_body = config["callback_body"]
|
||||
civitai_key = config["civitai_api_key"]
|
||||
web_app = FastAPI()
|
||||
|
||||
# Volume names may only contain alphanumeric characters, dashes, periods, and underscores, and must be less than 64 characters in length.
|
||||
def is_valid_name(name: str) -> bool:
|
||||
@@ -21,12 +29,6 @@ def create_volumes(volume_names, paths):
|
||||
|
||||
return path_to_vol
|
||||
|
||||
vol_name_to_links = config["volume_names"]
|
||||
vol_name_to_path = config["volume_paths"]
|
||||
callback_url = config["callback_url"]
|
||||
callback_body = config["callback_body"]
|
||||
civitai_key = config["civitai_api_key"]
|
||||
|
||||
volumes = create_volumes(vol_name_to_links, vol_name_to_path)
|
||||
image = (
|
||||
modal.Image.debian_slim().apt_install("wget").pip_install("requests")
|
||||
@@ -45,7 +47,7 @@ def download_model(volume_name, download_config):
|
||||
modified_download_url = download_url + ("&" if "?" in download_url else "?") + "token=" + civitai_key # civitai requires auth
|
||||
print('downloading', modified_download_url)
|
||||
|
||||
subprocess.run(["wget", modified_download_url , "--content-disposition", "-P", model_store_path])
|
||||
subprocess.run(["wget", modified_download_url , "--content-disposition", "-P", model_store_path, "-nv"])
|
||||
subprocess.run(["ls", "-la", volume_base_path])
|
||||
subprocess.run(["ls", "-la", model_store_path])
|
||||
volumes[volume_base_path].commit()
|
||||
@@ -56,11 +58,12 @@ def download_model(volume_name, download_config):
|
||||
print(f"finished! sending to {callback_url}")
|
||||
pprint({**status, **callback_body})
|
||||
|
||||
@stub.local_entrypoint()
|
||||
@stub.function(image=image)
|
||||
# @modal.asgi_app()
|
||||
def simple_download():
|
||||
import requests
|
||||
try:
|
||||
list(download_model.starmap([(vol_name, link) for vol_name,link in vol_name_to_links.items()]))
|
||||
list(download_model.starmap([(vol_name, download_conf) for vol_name,download_conf in vol_name_to_links.items()]))
|
||||
except modal.exception.FunctionTimeoutError as e:
|
||||
status = {"status": "failed", "error_logs": f"{str(e)}", "timeout": timeout}
|
||||
requests.post(callback_url, json={**status, **callback_body})
|
||||
@@ -71,4 +74,3 @@ def simple_download():
|
||||
requests.post(callback_url, json={**status, **callback_body})
|
||||
print(f"finished! sending to {callback_url}")
|
||||
pprint({**status, **callback_body})
|
||||
|
||||
+1
@@ -15,4 +15,5 @@ config = {
|
||||
"folder_path": "checkpoints",
|
||||
},
|
||||
"civitai_api_key": "",
|
||||
"app_name": "",
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import modal
|
||||
import requests
|
||||
from app import stub
|
||||
from config import config
|
||||
|
||||
modal.runner.deploy_stub(stub)
|
||||
print("deployed stub")
|
||||
# web_url = stub["simple_download"].web_url
|
||||
f = modal.Function.lookup(config['app_name'], "simple_download")
|
||||
f.spawn()
|
||||
# print(f"web_url: {web_url}")
|
||||
# requests.post(web_url)
|
||||
Reference in New Issue
Block a user