Kimi-K3

Kimi-K3

Kimi-K3은 Moonshot AI의 플래그십 하이브리드 MoE 비전-언어 모델로, 2.8조 파라미터, 토큰당 활성 전문가 16/896개, Kimi-K2 대비 약 2.5배의 스케일링 효율을 가지는 모델이에요. 이 페이지에서는 SGLang에서 Kimi-K3를 설치·배포·호출하는 방법과 추론, 툴 호출, HiCache, PD 분리, VLM 서빙, 대규모 서빙 프리셋까지 상세히 설명해요.

출처: 문서

본문

Deployment (배포)

SGLang 설치

설치 방법과 하드웨어 플랫폼에 대한 모든 내용은 공식 SGLang 설치 가이드를 참고해요. 아래 두 경로는 명령 패널의 Python / Docker 토글과 일치해요.

Python (pip / uv) — 우선 Python 환경에 SGLang을 설치해요.

pip install --upgrade pip
pip install uv
uv pip install --prerelease=allow sglang

그런 다음 아래 명령 패널의 Python 출력을 해당 환경에서 실행해요.

Docker — NVIDIA와 AMD용 Docker 이미지를 받아요.

docker pull lmsysorg/sglang:latest                                  # NVIDIA (CUDA)
docker pull lmsysorg/sglang-rocm:v0.5.19-rocm720-mi35x-20260916     # AMD MI350X / MI355X (ROCm)

이미지 실행 방법은 Install → Method 3: Using Docker를 참고해요. 내부의 sglang serve ...를 아래 명령 생성기가 만든 결과로 대체해요.

NPU — Ascend 시리즈용 이미지를 받아요.

docker pull quay.io/ascend/sglang:main-cann9.0.0-a3   # Ascend A3 Series
docker pull swr.cn-southwest-2.myhuaweicloud.com/base_image/dockerhub/lmsysorg/sglang:cann9.1.0-950-B070   # Ascend 950PR/DT Series

호스트와 플랫폼 설정은 NPU 설치 가이드퀵 스타트 가이드를 참고해요.

NPU 가중치 (Weights): Kimi-K3 (950PR/DT Series, MXFP4) · Kimi-K3-W4A8 (A3 Series, W4A8, 1.49 TB) · Kimi-K3-DSpark (DSPARK draft, 4.5 GB)

하드웨어 선택

하드웨어를 고른 다음 배포 형태(shaping)와 운영 지점을 선택해요. 노드 수는 하드웨어 레시피를 따라가므로 별도 선택이 아니에요 (B200 2×8, GB200 4×4, H100 4×8, B300 1×8, H200 2×8 — Unified High-Throughput에서는 4×8, GB300 2×4, MI350X/MI355X 1×8, Ascend A3 Series 4×8 — 32 카드 / 64 다이, Ascend 950PR/DT Series 4×8). NVFP4 체크포인트(nvidia/Kimi-K3-NVFP4, 아래 패널의 Quantization 행)를 서빙한다면 lmsysorg/sglang:dev-dev-kimi-k3-nvfp4 이미지를 사용해요.

PD ModeUnified는 prefill과 decode를 함께 서빙해요. Prefill / Decode는 이들을 전용 풀로 분리해요(PD disaggregation 참고). Prefill은 두 가지 전략을 제공하며 둘 다 16k로 청킹되요. 8-GPU 플랫폼(B300 1×8, GB300 2×4)에서 Default는 TP8, Long-Context--pp-size 8 --tp-size 1이에요. 16-GPU 플랫폼(B200 2×8, GB200 4×4)에서는 둘 다 --pp-size 16 --tp-size 1이며 --mem-fraction-static(0.85 vs 0.90)만 달라요 — 거기서 deep PP는 long-context 전용이 아니라 처리량 형태예요(Deep PP 참고).

Strategy — 그 형태 안에서의 운영 지점이에요.

  • Low-Latency — DCP가 없어 MLA KV가 TP-replicated 상태로 유지돼요. 채팅용. B200은 두 노드를 PP2 × TP8로 나누고, 다른 모든 플랫폼은 평평한 TP예요.
  • Balanced — 정확도 보존 기본값: B200에서 PP2 × DCPEP8(두 파이프라인 스테이지와 DCP8이 KV와 KDA 상태를 나눔), GB200에서 TP16/DCP16, B300/GB300에서 TP8/DCP8, MI35x에서 TP8/DCP8 ROCm/AITER.
  • High-Throughput — 대규모 레인: Playground에서 Cluster SizeLarge-Scale Preset을 골라요. 셀 자체는 Balanced이며, H100(extra_buffer_lazy 추가)과 H200(4×8 TP32/EP32, --mem-fraction-static 0.90)은 예외예요.

Long-ContextPrefill PD 모드에서만 나타나요. B200에서 long-context unified 서빙을 하려면 High-Throughput에서 시작해 --context-length를 높여요.

