From 2d27c38f13d07360574587a32e43addf28a4269e Mon Sep 17 00:00:00 2001 From: MingxuZh <109504044+MingxuZh@users.noreply.github.com> Date: Tue, 28 Apr 2026 19:03:11 -0700 Subject: [PATCH] Update XPU Docker runtime stack & hf_home config (#23820) Co-authored-by: Ma Mingfei --- .github/workflows/pr-test-xpu.yml | 6 ++-- docker/xpu.Dockerfile | 16 ++++++---- test/srt/xpu/test_deepseek_ocr.py | 23 ++++----------- test/srt/xpu/test_deepseek_ocr_triton.py | 10 +++++-- test/srt/xpu/test_intel_xpu_backend.py | 37 ++++++++---------------- 5 files changed, 38 insertions(+), 54 deletions(-) diff --git a/.github/workflows/pr-test-xpu.yml b/.github/workflows/pr-test-xpu.yml index fe3068ddc..f820e99ee 100644 --- a/.github/workflows/pr-test-xpu.yml +++ b/.github/workflows/pr-test-xpu.yml @@ -72,8 +72,6 @@ jobs: needs: [check-changes, pr-gate] if: needs.check-changes.outputs.main_package == 'true' runs-on: intel-bmg - env: - HF_HOME: /home/sdp/.cache/huggingface steps: - name: Checkout code uses: actions/checkout@v4 @@ -99,8 +97,10 @@ jobs: container_id=$(docker run -dt \ --group-add 992 \ --group-add $(getent group video | cut -d: -f3) \ - -v ${HF_HOME}:/root/.cache/huggingface \ + --group-add $(getent group render | cut -d: -f3) \ + -v $HOME/.cache/huggingface:/root/.cache/huggingface \ --device /dev/dri \ + -v /dev/dri/by-path:/dev/dri/by-path \ -e HF_TOKEN="$(cat ~/huggingface_token.txt)" \ xpu_sglang_main:bmg) echo "Started container: $container_id" diff --git a/docker/xpu.Dockerfile b/docker/xpu.Dockerfile index c50b19b5e..f69b2cb9e 100644 --- a/docker/xpu.Dockerfile +++ b/docker/xpu.Dockerfile @@ -20,6 +20,16 @@ ARG SG_LANG_KERNEL_BRANCH=main RUN useradd -m -d /home/sdp -s /bin/bash sdp && \ chown -R sdp:sdp /home/sdp +USER root + +# Install the latest UMD driver for SYCL-TLA +RUN apt-get install -y software-properties-common && \ + add-apt-repository -y ppa:kobuk-team/intel-graphics && \ + apt-get update && \ + apt-get install -y libze-intel-gpu1 libze1 intel-metrics-discovery intel-opencl-icd clinfo intel-gsc && \ + apt-get install -y intel-media-va-driver-non-free libmfx-gen1 libvpl2 libvpl-tools libva-glx2 va-driver-all vainfo && \ + apt-get install -y libze-dev intel-ocloc + # Switch to non-root user 'sdp' USER sdp @@ -38,12 +48,6 @@ RUN curl -fsSL -v -o miniforge.sh -O https://github.com/conda-forge/miniforge/re # Append environment activation to .bashrc for interactive shells echo ". /home/sdp/miniforge3/bin/activate; conda activate py${PYTHON_VERSION}; . /opt/intel/oneapi/setvars.sh; cd /home/sdp" >> /home/sdp/.bashrc -USER root -RUN apt-get update && apt install -y intel-ocloc - -# Switch back to user sdp -USER sdp - RUN --mount=type=secret,id=github_token \ cd /home/sdp && \ . /home/sdp/miniforge3/bin/activate && \ diff --git a/test/srt/xpu/test_deepseek_ocr.py b/test/srt/xpu/test_deepseek_ocr.py index 0bfc41fe2..1d8606e23 100644 --- a/test/srt/xpu/test_deepseek_ocr.py +++ b/test/srt/xpu/test_deepseek_ocr.py @@ -2,7 +2,6 @@ python3 -m unittest test_deepseek_ocr.py """ -import gc import json import os import unittest @@ -21,22 +20,8 @@ from sglang.test.test_utils import ( class TestDeepSeekOCR(CustomTestCase): - @classmethod - def _cleanup_xpu_memory(cls): - gc.collect() - try: - import torch - - if hasattr(torch, "xpu") and torch.xpu.is_available(): - torch.xpu.synchronize() - torch.xpu.empty_cache() - except Exception: - # Best-effort cleanup only; tests should continue if cleanup is unavailable. - pass - @classmethod def setUpClass(cls): - cls._cleanup_xpu_memory() cls.model = "deepseek-ai/DeepSeek-OCR" cls.tokenizer = get_tokenizer(cls.model) cls.base_url = DEFAULT_URL_FOR_TEST @@ -65,8 +50,12 @@ class TestDeepSeekOCR(CustomTestCase): def tearDownClass(cls): """Fixture that is run once after all tests in the class.""" if hasattr(cls, "process") and cls.process: - kill_process_tree(cls.process.pid) - cls._cleanup_xpu_memory() + cls.process.terminate() + try: + cls.process.wait(timeout=30) + except Exception: + # Force kill if it didn't exit cleanly in time + kill_process_tree(cls.process.pid) def get_request_json(self, max_new_tokens=32, n=1): response = requests.post( diff --git a/test/srt/xpu/test_deepseek_ocr_triton.py b/test/srt/xpu/test_deepseek_ocr_triton.py index 4381112f9..67b8c54da 100644 --- a/test/srt/xpu/test_deepseek_ocr_triton.py +++ b/test/srt/xpu/test_deepseek_ocr_triton.py @@ -6,7 +6,7 @@ import os import unittest from pathlib import Path -import test_deepseek_ocr as deepseek_ocr +from test_deepseek_ocr import TestDeepSeekOCR from sglang.srt.utils.hf_transformers import get_tokenizer from sglang.test.test_utils import ( @@ -16,10 +16,11 @@ from sglang.test.test_utils import ( ) -class TestDeepSeekOCRTriton(deepseek_ocr.TestDeepSeekOCR): +# TODO: Temporarily disable this test and re-enable it after Triton-XPU is upgraded. +@unittest.skip("Temporarily disabled until Triton-XPU upgrade") +class TestDeepSeekOCRTriton(TestDeepSeekOCR): @classmethod def setUpClass(cls): - cls._cleanup_xpu_memory() cls.model = "deepseek-ai/DeepSeek-OCR" cls.tokenizer = get_tokenizer(cls.model) cls.base_url = DEFAULT_URL_FOR_TEST @@ -45,5 +46,8 @@ class TestDeepSeekOCRTriton(deepseek_ocr.TestDeepSeekOCR): ) +# Prevent pytest from collecting the imported base test class here. +del TestDeepSeekOCR + if __name__ == "__main__": unittest.main() diff --git a/test/srt/xpu/test_intel_xpu_backend.py b/test/srt/xpu/test_intel_xpu_backend.py index 1be345212..c752b34dd 100644 --- a/test/srt/xpu/test_intel_xpu_backend.py +++ b/test/srt/xpu/test_intel_xpu_backend.py @@ -3,7 +3,6 @@ Usage: python3 -m unittest test_intel_xpu_backend.TestIntelXPUBackend.test_latency_qwen_model """ -import gc import unittest from functools import wraps @@ -16,29 +15,17 @@ from sglang.test.test_utils import ( ) -def _cleanup_xpu_memory(): - gc.collect() - try: - import torch - - if hasattr(torch, "xpu") and torch.xpu.is_available(): - torch.xpu.synchronize() - torch.xpu.empty_cache() - except Exception: - # Best-effort cleanup only. - pass - - -def intel_xpu_benchmark(extra_args=None, min_throughput=None): +def intel_xpu_benchmark( + extra_args=None, min_throughput=None, mem_fraction_static="0.4" +): def decorator(test_func): @wraps(test_func) def wrapper(self): - _cleanup_xpu_memory() common_args = [ "--disable-radix", "--trust-remote-code", "--mem-fraction-static", - "0.4", + str(mem_fraction_static), "--batch-size", "1", "--device", @@ -48,12 +35,9 @@ def intel_xpu_benchmark(extra_args=None, min_throughput=None): full_args = common_args + ci_args + (extra_args or []) model = test_func(self) - try: - prefill_latency, decode_throughput, decode_latency = ( - run_bench_one_batch(model, full_args) - ) - finally: - _cleanup_xpu_memory() + prefill_latency, decode_throughput, decode_latency = run_bench_one_batch( + model, full_args + ) print(f"{model=}") print(f"{prefill_latency=}") @@ -70,11 +54,14 @@ def intel_xpu_benchmark(extra_args=None, min_throughput=None): class TestIntelXPUBackend(CustomTestCase): - @intel_xpu_benchmark(min_throughput=10) + @intel_xpu_benchmark(min_throughput=10, mem_fraction_static="0.3") def test_latency_qwen_model(self): return DEFAULT_SMALL_MODEL_NAME_FOR_TEST_QWEN - @intel_xpu_benchmark(["--attention-backend", "intel_xpu", "--page-size", "128"]) + @intel_xpu_benchmark( + ["--attention-backend", "intel_xpu", "--page-size", "128"], + mem_fraction_static="0.5", + ) def test_attention_backend(self): return DEFAULT_SMALL_MODEL_NAME_FOR_TEST_BASE