[Kimi] Support kimi-k3 (#32541)

Co-authored-by: DarkSharpness <76582120+DarkSharpness@users.noreply.github.com>
Co-authored-by: Xiaoyu Zhang <1182563586@qq.com>
Co-authored-by: Mick <mickjagger19@icloud.com>
Co-authored-by: Yuhao Yang <47235274+yhyang201@users.noreply.github.com>
Co-authored-by: Cheng Wan <54331508+ch-wan@users.noreply.github.com>
Co-authored-by: Ke Bao <ispobaoke@gmail.com>
Co-authored-by: Baizhou Zhang <sobereddiezhang@gmail.com>
Co-authored-by: Chunan Zeng <zcnrex@gmail.com>
Co-authored-by: Khoa Pham <khoa.pham@radixark.ai>
Co-authored-by: Ziyi Xu <ziyi.xu@radixark.ai>
Co-authored-by: Zijie Xia <37504505+zijiexia@users.noreply.github.com>
Co-authored-by: Yuwei An <ayw.sirius19@gmail.com>
Co-authored-by: zhangxiaohao <1024393531@qq.com>
Co-authored-by: Yangmin Li <yangminl@nvidia.com>
Co-authored-by: Julien Lin <jullin@nvidia.com>
Co-authored-by: Hao Phan <htphan@nvidia.com>
Co-authored-by: Thomas Wang <1am9trash@gmail.com>
Co-authored-by: RolaoDenthu <xinyisong0111@gmail.com>
Co-authored-by: pigeonsoup <32922982+pigeonsoup@users.noreply.github.com>
Co-authored-by: HaiShaw <hixiao@gmail.com>
Co-authored-by: Xinyuan Tong <115166877+JustinTong0323@users.noreply.github.com>
Co-authored-by: Pranjal Shankhdhar <pranjal.ssh@gmail.com>
Co-authored-by: Lee Nau <lee.nau@gmail.com>
Co-authored-by: HMING <126185151+Hearum@users.noreply.github.com>
Co-authored-by: elvischenv <219235043+elvischenv@users.noreply.github.com>
Co-authored-by: Byron Hsu <byronhsu1230@gmail.com>
Co-authored-by: Byron Hsu <byron+per@periodiclabs.ai>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Thomas Wang <thomawan@amd.com>
Co-authored-by: Xinyi Song <86638975+RolaoDenthu@users.noreply.github.com>
Co-authored-by: Mohammad Miadh Angkad <176301910+mmangkad@users.noreply.github.com>
Co-authored-by: Cheng Wan <cheng.wan@radixark.ai>
Co-authored-by: BBuf <xiaoyu.zhang@radixark.ai>
Co-authored-by: Hanming Lu <hanminglu@meta.com>
Co-authored-by: Xinyi Song <xinyis10@illinois.edu>
This commit is contained in:
Liangsheng Yin
2026-08-04 13:22:49 -07:00
committed by GitHub
co-authored by DarkSharpness Xiaoyu Zhang Mick Yuhao Yang Cheng Wan Ke Bao Baizhou Zhang Chunan Zeng Khoa Pham Ziyi Xu Zijie Xia Yuwei An zhangxiaohao Yangmin Li Julien Lin Hao Phan Thomas Wang RolaoDenthu pigeonsoup HaiShaw Xinyuan Tong Pranjal Shankhdhar Lee Nau HMING elvischenv Byron Hsu Byron Hsu Claude Opus 5 Thomas Wang Xinyi Song Mohammad Miadh Angkad Cheng Wan BBuf Hanming Lu Xinyi Song
parent 0753663b8e
commit abddb1c7e9
139 changed files with 15414 additions and 911 deletions
@@ -1,102 +0,0 @@
"""Unit tests for DCP (Decode Context Parallelism) server args configuration.
Covers the ``--dcp-comm-backend`` field ({ag_rs, a2a, fi_a2a}) and its
validation in ``ServerArgs._handle_dcp_validation``:
- a2a / fi_a2a require --dcp-size > 1
- fi_a2a requires a CUDA platform (the authoritative MNNVL fabric probe runs
later, at model-runner init)
- dcp>1 requires CUDA or HIP (base behavior from the merged DCP PR)
Tests construct with safe defaults (dcp_size=1) then mutate the fields and call
``_handle_dcp_validation`` directly, so construction never trips the platform
gate; is_cuda / is_hip are patched per-test to pin the platform deterministically
(these are CPU-CI tests, where the real is_cuda() is False).
"""
import dataclasses
import unittest
from unittest.mock import patch
from sglang.srt.server_args import ServerArgs
from sglang.test.ci.ci_register import register_cpu_ci
from sglang.test.test_utils import CustomTestCase
register_cpu_ci(est_time=5, suite="base-a-test-cpu")
_mock_device = patch("sglang.srt.server_args.get_device", return_value="cuda")
_mock_device.start()
class TestDCPFieldDefaults(CustomTestCase):
"""Verify DCP-related dataclass fields exist with correct defaults."""
def test_dcp_size_field_exists(self):
fields = {f.name for f in dataclasses.fields(ServerArgs)}
self.assertIn("dcp_size", fields)
def test_dcp_comm_backend_field_exists(self):
fields = {f.name for f in dataclasses.fields(ServerArgs)}
self.assertIn("dcp_comm_backend", fields)
def test_dcp_size_default(self):
self.assertEqual(ServerArgs.dcp_size, 1)
def test_dcp_comm_backend_default(self):
self.assertEqual(ServerArgs.dcp_comm_backend, "ag_rs")
class TestDCPCommBackendValidation(CustomTestCase):
"""Verify ``_handle_dcp_validation`` accepts/rejects the right combos."""
@staticmethod
def _make_args(dcp_size, dcp_comm_backend):
# Construct with safe defaults (dcp_size=1) so __post_init__ never trips
# the dcp>1 platform gate, then set the fields under test.
args = ServerArgs(model_path="dummy")
args.dcp_size = dcp_size
args.dcp_comm_backend = dcp_comm_backend
return args
def test_a2a_requires_dcp_size_gt_1(self):
args = self._make_args(dcp_size=1, dcp_comm_backend="a2a")
with self.assertRaises(ValueError):
args._handle_dcp_validation()
def test_fi_a2a_requires_dcp_size_gt_1(self):
args = self._make_args(dcp_size=1, dcp_comm_backend="fi_a2a")
with self.assertRaises(ValueError):
args._handle_dcp_validation()
@patch("sglang.srt.server_args.is_hip", return_value=False)
@patch("sglang.srt.server_args.is_cuda", return_value=True)
def test_a2a_with_dcp_size_2_on_cuda_passes(self, *_):
args = self._make_args(dcp_size=2, dcp_comm_backend="a2a")
args._handle_dcp_validation() # no raise
self.assertEqual(args.dcp_comm_backend, "a2a")
@patch("sglang.srt.server_args.is_hip", return_value=False)
@patch("sglang.srt.server_args.is_cuda", return_value=True)
def test_fi_a2a_with_dcp_size_2_on_cuda_passes_server_args(self, *_):
# server_args accepts fi_a2a on CUDA; the MNNVL fabric probe is deferred
# to model-runner init (init_fi_a2a_workspace).
args = self._make_args(dcp_size=2, dcp_comm_backend="fi_a2a")
args._handle_dcp_validation() # no raise
self.assertEqual(args.dcp_comm_backend, "fi_a2a")
@patch("sglang.srt.server_args.is_hip", return_value=False)
@patch("sglang.srt.server_args.is_cuda", return_value=False)
def test_fi_a2a_on_non_cuda_raises(self, *_):
args = self._make_args(dcp_size=2, dcp_comm_backend="fi_a2a")
with self.assertRaises(ValueError):
args._handle_dcp_validation()
@patch("sglang.srt.server_args.is_hip", return_value=False)
@patch("sglang.srt.server_args.is_cuda", return_value=True)
def test_ag_rs_with_dcp_size_8_on_cuda_passes(self, *_):
args = self._make_args(dcp_size=8, dcp_comm_backend="ag_rs")
args._handle_dcp_validation() # no raise
self.assertEqual(args.dcp_size, 8)
if __name__ == "__main__":
unittest.main()
@@ -0,0 +1,89 @@
"""Unit tests for the MNNVL auto-inference gate.
The TP8 best-throughput launch used to require exporting
``SGLANG_ENABLE_CUSTOM_ALL_REDUCE_V2_MULTINODE=1`` by hand. It is now
capability-inferred; these cases pin the negative-branch contracts so a
refactor cannot silently turn the predicate into always-true (engaging fabric
paths on non-fabric clusters) or drop the explicit-off override.
"""
import unittest
from types import SimpleNamespace
from unittest.mock import patch
from sglang.srt.environ import envs
from sglang.srt.server_args import ServerArgs
from sglang.test.ci.ci_register import register_cpu_ci
from sglang.test.test_utils import CustomTestCase
register_cpu_ci(est_time=5, suite="base-a-test-cpu")
_HANDLE = ServerArgs._handle_custom_all_reduce_v2_multinode
def _cleared(*fields):
"""Context helper: run with the given env fields unset, restore after."""
import contextlib
import os
@contextlib.contextmanager
def ctx():
backup = {f.name: os.environ.pop(f.name, None) for f in fields}
try:
yield
finally:
for name, val in backup.items():
if val is None:
os.environ.pop(name, None)
else:
os.environ[name] = val
return ctx()
class TestCaV2MultinodeAuto(CustomTestCase):
def test_fabric_multinode_auto_enables(self):
"""GB200/GB300 + nnodes>1 + unset opt-in -> multinode mode on, v2 kept."""
with _cleared(
envs.SGLANG_ENABLE_CUSTOM_ALL_REDUCE_V2_MULTINODE,
envs.SGLANG_OPT_USE_CUSTOM_ALL_REDUCE_V2,
), patch("sglang.srt.server_args.is_mnnvl_fabric_device", return_value=True):
_HANDLE(SimpleNamespace(nnodes=2, tp_size=8))
self.assertTrue(envs.SGLANG_ENABLE_CUSTOM_ALL_REDUCE_V2_MULTINODE.get())
self.assertTrue(envs.SGLANG_OPT_USE_CUSTOM_ALL_REDUCE_V2.get())
def test_non_fabric_multinode_still_disables_v2(self):
"""Non-fabric multi-node keeps the legacy force-disable (the predicate
must not degrade to always-true)."""
with _cleared(
envs.SGLANG_ENABLE_CUSTOM_ALL_REDUCE_V2_MULTINODE,
envs.SGLANG_OPT_USE_CUSTOM_ALL_REDUCE_V2,
), patch("sglang.srt.server_args.is_mnnvl_fabric_device", return_value=False):
_HANDLE(SimpleNamespace(nnodes=2, tp_size=8))
self.assertFalse(envs.SGLANG_ENABLE_CUSTOM_ALL_REDUCE_V2_MULTINODE.get())
self.assertFalse(envs.SGLANG_OPT_USE_CUSTOM_ALL_REDUCE_V2.get())
def test_explicit_off_wins_over_fabric(self):
"""SGLANG_ENABLE_CUSTOM_ALL_REDUCE_V2_MULTINODE=0 on a fabric device
must still force-disable v2 (explicit off beats auto-detection)."""
with _cleared(envs.SGLANG_OPT_USE_CUSTOM_ALL_REDUCE_V2), patch(
"sglang.srt.server_args.is_mnnvl_fabric_device", return_value=True
), envs.SGLANG_ENABLE_CUSTOM_ALL_REDUCE_V2_MULTINODE.override("0"):
_HANDLE(SimpleNamespace(nnodes=2, tp_size=8))
self.assertFalse(envs.SGLANG_ENABLE_CUSTOM_ALL_REDUCE_V2_MULTINODE.get())
self.assertFalse(envs.SGLANG_OPT_USE_CUSTOM_ALL_REDUCE_V2.get())
def test_tp16_not_auto_opted_in(self):
"""CustomAllReduceV2 supports world sizes 2..8 only; a TP16 fabric
launch must not auto-set the multinode opt-in (it would log
'enabling' and then silently fall back downstream)."""
with _cleared(
envs.SGLANG_ENABLE_CUSTOM_ALL_REDUCE_V2_MULTINODE,
envs.SGLANG_OPT_USE_CUSTOM_ALL_REDUCE_V2,
), patch("sglang.srt.server_args.is_mnnvl_fabric_device", return_value=True):
_HANDLE(SimpleNamespace(nnodes=2, tp_size=16))
self.assertFalse(envs.SGLANG_ENABLE_CUSTOM_ALL_REDUCE_V2_MULTINODE.is_set())
if __name__ == "__main__":
unittest.main()