Spec Decode — B200을 제외한 모든 플랫폼에서 전략을 바꾸지 않고 그 위에 얹어요. DSPARK는 스텝당 7개의 드래프트 토큰을 제안하며(Playground에서 튜닝) pp_size == 1을 요구해요. 그래서 B200에서는 파이프라인을 버리고 같은 16개 GPU를 평평하게 재배치해요: PP2 × TP8 → TP16, PP2 × DCPEP8 → DCPEP16. DFLASH는 Kimi-K3-DFlash 드래프트를 block size 8로 사용해요. 파이프라인 병렬이나 DP attention을 아직 지원하지 않으므로 pipelined B200 Unified 레시피에서는 사용할 수 없어요. Blackwell에서만 검증되었기 때문에 Hopper와 AMD 레시피에는 아직 없어요. 이득은 짧은 인터랙티브 트래픽에서 가장 크고 프롬프트가 길어질수록 줄어들어요.

`--mamba-full-memory-ratio`는 실시간으로 계산되는 하나의 크기 조정 플래그예요. [Mamba ratio calculator](#mamba-ratio-calculator)에서 평균 요청 길이를 설정하고, 나머지는 패널을 따르며 결과가 명령에 고정돼요. (Ascend NPU 레시피는 계산기를 사용하지 않으며 ratio를 설정하지 않아요 — Ascend 경로가 두 풀을 자체적으로 크기 조정해요: A3 Series는 `--max-mamba-cache-size`를 고정하고, A5 레시피는 radix cache를 끄고 서빙해요.) B300 1×8 Unified 속도 수치는 `v0.5.18 @ 71de97b2`에서 `--random-range-ratio 1.0`, `--warmup-requests 64`, `--flush-cache`, ISL 8192 / OSL 1024로 측정돼요. DSPARK 셀은 수용 길이를 serve env `SGLANG_SIMULATE_ACC_LEN=4.5`로 고정해요 — block size 7이 그 수용도에서 무엇을 제공하는지를 보고하며, 이 워크로드에 대해 측정된 수용률은 아니에요. Balanced DSPARK는 `--max-running-requests 256`을 추가해요. 없으면 스펙이 상한을 48로 리셋해요. KDA 상태 풀은 여전히 수용을 101/68/91/60 개의 동시 요청(MXFP4 NOSPEC / MXFP4 DSPARK / NVFP4 NOSPEC / NVFP4 DSPARK)으로 제한하는데, 그래서 Balanced에 대해 concurrency 64 이후의 지점은 게시되지 않아요.

AMD AITER with DCP8

MI350X/MI355X unified Balanced 레시피는 TP8/DCP8을 AITER prefill과 decode attention과 함께 사용해요. DCP는 타깃 MLA KV cache를 샤딩하고, RadixArk DSPARK 드래프트 KV는 replicated로 유지돼요. 고정된 v0.5.19-rocm720-mi35x-20260916 이미지는 SGLang 리비전 e7f7447333을 기록하며, 여기에는 AITER DCP support (#34432)DCP KV-free fix (#38941)가 포함돼요. DCP에 소스 오버레이(source overlay)는 필요 없어요.

이 이미지에서는 SGLANG_K3_KDA_FUSED_BACKEND를 설정하지 않은 채로 유지해요. 별도의 fused-KDA 옵트인은 deferred-gate fix (#39066)가 필요하며, 이 이미지에는 포함되지 않아요. 이 업데이트된 레시피는 여전히 Final Verification In Progress 상태이며, 기록된 속도 수치는 원래 구성을 사용하고 새 이미지나 DCP8 레시피를 검증하지 않아요.

Mamba ratio calculator

--mamba-full-memory-ratio 계산 방법 — 이 값은 KDA 상태 풀과 MLA KV 풀 사이의 비율이에요. 아래 파라미터 중 L을 제외한 모든 값은 Deploy 패널과 Playground 선택에서 실시간으로 읽히며, balanced 값은 요청당 비용 비율이에요:

ratio = (S + D) x state_bytes / (L x (mla_kv_bytes / DCP + draft_kv_bytes))
  • S — 요청당 KDA 상태 슬롯: extra_buffer=5, extra_buffer_lazy=4, no_buffer=3, radix cache 비활성=1. SGLANG_OPT_MAMBA_SKIP_DECODE_LOCK은 extra-buffer 전략에서 슬롯 하나를 해제해요. overlap 스케줄러가 꺼져 있거나(pp > 1이면 비활성) track 버퍼가 슬롯 하나 대신 두 개를 차지해요.
  • D — 추측 디코딩 아래의 verify 중간 상태: 비활성이면 0, 그 외에는 DSPARK block size + 1(7 기본값에서 8). ReplaySSM(--enable-linear-replayssm-spec)은 이를 슬롯당 링으로 접어 D0으로 돌려요.
  • state_bytes — K3의 고정 지오메트리, attention-TP 폭, SSM dtype에서 나오는 상태 슬롯 하나의 바이트.
  • mla_kv_bytes — 토큰 하나의 MLA latent KV 바이트(KV-dtype 의존). DCP가 이를 rank들로 샤딩해요. DSPARK 드래프트 모델의 KV(토큰당 약 1.4 KB)는 모든 rank에 replicated되므로 평평하게 들어가요 — DCP 없이는 무시할 수 있고, DCP8 아래에서는 샤딩된 MLA share와 같은 차수예요.
  • L — 토큰 단위 평균 총 요청 길이: 입력 + 출력.

Advanced Features Playground

Playground는 배포 행렬을 넘어선 SGLang 기능을 실험하는 곳이에요. 위의 Deploy 패널은 SGLang 팀이 수렴 중인 레시피를 내보내고, Playground는 Deploy 패널이 현재 보여주는 셀 위에 추가 노브를 켤 수 있게 해줘요.

1. Model Introduction (모델 소개)

Kimi-K3는 Moonshot AI의 플래그십 하이브리드 MoE 비전-언어 모델이에요: 2.8조 파라미터, 토큰당 활성 전문가 16/896개, Kimi-K2 대비 약 2.5배의 스케일링 효율. 백본은 93개 레이어에 걸쳐 **Kimi Delta Attention (KDA)**과 MLA를 인터리브해요(Attention Residuals와 Stable LatentMoE 포함). 서빙은 이미지 입력과 prefix caching이 있는 1M-토큰 윈도우를 지원해요. 가중치는 MXFP4로 배포돼요: FlashInfer MXFP4(trtllm-gen SiTU) 러너가 Blackwell에서 서빙하고, Marlin(W4A16)은 그 외, MegaMoE는 short-context 배치 처리량용이에요.

K3는 항상 thinking을 활성화하고, 추론 깊이는 reasoning_effort(low / high / max; 기본 max)로 제어돼요.

Kimi-K3는 Moonshot AI의 첫 조(兆)-클래스 이상 오픈소스 모델이며, **전체 모델 가중치는 2026년 7월 27일까지 공개 예정**이에요. 이 페이지의 레시피는 공개 [`sgl-project/sglang` `kimi-k3` 브랜치](https://github.com/sgl-project/sglang/tree/kimi-k3)에서 검증되었어요 — HuggingFace 리포(`moonshotai/Kimi-K3`)와 K3 지원이 포함된 공개 `lmsysorg/sglang` 이미지는 출시 시 제공될 거예요.

B300 1×8 Unified Low-Latency와 Balanced 셀은 Verified — 최종 가중치에 대한 속도 라운드가 아래 게시돼요. 다른 모든 셀은 여전히 Final Verification In Progress로 표시돼요: 레시피는 실행되지만 최종 가중치와 현재 코드에 대한 서빙 라운드는 여전히 열려 있어요. 어느 셀에서도 정확도는 재측정되지 않았어요 — 의존하기 전에 재측정해요.

권장 생성: temperature=1.0, top_p=0.95, presence_penalty=0, frequency_penalty=0(모델이 고정 — 정보용이며 샘플 코드에 하드코딩하지 말 것).

리소스: HuggingFace · Kimi-K3 Quickstart

2. Configuration Tips (설정 팁)

메모리: 두 풀, 하나의 플래그. K3는 정적 메모리를 worst-case 예약 KDA 상태 풀(동시성 상한을 설정)과 페이징 MLA KV 풀로 나누며, --mamba-full-memory-ratio로 나눠요. 명령 패널은 이 플래그를 계산기의 출력에 고정해요 — 평균 요청 길이를 거기 설정하고, 나머지 계산기 입력은 패널을 따르면 돼요. (Ascend NPU 레시피에서는 계산기와 ratio 플래그가 없어요: Ascend 경로가 두 풀을 자체적으로 크기 조정해요 — A3 Series는 --max-mamba-cache-size를 고정하고, A5 레시피는 radix cache를 꺼요.) 부팅 후 max_total_num_tokens(KV 쪽)와 수용된 요청 상한(상태 쪽)을 읽어 확인해요.

용량 레버는 모두 Playground에 있어요. 각각은 정밀도나 캐시 동작을 용량으로 바꾸므로, 워크로드에서 정확도를 재검증해요.

레버 효과
--mamba-radix-cache-strategy extra_buffer_lazy 요청당 상태 슬롯 5개 대신 4개
--mamba-ssm-dtype bfloat16 상태 바이트 절반으로; 스펙 켜면 KDA 검증이 fused 커널에서 Triton으로 폴백
--kv-cache-dtype fp8_e4m3 토큰당 KV 바이트 절반; PD 아래에서는 두 역할 모두 connect에서 일치해야 함
--mem-fraction-static 0.90–0.92 부팅 로그에 큰 유휴 avail mem이 보일 때 가장 싼 첫 승리
SGLANG_OPT_MAMBA_SKIP_DECODE_LOCK=1 요청당 슬롯 하나 더 해제 (실험적, 검증 중)

추측(Speculation): DSPARK는 요청당 block size + 1 (= 8)개의 중간 상태를 보유해요 — 계산기가 이를 반영해요 — 그리고 설정하지 않은 --max-running-requests는 스펙 아래에서 48로 리셋돼요 (명령 패널이 알려주며, 높이려면 명시적으로 설정해요).

MoE 러너. Blackwell에서 --moe-runner-backend를 설정하지 않은 채로 둬요: FlashInfer MXFP4(W4A8, 공식 trtllm-gen SiTU 커널)가 선택되고, H100/H200은 Marlin을 고정해요. B200 Balanced와 High-Throughput 셀은 flashinfer_mxfp4을 명시적으로 고정하는데, 그것이 이들이 구축된 형태이기 때문이에요.

Attention 백엔드. Blackwell에서 세 attention 노브를 모두 설정하지 않은 채로 둬요: K3는 prefill, decode, 그리고(DSPARK 아래) 검증을 하나의 세트로 해결해요(trtllm_mla 전체; cutedsl_mla는 DCP 아래 decode와 검증을 담당). 비-DCP 레시피에서 셋 중 하나를 설정하면 나머지의 자동 해결이 취소돼요. B200 Balanced와 High-Throughput 셀은 --decode-attention-backend cutedsl_mla를 고정하는데, 이것이 자동 해결이 그 DCP 레시피에 대해 선택하는 것과 같아요 — 해결을 바꾸기 때문이 아니라 이들이 구축된 형태이기 때문에 적어둔 거예요. H100/H200은 decode에 flashmla를 고정해요.

컨텍스트 길이. --context-length은 수용되는 가장 긴 요청과 일부 컨텍스트 스케일 버퍼를 제한해요. KV 풀 크기를 정하지는 않아요. long context에서 용량을 추가하는 레버는 fp8_e4m3 KV예요.

DSPARK. 보여지는 전략 위에 --speculative-algorithm DSPARK와 드래프트 체크포인트를 추가해요. --speculative-draft-attention-backend는 설정하지 않은 채로 둬요. 게시된 B300 DSPARK 수치는 SGLANG_SIMULATE_ACC_LEN으로 수용 길이를 고정하므로, 실제 워크로드에 대한 측정 수용률은 아직 없어요 — 채택 전에 NOSPEC과 같은 레시피로 측정해요.

플랫폼별 참고:

플랫폼 토폴로지 참고
B300 1×8 TP8 (+DCP8) Low-Latency와 Balanced에서 accuracy-first 기본값
GB300 2×4 TP8/DCP8 MNNVL 전송과 cuMem 자동 감지
B200 2×8 Low-Latency에서 PP2 × TP8, Balanced·High-Throughput에서 PP2 × DCPEP8. DSPARK가 같은 16개 GPU를 TP16 / TP16+DCP16+EP16으로 재배치. PD prefill은 TP1 × PP16 Unified가 세 운영 지점을 모두 서빙; Long-ContextPrefill-only 전략
GB200 4×4 TP16/DCP16 MNNVL 자동 감지
H200 2×8 (Unified High-Throughput에서 4×8) TP16/EP16 + symm-mem, Marlin + FlashMLA; High-Throughput은 4노드에 걸쳐 TP32/EP32, mem-frac 0.90, extra_buffer_lazy 모든 노드에서 같은 block; 노드 간 NIC export(GLOO_SOCKET_IFNAME / NCCL_SOCKET_IFNAME, SGLANG_HOST_IP); NCCL_MNNVL_ENABLE=1 NCCL_CUMEM_ENABLE=1 유지
H100 4×8 TP32/EP32, Marlin + FlashMLA K3 이미지의 SM90a 빌드; 모든 노드에서 NCCL/Gloo를 같은 NIC에 고정; post-weight headroom이 가장 작음 (80 GB)
MI350X/MI355X 1×8 TP8/DCP8 ROCm/AITER (Unified Balanced) AITER A8W4 FlyDSL MoE, 샤딩된 타깃 MLA KV를 사용하는 AITER prefill/decode attention, graph bs 최대 256, fp8 kvcache; DSPARK 지원. Activation-quant 및 fused-KDA-decode 노브: AMD ROCm/AITER 환경
Ascend A3 Series 4×8 (32 cards / 64 dies) TP64/DP4 + DeepEP PD-mixed Unified only; DSPARK 내장; 모든 노드에서 GLOO/HCCL_SOCKET_IFNAME 고정
Ascend 950PR/DT Series 4×8 TP32/dp1 + DeepEP PD-mixed Unified only; DSPARK 내장; 공유 experts / dense MLP가 attention-TP에 걸쳐 샤딩(--shared-experts-tp-size 4); radix cache 꺼짐; 모든 노드에서 GLOO/HCCL_SOCKET_IFNAME 고정

Blackwell DCP 참고 — DCP 셀은 모든 Blackwell 플랫폼의 Balanced와 High-Throughput이며, UnifiedDecode 역할 모두에서:

  • DCP는 TP-replicated MLA KV를 샤딩하는 유일한 축이에요. Low-Latency는 이를 건너뛰어요.
  • --dcp-comm-backend는 설정하지 않은 채로 둬요(fabric-resolved: GB200/GB300에서 fi_a2a, B200/B300에서 a2a).
  • DCP 아래에서는 --enable-symm-mem 없음(decode-graph 정확성을 위해 강제 비활성).
  • 명시적 tokenspeed_mla--kv-cache-dtype을 fp8로 강제 재작성해요. 기본 cutedsl_mla는 어느 dtype이든 서빙해요.
  • 여기서 계산기 비율은 1을 훨씬 웃돌아요(r > 1 합법): bfloat16 상태는 수용을 사고, fp8 KV는 컨텍스트를 사요.
  • a2a backend와 EP를 함께 쓰지 마요: a2a 버퍼가 DCP가 확보한 KV를 다시 가져가요. 측정 목적으로만 구성해요. a2a backend는 --moe-a2a-backend가 설정될 때 켜져요.

검증된 두 B300 1×8 Unified 셀을 제외하고, 이 정확한 형태로 서빙 라운드가 있는 셀은 없어요 — 이것들을 시작점으로 여기고 검증해요.

AMD ROCm/AITER 환경 (MI350X / MI355X). MI35x 셀은 SGLANG_USE_AITER=1 SGLANG_AITER_K3_OPT=1 AITER_FLYDSL_FORCE=1 AITER_SITUV2_A8W4=1을 내보내요 — 처음 셋은 AITER ROCm 경로, 그것의 K3 특화 fused 커널, FlyDSL MoE 커널을 켜요. 이 표의 나머지는 그 위에서 바꿀 수 있는 항목이에요. 여기 모든 것은 gfx950/ROCm 전용이며 다른 곳에서는 무효해요. 이 노브들은 위에서 고정한 20260903 일일 ROCm 이미지에 처음 포함돼요 — 오래된 이미지에서는 단순히 읽히지 않아요 — 그리고 두 SiTU 행은 ROCm/aiter#4534(FlyDSL 0.3.0) 이상의 AITER 리비전도 필요해요.

Env var 기본값 효과
AITER_SITUV2_A8W4=1 unset GU-interleaved preshuffled weight layout의 AITER에서 A8W4 활성화 양자화를 가진 SiTU v2 MoE. 셀이 배포하는 성능 기본값.
AITER_SITUV2_A4W4=1 unset 대신 A4W4, 범용 separated shuffle layout. 수치적으로 맞지만 A8W4보다 느림 (8×MI35x에서 중간 출력 530.8 vs 537.3 tok/s). 둘 다 설정하면 A8W4가 우선 — SGLang은 AITER를 따르고 GU-interleaved layout을 유지.
SGLANG_K3_KDA_FUSED_BACKEND=aiter unset fused ROCm KDA decode 경계에 옵트인: f_b projection이 gfx950 FlyDSL 커널로 지연되어 decode가 f_b + convolution + recurrent state update + gated RMSNorm을 융합. 다른 값(또는 unset)은 unfused KDA 경로 유지.
SGLANG_K3_FLYDSL_SOURCE auto fused decode를 뒷받침하는 FlyDSL 구현: auto는 SGLang vendored 커널을 선호하고 AITER 모듈로 폴백, sglang / aiter는 하나를 고정. 둘을 bisect하지 않는 한 건드리지 마요.

fused KDA backend는 두 수준에서 fail-closed돼요: 모델 초기화 중에 플래그가 정확히 aiter 이고 gfx950 FlyDSL 커널이 importable일 때만 arm되고, 각 decode 단계는 dispatch 전에 shapes, dtypes, strides, state indices, 출력 버퍼를 재검증해요 — 예상치 못한 것은 에러 대신 스톡 KDA 구현으로 폴백돼요. Batch size 2는 별도로 검증된 커널 스케줄을 자동 선택하고, 다른 모든 배치는 원래 빌드 옵션을 유지해요. 69-레이어 그래프에서 측정 시 fused 경계는 9.20 → 8.38 µs/layer (−8.9%)이고, GSM8K 1319는 0.950.

3. Advanced Usage (고급 사용법)

3.1 Reasoning

K3는 항상 생각하며, kimi_k3 reasoning 파서(PlaygroundParsers 카드에서 Reasoning Parser 토글)가 그 thinking을 최종 답변에서 분리해요 — thinking은 message.reasoning_content에, 답변은 message.content에 들어가요. 추론 깊이는 reasoning_effort(low / high / max; 기본 max)로 제어해요.

from openai import OpenAI

client = OpenAI(base_url="http://localhost:30000/v1", api_key="EMPTY")
resp = client.chat.completions.create(
    model="moonshotai/Kimi-K3",
    messages=[{"role": "user", "content": "What is 15% of 240?"}],
    reasoning_effort="high",  # "low" | "high" | "max" (default max)
)
msg = resp.choices[0].message
print("Reasoning:", getattr(msg, "reasoning_content", None))
print("Answer:", msg.content)
Pending update...

3.2 Tool Calling

kimi_k3 tool-call parser를 활성화(PlaygroundParsers 카드에서 Tool Call Parser 토글)하면 message.tool_calls를 통해 구조화된 툴 호출이 표시돼요. K3는 thinking 모델이므로 후속 턴은 reasoning_contentcontent 모두에 텍스트를 넣을 수 있어요 — 둘 다 출력해요. (Ascend NPU 레시피 — A3 및 A5 — 에서는 아직 지원되지 않아요.)

from openai import OpenAI

client = OpenAI(base_url="http://localhost:30000/v1", api_key="EMPTY")
tools = [{
    "type": "function",
    "function": {
        "name": "get_weather",
        "description": "Get the current weather for a city",
        "parameters": {
            "type": "object",
            "properties": {"city": {"type": "string"}},
            "required": ["city"],
        },
    },
}]
resp = client.chat.completions.create(
    model="moonshotai/Kimi-K3",
    messages=[{"role": "user", "content": "What's the weather in Beijing?"}],
    tools=tools,
)
msg = resp.choices[0].message
print("Reasoning:", getattr(msg, "reasoning_content", None))
print("Tool calls:", msg.tool_calls)
Pending update...

3.3 HiCache (Hierarchical KV Caching)

K3의 하이브리드 HiCache는 페이징 MLA KV KDA/mamba 상태를 L1 (GPU) / L2 (host) / L3 (Mooncake)에 계층화해요 — 긴 다중 턴 워크로드를 위해 PlaygroundHiCache 카드에서 활성화해요.

  • DCP 레시피(Blackwell Balanced / High-Throughput, UnifiedDecode 역할)에서 L1+L2는 DCP를 유지해요, Spec Decode는 off 또는 DSPARK. B200에서는 DSPARK 파이프라인 붕괴도 이를 확장해요 (PP2 × DCPEP8 → DCPEP16).
  • 이 레시피에서 L3는 DCP 플래그를 없애요 (스토리지 키가 아직 dcp_rank-aware 하지 않음; 명령 힌트가 이를 알려주고 요청당 KV 용량이 줄어요). DCP만 빠져요: MLA KV는 TP-replicated로 되돌아가고 셀의 다른 병렬성은 유지되므로, B300/GB300/GB200은 순수 TP로, B200 Unified는 --pp-size 2 / --ep-size를 유지해요.
  • Low-Latency와 Hopper 레시피는 모든 티어를 그대로 가져요.

3.4 PD Disaggregation

PD는 prefill과 decode를 별도 서버 그룹으로 분리해요. K3는 하이브리드이므로 전송은 페이징 MLA KV KDA recurrent state 둘 다 옮겨요.

  • 전송: 셀은 NiXL(RDMA)을 내보내요. Mooncake은 Playground에서 계속 선택 가능해요.
  • 포트: prefill 30000, decode 30100(파생 ZMQ/dist 범위는 공유 호스트에서 충돌하지 않아야 해요). --prefill 뒤의 위치 8998--disaggregation-bootstrap-port와 일치해야 해요, 그렇지 않으면 decode 워커만 등록돼요.
  • Decode 상태 풀: chunk cache — 요청당 슬롯 하나. --mamba-radix-cache-strategy는 무효해요. --disaggregation-decode-extra-slots를 고정해 두세요: 고정하지 않으면 32개 미만 요청에서 배치의 두 배로 기본값이 되고 그 이상에서는 0으로 돼요.

Deep PP for prefill

Deep PP는 GPU당 하나의 파이프라인 스테이지를 갖는 --tp-size 1이에요 — B300/GB300에서 --pp-size 8, B200/GB200에서 --pp-size 16. TP/EP collective과 달리 Pipeline P2P는 다음 microbatch의 compute와 겹치고, 각 스테이지는 전체 레이어(KV와 상태의 깔끔한 슬라이스)를 소유해요. --tp-size 1은 또한 컨텍스트를 사는 요인이에요: TP1 위에서는 MLA KV가 TP rank에 걸쳐 replicated되므로 TP2 × PP8은 같은 메모리에서 TP1 × PP16의 토큰 수의 절반 정도를 보유해요.

  • GPU당 한 스테이지를 사용해요. 얕은 분할은 여전히 in-stage all-reduce를 지불하고 평평한 TP에 질 수 있어요.
  • 여러 요청이 flight에 있을 때만 이득이 돼요. 8-GPU 플랫폼에서 그래서 Default가 TP8을 유지하고, 16-GPU 플랫폼에서 deep PP는 Default 운영 지점에서도 승리하므로 두 전략 모두 이를 사용해요 — GB200에서 ISL 8192 / concurrency 32, PP16 × TP1은 4550 prefill tok/s/GPU에 도달했고, PP8 × TP2는 3596, TEP16은 2407, TP16은 1652. concurrency ~8 미만에서는 파이프라인이 채워지지 않아 TEP16이 대신 리드해요 (1947 vs 1227) — 그럴 때는 --tp-size 16 --ep-size 16을 사용해요.
  • DSPARK off(pp_size == 1 필요) — B200/GB200에서는 Default에도 적용돼요.
  • 하나의 prefill 역할을 여러 decode 역할로 팬아웃하고, decode 쪽의 in-transfer KV를 예산에 반영해요.
python3 -m sglang_router.launch_router \
  --pd-disaggregation \
  --prefill http://<prefill-host>:30000 8998 \
  --decode http://<decode-host>:30100 \
  --host 0.0.0.0 --port 8000 \
  --disable-circuit-breaker \
  --health-check-interval-secs 999999

그런 다음 클라이언트는 개별 역할 서버 대신 라우터(:8000)로 요청을 보내요.

3.5 VLM Serving Profiles

오픈소스 K3 서빙 계약은 현재 이미지 입력만 지원해요 — 프로세서는 비디오와 오디오 입력을 거부해요.

VLM feature transport

명령 선택기에서 VLM Transport를 사용해요. Auto는 토폴로지 인식 시작점이며, 어떤 구성이 모든 워크로드에서 가장 빠르다는 주장은 아니에요.

Picker 선택 Processor-to-scheduler feature path
Auto · single-node Unified CUDA CUDA IPC
Auto · Unified GB200/GB300 IMEX가 있으면 CUDA VMM, 아니면 CPU
Auto · PD 또는 다른 토폴로지 CPU
CPU CPU, GPU feature pool 없음

CUDA IPC와 CUDA VMM은 베이스 GPU에서 최대 SGLANG_MM_FEATURE_CACHE_MB(기본 1 GiB)를 예약하고, 꽉 차면 텐서별로 CPU로 폴백해요. 이 설정은 EPD 인코더 출력이나 PD KV/KDA 전송을 제어하지 않아요. K3는 이미 기본적으로 2개의 processor 워커와 16개의 I/O 워커를 사용하므로, 튜닝하지 않으면 이 플래그들을 설정하지 않은 채로 둬요.

VLM compatibility

Feature K3 동작
PD 지원. 이미지 처리와 ViT는 prefill에서 실행되고, PD 전송은 PD disaggregation에서 설명한 대로 페이징 MLA KV와 KDA recurrent state를 모두 옮겨요.
EPD 공개 kimi-k3 브랜치에서 지원. --encoder-only 비전 역할과 --language-only prefill 역할을 사용하고, 전체 EPD를 위해 일반 decode 역할을 추가해요. EPD 가이드 참고.
MM encoder DP 내장. K3는 TP rank에 걸쳐 완전한 이미지를 샤딩하므로, unified, PD-prefill, encoder-only 역할에서 --mm-enable-dp-encoder를 설정하지 않은 채로 둬요.
MM feature transport Processor-to-scheduler features 전용. EPD 인코더 출력과 PD KV/KDA 전송은 자체 backend를 사용해요.
ViT BCG unified와 encoder-only 역할과 호환되지만, 아래 HBM trade-off를 측정한 후 반복되는 encoder 모양에만 권장.

Should ViT BCG be enabled?

일반 서빙에서는 ViT BCG를 끄고, 반복되는 이미지 모양과 여유 HBM이 있는 ViT-only / EPD encoder 워크로드에만 SGLANG_VIT_ENABLE_CUDA_GRAPH=1을 활성화해요.

  • 이득은 encoder에 국한돼요 — full-model 서빙에서 안정적인 end-to-end TTFT/TPOT 이득은 없어요.
  • 각 캡처된 그래프는 HBM(graph + 항목별 메타데이터)을 유지해요. 자신의 모양에서 측정해요.
  • 기본 캐시는 두 번의 hit 후 캡처하고 6,144 토큰을 넘으면 eager로 폴백해요. 측정 없이 키우지 마요.

Low-HBM VLM

이 프로필은 피크 동시성보다 HBM 헤드룸 유지가 더 중요할 때 사용해요. GPU feature pool을 제거하고, ViT BCG를 비활성화하고, 컨텍스트 윈도우를 절반으로 줄이고, 동시성을 상한하고, 정적 메모리 타깃을 낮춰요:

sglang serve \
  --trust-remote-code \
  --model-path moonshotai/Kimi-K3 \
  --tp-size 8 \
  --context-length 65536 \
  --enable-symm-mem \
  --mem-fraction-static 0.82 \
  --mm-feature-transport cpu \
  --reasoning-parser kimi_k3 \
  --tool-call-parser kimi_k3 \
  --host 0.0.0.0 \
  --port 30000

--mem-fraction-static 0.82는 보수적인 B300 시작점이며 휴대용 최솟값이 아니에요: 시작 시 메모리 부족이 보고되면 0.85 쪽으로 올리고, HBM을 다른 워크로드에 돌려줘야 하면 컨텍스트/동시성을 먼저 줄여요. 정밀도 레버(fp8_e4m3 KV, bfloat16 SSM state)는 훨씬 더 많이 절약하지만 accuracy-gated 상태로 남아요.

3.6 Large-Scale Serving Presets (16–64 GPUs, Blackwell)

KDA 상태 풀은 동시성 상한이에요 — DP, EP, DCP는 이를 샤딩하지 않아요. 오직 attention-TP 폭, SSM dtype, 캐시 전략만 GPU당 비용을 바꿔요. MLA KV는 싸게 줄이거나(fp8) 중복 제거(DCP)할 수 있어요.

N = 8k GPU에서 두 개의 프리셋이 나와요:

프리셋 무엇을 맞바꾸는가 용도
Peak Throughputdp = k, attention-TP 8 상태가 8-way 샤딩. 단계별 KDA all-reduce는 하나의 8-GPU B200/B300 노드 안에 머물거나, MNNVL을 통해 두 4-GPU GB200/GB300 노드에 걸침. --kv-cache-dtype fp8_e4m3이 핵심 — bf16 KV는 replica당 128 요청에 맞지 않음. 최대 지속 TPS — 기본 대규모 형태.
Peak Capacity (+DCP8)dp = k + --dcp-size 8 attention-TP 그룹의 MLA KV를 중복 제거: 같은 엔진 처리량에서 동시성 상한 +72%, 약 1.8× ITL. 컨텍스트 ≥ ~16K, 또는 replica당 동시성이 128 초과.
  • Radix cache는 프리셋과 독립적이에요: prefix-free 트래픽(오프라인 배치, evals)에서는 꺼요(Playground의 Prefix Cache 카드) — 요청당 4–5개 대신 상태 슬롯 하나.
  • 완전 data-parallel 극한(--dp-size = GPU 수, attention-TP 1) — 64-GPU 스윕의 GPU당 ~3K tok/s 뒤의 형태 — 은 프리셋이 아니에요: 288 GB GPU 전용, radix 강제 off, 프리셋 형태와의 head-to-head 없음.

B200/B300에서 32 GPU의 Peak Throughput 프리셋 (4 노드 × 8; 모든 노드는 자신의 --node-rank로 같은 명령 실행). GB200/GB300에서 같은 32-GPU 모양은 8 노드 × 4를 사용하고, Playground는 --nnodes 8을 내보내요:

SGLANG_OPT_DEEPGEMM_MEGA_MOE_NUM_MAX_TOKENS_PER_RANK=20480 \
sglang serve \
  --trust-remote-code \
  --model-path moonshotai/Kimi-K3 \
  --tp-size 32 --ep-size 32 \
  --enable-dp-attention --dp-size 4 --enable-dp-lm-head \
  --nnodes 4 --node-rank <rank> --dist-init-addr <node0-ip>:20000 \
  --moe-a2a-backend megamoe --moe-runner-backend deep_gemm \
  --kv-cache-dtype fp8_e4m3 \
  --mamba-ssm-dtype bfloat16 \
  --mamba-radix-cache-strategy extra_buffer_lazy \
  --mem-fraction-static 0.92 \
  --reasoning-parser kimi_k3 --tool-call-parser kimi_k3 \
  --host 0.0.0.0 --port 30000

per-replica 형태를 고정하고 replica 수만 옮겨서 확장해요. 풀 크기 조정은 계산기 기반 --mamba-full-memory-ratio에 달려 있으며, 이것은 DP, DCP, 정밀도, 추측을 반영해요:

GPUs B200/B300 nodes GB200/GB300 nodes --tp-size / --ep-size --dp-size
16 2×8 4×4 16 2
32 4×8 8×4 32 4
64 8×8 16×4 64 8

Peak Capacity에서는 --dcp-size 8을 추가하고 Mamba ratio calculator로 풀 분할을 다시 도출해요.

두 프리셋 모두 Playground에서 한 번 클릭으로 사용할 수 있어요: Cluster SizeLarge-Scale Preset을 고르면 전체 명령이 보여지는 셀 위에 구성돼요.

프리셋이 이미 내린 결정:

  • MegaMoE + deep_gemm — K3의 SiTU 활성화로 이 대규모 DP/EP 처리량 프리셋이 사용하는 fused DeepGEMM all-to-all/MoE 경로.
  • SP-MoE와 shared-expert overlap은 EP a2a 아래에서 자동으로 작동해요. K3 all-reduce fusion은 그렇지 않아요.
  • Spec Decode는 Deploy 노브를 따름. 대형 배치에서 수용이 얇아져요. spec × EP × DP-attention은 8-GPU EP8 × DP2(전체 GSM8K)에서만 검증돼요 — 이 규모에서는 실험적.
어떤 프리셋도 최종 가중치에 대한 전체 서빙 라운드가 없어요. 상수는 측정된 단일·이중 노드 라운드와 64-GPU 스윕에서 유도돼요. 팔릿(fleet)을 확정하기 전에 워크로드에서 처리량과 정확도를 검증해요.

더 알아보기 (Learn more)