Files
vLLM/tests/distributed/test_kimi_linear_context_parallel.py
T
63ac04a61e [Kimi-K3] DCP support (#50484)
Signed-off-by: girasoley <girasoley@inferact.ai>
Signed-off-by: Summer Yang <girasoleyang@gmail.com>
Signed-off-by: 云挚 <ningyunxiao.nyx@antgroup.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: 云挚 <ningyunxiao.nyx@antgroup.com>
Co-authored-by: foraxe <73625538+foraxe@users.noreply.github.com>
Co-authored-by: Woosuk Kwon <woosuk@inferact.ai>
2026-08-10 12:54:26 -07:00

129 lines
3.8 KiB
Python

# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
import math
import pytest
from tests.conftest import VllmRunner
from tests.utils import create_new_process_for_each_test
from vllm import SamplingParams, TokensPrompt
MODEL = "moonshotai/Kimi-Linear-48B-A3B-Instruct"
def _make_tiny_overrides() -> dict:
linear_attn_config = {
"full_attn_layers": [4],
"head_dim": 128,
"kda_layers": [1, 2, 3],
"num_heads": 8,
"short_conv_kernel_size": 4,
"use_full_rank_gate": True,
}
return {
"bos_token_id": 1,
"eos_token_id": 2,
"pad_token_id": 0,
"vocab_size": 256,
"hidden_size": 256,
"head_dim": 32,
"intermediate_size": 512,
"num_hidden_layers": 4,
"num_attention_heads": 8,
"num_key_value_heads": 8,
"num_experts": None,
"num_experts_per_token": None,
"num_shared_experts": 0,
"q_lora_rank": 128,
"kv_lora_rank": 512,
"qk_nope_head_dim": 128,
"qk_rope_head_dim": 64,
"v_head_dim": 128,
"mla_use_nope": True,
"mla_use_output_gate": True,
"linear_attn_config": linear_attn_config,
"max_position_embeddings": 512,
"model_max_length": 512,
}
def _run_tiny_model(
vllm_runner: type[VllmRunner], dcp_size: int
) -> list[tuple[list[int], list[float]]]:
with vllm_runner(
model_name=MODEL,
skip_tokenizer_init=True,
load_format="dummy",
hf_overrides=_make_tiny_overrides(),
tensor_parallel_size=2,
decode_context_parallel_size=dcp_size,
cp_kv_cache_interleave_size=1,
distributed_executor_backend="mp",
dtype="bfloat16",
seed=0,
enforce_eager=True,
max_model_len=512,
max_num_seqs=8,
max_num_batched_tokens=1024,
gpu_memory_utilization=0.25,
enable_chunked_prefill=True,
enable_prefix_caching=False,
) as runner:
lengths = [1, 32, 33, 129]
prompts = [
TokensPrompt(
prompt_token_ids=[
3 + ((request_idx + token_idx) % 251) for token_idx in range(length)
]
)
for request_idx, length in enumerate(lengths)
]
outputs = runner.llm.generate(
prompts,
SamplingParams(
temperature=0,
max_tokens=8,
seed=0,
ignore_eos=True,
logprobs=20,
),
use_tqdm=False,
)
results = []
for request_output in outputs:
completion = request_output.outputs[0]
token_ids = list(completion.token_ids)
assert completion.logprobs is not None
selected_logprobs = [
step_logprobs[token_id].logprob
for token_id, step_logprobs in zip(token_ids, completion.logprobs)
]
results.append((token_ids, selected_logprobs))
return results
@create_new_process_for_each_test()
@pytest.mark.distributed(num_gpus=2)
def test_kimi_linear_dcp_tiny(
vllm_runner: type[VllmRunner],
num_gpus_available: int,
) -> None:
if num_gpus_available < 2:
pytest.skip("Need at least 2 GPUs")
baseline = _run_tiny_model(vllm_runner, dcp_size=1)
dcp = _run_tiny_model(vllm_runner, dcp_size=2)
assert [tokens for tokens, _ in dcp] == [tokens for tokens, _ in baseline]
logprob_drifts = []
for (_, baseline_logprobs), (_, dcp_logprobs) in zip(baseline, dcp):
for baseline_logprob, dcp_logprob in zip(baseline_logprobs, dcp_logprobs):
assert math.isfinite(baseline_logprob)
assert math.isfinite(dcp_logprob)
logprob_drifts.append(abs(baseline_logprob - dcp_logprob))
assert max(logprob_drifts) <= 1e-2