Files
wehub-resource-sync 94057c3d3e
PR Test (NPU) / check-changes (push) Has been cancelled
PR Test (NPU) / pr-gate (push) Has been cancelled
PR Test (NPU) / set-image-config (push) Has been cancelled
PR Test (NPU) / stage-b-test-1-npu-a2 (0) (push) Has been cancelled
PR Test (NPU) / stage-b-test-1-npu-a2 (1) (push) Has been cancelled
PR Test (NPU) / stage-b-test-2-npu-a2 (0) (push) Has been cancelled
PR Test (NPU) / stage-b-test-2-npu-a2 (1) (push) Has been cancelled
PR Test (NPU) / stage-b-test-4-npu-a3 (push) Has been cancelled
PR Test (NPU) / stage-b-test-16-npu-a3 (push) Has been cancelled
PR Test (NPU) / multimodal-gen-test-1-npu-a3 (push) Has been cancelled
PR Test (NPU) / multimodal-gen-test-2-npu-a3 (push) Has been cancelled
PR Test (Arm64) / pr-gate (push) Has been cancelled
PR Test (Arm64) / check-changes (push) Has been cancelled
PR Test (Arm64) / build-test (push) Has been cancelled
PR Test (sgl-router) / gate (push) Has been cancelled
PR Test (sgl-router) / tier-1 — lint (push) Has been cancelled
PR Test (sgl-router) / tier-2 — build + test (push) Has been cancelled
PR Test (sgl-router) / tier-3 — docker (placeholder) (push) Has been cancelled
PR Test (sgl-router) / tier-3 — k8s integration (push) Has been cancelled
PR Test (sgl-router) / tier-3 — e2e (push) Has been cancelled
PR Test (sgl-router) / finish (push) Has been cancelled
PR Test (NPU) / single-node-poc (map[name:qwen3_6_27b_w8a8_1p_in64k_out1k_50ms runner:linux-aarch64-a3-2 test_case:test/registered/ascend/performance/qwen3_6_27b/test_npu_qwen3_6_27b_w8a8_1p_in64k_out1k_50ms.py test_type:perf]) (push) Has been cancelled
PR Test (NPU) / pr-test-npu-finish (push) Has been cancelled
PR Test (Xeon) / pr-gate (push) Has been cancelled
PR Test (Xeon) / check-changes (push) Has been cancelled
PR Test (Xeon) / build-test (, xeon-gnr, base-b-test-cpu) (push) Has been cancelled
PR Test (XPU) / check-changes (push) Has been cancelled
PR Test (XPU) / pr-gate (push) Has been cancelled
PR Test (XPU) / stage-a-test-1-gpu-xpu (push) Has been cancelled
PR Test (XPU) / wait-for-stage-a (push) Has been cancelled
PR Test (XPU) / stage-b-test-1-gpu-xpu (push) Has been cancelled
PR Test (XPU) / finish (push) Has been cancelled
CI Model Inventory / build-inventory (push) Has been cancelled
Lint / lint (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark Compilation Check (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark - Manual Policy (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark - Request Processing (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark Summary (push) Has been cancelled
PR Test (SMG) / build-wheel (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on windows (x86_64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on macos (x86_64 - auto) (push) Has been cancelled
PR Test (SMG) / python-unit-tests (push) Has been cancelled
PR Test (SMG) / unit-tests (push) Has been cancelled
PR Test (SMG) / benchmarks (push) Has been cancelled
PR Test (SMG) / chat-completions (push) Has been cancelled
PR Test (SMG) / chat-completions-4gpu (push) Has been cancelled
PR Test (SMG) / e2e (push) Has been cancelled
PR Test (SMG) / docker-build-test (push) Has been cancelled
PR Test (SMG) / k8s-integration (push) Has been cancelled
PR Test (SMG) / finish (push) Has been cancelled
PR Test (SMG) / summarize-benchmarks (push) Has been cancelled
Release SGLang Model Gateway Docker Image / publish (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on macos (aarch64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (aarch64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (x86_64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (aarch64 - musllinux_1_1) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (x86_64 - musllinux_1_1) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / Build SDist (push) Has been cancelled
Release SGLang Model Gateway to PyPI / Upload to PyPI (push) Has been cancelled
Release SGLang Kernels / build-cu129-matrix (aarch64, 12.9, 3.10, arm-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / build-cu129-matrix (x86_64, 12.9, 3.10, x64-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / release-cu129 (push) Has been cancelled
Release SGLang Kernels / build-cu130-matrix (aarch64, 13.0, 3.10, arm-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / build-cu130-matrix (x86_64, 13.0, 3.10, x64-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / release-cu130 (push) Has been cancelled
Release SGLang Kernels / build-rocm-matrix (3.10, 700) (push) Has been cancelled
Release SGLang Kernels / build-rocm-matrix (3.10, 720) (push) Has been cancelled
Release SGLang Kernels / release-rocm700 (push) Has been cancelled
Release SGLang Kernels / release-rocm720 (push) Has been cancelled
Release SGLang Kernels / build-musa43 (43, 3.10) (push) Has been cancelled
Release SGLang Kernels / release-musa43 (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:38:16 +08:00

202 lines
6.7 KiB
Python

"""
Configuration loader for auto-tuned LoRA CSGMV kernel block sizes.
Follows the same pattern as fused_moe_triton_config.py:
- Offline tuning script writes JSON files keyed by chunk_size (BLOCK_M)
- At server startup, the config loader reads the best block sizes for each kernel
- Kernels use these instead of hardcoded defaults
Config file naming: lora_{kernel},K={K},R={R},S={S},device={device}.json
Where kernel is "shrink" or "expand", K is input_dim, R is max_rank, S is num_slices.
Config file format (keyed by chunk_size):
{
"16": {"BLOCK_N": 16, "BLOCK_K": 256, "num_warps": 4, "num_stages": 3},
"32": {"BLOCK_N": 32, "BLOCK_K": 128, "num_warps": 4, "num_stages": 4},
"128": {"BLOCK_N": 64, "BLOCK_K": 256, "num_warps": 8, "num_stages": 3}
}
Usage:
python3 benchmark/kernels/lora_csgmv/tune_lora_csgmv.py \
--model Qwen/Qwen3-Embedding-0.6B --max-lora-rank 64
# Configs saved to python/sglang/kernels/ops/gemm/configs/
# Server automatically picks them up:
python3 -m sglang.launch_server --model ... --enable-lora --lora-backend csgmv
"""
from __future__ import annotations
import functools
import json
import logging
import os
from typing import Any, Dict, Optional
import triton
from sglang.srt.utils import get_device_name
logger = logging.getLogger(__name__)
def get_lora_config_file_name(
kernel: str,
K: int,
R: int,
S: int,
) -> str:
"""Generate config filename for a LoRA kernel configuration.
Args:
kernel: "shrink" or "expand"
K: The large dimension (input_dim for shrink, output_dim for expand)
R: The max LoRA rank
S: num_slices (qkv=3, gate_up=2, others=1)
"""
device_name = get_device_name().replace(" ", "_")
return f"lora_{kernel},K={K},R={R},S={S},device={device_name}.json"
@functools.lru_cache
def get_lora_configs(
kernel: str,
K: int,
R: int,
S: int,
) -> Optional[Dict[int, Dict[str, Any]]]:
"""Load pre-tuned LoRA kernel configs from JSON files.
Returns a dict mapping chunk_size (BLOCK_M) to block size configs,
or None if no config file is found.
"""
json_file_name = get_lora_config_file_name(kernel, K, R, S)
config_dir = os.environ.get(
"SGLANG_LORA_CONFIG_DIR", os.path.dirname(os.path.realpath(__file__))
)
configs_root = os.path.join(config_dir, "csgmv_configs")
triton_version = triton.__version__
version_dir = f"triton_{triton_version.replace('.', '_')}"
# Try exact triton version first
config_file_path = os.path.join(configs_root, version_dir, json_file_name)
if os.path.exists(config_file_path):
with open(config_file_path) as f:
logger.info(f"Using LoRA {kernel} config from {config_file_path}.")
return {int(key): val for key, val in json.load(f).items()}
# Scan existing version directories as fallback (newest first)
if os.path.isdir(configs_root):
version_dirs = sorted(
(d for d in os.listdir(configs_root) if d.startswith("triton_")),
reverse=True,
)
for vdir in version_dirs:
if vdir == version_dir:
continue
try_path = os.path.join(configs_root, vdir, json_file_name)
if os.path.exists(try_path):
with open(try_path) as f:
logger.warning(
f"LoRA {kernel} config not found for Triton {triton_version}. "
f"Falling back to {try_path}."
)
return {int(key): val for key, val in json.load(f).items()}
return None
# Default block sizes (current hardcoded values)
DEFAULT_SHRINK_CONFIG = {"BLOCK_N": 16, "BLOCK_K": 256}
DEFAULT_EXPAND_CONFIG = {"BLOCK_N": 64, "BLOCK_K": 16}
# Track which configs have been logged to avoid spamming on every forward pass
_logged_configs: set = set()
def get_lora_shrink_config(
K: int,
R: int,
num_slices: int,
chunk_size: int,
) -> Dict[str, int]:
"""Get block sizes for the CSGMV shrink (lora_a) kernel.
Args:
K: input_dim
R: max_rank
num_slices: number of slices (qkv=3, gate_up=2, others=1)
chunk_size: BLOCK_M value (= batch_info.max_len)
"""
log_key = ("shrink", K, R, num_slices, chunk_size)
configs = get_lora_configs("shrink", K, R, num_slices)
if configs is not None:
config = configs.get(chunk_size)
if config is None:
closest = min(configs.keys(), key=lambda x: abs(x - chunk_size))
config = configs[closest]
if log_key not in _logged_configs:
_logged_configs.add(log_key)
logger.info(
f"LoRA shrink (K={K}, R={R}): no config for chunk_size={chunk_size}, "
f"using closest={closest}: {config}"
)
else:
if log_key not in _logged_configs:
_logged_configs.add(log_key)
logger.info(
f"LoRA shrink (K={K}, R={R}, chunk_size={chunk_size}): tuned config {config}"
)
return config
if log_key not in _logged_configs:
_logged_configs.add(log_key)
logger.info(
f"LoRA shrink (K={K}, R={R}): no tuned config, using defaults {DEFAULT_SHRINK_CONFIG}"
)
return dict(DEFAULT_SHRINK_CONFIG)
def get_lora_expand_config(
K: int,
R: int,
num_slices: int,
chunk_size: int,
) -> Dict[str, int]:
"""Get block sizes for the CSGMV expand (lora_b) kernel.
Args:
K: output_dim
R: max_rank
num_slices: number of slices (qkv=3, gate_up=2, others=1)
chunk_size: BLOCK_M value (= batch_info.max_len)
"""
log_key = ("expand", K, R, num_slices, chunk_size)
configs = get_lora_configs("expand", K, R, num_slices)
if configs is not None:
config = configs.get(chunk_size)
if config is None:
closest = min(configs.keys(), key=lambda x: abs(x - chunk_size))
config = configs[closest]
if log_key not in _logged_configs:
_logged_configs.add(log_key)
logger.info(
f"LoRA expand (K={K}, R={R}): no config for chunk_size={chunk_size}, "
f"using closest={closest}: {config}"
)
else:
if log_key not in _logged_configs:
_logged_configs.add(log_key)
logger.info(
f"LoRA expand (K={K}, R={R}, chunk_size={chunk_size}): tuned config {config}"
)
return config
if log_key not in _logged_configs:
_logged_configs.add(log_key)
logger.info(
f"LoRA expand (K={K}, R={R}): no tuned config, using defaults {DEFAULT_EXPAND_CONFIG}"
)
return dict(DEFAULT_EXPAND_CONFIG)