sgl-project--sglang
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
538 行
19 KiB
Python
538 行
19 KiB
Python
"""Unit tests for the sglang.srt.utils.hf_transformers subpackage.
|
|
|
|
Tests cover the pure utility functions (compat patches, config helpers,
|
|
context length, GGUF detection, etc.) that don't require actual model files.
|
|
"""
|
|
|
|
import tempfile
|
|
import unittest
|
|
from types import SimpleNamespace
|
|
|
|
from transformers import PretrainedConfig
|
|
|
|
from sglang.srt.utils.hf_transformers.common import (
|
|
_is_deepseek_ocr2_model,
|
|
_is_deepseek_ocr_model,
|
|
_override_v_head_dim_if_zero,
|
|
_patch_text_config,
|
|
check_gguf_file,
|
|
get_context_length,
|
|
get_hf_text_config,
|
|
get_rope_config,
|
|
)
|
|
from sglang.srt.utils.hf_transformers.tokenizer import _fix_special_tokens_pattern
|
|
from sglang.srt.utils.hf_transformers_patches import normalize_rope_scaling_compat
|
|
from sglang.test.ci.ci_register import register_cpu_ci
|
|
|
|
register_cpu_ci(est_time=6, suite="base-a-test-cpu")
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# normalize_rope_scaling_compat
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
class TestNormalizeRopeScalingCompat(unittest.TestCase):
|
|
def test_adds_type_from_rope_type(self):
|
|
cfg = PretrainedConfig()
|
|
cfg.rope_scaling = {"rope_type": "llama3", "factor": 8.0}
|
|
normalize_rope_scaling_compat(cfg)
|
|
self.assertEqual(cfg.rope_scaling["type"], "llama3")
|
|
|
|
def test_preserves_existing_type(self):
|
|
cfg = PretrainedConfig()
|
|
cfg.rope_scaling = {"rope_type": "llama3", "type": "custom", "factor": 8.0}
|
|
normalize_rope_scaling_compat(cfg)
|
|
self.assertEqual(cfg.rope_scaling["type"], "custom")
|
|
|
|
def test_no_op_when_rope_scaling_is_none(self):
|
|
cfg = PretrainedConfig()
|
|
cfg.rope_scaling = None
|
|
normalize_rope_scaling_compat(cfg)
|
|
self.assertIsNone(cfg.rope_scaling)
|
|
|
|
def test_recurses_into_text_config(self):
|
|
text_cfg = PretrainedConfig()
|
|
text_cfg.rope_scaling = {"rope_type": "yarn", "factor": 4.0}
|
|
cfg = PretrainedConfig()
|
|
cfg.text_config = text_cfg
|
|
normalize_rope_scaling_compat(cfg)
|
|
self.assertEqual(text_cfg.rope_scaling["type"], "yarn")
|
|
|
|
def test_recurses_into_llm_config(self):
|
|
llm_cfg = PretrainedConfig()
|
|
llm_cfg.rope_scaling = {"rope_type": "dynamic", "factor": 2.0}
|
|
cfg = PretrainedConfig()
|
|
cfg.llm_config = llm_cfg
|
|
normalize_rope_scaling_compat(cfg)
|
|
self.assertEqual(llm_cfg.rope_scaling["type"], "dynamic")
|
|
|
|
def test_no_crash_on_non_dict_rope_scaling(self):
|
|
cfg = PretrainedConfig()
|
|
cfg.rope_scaling = "not_a_dict"
|
|
normalize_rope_scaling_compat(cfg)
|
|
self.assertEqual(cfg.rope_scaling, "not_a_dict")
|
|
|
|
def test_no_crash_on_dict_without_rope_type(self):
|
|
cfg = PretrainedConfig()
|
|
cfg.rope_scaling = {"factor": 4.0}
|
|
normalize_rope_scaling_compat(cfg)
|
|
self.assertNotIn("type", cfg.rope_scaling)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# get_rope_config
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
class TestGetRopeConfig(unittest.TestCase):
|
|
def test_v5_rope_parameters(self):
|
|
cfg = PretrainedConfig()
|
|
cfg.rope_parameters = {"rope_theta": 10000.0, "rope_type": "default"}
|
|
theta, params = get_rope_config(cfg)
|
|
self.assertEqual(theta, 10000.0)
|
|
self.assertIs(params, cfg.rope_parameters)
|
|
|
|
def test_v4_fallback_remote_code_config(self):
|
|
# Remote-code configs (SimpleNamespace) lack the v5 rope_parameters property
|
|
cfg = SimpleNamespace(
|
|
rope_theta=500000.0,
|
|
rope_scaling={"type": "llama3", "factor": 8.0},
|
|
)
|
|
theta, params = get_rope_config(cfg)
|
|
self.assertEqual(theta, 500000.0)
|
|
self.assertEqual(params, {"type": "llama3", "factor": 8.0})
|
|
|
|
def test_v4_no_scaling(self):
|
|
cfg = SimpleNamespace(rope_theta=10000.0)
|
|
theta, params = get_rope_config(cfg)
|
|
self.assertEqual(theta, 10000.0)
|
|
self.assertIsNone(params)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# _patch_text_config
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
class TestPatchTextConfig(unittest.TestCase):
|
|
def test_propagates_parent_to_text(self):
|
|
parent = PretrainedConfig()
|
|
parent.pad_token_id = 0
|
|
parent.bos_token_id = 1
|
|
parent.eos_token_id = 2
|
|
parent.tie_word_embeddings = False
|
|
|
|
text = PretrainedConfig()
|
|
text.num_attention_heads = 32
|
|
|
|
result = _patch_text_config(parent, text)
|
|
self.assertEqual(result.pad_token_id, 0)
|
|
self.assertEqual(result.bos_token_id, 1)
|
|
self.assertEqual(result.eos_token_id, 2)
|
|
self.assertIs(result, text)
|
|
|
|
def test_propagates_text_to_parent(self):
|
|
parent = PretrainedConfig()
|
|
text = PretrainedConfig()
|
|
text.pad_token_id = 42
|
|
|
|
_patch_text_config(parent, text)
|
|
self.assertEqual(parent.pad_token_id, 42)
|
|
|
|
def test_no_overwrite_when_both_have_attr(self):
|
|
parent = PretrainedConfig()
|
|
parent.pad_token_id = 0
|
|
text = PretrainedConfig()
|
|
text.pad_token_id = 99
|
|
|
|
_patch_text_config(parent, text)
|
|
self.assertEqual(parent.pad_token_id, 0)
|
|
self.assertEqual(text.pad_token_id, 99)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# get_context_length
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
class TestGetContextLength(unittest.TestCase):
|
|
def test_max_position_embeddings(self):
|
|
cfg = PretrainedConfig()
|
|
cfg.max_position_embeddings = 4096
|
|
self.assertEqual(get_context_length(cfg), 4096)
|
|
|
|
def test_max_sequence_length_takes_priority(self):
|
|
cfg = PretrainedConfig()
|
|
cfg.max_sequence_length = 8192
|
|
cfg.max_position_embeddings = 4096
|
|
self.assertEqual(get_context_length(cfg), 8192)
|
|
|
|
def test_rope_scaling_factor(self):
|
|
cfg = PretrainedConfig()
|
|
cfg.max_position_embeddings = 4096
|
|
cfg.rope_scaling = {"factor": 4.0}
|
|
self.assertEqual(get_context_length(cfg), 16384)
|
|
|
|
def test_rope_scaling_llama3_ignores_factor(self):
|
|
cfg = PretrainedConfig()
|
|
cfg.max_position_embeddings = 131072
|
|
cfg.rope_scaling = {"rope_type": "llama3", "factor": 8.0}
|
|
self.assertEqual(get_context_length(cfg), 131072)
|
|
|
|
def test_original_max_position_embeddings_ignores_factor(self):
|
|
cfg = PretrainedConfig()
|
|
cfg.max_position_embeddings = 131072
|
|
cfg.rope_scaling = {
|
|
"factor": 8.0,
|
|
"original_max_position_embeddings": 8192,
|
|
}
|
|
self.assertEqual(get_context_length(cfg), 131072)
|
|
|
|
def test_default_when_no_keys(self):
|
|
cfg = PretrainedConfig()
|
|
self.assertEqual(get_context_length(cfg), 2048)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# check_gguf_file
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
class TestCheckGgufFile(unittest.TestCase):
|
|
def test_gguf_suffix(self):
|
|
with tempfile.NamedTemporaryFile(suffix=".gguf") as f:
|
|
self.assertTrue(check_gguf_file(f.name))
|
|
|
|
def test_gguf_magic_header(self):
|
|
with tempfile.NamedTemporaryFile(suffix=".bin") as f:
|
|
f.write(b"GGUF" + b"\x00" * 100)
|
|
f.flush()
|
|
self.assertTrue(check_gguf_file(f.name))
|
|
|
|
def test_non_gguf_file(self):
|
|
with tempfile.NamedTemporaryFile(suffix=".bin") as f:
|
|
f.write(b"NOT_GGUF" + b"\x00" * 100)
|
|
f.flush()
|
|
self.assertFalse(check_gguf_file(f.name))
|
|
|
|
def test_nonexistent_file(self):
|
|
self.assertFalse(check_gguf_file("/nonexistent/path/model.bin"))
|
|
|
|
def test_directory(self):
|
|
with tempfile.TemporaryDirectory() as d:
|
|
self.assertFalse(check_gguf_file(d))
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# _is_deepseek_ocr_model / _is_deepseek_ocr2_model
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
class TestDeepseekOcrDetection(unittest.TestCase):
|
|
def test_ocr_model_detected(self):
|
|
cfg = PretrainedConfig()
|
|
cfg.auto_map = {"AutoModel": "modeling_deepseekocr.DeepseekOCRForCausalLM"}
|
|
self.assertTrue(_is_deepseek_ocr_model(cfg))
|
|
|
|
def test_ocr2_model_detected(self):
|
|
cfg = PretrainedConfig()
|
|
cfg.auto_map = {"AutoModel": "modeling_deepseekocr2.DeepseekOCR2ForCausalLM"}
|
|
self.assertTrue(_is_deepseek_ocr2_model(cfg))
|
|
|
|
def test_non_ocr_model(self):
|
|
cfg = PretrainedConfig()
|
|
cfg.auto_map = {"AutoModel": "modeling_llama.LlamaForCausalLM"}
|
|
self.assertFalse(_is_deepseek_ocr_model(cfg))
|
|
self.assertFalse(_is_deepseek_ocr2_model(cfg))
|
|
|
|
def test_no_auto_map(self):
|
|
cfg = PretrainedConfig()
|
|
self.assertFalse(_is_deepseek_ocr_model(cfg))
|
|
self.assertFalse(_is_deepseek_ocr2_model(cfg))
|
|
|
|
def test_empty_auto_map(self):
|
|
cfg = PretrainedConfig()
|
|
cfg.auto_map = {}
|
|
self.assertFalse(_is_deepseek_ocr_model(cfg))
|
|
self.assertFalse(_is_deepseek_ocr2_model(cfg))
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# _override_v_head_dim_if_zero
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
class TestOverrideVHeadDimIfZero(unittest.TestCase):
|
|
def test_patches_zero_v_head_dim(self):
|
|
text_cfg = SimpleNamespace(v_head_dim=0)
|
|
cfg = PretrainedConfig()
|
|
cfg.text_config = text_cfg
|
|
_override_v_head_dim_if_zero(cfg)
|
|
self.assertEqual(text_cfg.v_head_dim, 128)
|
|
|
|
def test_custom_patch_value(self):
|
|
text_cfg = SimpleNamespace(v_head_dim=0)
|
|
cfg = PretrainedConfig()
|
|
cfg.text_config = text_cfg
|
|
_override_v_head_dim_if_zero(cfg, patch=64)
|
|
self.assertEqual(text_cfg.v_head_dim, 64)
|
|
|
|
def test_no_patch_when_nonzero(self):
|
|
text_cfg = SimpleNamespace(v_head_dim=256)
|
|
cfg = PretrainedConfig()
|
|
cfg.text_config = text_cfg
|
|
_override_v_head_dim_if_zero(cfg)
|
|
self.assertEqual(text_cfg.v_head_dim, 256)
|
|
|
|
def test_dict_sub_config(self):
|
|
cfg = PretrainedConfig()
|
|
cfg.text_config = {"v_head_dim": 0}
|
|
_override_v_head_dim_if_zero(cfg)
|
|
self.assertEqual(cfg.text_config["v_head_dim"], 128)
|
|
|
|
def test_no_sub_config(self):
|
|
cfg = PretrainedConfig()
|
|
_override_v_head_dim_if_zero(cfg) # should not raise
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# get_hf_text_config
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
class TestGetHfTextConfig(unittest.TestCase):
|
|
def test_returns_config_for_pure_text_model(self):
|
|
cfg = PretrainedConfig()
|
|
cfg.architectures = ["LlamaForCausalLM"]
|
|
result = get_hf_text_config(cfg)
|
|
self.assertIs(result, cfg)
|
|
|
|
def test_returns_text_config_for_multimodal(self):
|
|
text_cfg = PretrainedConfig()
|
|
text_cfg.num_attention_heads = 32
|
|
cfg = PretrainedConfig()
|
|
cfg.architectures = ["SomeVLMForCausalLM"]
|
|
cfg.text_config = text_cfg
|
|
result = get_hf_text_config(cfg)
|
|
self.assertIs(result, text_cfg)
|
|
|
|
def test_llm_config_priority_over_text_config(self):
|
|
llm_cfg = PretrainedConfig()
|
|
llm_cfg.num_attention_heads = 16
|
|
text_cfg = PretrainedConfig()
|
|
text_cfg.num_attention_heads = 32
|
|
cfg = PretrainedConfig()
|
|
cfg.architectures = ["SomeModel"]
|
|
cfg.llm_config = llm_cfg
|
|
cfg.text_config = text_cfg
|
|
result = get_hf_text_config(cfg)
|
|
self.assertIs(result, llm_cfg)
|
|
|
|
def test_thinker_config_highest_priority(self):
|
|
thinker_cfg = PretrainedConfig()
|
|
thinker_cfg.num_attention_heads = 8
|
|
cfg = PretrainedConfig()
|
|
cfg.architectures = ["SomeModel"]
|
|
cfg.thinker_config = thinker_cfg
|
|
result = get_hf_text_config(cfg)
|
|
self.assertIs(result, thinker_cfg)
|
|
|
|
def test_thinker_config_with_text_sub_config(self):
|
|
inner_text = PretrainedConfig()
|
|
inner_text.num_attention_heads = 8
|
|
thinker_cfg = PretrainedConfig()
|
|
thinker_cfg.text_config = inner_text
|
|
thinker_cfg.torch_dtype = "float16"
|
|
cfg = PretrainedConfig()
|
|
cfg.architectures = ["Qwen2OmniModel"]
|
|
cfg.thinker_config = thinker_cfg
|
|
result = get_hf_text_config(cfg)
|
|
self.assertIs(result, inner_text)
|
|
self.assertEqual(inner_text.torch_dtype, "float16")
|
|
|
|
def test_converts_dict_sub_config(self):
|
|
cfg = PretrainedConfig()
|
|
cfg.architectures = ["SomeModel"]
|
|
cfg.text_config = {
|
|
"num_attention_heads": 32,
|
|
"hidden_size": 4096,
|
|
}
|
|
result = get_hf_text_config(cfg)
|
|
self.assertIsInstance(cfg.text_config, PretrainedConfig)
|
|
self.assertEqual(result.num_attention_heads, 32)
|
|
|
|
def test_llava_returns_parent_config(self):
|
|
cfg = PretrainedConfig()
|
|
cfg.architectures = ["LlavaForCausalLM"]
|
|
text_cfg = PretrainedConfig()
|
|
text_cfg.num_attention_heads = 32
|
|
cfg.text_config = text_cfg
|
|
result = get_hf_text_config(cfg)
|
|
self.assertIs(result, cfg)
|
|
|
|
def test_calls_normalize_rope_scaling(self):
|
|
cfg = PretrainedConfig()
|
|
cfg.architectures = ["LlamaForCausalLM"]
|
|
cfg.rope_scaling = {"rope_type": "llama3", "factor": 8.0}
|
|
get_hf_text_config(cfg)
|
|
self.assertIn("type", cfg.rope_scaling)
|
|
self.assertEqual(cfg.rope_scaling["type"], "llama3")
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# _fix_special_tokens_pattern
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
class TestFixSpecialTokensPattern(unittest.TestCase):
|
|
def test_fixes_cls_sep_with_missing_tokens(self):
|
|
tok = SimpleNamespace(
|
|
special_tokens_pattern="cls_sep",
|
|
cls_token_id=None,
|
|
sep_token_id=None,
|
|
)
|
|
_fix_special_tokens_pattern(tok)
|
|
self.assertEqual(tok.special_tokens_pattern, "none")
|
|
|
|
def test_no_change_when_tokens_present(self):
|
|
tok = SimpleNamespace(
|
|
special_tokens_pattern="cls_sep",
|
|
cls_token_id=101,
|
|
sep_token_id=102,
|
|
)
|
|
_fix_special_tokens_pattern(tok)
|
|
self.assertEqual(tok.special_tokens_pattern, "cls_sep")
|
|
|
|
def test_no_change_for_other_patterns(self):
|
|
tok = SimpleNamespace(
|
|
special_tokens_pattern="none",
|
|
cls_token_id=None,
|
|
sep_token_id=None,
|
|
)
|
|
_fix_special_tokens_pattern(tok)
|
|
self.assertEqual(tok.special_tokens_pattern, "none")
|
|
|
|
def test_no_change_when_no_pattern(self):
|
|
tok = SimpleNamespace(cls_token_id=None, sep_token_id=None)
|
|
_fix_special_tokens_pattern(tok)
|
|
self.assertFalse(hasattr(tok, "special_tokens_pattern"))
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# __init__.py re-exports
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
class TestModuleReExports(unittest.TestCase):
|
|
def test_all_public_symbols_importable(self):
|
|
import sglang.srt.utils.hf_transformers as pkg
|
|
|
|
for name in pkg.__all__:
|
|
self.assertTrue(
|
|
hasattr(pkg, name),
|
|
f"{name} listed in __all__ but not importable from package",
|
|
)
|
|
|
|
def test_shim_module_exports_match(self):
|
|
import sglang.srt.utils.hf_transformers as pkg
|
|
import sglang.srt.utils.hf_transformers_utils as shim
|
|
|
|
for name in pkg.__all__:
|
|
self.assertTrue(
|
|
hasattr(shim, name),
|
|
f"{name} not available through shim module hf_transformers_utils",
|
|
)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# compat: _patch_removed_symbols
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
class TestPatchRemovedSymbols(unittest.TestCase):
|
|
def test_llama_flash_attention2_exists(self):
|
|
from transformers.models.llama import modeling_llama
|
|
|
|
self.assertTrue(
|
|
hasattr(modeling_llama, "LlamaFlashAttention2"),
|
|
"LlamaFlashAttention2 should be patched onto modeling_llama",
|
|
)
|
|
|
|
def test_is_flash_attn_greater_or_equal_2_10_callable(self):
|
|
import transformers.utils as _u
|
|
|
|
self.assertTrue(
|
|
hasattr(_u, "is_flash_attn_greater_or_equal_2_10"),
|
|
"is_flash_attn_greater_or_equal_2_10 should be patched onto transformers.utils",
|
|
)
|
|
self.assertIsInstance(_u.is_flash_attn_greater_or_equal_2_10(), bool)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# compat: _patch_rope_parameters_validation
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# compat: _ensure_clean_up_tokenization_compat
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
class TestCleanUpTokenizationCompat(unittest.TestCase):
|
|
def test_clean_up_tokenization_exists(self):
|
|
from transformers import PreTrainedTokenizerBase
|
|
|
|
self.assertTrue(hasattr(PreTrainedTokenizerBase, "clean_up_tokenization"))
|
|
|
|
def test_clean_up_tokenization_callable(self):
|
|
from transformers import PreTrainedTokenizerBase
|
|
|
|
self.assertTrue(callable(PreTrainedTokenizerBase.clean_up_tokenization))
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# compat: _ensure_is_torch_fx_available_compat
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
class TestIsTorchFxAvailableCompat(unittest.TestCase):
|
|
def test_is_torch_fx_available_exists(self):
|
|
import transformers.utils.import_utils as _iu
|
|
|
|
self.assertTrue(hasattr(_iu, "is_torch_fx_available"))
|
|
self.assertTrue(_iu.is_torch_fx_available())
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# compat: _patch_nemotron_h_pattern
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
class TestPatchNemotronHPattern(unittest.TestCase):
|
|
def test_pattern_to_list_skips_mlp_dash(self):
|
|
try:
|
|
from transformers.models.nemotron_h.configuration_nemotron_h import (
|
|
NemotronHConfig,
|
|
)
|
|
|
|
result = NemotronHConfig._pattern_to_list("M-*-")
|
|
self.assertEqual(result, ["mamba", "attention"])
|
|
except ImportError:
|
|
self.skipTest("NemotronHConfig not available in this transformers version")
|
|
|
|
def test_pattern_to_list_standard_chars(self):
|
|
try:
|
|
from transformers.models.nemotron_h.configuration_nemotron_h import (
|
|
NemotronHConfig,
|
|
)
|
|
|
|
result = NemotronHConfig._pattern_to_list("ME*")
|
|
self.assertEqual(result, ["mamba", "moe", "attention"])
|
|
except ImportError:
|
|
self.skipTest("NemotronHConfig not available in this transformers version")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|