|
@@ -19,6 +19,8 @@ from exo.orchestration import Node
|
|
|
from exo.models import build_base_shard, model_cards, get_repo, pretty_name
|
|
|
from typing import Callable, Optional
|
|
|
from exo.download.hf.hf_shard_download import HFShardDownloader
|
|
|
+import shutil
|
|
|
+from exo.download.hf.hf_helpers import get_hf_home, get_repo_root
|
|
|
|
|
|
class Message:
|
|
|
def __init__(self, role: str, content: Union[str, List[Dict[str, Union[str, Dict[str, str]]]]]):
|
|
@@ -176,6 +178,7 @@ class ChatGPTAPI:
|
|
|
cors.add(self.app.router.add_get("/modelpool", self.handle_model_support), {"*": cors_options})
|
|
|
cors.add(self.app.router.add_get("/healthcheck", self.handle_healthcheck), {"*": cors_options})
|
|
|
cors.add(self.app.router.add_post("/quit", self.handle_quit), {"*": cors_options})
|
|
|
+ cors.add(self.app.router.add_delete("/models/{model_name}", self.handle_delete_model), {"*": cors_options})
|
|
|
|
|
|
if "__compiled__" not in globals():
|
|
|
self.static_dir = Path(__file__).parent.parent/"tinychat"
|
|
@@ -415,6 +418,58 @@ class ChatGPTAPI:
|
|
|
deregistered_callback = self.node.on_token.deregister(callback_id)
|
|
|
if DEBUG >= 2: print(f"Deregister {callback_id=} {deregistered_callback=}")
|
|
|
|
|
|
+ async def handle_delete_model(self, request):
|
|
|
+ try:
|
|
|
+ model_name = request.match_info.get('model_name')
|
|
|
+ if DEBUG >= 2: print(f"Attempting to delete model: {model_name}")
|
|
|
+
|
|
|
+ if not model_name or model_name not in model_cards:
|
|
|
+ return web.json_response(
|
|
|
+ {"detail": f"Invalid model name: {model_name}"},
|
|
|
+ status=400
|
|
|
+ )
|
|
|
+
|
|
|
+ shard = build_base_shard(model_name, self.inference_engine_classname)
|
|
|
+ if not shard:
|
|
|
+ return web.json_response(
|
|
|
+ {"detail": "Could not build shard for model"},
|
|
|
+ status=400
|
|
|
+ )
|
|
|
+
|
|
|
+ repo_id = get_repo(shard.model_id, self.inference_engine_classname)
|
|
|
+ if DEBUG >= 2: print(f"Repo ID for model: {repo_id}")
|
|
|
+
|
|
|
+ # Get the HF cache directory using the helper function
|
|
|
+ hf_home = get_hf_home()
|
|
|
+ cache_dir = get_repo_root(repo_id)
|
|
|
+
|
|
|
+ if DEBUG >= 2: print(f"Looking for model files in: {cache_dir}")
|
|
|
+
|
|
|
+ if os.path.exists(cache_dir):
|
|
|
+ if DEBUG >= 2: print(f"Found model files at {cache_dir}, deleting...")
|
|
|
+ try:
|
|
|
+ shutil.rmtree(cache_dir)
|
|
|
+ return web.json_response({
|
|
|
+ "status": "success",
|
|
|
+ "message": f"Model {model_name} deleted successfully",
|
|
|
+ "path": str(cache_dir)
|
|
|
+ })
|
|
|
+ except Exception as e:
|
|
|
+ return web.json_response({
|
|
|
+ "detail": f"Failed to delete model files: {str(e)}"
|
|
|
+ }, status=500)
|
|
|
+ else:
|
|
|
+ return web.json_response({
|
|
|
+ "detail": f"Model files not found at {cache_dir}"
|
|
|
+ }, status=404)
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ print(f"Error in handle_delete_model: {str(e)}")
|
|
|
+ traceback.print_exc()
|
|
|
+ return web.json_response({
|
|
|
+ "detail": f"Server error: {str(e)}"
|
|
|
+ }, status=500)
|
|
|
+
|
|
|
async def run(self, host: str = "0.0.0.0", port: int = 52415):
|
|
|
runner = web.AppRunner(self.app)
|
|
|
await runner.setup()
|