Spaces:
Paused
Paused
Update app.py
Browse files
app.py
CHANGED
|
@@ -3,10 +3,11 @@ import gradio as gr
|
|
| 3 |
import subprocess, os, sys, time
|
| 4 |
import urllib.request, urllib.error
|
| 5 |
from fastapi import Request
|
| 6 |
-
from fastapi.responses import Response, HTMLResponse
|
| 7 |
|
| 8 |
PORT = 9001
|
| 9 |
FM_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "file-manager")
|
|
|
|
| 10 |
|
| 11 |
# --- Launch the file manager as a background child process ---
|
| 12 |
proc = {"p": None}
|
|
@@ -22,13 +23,52 @@ def start_fm():
|
|
| 22 |
|
| 23 |
start_fm()
|
| 24 |
|
| 25 |
-
# ---
|
| 26 |
@spaces.GPU
|
| 27 |
-
def
|
| 28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
|
|
|
|
| 30 |
with gr.Blocks() as demo:
|
| 31 |
-
gr.Markdown("Self-editing computer. File manager
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 32 |
|
| 33 |
demo.queue()
|
| 34 |
demo.launch(server_name="0.0.0.0", server_port=7860,
|
|
@@ -43,6 +83,16 @@ def reload_fm():
|
|
| 43 |
time.sleep(1)
|
| 44 |
return HTMLResponse('Reloaded file-manager process. <a href="/fm/">back to /fm</a>')
|
| 45 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 46 |
# --- Proxy: /fm/... -> 127.0.0.1:9001/fm/... (methods + body forwarded) ---
|
| 47 |
@app.api_route("/fm", methods=["GET", "POST"])
|
| 48 |
@app.api_route("/fm/{path:path}", methods=["GET", "POST"])
|
|
@@ -64,5 +114,6 @@ async def proxy(request: Request, path: str = ""):
|
|
| 64 |
if k.lower() in ("set-cookie", "location", "content-type")}
|
| 65 |
return Response(content=data, status_code=status, headers=out)
|
| 66 |
|
|
|
|
| 67 |
while True:
|
| 68 |
time.sleep(3600)
|
|
|
|
| 3 |
import subprocess, os, sys, time
|
| 4 |
import urllib.request, urllib.error
|
| 5 |
from fastapi import Request
|
| 6 |
+
from fastapi.responses import Response, PlainTextResponse, HTMLResponse
|
| 7 |
|
| 8 |
PORT = 9001
|
| 9 |
FM_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "file-manager")
|
| 10 |
+
MODEL_ID = "Qwen/Qwen2.5-0.5B-Instruct"
|
| 11 |
|
| 12 |
# --- Launch the file manager as a background child process ---
|
| 13 |
proc = {"p": None}
|
|
|
|
| 23 |
|
| 24 |
start_fm()
|
| 25 |
|
| 26 |
+
# --- GPU info: runs nvidia-smi INSIDE the gate (GPU only attached here) ---
|
| 27 |
@spaces.GPU
|
| 28 |
+
def gpu_report():
|
| 29 |
+
import torch
|
| 30 |
+
lines = [f"torch.cuda.is_available(): {torch.cuda.is_available()}"]
|
| 31 |
+
if torch.cuda.is_available():
|
| 32 |
+
props = torch.cuda.get_device_properties(0)
|
| 33 |
+
lines.append(f"Device name: {torch.cuda.get_device_name(0)}")
|
| 34 |
+
lines.append(f"Device count: {torch.cuda.device_count()}")
|
| 35 |
+
lines.append(f"Total memory: {props.total_memory / 1024**3:.1f} GB")
|
| 36 |
+
lines.append(f"Compute capability: {props.major}.{props.minor}")
|
| 37 |
+
try:
|
| 38 |
+
smi = subprocess.run(["nvidia-smi"], capture_output=True, text=True, timeout=30)
|
| 39 |
+
lines.append("\n--- nvidia-smi ---\n" + smi.stdout + smi.stderr)
|
| 40 |
+
except Exception as e:
|
| 41 |
+
lines.append(f"nvidia-smi error: {e}")
|
| 42 |
+
return "\n".join(lines)
|
| 43 |
+
|
| 44 |
+
# --- LLM inference: model loads + generates INSIDE the gate ---
|
| 45 |
+
_state = {"model": None, "tok": None}
|
| 46 |
+
|
| 47 |
+
@spaces.GPU
|
| 48 |
+
def run_llm(prompt: str):
|
| 49 |
+
import torch
|
| 50 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 51 |
+
if _state["model"] is None:
|
| 52 |
+
_state["tok"] = AutoTokenizer.from_pretrained(MODEL_ID)
|
| 53 |
+
_state["model"] = AutoModelForCausalLM.from_pretrained(
|
| 54 |
+
MODEL_ID, torch_dtype=torch.float16, device_map="cuda")
|
| 55 |
+
tok, model = _state["tok"], _state["model"]
|
| 56 |
+
msgs = [{"role": "user", "content": prompt}]
|
| 57 |
+
text = tok.apply_chat_template(msgs, tokenize=False, add_generation_prompt=True)
|
| 58 |
+
inputs = tok(text, return_tensors="pt").to("cuda")
|
| 59 |
+
out = model.generate(**inputs, max_new_tokens=256)
|
| 60 |
+
reply = tok.decode(out[0][inputs.input_ids.shape[1]:], skip_special_tokens=True)
|
| 61 |
+
return f"[GPU: {torch.cuda.get_device_name(0)}]\n\n{reply}"
|
| 62 |
|
| 63 |
+
# --- Gradio owns the ONLY public port 7860 ---
|
| 64 |
with gr.Blocks() as demo:
|
| 65 |
+
gr.Markdown("Self-editing computer. File manager + terminal at /fm")
|
| 66 |
+
with gr.Row():
|
| 67 |
+
prompt = gr.Textbox(label="Ask the LLM")
|
| 68 |
+
out = gr.Textbox(label="Reply")
|
| 69 |
+
gr.Button("Run LLM").click(run_llm, inputs=prompt, outputs=out)
|
| 70 |
+
gpu_out = gr.Textbox(label="GPU")
|
| 71 |
+
gr.Button("GPU info").click(gpu_report, outputs=gpu_out)
|
| 72 |
|
| 73 |
demo.queue()
|
| 74 |
demo.launch(server_name="0.0.0.0", server_port=7860,
|
|
|
|
| 83 |
time.sleep(1)
|
| 84 |
return HTMLResponse('Reloaded file-manager process. <a href="/fm/">back to /fm</a>')
|
| 85 |
|
| 86 |
+
# --- GPU info route ---
|
| 87 |
+
@app.get("/gpuinfo")
|
| 88 |
+
def gpuinfo():
|
| 89 |
+
return PlainTextResponse(gpu_report())
|
| 90 |
+
|
| 91 |
+
# --- LLM route ---
|
| 92 |
+
@app.get("/llm")
|
| 93 |
+
def llm(q: str = "Say hello and tell me which GPU you are running on."):
|
| 94 |
+
return PlainTextResponse(run_llm(q))
|
| 95 |
+
|
| 96 |
# --- Proxy: /fm/... -> 127.0.0.1:9001/fm/... (methods + body forwarded) ---
|
| 97 |
@app.api_route("/fm", methods=["GET", "POST"])
|
| 98 |
@app.api_route("/fm/{path:path}", methods=["GET", "POST"])
|
|
|
|
| 114 |
if k.lower() in ("set-cookie", "location", "content-type")}
|
| 115 |
return Response(content=data, status_code=status, headers=out)
|
| 116 |
|
| 117 |
+
# --- Keep the process alive (launch returned control) ---
|
| 118 |
while True:
|
| 119 |
time.sleep(3600)
|