A large language model inference and chat service framework designed for Enflame GCU, built on top of
Candle-GCUand the open-source projectCandle-vLLM, and fully compatible with the OpenAI API.
English | ็ฎไฝไธญๆ |
# Install Enflame drivers and runtime
sudo ./TopsPlatform_1.7.*.run
dpkg -i eccl_3.6.*.deb
dpkg -i topsaten_3.6.*_amd64.debDownload the GCU .deb from the GitHub Releases page (asset name like candle-vllm_*_amd64.deb), then install:
# Example (replace with the asset version from the latest release):
wget https://github.com/EnflameTechnology/candle-vllm-gcu/releases/download/v0.8.8/candle-vllm_0.8.8-1_amd64.deb
sudo dpkg -i candle-vllm_0.8.8-1_amd64.deb
# Binary installs to /usr/local/bin/candle-vllm
candle-vllm --p 2000 --w /path/to/model --ui-server# Install Rust (version 1.88.0 or higher)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Install bindgen
cargo install bindgen-cli
# Update sub-project
git submodule update --init --recursive
cd candle-vllm
# Install (then use `candle-vllm` directly); aten is optional and incompatible with graph
cargo install --features gcu,eccl,aten --path .- โ Multi-rank (Multi-GPUs, Multi-Nodes)
- โ Quantization (GPTQ, AWQ)
- โ Continuous Batching
- โ Paged Attention
- โ Flash Attention
- โ Chunked Prefill
- โ Prefix Caching
- โ
KV Cache
- โ BF16
- โ FP16
- โ INT8
- โ KVCache / GDN State Offloading (swap KV cache and GDN/Mamba state to CPU under GPU/GCU memory pressure)
- โ OpenAI-Compatible Server
- โ Multimodal Models
- ๐ ๏ธ CUDA Graph (Under Development)
-
[
ENV_PARAM] candle-vllm [PROGRAM_PARAM] [MODEL_ID/MODEL_WEIGHT_PATH]Show details
Example:
[RUST_LOG=warn] candle-vllm [--log --dtype bf16 --p 2000 --d 0,1 --kv-fraction 0.6 --ui-server] [--w /home/weights/QwQ-32B/]ENV_PARAM: RUST_LOG=warnPROGRAM_PARAM๏ผ--log --dtype bf16 --p 2000 --d 0,1 --ui-server --kv-fraction 0.6MODEL_WEIGHT_PATH: --w /home/weights/QwQ-32Bwhere,
--p: server port;--d: device ids;--w: weight path (safetensors folder);--f: weight file (for gguf);--m: huggingface model-id;--kvcache-dtype int8enables INT8 KV cache;--kv-fractionauto-sizes the KV cache as a fraction of remaining device memory after model load (default about0.6; raise it, e.g.0.8, for longer context or larger batches);--prefill-chunk-sizechunk the prefill into size defined in this flag (default 8K,0for disable);--ui-serverstart with a ChatGPT-like WebUI.
๐ท Qwen3-30B-MoE BF16 (Enflame S60) 
Currently supported models on Enflame S60 (48GB) (under graph mode disabled):
List of 1k decoding results:
| Model ID | Model Type | Supported | Speed (BF16, bs=1) | Thoughput (BF16, bs=16) |
|---|---|---|---|---|
| #1 | LLAMA | โ | 30 tks/s (7B), 27 tks/s (LLaMa3.1 8B) | 375 tks/s (LLaMa3.1 8B) |
| #2 | Mistral | โ | 29 tks/s (7B) | 330 tks/s (7B) |
| #3 | Phi (v1, v1.5, v2) | โ | TBD | TBD |
| #4 | Phi-3 | โ | 38 tks/s (3.8B) | 320 tks/s (BF16+F32, 7B) |
| #5 | Yi | โ | 28 tks/s (6B) | 305 tks/s (6B) |
| #6 | StableLM | โ | 48 tks/s (3B) | 425 tks/s (BF16, 3B) |
| #7 | BigCode/StarCode | TBD | TBD | TBD |
| #8 | ChatGLM | TBD | TBD | TBD |
| #9 | QWen2 | โ | 25 tks/s (14B, tp=2) | 322 tks/s (14B, tp=2, bs=32) |
| #9 | Qwen3 | โ | 28 tks/s (8B, bs=1) | 607 tks/s (14B, bs=48) |
| #10 | Qwen3-MoE | โ | 48 tks/s (30B, tp=2) | 175 tks/s (30B, tp=2, bs=8) |
| #11 | Qwen3.5/3.6 35B | โ | 35 tks/s (35B, tp=2) | TBD |
| #12 | Google Gemma | โ | 73 tks/s (2B) | 920 tks/s (2B) |
| #13 | GLM4 | โ | TBD | TBD |
| #14 | Moondream-2 (Multimodal LLM) | TBD | TBD | TBD |
| #15 | DeepSeek-V3/R1 (awq 671/685B, offloading) | โ | ~8tks/s (tp=8) | 155tks/s (tp=8, bs=48) |
| #16 | QwQ-32B | โ | 15 tokens (tp=2) | 230 tokens (tp=2, bs=32) |
Run Uncompressed Models
candle-vllm --p 2000 --w /home/DeepSeek-R1-Distill-Llama-8B/ --ui-servercandle-vllm --w /home/Qwen3-30B-A3B-Instruct-2507/ --d 0,1Qwen3.5/3.6
candle-vllm --m Qwen/Qwen3.5-35B-A3B --d 0,1 --ui-serverWith INT8 KV cache
candle-vllm --m Qwen/Qwen3.5-35B-A3B --d 0,1 --kvcache-dtype int8 --ui-serverRun GPTQ Quantized Models
# convert (8bit gptq) model to Enflame format
python3 transform_safetensors.py --src /path/to/gptq \
--dst /path/to/gptq-enflame --bits 8 --method gptq --group 128 --nk True
# run the converted model
candle-vllm --p 2000 --w /path/to/gptq-enflame --ui-serverRun AWQ Quantized Models
# convert (4bit awq) model to Enflame format
python3 transform_safetensors.py --src /path/to/awq \
--dst /path/to/awq-enflame --bits 4 --method awq --group 64 --nk True
# run the converted model
candle-vllm --p 2000 --w /path/to/awq-enflame --ui-serverMulti-Process, Multi-GPU
# Use card 0 and card 1
candle-vllm --p 2000 --d 0,1 --w /path/to/model --ui-serverMulti-Node (TCP, no MPI)
For cross-machine tensor parallelism, nodes exchange the ECCL UniqueId over TCP (to bootstrap collective communication); local multi-process ECCL then handles per-device traffic. MPI / mpirun is not required. Build with --features gcu,eccl as usual.
# Master node (e.g. 192.168.1.100), from the candle-vllm directory:
candle-vllm --d 0,1,2,3,4,5,6,7 --w /data/deepseek-enflame \
--num-nodes 2 --node-rank 0 --master-addr 192.168.1.100 --master-port 29500
# Worker node (e.g. 192.168.1.101):
candle-vllm --d 0,1,2,3,4,5,6,7 --w /data/deepseek-enflame \
--num-nodes 2 --node-rank 1 --master-addr 192.168.1.100 --master-port 29500| Flag | Description |
|---|---|
--num-nodes N |
Total nodes in the cluster |
--node-rank R |
Rank of this node (0 = master) |
--master-addr ADDR |
Master IP; workers must set a reachable master address. If omitted on the master, it binds 0.0.0.0 |
--master-port PORT |
ECCL ID exchange port (default 29500); forward coordination also uses PORT+1 โ open both in the firewall |
Requirements:
- Every node has the same model weights locally and the same
candle-vllmbinary; each node's local device count in--dshould match. - Workers can reach the master on
--master-portand--master-port + 1over TCP. - Global world size =
num_nodes ร local devices per node(e.g. 2 nodes ร 8 cards = tp=16).
After the server starts, an OpenAI-compatible API is available (default http://localhost:2000). Use interactive chat, the built-in Web UI, concurrent benchmarks, or agent automation.
pip install openai rich click
python3 examples/chat.py
python3 examples/chat.py --live # live Markdown rendering# Start the API together with a ChatGPT-style Web UI (with chat history)
candle-vllm --p 2000 --w /path/to/model --ui-server
# Open the UI in a browser: http://localhost:1999 (UI port = API port - 1)# --batch is an alias for total prompts; also supports --num-prompts / --concurrency, etc.
python3 examples/benchmark.py --max_tokens 1024
python3 examples/benchmark.py --num-prompts 64 --concurrency 8 \
--input-lens 128,512,2048 --output-lens 128,512See benchmark.py for the full option list.
xbot is a Rust AI agent that talks to candle-vllmโs OpenAI-compatible API for project scanning, interactive REPL, or automation.
# 1) Start the server (example port 8000)
candle-vllm --p 8000 --w /path/to/model
# 2) Install and configure xbot
cargo install xbot # or: npm install -g @trusted-ai/xbot
xbot onboard
xbot config --provider
# Provider: custom โ name candle-vllm โ API Base: http://localhost:8000/v1/ โ no API key
# 3) Run in your project
cd YOUR_PROJECT
xbot chat /init
xbot chat "find bugs in this project."
xbot repl # interactive TUIFull guide: docs/xbot.md.
- Use
transform_safetensors.pyto convert models. - Samples:
# 8bit gptq conversion
python3 transform_safetensors.py --src /data/Meta-Llama-3.1-8B-Instruct-GPTQ-8bit --dst /data/Meta-Llama-3.1-8B-Instruct-GPTQ-8bit-Enflame --bits 8 --method gptq --group 128 --nk True
# 4bit awq conversion
python3 transform_safetensors.py --src /data/DeepSeek-R1-AWQ --dst /data/DeepSeek-R1-AWQ-Enflame/ --bits 4 --method awq --group 64 --nk True
# run the converted model
candle-vllm --p 2000 --w /data/Meta-Llama-3.1-8B-Instruct-GPTQ-8bit-Enflame