Spaces:
Sleeping
Sleeping
File size: 4,427 Bytes
e10f837 7767422 569c8fb 7767422 569c8fb 7767422 569c8fb 7767422 1c98e37 7767422 1c98e37 e10f837 2cf14fd 1c98e37 e10f837 1c98e37 e10f837 1c98e37 e10f837 7767422 1c98e37 e10f837 1c98e37 569c8fb 4f84779 569c8fb a2a263b 569c8fb 4f84779 569c8fb 4f84779 569c8fb 4f84779 569c8fb 1c98e37 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | import re, time, json, os, shutil, torch, gradio as gr
import tempfile
from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import PeftModel
from huggingface_hub import snapshot_download
BASE_ID = "openbmb/MiniCPM5-1B"
ADAPTER_ID = "Georgefifth/tiny-browser-planner-reason"
print("Loading model (this may take a minute)...")
start = time.time()
# Download adapter and create clean config
adapter_dir = os.path.join(tempfile.gettempdir(), "adapter")
from huggingface_hub import snapshot_download
snapshot_download(repo_id="Georgefifth/tiny-browser-planner-reason", local_dir=adapter_dir)
with open(os.path.join(adapter_dir, "adapter_config.json")) as f:
raw_cfg = json.load(f)
KEEP = {"r","lora_alpha","lora_dropout","target_modules","bias","task_type","peft_type","inference_mode"}
clean_cfg = {k: v for k, v in json.load(open(os.path.join(adapter_dir, "adapter_config.json"))).items() if k in {"r","lora_alpha","lora_dropout","target_modules","bias","task_type","peft_type","inference_mode"}}
clean_dir = os.path.join(tempfile.gettempdir(), "clean_adapter")
os.makedirs(clean_dir, exist_ok=True)
import shutil
for fname in os.listdir(adapter_dir):
src = os.path.join(adapter_dir, fname)
dst = os.path.join(clean_dir, fname)
if os.path.isfile(src):
if fname == "adapter_config.json":
with open(dst, "w") as f:
json.dump({"r":16,"lora_alpha":16,"lora_dropout":0,"target_modules":["q_proj","k_proj","v_proj","o_proj","gate_proj","up_proj","down_proj"],"bias":"none","task_type":"CAUSAL_LM","peft_type":"LORA","inference_mode":True}, f)
else:
shutil.copy2(src, dst)
model = AutoModelForCausalLM.from_pretrained("openbmb/MiniCPM5-1B", torch_dtype=torch.float16, trust_remote_code=True)
model = PeftModel.from_pretrained(model, clean_dir)
tokenizer = AutoTokenizer.from_pretrained("openbmb/MiniCPM5-1B", trust_remote_code=True)
if tokenizer.pad_token is None:
tokenizer.pad_token = tokenizer.eos_token
print(f"Ready! ({time.time()-start:.0f}s)")
ACTIONS = ["search", "open_page", "extract", "refine_search", "back", "finish"]
def predict(task, history_text):
if not task or not task.strip():
return "Error: task is empty", ""
history = [l.strip() for l in history_text.strip().split("\n") if l.strip()]
hist_str = "\n".join(history)
msgs = [
{"role": "system", "content": "You are a browser planner. First reason about the situation, then output the next action."},
{"role": "user", "content": f"Task: {task}\n\nHistory:\n{hist_str}\n\nWhat is the next action?"},
]
prompt = tokenizer.apply_chat_template(msgs, tokenize=False, add_generation_prompt=True)
inputs = tokenizer(prompt, return_tensors="pt")
input_len = inputs["input_ids"].shape[1]
inputs.pop("token_type_ids", None)
outs = model.generate(**inputs, max_new_tokens=64, temperature=0.01, do_sample=False,
pad_token_id=tokenizer.eos_token_id)
output = tokenizer.decode(outs[0][input_len:], skip_special_tokens=True).strip()
reason_m = re.search(r"Reason:\s*(.+?)(?:\n|$)", output)
action_m = re.search(r"Action:\s*(\S+)", output)
reason = reason_m.group(1).strip() if reason_m else "?"
action = action_m.group(1).strip().lower() if action_m else "?"
if action not in ["search", "open_page", "extract", "refine_search", "back", "finish"]:
action = f"{action} (unknown)"
return reason, action
with gr.Blocks(title="Tiny Browser Planner", theme=gr.themes.Soft()) as demo:
gr.Markdown("""
# Tiny Browser Planner — Reason-First
MiniCPM5-1B + LoRA | Actions: `search`, `open_page`, `extract`, `refine_search`, `back`, `finish`
""")
with gr.Row():
with gr.Column(scale=2):
task = gr.Textbox(label="Task", placeholder="e.g. Find Apple stock price")
history = gr.Textbox(label="History (one action per line)", lines=5,
placeholder="[search] Search completed.\n[open_page] Page content here...")
btn = gr.Button("Predict", variant="primary")
with gr.Column(scale=1):
reason = gr.Textbox(label="Reason", lines=3, interactive=False)
action = gr.Textbox(label="Next Action", lines=1, interactive=False)
btn.click(fn=predict, inputs=[task, history], outputs=[reason, action])
if __name__ == "__main__":
demo.launch() |