[!Note] This repository contains model weights and configuration files for the post-trained model in the Hugging Face Transformers format.
We are introducing Spark-X2.5-4B and Spark-X2.5-1.7B, two compact, general-purpose language models designed to make capable AI more practical, efficient, and accessible. The models deliver strong performance across a broad range of everyday tasks—including conversation, writing, translation, reasoning, coding, tool use, and agentic workflows—achieving leading results among open-source models of comparable size. Spark-X2.5 combines an efficiency-oriented architecture with native context windows of up to 1M tokens, and support for more than 200 languages.
Technical Highlights:
For agent tasks, balancing performance, inference speed, and cache usage has long been a key bottleneck limiting model performance. Spark-X2.5 systematically integrates and optimizes mature attention technologies, combining sliding-window attention (SWA) with a hybrid full-attention architecture. This approach leverages the strengths of both mechanisms while avoiding the limitations of relying on a single structure, achieving an effective balance among performance, inference efficiency, and KV-cache size—thereby improving its practicality and effectiveness across real-world deployment scenarios.
Spark-X2.5 is pretrained on approximately 20 trillion tokens from a diverse corpus spanning web pages, books, academic publications, code, and encyclopedic materials. Particular attention is paid to data quality, domain coverage, and the sampling weights assigned to different data categories. Extensive data-mixture studies are conducted to determine an effective balance among mathematics, logic, code, and other high-value domains. This enables the models to acquire broad general knowledge while developing stronger capabilities in complex reasoning and code generation. Long-context capability is developed through a dedicated training stage comprising hundreds of billions of tokens, with sequence lengths extending to 1M tokens.
Post-training begins with supervised fine-tuning on a carefully curated corpus. This stage establishes robust instruction following, structured generation, and task-completion, while providing a stable policy initialization for reinforcement learning. We subsequently apply large-scale reinforcement learning across several capability domains, including language understanding, reasoning, programming, tool-augmented agentic behavior, and instruction following. This process yields a set of domain-specialized teacher policies, whose complementary strengths are consolidated into a single deployable model through MOPD.
We evaluate our models and compare them with leading on-device models of similar size across a broad range of tasks, including agent, code, math, general and knowledge.
| Benchmark | Spark‑X2.5‑4B | Spark‑X2.5‑1.7B | Qwen3.5‑9B | Qwen3.5‑4B | Qwen3.5‑2B | Gemma4‑12B | Gemma4‑E4B | Gemma4‑E2B |
|---|---|---|---|---|---|---|---|---|
| Agent | ||||||||
| BFCL‑V4 | 65.1 | 46.9 | 66.1* | 50.3* | 43.6* | 37.4 | 36.9 | 30.2 |
| τ²‑bench | 75.1 | 65.3 | 79.1* | 79.9* | 48.8* | 69.0* | 42.2* | 24.5* |
| τ³‑bench | 30.4 | 20.1 | 9.3 | 6.7 | 4.1 | 13.3 | 10.1 | 8.8 |
| MCP‑Atlas | 54.6 | 23.4 | 47.4* | 40.8* | 14.8 | 30.5* | 15.0* | 12.6 |
| MCP‑Mark | 14.2 | 2.3 | 13.4 | 12.5 | – | – | – | – |
| Workspace Bench | 31.2 | 18.9 | 25.5 | 21.3 | 7.7 | – | – | – |
| VitaBench2.0 | 25.2 | 8.3 | 15.6 | 18.2 | 5.2 | 12.4 | 4.8 | 4.4 |
| BrowseComp | 40.9 | 29.7 | 8.3 | 14.3 | 3.1 | 10.0 | 8.3 | 3.7 |
| Code | ||||||||
| SWE‑Bench Pro | 44.4 | 10.4 | 33.8* | 29.4* | 1.9 | 21.9* | 4.0* | – |
| SWE‑Bench Verified | 41.6 | 28.3 | 53.1* | 38.8* | 6.8 | 44.2* | 14.0* | – |
| SWE‑Bench Multilingual | 53.3 | 23.3 | 43.3 | 27.7 | 5.0 | 32.5* | – | – |
| SciCode | 34.7 | 18.2 | 32.7* | 24.0 | 6.0 | 39.8 | 27.5 | 20.5 |
| Math | ||||||||
| Gaokao 2026 | 133.4 | 114.8 | 135.5 | 130.3 | 94.0 | 130.6 | 102.4 | 81.8 |
| AIME 2026 | 90.7 | 69.4 | 88.2 | 83.0 | 30.8 | 82.1* | 42.5* | 37.5* |
| HMMT Feb 2026 | 81.2 | 48.4 | 70.8 | 69.7 | 21.5 | 65.6 | 34.2 | 20.5 |
| IMO‑AnswerBench | 74.2 | 45.4 | 69.8 | 68.5 | – | 57.2 | 26.9 | 22.6 |
| General & Knowledge | ||||||||
| IFEval | 93.0 | 89.5 | 91.5* | 89.8* | 78.6* | 94.8 | 45.3 | 34.8 |
| IFBench | 75.0 | 66.3 | 64.5 | 59.2 | 41.3* | 73.5* | 44.0* | 22.7 |
| AA‑LCR | 56.3 | 24.3 | 63.0* | 57.0* | 25.6* | 55.3* | 34.7 | 18.3 |
| HLE | 12.3 | 6.3 | 14.3 | 8.6 | 2.1 | 13.1 | 3.9 | 2.5 |
| GPQA | 67.4 | 43.8 | 77.2 | 67.2 | 44.6 | 72.8 | 54.5 | 43.8 |
The examples below serve a local Spark-X2.5-1.7B checkpoint. Set MODEL_PATH to its absolute path before starting a container:
export MODEL_PATH=/absolute/path/to/Spark-X2.5-1.7B
Use the pre-built image that tracks the Spark-X2.5 runtime:
docker pull lmsysorg/sglang:nightly-dev-cu13-20260827-20621aa1
# A3 daily build
export SGLANG_IMAGE=quay.io/ascend/sglang:main-cann9.0.0-a3
# A2 daily build (use this instead on A2 hardware)
export SGLANG_IMAGE=quay.io/ascend/sglang:main-cann9.0.0-910b
docker pull "$SGLANG_IMAGE"
The following commands start an OpenAI-compatible API server configured for a maximum context length of 1,048,576 tokens. This setting requires sufficient device memory; reduce --context-length when necessary.
docker run --rm -it \
--gpus '"device=0"' \
--ipc=host \
-p 30000:30000 \
-v "$MODEL_PATH:/root/Spark-X2.5-1.7B:ro" \
lmsysorg/sglang:nightly-dev-cu13-20260827-20621aa1 \
python -m sglang.launch_server \
--model-path /root/Spark-X2.5-1.7B \
--served-model-name spark2.5 \
--tool-call-parser spark25 \
--reasoning-parser qwen3 \
--tp-size 1 \
--mem-fraction-static 0.8 \
--context-length 1048576 \
--chat-template /root/Spark-X2.5-1.7B/chat_template.jinja \
--host 0.0.0.0 \
--port 30000
docker run -it --rm -e ASCEND_USE_FIA=1 --network=host --ipc=host --shm-size=16g \
--device=/dev/davinci0 --device=/dev/davinci1 --device=/dev/davinci2 --device=/dev/davinci3 \
--device=/dev/davinci4 --device=/dev/davinci5 --device=/dev/davinci6 --device=/dev/davinci7 \
--device=/dev/davinci8 --device=/dev/davinci9 --device=/dev/davinci10 --device=/dev/davinci11 \
--device=/dev/davinci12 --device=/dev/davinci13 --device=/dev/davinci14 --device=/dev/davinci15 \
--device=/dev/davinci_manager \
--device=/dev/devmm_svm \
--device=/dev/hisi_hdc \
--volume /usr/local/sbin:/usr/local/sbin \
--volume /usr/local/Ascend/driver:/usr/local/Ascend/driver \
--volume /usr/local/Ascend/firmware:/usr/local/Ascend/firmware \
--volume /etc/ascend_install.info:/etc/ascend_install.info \
--volume /var/queue_schedule:/var/queue_schedule \
--volume ~/.cache/:/root/.cache/ \
--volume "$MODEL_PATH:/root/Spark-X2.5-1.7B:ro" \
--entrypoint=python \
"$SGLANG_IMAGE" \
-m sglang.launch_server \
--model-path /root/Spark-X2.5-1.7B \
--served-model-name spark2.5 \
--tool-call-parser spark25 \
--reasoning-parser qwen3 \
--tp-size 1 \
--mem-fraction-static 0.8 \
--context-length 1048576 \
--chat-template /root/Spark-X2.5-1.7B/chat_template.jinja \
--host 0.0.0.0 \
--port 30000
Thinking is enabled by default by both the chat template and the Qwen3 reasoning parser. To disable thinking for a specific request, set "chat_template_kwargs": {"enable_thinking": false}.
curl -s http://localhost:30000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "spark2.5",
"messages": [
{
"role": "user",
"content": "What is the capital of Anhui Province?"
}
],
"max_tokens": 131072,
"temperature": 1,
"top_k": -1,
"top_p": 0.95,
"repetition_penalty": 1,
"presence_penalty": 0,
"frequency_penalty": 0
}'
vLLM provides an official Docker image for NVIDIA GPU deployment:
docker run --rm --gpus all \
--ipc=host \
-p 30000:30000 \
-v "$MODEL_PATH:/models/Spark-X2.5-1.7B:ro" \
vllm/vllm-openai:latest \
--model /models/Spark-X2.5-1.7B \
--port 30000 \
--trust-remote-code \
--served-model-name spark25 \
--tensor-parallel-size 1 \
--gpu-memory-utilization 0.7 \
--enable-prefix-caching \
--chat-template /models/Spark-X2.5-1.7B/chat_template.jinja
For Ascend NPUs, choose an official image for the fastest setup.
export IMAGE=quay.io/ascend/vllm-ascend:nightly-main
docker pull "$IMAGE"
export DEVICE=/dev/davinci0
export MODEL_CACHE="${HOME}/.cache"
mkdir -p "$MODEL_CACHE"
docker run --rm \
--name vllm-ascend \
--shm-size=1g \
--device "$DEVICE" \
--device /dev/davinci_manager \
--device /dev/devmm_svm \
--device /dev/hisi_hdc \
-v /usr/local/dcmi:/usr/local/dcmi \
-v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \
-v /usr/local/Ascend/driver/lib64/:/usr/local/Ascend/driver/lib64/ \
-v /usr/local/Ascend/driver/version.info:/usr/local/Ascend/driver/version.info \
-v /etc/ascend_install.info:/etc/ascend_install.info \
-v "$MODEL_CACHE:/root/.cache" \
-p 8000:8000 \
-it "$IMAGE" bash
export IMAGE=quay.io/ascend/vllm-ascend:nightly-main-a3
docker pull "$IMAGE"
export DEVICE0=/dev/davinci0
export DEVICE1=/dev/davinci1
export MODEL_CACHE="${HOME}/.cache"
mkdir -p "$MODEL_CACHE"
docker run --rm \
--name vllm-ascend \
--shm-size=1g \
--device "$DEVICE0" \
--device "$DEVICE1" \
--device /dev/davinci_manager \
--device /dev/devmm_svm \
--device /dev/hisi_hdc \
-v /usr/local/dcmi:/usr/local/dcmi \
-v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \
-v /usr/local/Ascend/driver/lib64/:/usr/local/Ascend/driver/lib64/ \
-v /usr/local/Ascend/driver/version.info:/usr/local/Ascend/driver/version.info \
-v /etc/ascend_install.info:/etc/ascend_install.info \
-v "$MODEL_CACHE:/root/.cache" \
-p 8000:8000 \
-it "$IMAGE" bash
export IMAGE=quay.io/ascend/vllm-ascend:nightly-main-a5
docker pull "$IMAGE"
export MODEL_CACHE="${HOME}/.cache"
mkdir -p "$MODEL_CACHE"
docker run --rm \
--name vllm-ascend \
--net=host \
--shm-size=1g \
--device /dev/davinci0 \
--device /dev/davinci_manager \
--device /dev/devmm_svm \
--device /dev/hisi_hdc \
-v /usr/local/dcmi:/usr/local/dcmi \
-v /usr/local/Ascend/driver/tools/hccn_tool:/usr/local/Ascend/driver/tools/hccn_tool \
-v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \
-v /usr/local/Ascend/driver/lib64/:/usr/local/Ascend/driver/lib64/ \
-v /usr/local/Ascend/driver/version.info:/usr/local/Ascend/driver/version.info \
-v /etc/ascend_install.info:/etc/ascend_install.info \
-v "$MODEL_CACHE:/root/.cache" \
-it "$IMAGE" bash
Install the Spark plugin inside the container:
pip install uv
uv venv ~/spark2_5
source ~/spark2_5/bin/activate
git clone https://github.com/XHToken/Spark-plugin.git
cd ./Spark-plugin
uv pip install .
vllm serve "/models/Spark-X2.5-1.7B" \
--port "30000" \
--trust-remote-code \
--served-model-name spark25 \
--tensor-parallel-size 1 \
--gpu-memory-utilization 0.7 \
--enable-prefix-caching \
--chat-template /models/Spark-X2.5-1.7B/chat_template.jinja
curl -s http://127.0.0.1:30000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "spark25",
"messages": [{"role": "user", "content": "What is the capital of Anhui Province?"}],
"temperature": 1.0,
"top_k": -1,
"top_p": 0.95
}'
Spark-MLX-LLM runs the original Spark-X2.5 Hugging Face checkpoints locally. It supports Apple silicon GPU, Linux CPU, and NVIDIA CUDA on Linux. No GGUF conversion is required.
git clone https://github.com/XHToken/Spark-MLX-LLM.git
cd Spark-MLX-LLM
python3 -m venv .venv
source .venv/bin/activate
# Apple silicon
python -m pip install -e .
# Linux CPU
python -m pip install -e '.[cpu]'
# Linux with CUDA 12
python -m pip install -e '.[cuda12]'
# Linux with CUDA 13
python -m pip install -e '.[cuda13]'
spark-mlx-generate \
--device gpu \
--dtype bfloat16 \
--model XHToken/Spark-X2.5-1.7B \
--prompt "What is the capital of Anhui Province?" \
--max-tokens 512 \
--temp 0
git clone https://github.com/XHToken/llama.cpp.git llama.cpp-spark
git clone https://github.com/ollama/ollama.git ollama-spark
cd ollama-spark
export OLLAMA_LLAMA_CPP_SOURCE="$(cd ../llama.cpp-spark && pwd)"
cmake -S . -B build
cmake --build build --parallel 8
Create the model definition, then start the Ollama server in one terminal:
printf 'FROM /absolute/path/to/your.gguf\n' > ./Modelfile.spark
./ollama serve
Create and run the model from another terminal:
./ollama create Spark-X2.5-1.7B -f ./Modelfile.spark
./ollama run Spark-X2.5-1.7B
git clone https://github.com/XHToken/llama.cpp.git llama.cpp-spark
cd llama.cpp-spark
cmake -S . -B build
cmake --build build --parallel 8
Close LM Studio.
Back up the selected runtime directory:
<LM_STUDIO_HOME>/extensions/backends/<selected-runtime>/
Copy the llama.cpp-spark build output into the selected runtime directory, overwriting the existing files.
Place the GGUF model in the following directory:
<LM_STUDIO_HOME>/models/<org>/<name>/
Example runtime directory on macOS:
./build/bin/* -> ~/.lmstudio/extensions/backends/llama.cpp-mac-arm64-apple-metal-advsimd-<version>/
Open My Models, select the Spark-X2.5 model, click Load, then start a new Chat.
# Replace <model> with a model listed by lms ls.
lms load <model>
lms chat <model>
We recommend using Llama-Factory to fine-tune the model.
The Spark-X2.5 model series is licensed under the Apache 2.0 License.
If you find our work helpful, feel free to give us a cite.
@misc{sparkx2.5,
title = {Spark-X2.5 4B&1.7B: Pushing the Limits of Agentic Capabilities in On-Device Models},
author = {SparkLLM Team},
year = {2026}
}
2 commits
1 commits
[!Note] This repository contains model weights and configuration files for the post-trained model in the Hugging Face Transformers format.
We are introducing Spark-X2.5-4B and Spark-X2.5-1.7B, two compact, general-purpose language models designed to make capable AI more practical, efficient, and accessible. The models deliver strong performance across a broad range of everyday tasks—including conversation, writing, translation, reasoning, coding, tool use, and agentic workflows—achieving leading results among open-source models of comparable size. Spark-X2.5 combines an efficiency-oriented architecture with native context windows of up to 1M tokens, and support for more than 200 languages.
Technical Highlights:
For agent tasks, balancing performance, inference speed, and cache usage has long been a key bottleneck limiting model performance. Spark-X2.5 systematically integrates and optimizes mature attention technologies, combining sliding-window attention (SWA) with a hybrid full-attention architecture. This approach leverages the strengths of both mechanisms while avoiding the limitations of relying on a single structure, achieving an effective balance among performance, inference efficiency, and KV-cache size—thereby improving its practicality and effectiveness across real-world deployment scenarios.
Spark-X2.5 is pretrained on approximately 20 trillion tokens from a diverse corpus spanning web pages, books, academic publications, code, and encyclopedic materials. Particular attention is paid to data quality, domain coverage, and the sampling weights assigned to different data categories. Extensive data-mixture studies are conducted to determine an effective balance among mathematics, logic, code, and other high-value domains. This enables the models to acquire broad general knowledge while developing stronger capabilities in complex reasoning and code generation. Long-context capability is developed through a dedicated training stage comprising hundreds of billions of tokens, with sequence lengths extending to 1M tokens.
Post-training begins with supervised fine-tuning on a carefully curated corpus. This stage establishes robust instruction following, structured generation, and task-completion, while providing a stable policy initialization for reinforcement learning. We subsequently apply large-scale reinforcement learning across several capability domains, including language understanding, reasoning, programming, tool-augmented agentic behavior, and instruction following. This process yields a set of domain-specialized teacher policies, whose complementary strengths are consolidated into a single deployable model through MOPD.
We evaluate our models and compare them with leading on-device models of similar size across a broad range of tasks, including agent, code, math, general and knowledge.
| Benchmark | Spark‑X2.5‑4B | Spark‑X2.5‑1.7B | Qwen3.5‑9B | Qwen3.5‑4B | Qwen3.5‑2B | Gemma4‑12B | Gemma4‑E4B | Gemma4‑E2B |
|---|---|---|---|---|---|---|---|---|
| Agent | ||||||||
| BFCL‑V4 | 65.1 | 46.9 | 66.1* | 50.3* | 43.6* | 37.4 | 36.9 | 30.2 |
| τ²‑bench | 75.1 | 65.3 | 79.1* | 79.9* | 48.8* | 69.0* | 42.2* | 24.5* |
| τ³‑bench | 30.4 | 20.1 | 9.3 | 6.7 | 4.1 | 13.3 | 10.1 | 8.8 |
| MCP‑Atlas | 54.6 | 23.4 | 47.4* | 40.8* | 14.8 | 30.5* | 15.0* | 12.6 |
| MCP‑Mark | 14.2 | 2.3 | 13.4 | 12.5 | – | – | – | – |
| Workspace Bench | 31.2 | 18.9 | 25.5 | 21.3 | 7.7 | – | – | – |
| VitaBench2.0 | 25.2 | 8.3 | 15.6 | 18.2 | 5.2 | 12.4 | 4.8 | 4.4 |
| BrowseComp | 40.9 | 29.7 | 8.3 | 14.3 | 3.1 | 10.0 | 8.3 | 3.7 |
| Code | ||||||||
| SWE‑Bench Pro | 44.4 | 10.4 | 33.8* | 29.4* | 1.9 | 21.9* | 4.0* | – |
| SWE‑Bench Verified | 41.6 | 28.3 | 53.1* | 38.8* | 6.8 | 44.2* | 14.0* | – |
| SWE‑Bench Multilingual | 53.3 | 23.3 | 43.3 | 27.7 | 5.0 | 32.5* | – | – |
| SciCode | 34.7 | 18.2 | 32.7* | 24.0 | 6.0 | 39.8 | 27.5 | 20.5 |
| Math | ||||||||
| Gaokao 2026 | 133.4 | 114.8 | 135.5 | 130.3 | 94.0 | 130.6 | 102.4 | 81.8 |
| AIME 2026 | 90.7 | 69.4 | 88.2 | 83.0 | 30.8 | 82.1* | 42.5* | 37.5* |
| HMMT Feb 2026 | 81.2 | 48.4 | 70.8 | 69.7 | 21.5 | 65.6 | 34.2 | 20.5 |
| IMO‑AnswerBench | 74.2 | 45.4 | 69.8 | 68.5 | – | 57.2 | 26.9 | 22.6 |
| General & Knowledge | ||||||||
| IFEval | 93.0 | 89.5 | 91.5* | 89.8* | 78.6* | 94.8 | 45.3 | 34.8 |
| IFBench | 75.0 | 66.3 | 64.5 | 59.2 | 41.3* | 73.5* | 44.0* | 22.7 |
| AA‑LCR | 56.3 | 24.3 | 63.0* | 57.0* | 25.6* | 55.3* | 34.7 | 18.3 |
| HLE | 12.3 | 6.3 | 14.3 | 8.6 | 2.1 | 13.1 | 3.9 | 2.5 |
| GPQA | 67.4 | 43.8 | 77.2 | 67.2 | 44.6 | 72.8 | 54.5 | 43.8 |
The examples below serve a local Spark-X2.5-1.7B checkpoint. Set MODEL_PATH to its absolute path before starting a container:
export MODEL_PATH=/absolute/path/to/Spark-X2.5-1.7B
Use the pre-built image that tracks the Spark-X2.5 runtime:
docker pull lmsysorg/sglang:nightly-dev-cu13-20260827-20621aa1
# A3 daily build
export SGLANG_IMAGE=quay.io/ascend/sglang:main-cann9.0.0-a3
# A2 daily build (use this instead on A2 hardware)
export SGLANG_IMAGE=quay.io/ascend/sglang:main-cann9.0.0-910b
docker pull "$SGLANG_IMAGE"
The following commands start an OpenAI-compatible API server configured for a maximum context length of 1,048,576 tokens. This setting requires sufficient device memory; reduce --context-length when necessary.
docker run --rm -it \
--gpus '"device=0"' \
--ipc=host \
-p 30000:30000 \
-v "$MODEL_PATH:/root/Spark-X2.5-1.7B:ro" \
lmsysorg/sglang:nightly-dev-cu13-20260827-20621aa1 \
python -m sglang.launch_server \
--model-path /root/Spark-X2.5-1.7B \
--served-model-name spark2.5 \
--tool-call-parser spark25 \
--reasoning-parser qwen3 \
--tp-size 1 \
--mem-fraction-static 0.8 \
--context-length 1048576 \
--chat-template /root/Spark-X2.5-1.7B/chat_template.jinja \
--host 0.0.0.0 \
--port 30000
docker run -it --rm -e ASCEND_USE_FIA=1 --network=host --ipc=host --shm-size=16g \
--device=/dev/davinci0 --device=/dev/davinci1 --device=/dev/davinci2 --device=/dev/davinci3 \
--device=/dev/davinci4 --device=/dev/davinci5 --device=/dev/davinci6 --device=/dev/davinci7 \
--device=/dev/davinci8 --device=/dev/davinci9 --device=/dev/davinci10 --device=/dev/davinci11 \
--device=/dev/davinci12 --device=/dev/davinci13 --device=/dev/davinci14 --device=/dev/davinci15 \
--device=/dev/davinci_manager \
--device=/dev/devmm_svm \
--device=/dev/hisi_hdc \
--volume /usr/local/sbin:/usr/local/sbin \
--volume /usr/local/Ascend/driver:/usr/local/Ascend/driver \
--volume /usr/local/Ascend/firmware:/usr/local/Ascend/firmware \
--volume /etc/ascend_install.info:/etc/ascend_install.info \
--volume /var/queue_schedule:/var/queue_schedule \
--volume ~/.cache/:/root/.cache/ \
--volume "$MODEL_PATH:/root/Spark-X2.5-1.7B:ro" \
--entrypoint=python \
"$SGLANG_IMAGE" \
-m sglang.launch_server \
--model-path /root/Spark-X2.5-1.7B \
--served-model-name spark2.5 \
--tool-call-parser spark25 \
--reasoning-parser qwen3 \
--tp-size 1 \
--mem-fraction-static 0.8 \
--context-length 1048576 \
--chat-template /root/Spark-X2.5-1.7B/chat_template.jinja \
--host 0.0.0.0 \
--port 30000
Thinking is enabled by default by both the chat template and the Qwen3 reasoning parser. To disable thinking for a specific request, set "chat_template_kwargs": {"enable_thinking": false}.
curl -s http://localhost:30000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "spark2.5",
"messages": [
{
"role": "user",
"content": "What is the capital of Anhui Province?"
}
],
"max_tokens": 131072,
"temperature": 1,
"top_k": -1,
"top_p": 0.95,
"repetition_penalty": 1,
"presence_penalty": 0,
"frequency_penalty": 0
}'
vLLM provides an official Docker image for NVIDIA GPU deployment:
docker run --rm --gpus all \
--ipc=host \
-p 30000:30000 \
-v "$MODEL_PATH:/models/Spark-X2.5-1.7B:ro" \
vllm/vllm-openai:latest \
--model /models/Spark-X2.5-1.7B \
--port 30000 \
--trust-remote-code \
--served-model-name spark25 \
--tensor-parallel-size 1 \
--gpu-memory-utilization 0.7 \
--enable-prefix-caching \
--chat-template /models/Spark-X2.5-1.7B/chat_template.jinja
For Ascend NPUs, choose an official image for the fastest setup.
export IMAGE=quay.io/ascend/vllm-ascend:nightly-main
docker pull "$IMAGE"
export DEVICE=/dev/davinci0
export MODEL_CACHE="${HOME}/.cache"
mkdir -p "$MODEL_CACHE"
docker run --rm \
--name vllm-ascend \
--shm-size=1g \
--device "$DEVICE" \
--device /dev/davinci_manager \
--device /dev/devmm_svm \
--device /dev/hisi_hdc \
-v /usr/local/dcmi:/usr/local/dcmi \
-v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \
-v /usr/local/Ascend/driver/lib64/:/usr/local/Ascend/driver/lib64/ \
-v /usr/local/Ascend/driver/version.info:/usr/local/Ascend/driver/version.info \
-v /etc/ascend_install.info:/etc/ascend_install.info \
-v "$MODEL_CACHE:/root/.cache" \
-p 8000:8000 \
-it "$IMAGE" bash
export IMAGE=quay.io/ascend/vllm-ascend:nightly-main-a3
docker pull "$IMAGE"
export DEVICE0=/dev/davinci0
export DEVICE1=/dev/davinci1
export MODEL_CACHE="${HOME}/.cache"
mkdir -p "$MODEL_CACHE"
docker run --rm \
--name vllm-ascend \
--shm-size=1g \
--device "$DEVICE0" \
--device "$DEVICE1" \
--device /dev/davinci_manager \
--device /dev/devmm_svm \
--device /dev/hisi_hdc \
-v /usr/local/dcmi:/usr/local/dcmi \
-v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \
-v /usr/local/Ascend/driver/lib64/:/usr/local/Ascend/driver/lib64/ \
-v /usr/local/Ascend/driver/version.info:/usr/local/Ascend/driver/version.info \
-v /etc/ascend_install.info:/etc/ascend_install.info \
-v "$MODEL_CACHE:/root/.cache" \
-p 8000:8000 \
-it "$IMAGE" bash
export IMAGE=quay.io/ascend/vllm-ascend:nightly-main-a5
docker pull "$IMAGE"
export MODEL_CACHE="${HOME}/.cache"
mkdir -p "$MODEL_CACHE"
docker run --rm \
--name vllm-ascend \
--net=host \
--shm-size=1g \
--device /dev/davinci0 \
--device /dev/davinci_manager \
--device /dev/devmm_svm \
--device /dev/hisi_hdc \
-v /usr/local/dcmi:/usr/local/dcmi \
-v /usr/local/Ascend/driver/tools/hccn_tool:/usr/local/Ascend/driver/tools/hccn_tool \
-v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \
-v /usr/local/Ascend/driver/lib64/:/usr/local/Ascend/driver/lib64/ \
-v /usr/local/Ascend/driver/version.info:/usr/local/Ascend/driver/version.info \
-v /etc/ascend_install.info:/etc/ascend_install.info \
-v "$MODEL_CACHE:/root/.cache" \
-it "$IMAGE" bash
Install the Spark plugin inside the container:
pip install uv
uv venv ~/spark2_5
source ~/spark2_5/bin/activate
git clone https://github.com/XHToken/Spark-plugin.git
cd ./Spark-plugin
uv pip install .
vllm serve "/models/Spark-X2.5-1.7B" \
--port "30000" \
--trust-remote-code \
--served-model-name spark25 \
--tensor-parallel-size 1 \
--gpu-memory-utilization 0.7 \
--enable-prefix-caching \
--chat-template /models/Spark-X2.5-1.7B/chat_template.jinja
curl -s http://127.0.0.1:30000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "spark25",
"messages": [{"role": "user", "content": "What is the capital of Anhui Province?"}],
"temperature": 1.0,
"top_k": -1,
"top_p": 0.95
}'
Spark-MLX-LLM runs the original Spark-X2.5 Hugging Face checkpoints locally. It supports Apple silicon GPU, Linux CPU, and NVIDIA CUDA on Linux. No GGUF conversion is required.
git clone https://github.com/XHToken/Spark-MLX-LLM.git
cd Spark-MLX-LLM
python3 -m venv .venv
source .venv/bin/activate
# Apple silicon
python -m pip install -e .
# Linux CPU
python -m pip install -e '.[cpu]'
# Linux with CUDA 12
python -m pip install -e '.[cuda12]'
# Linux with CUDA 13
python -m pip install -e '.[cuda13]'
spark-mlx-generate \
--device gpu \
--dtype bfloat16 \
--model XHToken/Spark-X2.5-1.7B \
--prompt "What is the capital of Anhui Province?" \
--max-tokens 512 \
--temp 0
git clone https://github.com/XHToken/llama.cpp.git llama.cpp-spark
git clone https://github.com/ollama/ollama.git ollama-spark
cd ollama-spark
export OLLAMA_LLAMA_CPP_SOURCE="$(cd ../llama.cpp-spark && pwd)"
cmake -S . -B build
cmake --build build --parallel 8
Create the model definition, then start the Ollama server in one terminal:
printf 'FROM /absolute/path/to/your.gguf\n' > ./Modelfile.spark
./ollama serve
Create and run the model from another terminal:
./ollama create Spark-X2.5-1.7B -f ./Modelfile.spark
./ollama run Spark-X2.5-1.7B
git clone https://github.com/XHToken/llama.cpp.git llama.cpp-spark
cd llama.cpp-spark
cmake -S . -B build
cmake --build build --parallel 8
Close LM Studio.
Back up the selected runtime directory:
<LM_STUDIO_HOME>/extensions/backends/<selected-runtime>/
Copy the llama.cpp-spark build output into the selected runtime directory, overwriting the existing files.
Place the GGUF model in the following directory:
<LM_STUDIO_HOME>/models/<org>/<name>/
Example runtime directory on macOS:
./build/bin/* -> ~/.lmstudio/extensions/backends/llama.cpp-mac-arm64-apple-metal-advsimd-<version>/
Open My Models, select the Spark-X2.5 model, click Load, then start a new Chat.
# Replace <model> with a model listed by lms ls.
lms load <model>
lms chat <model>
We recommend using Llama-Factory to fine-tune the model.
The Spark-X2.5 model series is licensed under the Apache 2.0 License.
If you find our work helpful, feel free to give us a cite.
@misc{sparkx2.5,
title = {Spark-X2.5 4B&1.7B: Pushing the Limits of Agentic Capabilities in On-Device Models},
author = {SparkLLM Team},
year = {2026}
}
2 commits
1 commits