Image-Text-to-Text
Transformers
Safetensors
Korean
English
qwen3_5
gui-agent
web-agent
computer-use
browser
korean
conversational
Instructions to use KORMo-VL/KORMo-Web-9B with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use KORMo-VL/KORMo-Web-9B with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("image-text-to-text", model="KORMo-VL/KORMo-Web-9B") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] pipe(text=messages)# pip install -U transformers accelerate # Load model directly from transformers import AutoProcessor, AutoModelForMultimodalLM processor = AutoProcessor.from_pretrained("KORMo-VL/KORMo-Web-9B") model = AutoModelForMultimodalLM.from_pretrained("KORMo-VL/KORMo-Web-9B", device_map="auto") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] inputs = processor.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=256) print(processor.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use KORMo-VL/KORMo-Web-9B with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "KORMo-VL/KORMo-Web-9B" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "KORMo-VL/KORMo-Web-9B", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }'Use Docker
docker model run hf.co/KORMo-VL/KORMo-Web-9B
- SGLang
How to use KORMo-VL/KORMo-Web-9B with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "KORMo-VL/KORMo-Web-9B" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "KORMo-VL/KORMo-Web-9B", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "KORMo-VL/KORMo-Web-9B" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "KORMo-VL/KORMo-Web-9B", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }' - Docker Model Runner
How to use KORMo-VL/KORMo-Web-9B with Docker Model Runner:
docker model run hf.co/KORMo-VL/KORMo-Web-9B
|
Download README.md from KORMo-VL/KORMo-Web-9B: direct link, hf CLI and curl.
- Browser
- Download file 8.98 kB
-
https://huggingface.co/KORMo-VL/KORMo-Web-9B/resolve/main/README.md
- Command line
-
hf download hf://KORMo-VL/KORMo-Web-9B/README.md
-
curl -L -o README.md https://huggingface.co/KORMo-VL/KORMo-Web-9B/resolve/main/README.md
8.98 kB
| license: apache-2.0 | |
| base_model: | |
| - Qwen/Qwen3.5-9B | |
| language: | |
| - ko | |
| - en | |
| pipeline_tag: image-text-to-text | |
| library_name: transformers | |
| tags: | |
| - gui-agent | |
| - web-agent | |
| - computer-use | |
| - browser | |
| - korean | |
| <style> | |
| #kormo-web-card { font-size: 16px; line-height: 1.6; overflow-wrap: break-word; } | |
| #kormo-web-card h1 { margin: 0 0 12px; font-size: 30px; line-height: 1.25; letter-spacing: -0.018em; } | |
| #kormo-web-card h2 { margin: 30px 0 10px; font-size: 22px; line-height: 1.3; letter-spacing: -0.012em; } | |
| #kormo-web-card h3 { margin: 22px 0 8px; font-size: 17px; font-weight: 700; line-height: 1.4; } | |
| #kormo-web-card h2 + h3 { margin-top: 14px; } | |
| #kormo-web-card p { margin: 0 0 10px; } | |
| #kormo-web-card ul, #kormo-web-card ol { margin: 6px 0 12px; padding-left: 22px; } | |
| #kormo-web-card li { margin: 4px 0; line-height: 1.55; } | |
| #kormo-web-card table { width: 100%; margin: 6px 0 14px; border-collapse: collapse; font-size: 14px; line-height: 1.45; font-variant-numeric: tabular-nums; } | |
| #kormo-web-card th, #kormo-web-card td { padding: 7px 10px; vertical-align: middle; } | |
| #kormo-web-card blockquote { margin: 12px 0 16px; padding: 0 0 0 14px; font-size: 15px; } | |
| #kormo-web-card blockquote p { margin: 0; } | |
| #kormo-web-card pre { margin: 10px 0 14px; padding: 14px 16px; overflow-x: auto; line-height: 1.5; } | |
| #kormo-web-card pre code { font-size: 13px; } | |
| #kormo-web-card > p:has(> em:only-child) { margin: 4px 0 14px; font-size: 13px; } | |
| #kormo-web-card .pills { margin: 4px 0 18px; } | |
| #kormo-web-card .pill { display: inline-block; margin: 0 6px 6px 0; padding: 3px 10px; border-radius: 999px; border: 1px solid rgba(127,127,127,.35); font-size: 13px; } | |
| @media (max-width: 640px) { | |
| #kormo-web-card h1 { font-size: 26px; } | |
| #kormo-web-card table { font-size: 13px; } | |
| #kormo-web-card th, #kormo-web-card td { padding: 7px 6px; } | |
| } | |
| </style> | |
| <div id="kormo-web-card"> | |
| # KORMo-Web-9B | |
| **KORMo-Web-9B** is a 9B vision-language agent that completes real browser tasks **from screenshots alone**. Give it a request in Korean or English; it plans, clicks, types and moves between sites and tabs until the task is done. In the same live-web evaluation, it beats every open-weight web agent we compared, **by +18.3 points in English and +27.9 points in Korean**. | |
| On **Online-Mind2Web** it reaches **51.0% in English** and **48.1% in Korean**, which is **+26.3 / +31.4 points** over the base Qwen3.5-9B. | |
| ## Demo | |
| <video controls muted playsinline style="width: 100%; border-radius: 8px;" src="https://huggingface.co/KORMo-VL/KORMo-Web-9B/resolve/main/assets/demo_movie_booking.mp4"></video> | |
| KORMo-Web-9B books a movie ticket on the live CGV website from a single Korean request: it logs in, picks the theater, date and showtime, selects seats and goes to the payment step. | |
| ## Performance | |
| All models below ran **the same 612 live-website tasks** (300 English, 312 Korean), each with its own prompt and action format, and were scored by **the same LLM judge**. | |
| | Model | Size | Online-Mind2Web EN | Online-Mind2Web KO | | |
| |---|---:|---:|---:| | |
| | Qwen3.5-9B (base, no fine-tuning) | 9B | 24.7 | 16.7 | | |
| | Fara-1.5-4B | 4B | 20.7 | 7.7 | | |
| | UI-TARS-1.5-7B | 7B | 22.3 | 20.2 | | |
| | OpenWebRL-4B | 4B | 32.7 | 15.4 | | |
| | **KORMo-Web-9B (ours)** | **9B** | **51.0** | **48.1** | | |
| | GPT-6-luna (proprietary) | โ | 63.0 | 65.7 | | |
| | Gemini-3.8-flash (proprietary) | โ | 74.0 | 80.1 | | |
| Success rate (%). The denominator is always the full task count, so crashed or empty runs count as failures. | |
| KORMo-Web-9B outperforms open web agents of similar size in both English and Korean. | |
| ## Why KORMo-Web | |
| - **Korean and English, natural requests.** Handles short commands as well as long, conversational instructions in either language. | |
| - **Screenshot-only.** It needs no DOM or accessibility tree; it acts on what is on screen, like a person, and checks each action's result on the next screenshot. | |
| - **Thinks, then acts.** A short reasoning step precedes every action, so its behaviour is easy to inspect and debug. | |
| - **Multi-site, multi-tab workflows.** It can search on one site, verify on another and write the result into a third, managing tabs on its own. | |
| - **Open and ready to run.** Apache-2.0 weights, a reference browser harness, the tool schema and the exact inference settings are all included. | |
| ## Quickstart | |
| Tested with **vLLM 0.23.0** and **transformers 5.12.1**. The model runs on a single GPU (TP=1). | |
| ### Run the agent | |
| **1. Install and download** | |
| ```bash | |
| pip install -U "vllm>=0.23.0" openai playwright huggingface_hub | |
| playwright install chromium | |
| huggingface-cli download KORMo-VL/KORMo-Web-9B --local-dir KORMo-Web-9B | |
| ``` | |
| **2. Start the model server** | |
| ```bash | |
| vllm serve ./KORMo-Web-9B --served-model-name KORMo-Web-9B \ | |
| --max-model-len 131072 --limit-mm-per-prompt '{"image":1,"video":0}' | |
| ``` | |
| **3. Run a browser task** | |
| ```bash | |
| python KORMo-Web-9B/examples/agent_playwright.py --model KORMo-Web-9B \ | |
| --task "๋ค๋์์์ 50๋ง ์ ์ดํ, 10์ธ์น ์ด์ ํ๋ธ๋ฆฟ 3๊ฐ๋ฅผ ์ฐพ์์ ๊ฐ๊ฒฉ์ ์๋ ค์ค" | |
| ``` | |
| The agent opens Chromium, prints each action as it goes, and finishes with the model's answer. | |
| ### Inference example (one step) | |
| Send one screenshot with the request and get back one action: | |
| ```python | |
| import base64, json | |
| from openai import OpenAI | |
| SYSTEM = open("KORMo-Web-9B/system_prompt.md").read().strip() | |
| TOOLS = json.load(open("KORMo-Web-9B/tools.json")) | |
| shot = base64.b64encode(open("screen.png", "rb").read()).decode() | |
| obs = ("<observation>\nscreen size: 1280 x 720\nCurrent tab: 0\nAvailable tabs:\n" | |
| "- Tab 0 (active): https://www.google.com/\n\nurl: https://www.google.com/\nscreenshot:\n") | |
| messages = [ | |
| {"role": "system", "content": SYSTEM}, | |
| {"role": "user", "content": [ | |
| {"type": "text", "text": "<user_request>\n๊ตฌ๊ธ์์ KAIST ๋ฅผ ๊ฒ์ํด์ ๊ณต์ ํํ์ด์ง๋ฅผ ์ด์ด์ค.\n</user_request>\n" + obs}, | |
| {"type": "image_url", "image_url": {"url": f"data:image/png;base64,{shot}"}}, | |
| {"type": "text", "text": "\n</observation>"}, | |
| ]}, | |
| ] | |
| client = OpenAI(base_url="http://localhost:8000/v1", api_key="EMPTY") | |
| out = client.chat.completions.create( | |
| model="KORMo-Web-9B", messages=messages, tools=TOOLS, | |
| temperature=0.6, top_p=0.95, max_tokens=16384, | |
| extra_body={"top_k": 20, "chat_template_kwargs": {"enable_thinking": True}}, | |
| ) | |
| print(out.choices[0].message.content) | |
| ``` | |
| The output looks like this (illustrative): | |
| ```text | |
| <think> | |
| I can see the Google home page with an empty search box in the center. I have not searched yet. | |
| My plan: 1. Click the search box. 2. Type "KAIST". 3. Press Enter and open the official site. | |
| </think> | |
| <tool_call> | |
| <function=click> | |
| <parameter=x> | |
| 500 | |
| </parameter> | |
| <parameter=y> | |
| 427 | |
| </parameter> | |
| </function> | |
| </tool_call> | |
| ``` | |
| Coordinates in the tool call are normalized to 0โ1000. Convert them to pixels with `x / 1000 ร width` and `y / 1000 ร height`. | |
| ## How It Works | |
| ``` | |
| user <user_request> task </user_request> + observation (tabs, url, screenshot) | |
| assistant <think> what I see ยท what is done ยท plan </think> <tool_call> one action </tool_call> | |
| tool action result + new observation (newest screenshot only) | |
| โฆ repeat until finished(answer) | |
| ``` | |
| - **Action space:** 22 browser tools: click, type, hotkey, scroll, drag, goto, tab control, `finished`, and others ([`tools.json`](tools.json)). | |
| - **Memory:** the full text history of thoughts, actions and observations is kept. Only the current screenshot is sent. | |
| - **Recommended settings:** temperature 0.6, top_p 0.95, top_k 20, thinking on, up to 16k tokens per step and 50 steps. These are already set in `generation_config.json`. | |
| The exact message format, parsing rules and feedback strings are in **[HARNESS.md](HARNESS.md)**. Follow it if you build your own harness. | |
| ## Evaluation Details | |
| | | | | |
| |---|---| | |
| | Tasks | Online-Mind2Web: 300 English, 312 Korean | | |
| | Judge | GPT-6 | | |
| ## Files | |
| | File | Description | | |
| |---|---| | |
| | `chat_template.jinja` | Chat template (Qwen3.5 XML tool calls, thinking on) | | |
| | `system_prompt.md` ยท `tools.json` | System prompt and 22-tool schema, verbatim from training | | |
| | `HARNESS.md` | Full harness specification | | |
| | `examples/agent_playwright.py` | Reference browser agent (Playwright + OpenAI-compatible API). It does not execute `upload`. | | |
| | `config.json` ยท `generation_config.json` ยท `processor_config.json` ยท `tokenizer*.json` | Model, sampling and processor configs | | |
| ## ํ๊ตญ์ด ์์ฝ | |
| **KORMo-Web-9B**๋ ์คํฌ๋ฆฐ์ท๋ง ๋ณด๊ณ ํ๊ตญ์ดยท์์ด ์น ์์ ์ ์ํํ๋ 9B ๊ณต๊ฐ ์น ์์ด์ ํธ์ ๋๋ค. ๊ฐ์ ์กฐ๊ฑด์ ์ค์ ์น ํ๊ฐ์์ ๋น๊ตํ ๊ณต๊ฐ ๋ชจ๋ธ ์ค ๊ฐ์ฅ ๋์ ์ ์๋ฅผ ๋ฐ์์ต๋๋ค. | |
| - **Online-Mind2Web:** EN 51.0, KO 48.1 | |
| - ๋น์ทํ ํฌ๊ธฐ์ ๊ณต๊ฐ ์น ์์ด์ ํธ๋ณด๋ค ์์ดยทํ๊ตญ์ด ๋ชจ๋์์ ๋์ ์ฑ๋ฅ์ ๋ณด์ ๋๋ค. | |
| ## Acknowledgements | |
| Built on **[Qwen3.5-9B](https://huggingface.co/Qwen/Qwen3.5-9B)**. Evaluated on **Online-Mind2Web** and its Korean counterpart. | |
| </div> | |