Instructions to use moonshotai/Kimi-K3 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use moonshotai/Kimi-K3 with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("image-text-to-text", model="moonshotai/Kimi-K3", trust_remote_code=True) 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)# Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("moonshotai/Kimi-K3", trust_remote_code=True, device_map="auto") - Inference
- HuggingChat
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use moonshotai/Kimi-K3 with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "moonshotai/Kimi-K3" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "moonshotai/Kimi-K3", "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/moonshotai/Kimi-K3
- SGLang
How to use moonshotai/Kimi-K3 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 "moonshotai/Kimi-K3" \ --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": "moonshotai/Kimi-K3", "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 "moonshotai/Kimi-K3" \ --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": "moonshotai/Kimi-K3", "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 moonshotai/Kimi-K3 with Docker Model Runner:
docker model run hf.co/moonshotai/Kimi-K3
Kimi-K3 on 16× H200 141GB: Deployment Report
Successfully deployed moonshotai/Kimi-K3 (2.8T MoE, MXFP4) on 2× nodes (8× NVIDIA H200 141GB each) using SGLang.
This report documents what worked, what didn't, and measured performance — hopefully
it saves others some time, since most official recipes assume Blackwell (B300/GB300)
and the H200 path is less traveled.
TL;DR
| Hardware | 2 nodes × 8× H200 141GB |
| Engine that worked | SGLang (lmsysorg/sglang:kimi-k3 image), TP16 + EP16, marlin MoE backend |
| Engine that didn't | vLLM kimi-k3 branch (vllm/vllm-openai:kimi-k3) — weight-loading memory bug on H200, details below |
| Weights per GPU | 102.75 GB (SGLang, close to the 1561GB/16 ≈ 98GB theoretical) |
| KV cache per GPU | 7.95 GB pool, bf16, 308,608 tokens |
| Server startup (cold) | 13 min 02 s end-to-end (11.2 min weight load + 39 s CUDA graphs) |
| TTFT (short prompt) | 0.37–0.54 s |
| Single-request decode | 16.8 tok/s |
| Aggregate throughput | ~147 tok/s at 54 concurrent requests (scaling not yet saturated) |
Setup
- Model:
moonshotai/Kimi-K3(~1.56 TB, 96 safetensors shards) - Launch config: the official SGLang cookbook h200 / unified / balanced profile:
NCCL_MNNVL_ENABLE=1 NCCL_CUMEM_ENABLE=1 SGLANG_ENABLE_TP_MEMORY_INBALANCE_CHECK=0 \
sglang serve \
--trust-remote-code \
--model-path /path/to/Kimi-K3 \
--tp-size 16 --nnodes 2 --node-rank <0|1> --dist-init-addr <head-ip>:20000 \
--ep-size 16 \
--moe-runner-backend marlin \
--decode-attention-backend flashmla \
--enable-symm-mem \
--mem-fraction-static 0.85 \
--reasoning-parser kimi_k3 --tool-call-parser kimi_k3 \
--host 0.0.0.0 --port 30000
Two environment fixes were needed on top of the official recipe:
- Pin the cross-node NIC on every rank (
NCCL_SOCKET_IFNAME/GLOO_SOCKET_IFNAME).
Our nodes have different interface names, so I detect it at runtime from/sys/class/netinstead of hardcoding. Without this, Gloo bootstrap fails. - Move the Triton JIT cache off the shared filesystem
(TRITON_CACHE_DIR=/tmp/triton-cache-rank$RANK). With$HOMEon shared fs, 16 ranks
JIT-compiling the same kernel race on the cache's tmp-file + rename pattern and
crash withFileNotFoundErrorduring CUDA graph capture.
Measured performance (SGLang, TP16+EP16, marlin, bf16 KV)
Generation benchmark, 512-token completions, reasoning_effort=low:
| Concurrency | Aggregate tok/s | Per-request latency (p50 / max) |
|---|---|---|
| 1 | 16.8 | 28.3 s |
| 4 | 30.0 | ~28 s |
| 8 | 43.9 | ~31 s |
| 16 | 76.9 | ~43 s |
| 32 | 84.4 | 57 s / 89 s |
| 54 | 146.9 | 60 s / 102 s |
- TTFT: 0.37–0.54 s (short prompts, warm server)
- Throughput was still scaling at 54 concurrent (the highest CUDA-graph batch size
captured in this config) — with a larger--cuda-graph-max-bsor the
high-throughput profile, expect more. - Note: Kimi-K3 is always-thinking; per-request latency includes reasoning tokens.
16.8 tok/s single-stream is the marlin dequant cost on Hopper — Blackwell with
native MXFP4 paths will be substantially faster.
What didn't work: vLLM kimi-k3 branch on H200
I tried the vLLM route first (vllm/vllm-openai:kimi-k3, since K3 support has not
landed in main/nightly yet). On H200 it currently has a weight-loading memory bug
that makes 141GB GPUs infeasible regardless of parallelism:
| Parallelism | Expected weights/GPU | Measured (Model loading took) |
|---|---|---|
| TP16 (2 nodes) | ~98 GB | 130.2 GB |
| TP32 (4 nodes) | ~49 GB | 127.3 GB |
| TP16 + EP16 | ~98 GB | 130.2 GB |
| TP8 + PP4 | ~49 GB | 47 GB (but PP crashes, see below) |
Per-GPU weight memory does not decrease when doubling GPUs (130 → 127 GB from
TP16 to TP32), which points to a large component being replicated per-rank instead
of sharded in the K3 branch's loader. SGLang loading the same checkpoint with the
same marlin backend lands at 102.75 GB/GPU, confirming the checkpoint itself is fine.
With 130GB weights + runtime overhead, KV cache comes up 1–2 GB short even atgpu-memory-utilization 0.97 and max-model-len 65536 (vLLM estimated max context
22016 — unusable).
Other H200-specific landmines hit on the vLLM branch, for the record:
VLLM_ENABLE_K3_LATENT_MOE_TAIL_FUSION=1(recommended in the recipe's Hopper
profile) raisesValueError: K3 latent-MoE tail fusion requires SM100.— it's
Blackwell-only; don't set it on H200.- Pipeline parallel (TP8+PP4) loads fine but crashes in CUDA graph capture with
RuntimeError: cp_world_size must be positivefrom the MLA attention path —
PP appears unsupported on the K3 branch (the recipe also lists no PP strategy). --load-format fastsafetensorsstages one full16GB shard per rank with33 GB transient per GPU) — combined with the inflated weights
double-buffering (
it OOMs during loading. With the EP loader path it was worse (127 GB at 91%
loading progress on a config whose steady state should be ~49 GB).
Notes for anyone reproducing
- 8× B300/GB300 remains the intended single-node target for K3. On Hopper you pay
the marlin W4A16 dequant tax and need 2× 8-GPU nodes minimum. - The SGLang H200 profiles are marked
verified: false / in-progressin the
cookbook as of 2026-07-28, but the balanced profile worked as-is. - Multi-turn users: remember K3 requires passing back the full assistant message
includingreasoning_contentandtool_calls, not justcontent. - Startup timeline (cold start, weights on shared fs with warm FS cache):
process launch → distributed init + model build25 s → weight load 669 s1.56 TB,
(load_format=auto) → decode CUDA graph capture 39 s (11 batch
sizes up to bs=54) → warmup → ready in ~13 min total.
Following are the 2 scripts I use (generated):
run_node_sglang.sh
#!/bin/bash
# 在容器内由 srun 每节点执行一次。依赖外部传入:
# NODE0_IP, MODEL_PATH, HOST_PORT, TP_SIZE, EP_SIZE, NNODES, MEM_FRACTION
set -euo pipefail
NODE_RANK=$SLURM_PROCID
# 跨节点 NIC 必须在所有 rank 上显式指定 (SGLang H200 multiNodeHints 要求),
# 各节点网卡名不同, 运行时探测: 取默认路由所在接口。容器镜像可能无 ip 命令,
# 故从 /sys 读取而非依赖 iproute2。
detect_iface() {
local best="" max=0 sz
for d in /sys/class/net/*; do
n=$(basename "$d")
case "$n" in lo|docker*|veth*|br-*|virbr*) continue ;; esac
[ -e "$d/device" ] || continue
read -r sz < "$d/speed" 2>/dev/null || sz=0
[ "$sz" -gt "$max" ] 2>/dev/null && { max=$sz; best=$n; }
[ -z "$best" ] && best=$n
done
echo "$best"
}
IFACE=$(detect_iface)
LOCAL_IP=$(cat /sys/class/net/"$IFACE"/address >/dev/null 2>&1 && hostname -I | awk '{print $1}')
export NCCL_SOCKET_IFNAME="$IFACE"
export GLOO_SOCKET_IFNAME="$IFACE"
export SGLANG_HOST_IP="$LOCAL_IP"
# EFA: 用宿主机挂进来的 libfabric + efa
# export LD_LIBRARY_PATH to include efa related libs if needed
export FI_PROVIDER=efa
export FI_EFA_USE_DEVICE_RDMA=1
# Triton JIT 缓存放节点本地盘: 默认落到 $HOME 共享盘时, 多 rank 并发
# JIT 同一 kernel 的 tmp+rename 互踩, FileNotFoundError (job 36)
export TRITON_CACHE_DIR="/tmp/triton-cache-rank${NODE_RANK}"
# SGLang H200 unified/balanced 档指定的 env
export NCCL_MNNVL_ENABLE=1
export NCCL_CUMEM_ENABLE=1
export SGLANG_ENABLE_TP_MEMORY_INBALANCE_CHECK=0
echo "[rank ${NODE_RANK}] host=$(hostname) iface=${IFACE} ip=${LOCAL_IP}"
exec sglang serve \
--trust-remote-code \
--model-path "$MODEL_PATH" \
--tp-size "$TP_SIZE" \
--nnodes "$NNODES" \
--node-rank "$NODE_RANK" \
--dist-init-addr "${NODE0_IP}:20000" \
--ep-size "$EP_SIZE" \
--moe-runner-backend marlin \
--decode-attention-backend flashmla \
--enable-symm-mem \
--mem-fraction-static "$MEM_FRACTION" \
--reasoning-parser kimi_k3 \
--tool-call-parser kimi_k3 \
--host 0.0.0.0 \
--port "$HOST_PORT"
serve_2node_sglang.slurm
#!/bin/bash
#SBATCH --job-name=k3-sgl
#SBATCH --partition=p5e
#SBATCH --nodes=2
#SBATCH --ntasks-per-node=1
#SBATCH --gpus-per-node=8
#SBATCH --cpus-per-task=96
#SBATCH --mem=0
#SBATCH --exclusive
#SBATCH --time=7-00:00:00
#SBATCH --output=/home/ubuntu/workspace/kimi-k3-deploy/logs/sgl_%j.out
#SBATCH --error=/home/ubuntu/workspace/kimi-k3-deploy/logs/sgl_%j.err
###############################################################################
# Kimi-K3 —— SGLang 引擎
#
# 参数全部取自 SGLang 官方 cookbook 的 h200 / unified / balanced 档
# (docs.sglang.io/cookbook/autoregressive/Moonshotai/Kimi-K3.md):
# TP16 + EP16, moe-runner-backend marlin, decode-attention-backend flashmla,
# --enable-symm-mem, --mem-fraction-static 0.85
# H200 官方节点数就是 2×8, 与 vLLM 侧 job 31 同规模, 便于对比。
#
# 注意 (相对 vLLM 侧的已知情况):
# - SGLang H200 档同样用 marlin, 所以每卡权重大概率仍是 ~130GB
# (H200 无原生 MXFP4 硬件, 必须重打包成 W4A16, 体积涨 ~33%)
# - 官方 mem-fraction-static 只有 0.85, 比我vLLM 侧的 0.97 保守很多;
# 若 KV cache 不够, 先往上调这个值, 再考虑降 context
# - 三档 H200 配置在官方文档里均为 verified:false / in-progress,
# 成熟度与 vLLM recipe 的 H200 相当, 不是"更稳"的选择
#
###############################################################################
set -euo pipefail
export MODEL_PATH="/home/ubuntu/models/Kimi-K3"
export HOST_PORT=30000
export TP_SIZE=16
export EP_SIZE=16
export NNODES=2
export MEM_FRACTION=0.85
IMAGE="docker://lmsysorg/sglang:kimi-k3"
RUN_SCRIPT=/home/ubuntu/workspace/kimi-k3-deploy/sglang/run_node_sglang.sh
HEAD_NODE=$(scontrol show hostnames "$SLURM_JOB_NODELIST" | head -n1)
export NODE0_IP=$(srun --nodes=1 --ntasks=1 -w "$HEAD_NODE" hostname -i | awk '{print $1}')
echo "============================================"
echo "Kimi-K3 SGLang 2-node TP16+EP16 (p5e)"
echo "Nodes: $SLURM_JOB_NODELIST"
echo "Head: $HEAD_NODE ($NODE0_IP)"
echo "API: http://${NODE0_IP}:${HOST_PORT}/v1"
echo "============================================"
srun --container-image="$IMAGE" \
--container-mounts=/home:/home \
--export=ALL \
bash "$RUN_SCRIPT" \
2>&1 | tee /home/ubuntu/workspace/kimi-k3-deploy/logs/sgl_server_${SLURM_JOB_ID}.log
Hi @local0state , I see that you closed the discussion. Have you found a solution to get Kimi K3 working with vLLM with 2x8 H200 ?