Views
No views yet
1pip install mlx-vlm
2pip install git+https://github.com/Mininglamp-AI/cider.gitpip install mlx-vlm1import mlx_vlm as pm
2from vlm_service import custom_generate
3from PIL import Image
4
5# 1. Load model
6model, processor = pm.load("Mininglamp-2718/Mano-CUA-2.0-4B-MLX-8bit")
7
8# 2. Load a screenshot
9img = Image.open("screenshot.png")
10ratio = 1280 / img.width
11img = img.resize((1280, int(img.height * ratio)), Image.LANCZOS)
12
13# 3. Build prompt
14task = "Click the search bar and type hello"
15
16prompt_text = f"""You are a GUI agent. You are given a task and your action history, with screenshots. You need to perform the next action to complete the task.
17
18## Output Format
19<action>action</action>
20
21## Action Space
22open_app(app_name='') # Open an application by name.
23open_url(url='') # Open a URL in the browser.
24click(start_box='<|box_start|>(x1,y1)<|box_end|>')
25type(content='') # type the content.
26hotkey(key='') # Trigger a keyboard shortcut.
27scroll(start_box='<|box_start|>(x1,y1)<|box_end|>', direction='down or up or right or left', amount='scroll_amount')
28drag(start_box='<|box_start|>(x1,y1)<|box_end|>', end_box='<|box_start|>(x3,y3)<|box_end|>')
29wait(duration='') # Sleep for specified duration (in seconds).
30finish() # The task is completed.
31stop(reason='') # If the item can not found in the image, give the reason
32
33## User Instruction
34{task}"""
35
36messages = [
37 {"role": "system", "content": "You are a helpful assistant."},
38 {"role": "user", "content": prompt_text},
39]
40prompt = processor.tokenizer.apply_chat_template(
41 messages, tokenize=False, add_generation_prompt=True
42)
43prompt = prompt.replace("<image>", "<|vision_start|><|image_pad|><|vision_end|>")
44
45# 4. Run inference
46result = custom_generate(
47 model, processor, prompt,
48 [img],
49 max_tokens=512,
50 temperature=0.0,
51 prefill_step_size=2048,
52)
53
54print(f"Tokens: {result.generation_tokens}, Speed: {result.generation_tps:.1f} tok/s")
55print(result.text)1<think>The search bar is at the top of the page...</think>
2<action_desp>Click the search bar to focus it</action_desp>
3<action>click(start_box='<|box_start|>(500,38)<|box_end|>')</action>[0, 1000] range. To convert to pixel coordinates:1pixel_x = int(x / 1000 * screen_width)
2pixel_y = int(y / 1000 * screen_height)1from cider import convert_model, is_available
2
3if is_available():
4 convert_model(model.language_model)| Action | Syntax | Description |
|---|---|---|
| open_app | open_app(app_name='') | Open an application |
| open_url | open_url(url='') | Open a URL |
| click | click(start_box='<|box_start|>(x,y)<|box_end|>') | Left click |
| doubleclick | doubleclick(start_box='<|box_start|>(x,y)<|box_end|>') | Double click |
| triple_click | triple_click(start_box='<|box_start|>(x,y)<|box_end|>') | Triple click (select line) |
| right_single | right_single(start_box='<|box_start|>(x,y)<|box_end|>') | Right click |
| hover | hover(start_box='<|box_start|>(x,y)<|box_end|>') | Mouse hover |
| type | type(content='text') | Type text |
| hotkey | hotkey(key='cmd+c') | Keyboard shortcut |
| hotkey_click | hotkey_click(start_box='<|box_start|>(x,y)<|box_end|>', key='shift') | Modifier + click |
| scroll | scroll(start_box='<|box_start|>(x,y)<|box_end|>', direction='down', amount='3') | Scroll |
| drag | drag(start_box='<|box_start|>(x1,y1)<|box_end|>', end_box='<|box_start|>(x2,y2)<|box_end|>') | Drag and drop |
| wait | wait(duration='2') | Wait (seconds) |
| finish | finish() | Task completed |
| stop | stop(reason='...') | Task infeasible |
| call_user | call_user() | Request human help |
| Version | Repo | Description |
|---|---|---|
| fp16 | Mano-CUA-2.0-4B | Full precision, for archival / re-quantization / GPU inference |
| MLX-8bit (this) | Mano-CUA-2.0-4B-MLX-8bit | MLX 8-bit quantized, recommended for Apple Silicon local inference |