Text Generation
Transformers
Safetensors
English
Korean
Japanese
solar_open2
upstage
solar
Mixture of Experts
llm
vllm
conversational
Eval Results
Instructions to use upstage/Solar-Open2-250B with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use upstage/Solar-Open2-250B with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="upstage/Solar-Open2-250B") messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# Load model directly from transformers import AutoModelForCausalLM model = AutoModelForCausalLM.from_pretrained("upstage/Solar-Open2-250B", device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use upstage/Solar-Open2-250B with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "upstage/Solar-Open2-250B" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "upstage/Solar-Open2-250B", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/upstage/Solar-Open2-250B
- SGLang
How to use upstage/Solar-Open2-250B 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 "upstage/Solar-Open2-250B" \ --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": "upstage/Solar-Open2-250B", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'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 "upstage/Solar-Open2-250B" \ --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": "upstage/Solar-Open2-250B", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use upstage/Solar-Open2-250B with Docker Model Runner:
docker model run hf.co/upstage/Solar-Open2-250B
| {#- ======== Template Parameters ======== #} | |
| {%- set add_generation_prompt = add_generation_prompt if add_generation_prompt is defined else true %} | |
| {%- set provider_system_prompt = provider_system_prompt if provider_system_prompt else false %} | |
| {%- set reasoning_effort = reasoning_effort if reasoning_effort is defined else "high" %} | |
| {%- set think_render_option = think_render_option if think_render_option is defined else "interleaved" %} | |
| {#- ======== System Block State ======== #} | |
| {%- set sys_ns = namespace(is_first_block=true) -%} | |
| {#- ======== Find last user message index ======== #} | |
| {%- set last_user_idx = namespace(value=-1) -%} | |
| {%- for message in messages -%} | |
| {%- if message.role == 'user' -%} | |
| {%- set last_user_idx.value = loop.index0 -%} | |
| {%- endif -%} | |
| {%- endfor -%} | |
| {#- ======== System messages renderers ======== #} | |
| {%- macro render_system_message(user_system_messages) %} | |
| {%- if provider_system_prompt %} | |
| {%- if not sys_ns.is_first_block %}{{- "\n\n" }}{%- endif %} | |
| {%- set sys_ns.is_first_block = false %} | |
| {{- "## Provider System Prompt\n\nYou are Solar Open2 250B, a large language model trained by Upstage AI, a Korean startup. Your knowledge cutoff is 2026-02. The current date is " + strftime_now("%Y-%m-%d") + "." }} | |
| {%- endif -%} | |
| {%- if user_system_messages %} | |
| {%- if not sys_ns.is_first_block %}{{- "\n\n" }}{%- endif %} | |
| {%- set sys_ns.is_first_block = false %} | |
| {{- "## System Prompt" }} | |
| {%- for system_message in user_system_messages %} | |
| {{- "\n\n" }} | |
| {{- system_message }} | |
| {%- endfor %} | |
| {%- endif -%} | |
| {%- endmacro %} | |
| {%- macro render_tool_instruction(tools, is_last_block) %} | |
| {%- if not sys_ns.is_first_block %}{{- "\n\n" }}{%- endif %} | |
| {%- set sys_ns.is_first_block = false %} | |
| {{- "## Tools\n- You may invoke one or more tools to assist with the user's query." }} | |
| {{- "\n\n### Available Tools\n" }} | |
| {%- for tool in tools %} | |
| {{- "<|tool:start|>" }} | |
| {{- tool.function | tojson }} | |
| {{- "<|tool:end|>\n" }} | |
| {%- endfor %} | |
| {{- "\n### Tool Call Instruction\n" }} | |
| {{- "- If using a tool, any reasoning must strictly precede the call. Do not append any text after the tool call.\n" }} | |
| {{- "- If no tool is required, answer directly from your knowledge without ever mentioning the availability or absence of tools.\n" }} | |
| {{- "- Each tool call MUST use this following format: <|tool_call:start|>{example-tool-name}\n<|tool_arg:start|>{example-key-name-1}<|tool_arg:value|>{example-value-1}<|tool_arg:end|>\n<|tool_arg:start|>{example-key-name-2}<|tool_arg:value|>{example-value-2}<|tool_arg:end|>\n<|tool_call:end|>\n" }} | |
| {%- endmacro %} | |
| {#- | |
| Input convention for `response_format`: | |
| - Per the OpenAI Chat Completions API, `response_format` is an object of one of: | |
| {"type": "json_schema", "json_schema": {"name": ..., "schema": {...}, "strict": ...}} | |
| {"type": "json_object"} | |
| - Only `response_format.json_schema.schema` (the inner JSON Schema) is injected | |
| into the prompt; the OpenAI wrapper fields (`name`, `strict`, ...) are dropped. | |
| - For `json_object`, no schema exists, so we emit a generic JSON-only instruction. | |
| - vLLM does NOT pass `response_format` to chat templates by default; it routes it | |
| to guided decoding instead. This template/whale opts into prompt injection, | |
| so callers serving the model directly via vLLM must opt in via | |
| `chat_template_kwargs` (or rely on whale's normalization). | |
| -#} | |
| {%- macro render_json_response_format_instruction(response_format) %} | |
| {%- if not sys_ns.is_first_block %}{{- "\n\n" }}{%- endif %} | |
| {%- set sys_ns.is_first_block = false %} | |
| {{- "## Output Format Constraint" }} | |
| {%- if response_format.type == "json_schema" %} | |
| {{- "\n\n- Your final response should follow the JSON schema:\n```json\n" }} | |
| {{- response_format.json_schema.schema | tojson }} | |
| {{- "\n```\n- Please ensure your answers adhere to this format and do not contain any unnecessary text." }} | |
| {%- elif response_format.type == "json_object" %} | |
| {{- "\n\n- Your final response must be a valid JSON object." }} | |
| {{- "\n- Do not include any text outside the JSON object." }} | |
| {%- endif %} | |
| {%- endmacro %} | |
| {#- | |
| Input convention for `tool_arguments`: | |
| - Must be a mapping (dict), NOT a JSON-encoded string. | |
| - The OpenAI API spec defines `tool_calls[].function.arguments` as a JSON string, | |
| but vLLM, HuggingFace transformers tool-use templates (Qwen, Hermes, Llama, ...), | |
| and this template all expect the value to be parsed into a dict before rendering. | |
| - vLLM normalizes this in `_postprocess_messages()` (vllm/entrypoints/chat_utils.py). | |
| - Callers (whale, training pipelines that call `tokenizer.apply_chat_template` | |
| directly, ...) are responsible for parsing the JSON string into a dict before | |
| invoking the template. | |
| -#} | |
| {%- macro render_tool_arguments(tool_arguments) %} | |
| {%- for args_name, args_value in tool_arguments|items %} | |
| {{- "<|tool_arg:start|>"+ args_name + "<|tool_arg:value|>"}} | |
| {%- set args_value = args_value if args_value is string else (args_value | tojson | safe) %} | |
| {{- args_value }} | |
| {{- "<|tool_arg:end|>\n" }} | |
| {%- endfor %} | |
| {%- endmacro %} | |
| {#- ======== Render system message ======== #} | |
| {%- set ns = namespace(system_messages=[]) -%} | |
| {%- for message in messages -%} | |
| {%- if message.role == 'system' -%} | |
| {%- set ns.system_messages = ns.system_messages + [message.content] -%} | |
| {%- endif -%} | |
| {%- endfor -%} | |
| {%- if ns.system_messages or provider_system_prompt or tools or response_format -%} | |
| {{- "<|im:start|>system<|im:content|>" }} | |
| {{- render_system_message(ns.system_messages) }} | |
| {%- if tools -%} | |
| {{- render_tool_instruction(tools, not response_format) }} | |
| {%- endif %} | |
| {%- if response_format -%} | |
| {{- render_json_response_format_instruction(response_format) }} | |
| {%- endif %} | |
| {{- "<|im:end|>\n" }} | |
| {%- endif -%} | |
| {#- ======== Render main messages ======== #} | |
| {%- for message in messages -%} | |
| {%- if message.role == 'user' -%} | |
| {{- "<|im:start|>user<|im:content|>" + message.content + "<|im:end|>\n" }} | |
| {%- elif message.role == 'tool' -%} | |
| {%- if not message.tool_call_id -%} | |
| {{- raise_exception("tool message is missing required 'tool_call_id' field") -}} | |
| {%- endif -%} | |
| {%- set prev_is_tool = loop.index0 > 0 and messages[loop.index0 - 1].role == 'tool' -%} | |
| {#- Only render at the start of a contiguous tool block; subsequent tool messages -#} | |
| {#- are already emitted (reordered) within the first one. -#} | |
| {%- if not prev_is_tool -%} | |
| {%- set start_idx = loop.index0 -%} | |
| {#- Collect contiguous tool messages starting at start_idx -#} | |
| {%- set tool_ns = namespace(items=[], scanning=true) -%} | |
| {%- for j in range(start_idx, messages | length) -%} | |
| {%- if tool_ns.scanning -%} | |
| {%- if messages[j].role == 'tool' -%} | |
| {%- set tool_ns.items = tool_ns.items + [messages[j]] -%} | |
| {%- else -%} | |
| {%- set tool_ns.scanning = false -%} | |
| {%- endif -%} | |
| {%- endif -%} | |
| {%- endfor -%} | |
| {{- "<|im:start|>tool<|im:content|>" }} | |
| {%- set prev_msg = messages[start_idx - 1] if start_idx > 0 else none -%} | |
| {%- if prev_msg and prev_msg.role == 'assistant' and prev_msg.tool_calls -%} | |
| {#- Render tool responses in the order of the preceding assistant's tool_calls ids. -#} | |
| {%- set sep_ns = namespace(first=true, rendered_ids=[]) -%} | |
| {%- for tool_call in prev_msg.tool_calls -%} | |
| {%- for tool_msg in tool_ns.items -%} | |
| {%- if tool_msg.tool_call_id == tool_call.id -%} | |
| {%- if not sep_ns.first -%}{{- "\n" }}{%- endif -%} | |
| {%- set sep_ns.first = false -%} | |
| {%- set sep_ns.rendered_ids = sep_ns.rendered_ids + [tool_msg.tool_call_id] -%} | |
| {{- "<|tool_response:start|>" + tool_msg.content + "<|tool_response:end|>" }} | |
| {%- endif -%} | |
| {%- endfor -%} | |
| {%- endfor -%} | |
| {#- Append any orphan tool messages (no matching id) in their original order. -#} | |
| {%- for tool_msg in tool_ns.items -%} | |
| {%- if tool_msg.tool_call_id not in sep_ns.rendered_ids -%} | |
| {%- if not sep_ns.first -%}{{- "\n" }}{%- endif -%} | |
| {%- set sep_ns.first = false -%} | |
| {{- "<|tool_response:start|>" + tool_msg.content + "<|tool_response:end|>" }} | |
| {%- endif -%} | |
| {%- endfor -%} | |
| {%- else -%} | |
| {%- for tool_msg in tool_ns.items -%} | |
| {%- if not loop.first -%}{{- "\n" }}{%- endif -%} | |
| {{- "<|tool_response:start|>" + tool_msg.content + "<|tool_response:end|>" }} | |
| {%- endfor -%} | |
| {%- endif -%} | |
| {{- "\n<|im:end|>\n" }} | |
| {%- endif -%} | |
| {%- elif message.role == 'assistant' -%} | |
| {{- "<|im:start|>assistant<|im:content|>" }} | |
| {#- ======== Resolve reasoning field (reasoning or reasoning_content) ======== #} | |
| {%- if message.reasoning is defined -%} | |
| {%- set reasoning = message.reasoning -%} | |
| {%- elif message.reasoning_content is defined -%} | |
| {%- set reasoning = message.reasoning_content -%} | |
| {%- else -%} | |
| {%- set reasoning = none -%} | |
| {%- endif -%} | |
| {#- ======== Assistant Thinking ======== #} | |
| {%- if think_render_option == "preserved" -%} | |
| {%- if reasoning -%} | |
| {{- "<|think:start|>" + reasoning + "<|think:end|>" }} | |
| {%- else -%} | |
| {{- "<|think:start|><|think:end|>" }} | |
| {%- endif -%} | |
| {%- elif think_render_option == "interleaved" -%} | |
| {%- if reasoning and loop.index0 > last_user_idx.value -%} | |
| {{- "<|think:start|>" + reasoning + "<|think:end|>" }} | |
| {%- else -%} | |
| {{- "<|think:start|><|think:end|>" }} | |
| {%- endif -%} | |
| {%- endif -%} | |
| {#- ======== Assistant Messages ======== #} | |
| {%- if message.content -%} | |
| {{- message.content }} | |
| {%- endif -%} | |
| {#- ======== Assistant Tool calls ======== #} | |
| {%- if message.tool_calls -%} | |
| {%- for tool_call in message.tool_calls -%} | |
| {%- if not tool_call.id -%} | |
| {{- raise_exception("assistant tool_call is missing required 'id' field") -}} | |
| {%- endif -%} | |
| {%- if not loop.first -%}{{- "\n" }}{%- endif -%} | |
| {{- "<|tool_call:start|>" + tool_call.function.name + "\n" }} | |
| {%- if tool_call.function.arguments is defined %} | |
| {{- render_tool_arguments(tool_call.function.arguments) }} | |
| {%- endif %} | |
| {{- "<|tool_call:end|>" }} | |
| {%- endfor -%} | |
| {{- "\n" }} | |
| {%- endif -%} | |
| {{- "<|im:end|>\n" }} | |
| {%- endif -%} | |
| {%- endfor -%} | |
| {%- if add_generation_prompt -%} | |
| {%- if reasoning_effort in ["medium", "high", "xhigh"] -%} | |
| {{- "<|im:start|>assistant<|im:content|><|think:start|>" }} | |
| {%- else -%} | |
| {{- "<|im:start|>assistant<|im:content|><|think:start|><|think:end|>" }} | |
| {%- endif -%} | |
| {%- endif -%} | |