57
.github/workflows/ut.yml
vendored
Normal file
57
.github/workflows/ut.yml
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
name: Unit Test
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
test-kunlun:
|
||||
runs-on:
|
||||
labels:
|
||||
- self-hosted
|
||||
- Linux
|
||||
- X64
|
||||
- test-1 # Actions Runner Label
|
||||
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install vLLM-Kunlun Dependencies
|
||||
run: |
|
||||
pip install -r requirements.txt
|
||||
|
||||
python setup.py build
|
||||
python setup.py develop
|
||||
|
||||
# Install the KL3-customized build of PyTorch
|
||||
wget -O xpytorch-cp310-torch251-ubuntu2004-x64.run https://baidu-kunlun-public.su.bcebos.com/v1/baidu-kunlun-share/1130/xpytorch-cp310-torch251-ubuntu2004-x64.run?authorization=bce-auth-v1%2FALTAKypXxBzU7gg4Mk4K4c6OYR%2F2025-12-02T05%3A01%3A27Z%2F-1%2Fhost%2Ff3cf499234f82303891aed2bcb0628918e379a21e841a3fac6bd94afef491ff7
|
||||
bash xpytorch-cp310-torch251-ubuntu2004-x64.run
|
||||
|
||||
# Install custom ops
|
||||
pip install "https://baidu-kunlun-public.su.bcebos.com/v1/baidu-kunlun-share/1130/xtorch_ops-0.1.2209%2B6752ad20-cp310-cp310-linux_x86_64.whl?authorization=bce-auth-v1%2FALTAKypXxBzU7gg4Mk4K4c6OYR%2F2025-12-05T06%3A18%3A00Z%2F-1%2Fhost%2F14936c2b7e7c557c1400e4c467c79f7a9217374a7aa4a046711ac4d948f460cd"
|
||||
|
||||
# Install the KLX3 custom Triton build
|
||||
pip install "https://cce-ai-models.bj.bcebos.com/v1/vllm-kunlun-0.11.0/triton-3.0.0%2Bb2cde523-cp310-cp310-linux_x86_64.whl"
|
||||
|
||||
# Install the AIAK custom ops library
|
||||
pip install "https://cce-ai-models.bj.bcebos.com/XSpeedGate-whl/release_merge/20251219_152418/xspeedgate_ops-0.0.0-cp310-cp310-linux_x86_64.whl"
|
||||
|
||||
- name: Install vLLM
|
||||
run: |
|
||||
pip install vllm==0.11.0 --no-build-isolation --no-deps --no-deps --index-url https://pip.baidu-int.com/simple/
|
||||
|
||||
- name: Install Test Dependencies
|
||||
run: |
|
||||
pip install pytest
|
||||
|
||||
- name: Run Unit Test
|
||||
run: |
|
||||
echo "Running full suite..."
|
||||
export XPU_VISIBLE_DEVICES=1
|
||||
pytest \
|
||||
-vs \
|
||||
--cov=vllm_kunlun \
|
||||
--cov-report=term-missing \
|
||||
-p no:warnings tests/ut
|
||||
156
tests/ut/test.py
Normal file
156
tests/ut/test.py
Normal file
@@ -0,0 +1,156 @@
|
||||
from unittest.mock import MagicMock, Mock, patch
|
||||
import pytest
|
||||
import torch
|
||||
|
||||
|
||||
def test_import():
|
||||
"""Test that the module can be imported successfully."""
|
||||
from vllm_kunlun.compilation.wrapper import TorchCompileWrapperWithCustomDispatcher
|
||||
assert TorchCompileWrapperWithCustomDispatcher is not None
|
||||
|
||||
|
||||
def test_basic_instantiation():
|
||||
"""Test basic wrapper instantiation with mocked dependencies."""
|
||||
from vllm_kunlun.compilation.wrapper import TorchCompileWrapperWithCustomDispatcher
|
||||
|
||||
# Create a concrete implementation
|
||||
class TestWrapper(TorchCompileWrapperWithCustomDispatcher):
|
||||
def forward(self, x):
|
||||
return x * 2
|
||||
|
||||
# Mock all the dependencies
|
||||
mock_config = MagicMock()
|
||||
mock_config.compilation_config.init_backend.return_value = "eager"
|
||||
mock_config.compilation_config.inductor_compile_config = None
|
||||
|
||||
with patch('vllm.config.get_current_vllm_config', return_value=mock_config):
|
||||
with patch('vllm.config.CompilationLevel') as mock_level:
|
||||
mock_level.DYNAMO_ONCE = 1
|
||||
with patch('torch.compile', side_effect=lambda func, **kwargs: func):
|
||||
with patch('torch._dynamo.convert_frame.register_bytecode_hook'):
|
||||
wrapper = TestWrapper(compilation_level=0)
|
||||
|
||||
# Verify basic attributes exist
|
||||
assert hasattr(wrapper, 'vllm_config')
|
||||
assert hasattr(wrapper, 'compiled_callable')
|
||||
assert hasattr(wrapper, 'original_code_object')
|
||||
assert hasattr(wrapper, 'compiled_codes')
|
||||
assert isinstance(wrapper.compiled_codes, list)
|
||||
|
||||
|
||||
def test_forward_call():
|
||||
"""Test that the forward method can be called."""
|
||||
from vllm_kunlun.compilation.wrapper import TorchCompileWrapperWithCustomDispatcher
|
||||
|
||||
class TestWrapper(TorchCompileWrapperWithCustomDispatcher):
|
||||
def forward(self, x):
|
||||
return x * 2
|
||||
|
||||
mock_config = MagicMock()
|
||||
mock_config.compilation_config.init_backend.return_value = "eager"
|
||||
mock_config.compilation_config.inductor_compile_config = None
|
||||
|
||||
with patch('vllm.config.get_current_vllm_config', return_value=mock_config):
|
||||
with patch('vllm.config.CompilationLevel') as mock_level:
|
||||
mock_level.DYNAMO_ONCE = 1
|
||||
with patch('torch.compile', side_effect=lambda func, **kwargs: func):
|
||||
with patch('torch._dynamo.convert_frame.register_bytecode_hook'):
|
||||
wrapper = TestWrapper(compilation_level=0)
|
||||
|
||||
# Test calling the wrapper
|
||||
input_tensor = torch.tensor([1.0, 2.0, 3.0])
|
||||
result = wrapper(input_tensor)
|
||||
|
||||
expected = input_tensor * 2
|
||||
assert torch.allclose(result, expected)
|
||||
|
||||
|
||||
def test_custom_callable():
|
||||
"""Test wrapper with custom compiled callable."""
|
||||
from vllm_kunlun.compilation.wrapper import TorchCompileWrapperWithCustomDispatcher
|
||||
|
||||
class TestWrapper(TorchCompileWrapperWithCustomDispatcher):
|
||||
def forward(self, x):
|
||||
return x * 2
|
||||
|
||||
custom_func = Mock(return_value=torch.tensor([5.0]))
|
||||
mock_config = MagicMock()
|
||||
mock_config.compilation_config.init_backend.return_value = "eager"
|
||||
|
||||
with patch('vllm.config.get_current_vllm_config', return_value=mock_config):
|
||||
with patch('vllm.config.CompilationLevel') as mock_level:
|
||||
mock_level.DYNAMO_ONCE = 1
|
||||
with patch('torch._dynamo.convert_frame.register_bytecode_hook'):
|
||||
wrapper = TestWrapper(
|
||||
compiled_callable=custom_func,
|
||||
compilation_level=0
|
||||
)
|
||||
|
||||
# Verify custom callable is used
|
||||
assert wrapper.compiled_callable is custom_func
|
||||
|
||||
# Call should use custom callable
|
||||
result = wrapper(torch.tensor([1.0]))
|
||||
assert custom_func.called
|
||||
|
||||
|
||||
def test_bytecode_hook_basic():
|
||||
"""Test that bytecode hook can be called without errors."""
|
||||
from vllm_kunlun.compilation.wrapper import TorchCompileWrapperWithCustomDispatcher
|
||||
from types import CodeType
|
||||
|
||||
class TestWrapper(TorchCompileWrapperWithCustomDispatcher):
|
||||
def forward(self, x):
|
||||
return x * 2
|
||||
|
||||
mock_config = MagicMock()
|
||||
mock_config.compilation_config.init_backend.return_value = "eager"
|
||||
mock_config.compilation_config.inductor_compile_config = None
|
||||
mock_config.compilation_config.local_cache_dir = None
|
||||
|
||||
with patch('vllm.config.get_current_vllm_config', return_value=mock_config):
|
||||
with patch('vllm.config.CompilationLevel') as mock_level:
|
||||
mock_level.DYNAMO_ONCE = 1
|
||||
with patch('torch.compile', side_effect=lambda func, **kwargs: func):
|
||||
with patch('torch._dynamo.convert_frame.register_bytecode_hook'):
|
||||
wrapper = TestWrapper(compilation_level=0)
|
||||
|
||||
# Test with wrong code object (should be ignored)
|
||||
wrong_code = MagicMock(spec=CodeType)
|
||||
new_code = MagicMock(spec=CodeType)
|
||||
|
||||
initial_count = len(wrapper.compiled_codes)
|
||||
wrapper.bytecode_hook(wrong_code, new_code)
|
||||
|
||||
# Should not add anything
|
||||
assert len(wrapper.compiled_codes) == initial_count
|
||||
|
||||
|
||||
def test_use_custom_dispatcher_flag():
|
||||
"""Test that use_custom_dispatcher flag is set based on compilation_level."""
|
||||
from vllm_kunlun.compilation.wrapper import TorchCompileWrapperWithCustomDispatcher
|
||||
|
||||
class TestWrapper(TorchCompileWrapperWithCustomDispatcher):
|
||||
def forward(self, x):
|
||||
return x * 2
|
||||
|
||||
mock_config = MagicMock()
|
||||
mock_config.compilation_config.init_backend.return_value = "eager"
|
||||
mock_config.compilation_config.inductor_compile_config = None
|
||||
|
||||
with patch('vllm.config.get_current_vllm_config', return_value=mock_config):
|
||||
with patch('vllm.config.CompilationLevel') as mock_level:
|
||||
mock_level.DYNAMO_ONCE = 1
|
||||
with patch('torch.compile', side_effect=lambda func, **kwargs: func):
|
||||
with patch('torch._dynamo.convert_frame.register_bytecode_hook'):
|
||||
# Test with low level
|
||||
wrapper_low = TestWrapper(compilation_level=0)
|
||||
assert wrapper_low.use_custom_dispatcher is False
|
||||
|
||||
# Test with high level
|
||||
wrapper_high = TestWrapper(compilation_level=2)
|
||||
assert wrapper_high.use_custom_dispatcher is True
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pytest.main([__file__, "-v", "-s"])
|
||||
Reference in New Issue
Block a user