From fd390365604e148dc9efa34613245ad4f84431d6 Mon Sep 17 00:00:00 2001 From: "Sun, Xuehao" Date: Thu, 6 Aug 2026 13:24:18 +0800 Subject: [PATCH 01/18] Add pytest-timeout to unit test scripts for improved timeout handling Signed-off-by: Sun, Xuehao --- .../scripts/cuda_unit_test/run_cuda_ut.sh | 13 ++++++++----- .azure-pipelines/scripts/ut/run_ut.sh | 16 ++++++++++------ .azure-pipelines/scripts/ut/run_ut_cuda.sh | 2 +- .azure-pipelines/scripts/ut/run_ut_hpu.sh | 4 +++- .azure-pipelines/scripts/ut/run_ut_xpu.sh | 17 ++++++++++------- 5 files changed, 32 insertions(+), 20 deletions(-) diff --git a/.azure-pipelines/scripts/cuda_unit_test/run_cuda_ut.sh b/.azure-pipelines/scripts/cuda_unit_test/run_cuda_ut.sh index b8137f84b8..d9ef90a033 100644 --- a/.azure-pipelines/scripts/cuda_unit_test/run_cuda_ut.sh +++ b/.azure-pipelines/scripts/cuda_unit_test/run_cuda_ut.sh @@ -68,7 +68,7 @@ function run_unit_test() { uv pip install -r test/unit/test_cuda/requirements.txt uv pip install -r test/unit/test_cuda/requirements_diffusion.txt uv pip install -U transformers chardet - uv pip install -U pytest-cov + uv pip install -U pytest-cov pytest-timeout uv pip install kernels==0.15.2 # For sm120: https://github.com/huggingface/transformers/blob/v5.13.1/setup.py#L93 uv pip uninstall torch torchvision uv pip install torch==2.13.0 torchvision torchao --index-url https://download.pytorch.org/whl/cu130 @@ -100,7 +100,10 @@ function run_unit_test() { local test_basename=$(basename ${test_file} .py) local ut_log_name=${LOG_DIR}/unittest_cuda_${test_basename}.log - pytest -m "not skip_ci" --cov=auto_round --cov-report= --cov-append -vs --disable-warnings --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} + pytest -m "not skip_ci" --timeout=30 --session-timeout=600 \ + --cov=auto_round --cov-report= --cov-append \ + -vs --disable-warnings --junitxml="${ut_log_name%.log}.xml" \ + ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" done [ -f .coverage ] && cp .coverage "${LOG_DIR}/.coverage.part${test_part}" @@ -113,7 +116,7 @@ function run_unit_test_llmc() { cd "${BUILD_SOURCESDIRECTORY}" || exit 1 rm -rf /root/.venv uv venv --python=3.12 /root/.venv - uv pip install -U pytest-cov + uv pip install -U pytest-cov pytest-timeout BUILD_TYPE="nightly" uv pip install \ -r test/integration/test_cuda/requirements_llmc.txt \ --extra-index-url https://download.pytorch.org/whl/cu130 \ @@ -144,7 +147,7 @@ function run_unit_test_sglang() { cd "${BUILD_SOURCESDIRECTORY}" || exit 1 rm -rf /root/.venv uv venv --python=3.12 /root/.venv - uv pip install -U pytest-cov + uv pip install -U pytest-cov pytest-timeout uv pip install -r test/integration/test_cuda/requirements_sglang.txt \ --prerelease=allow \ --extra-index-url https://download.pytorch.org/whl/cu130 \ @@ -175,7 +178,7 @@ function run_unit_test_vllm() { cd "${BUILD_SOURCESDIRECTORY}" || exit 1 rm -rf /root/.venv uv venv --python=3.12 /root/.venv - uv pip install -U pytest-cov + uv pip install -U pytest-cov pytest-timeout uv pip install -r test/integration/test_cuda/requirements_vllm.txt \ --extra-index-url https://download.pytorch.org/whl/cu130 \ --index-strategy unsafe-best-match diff --git a/.azure-pipelines/scripts/ut/run_ut.sh b/.azure-pipelines/scripts/ut/run_ut.sh index 8b29478264..e3e5c46124 100644 --- a/.azure-pipelines/scripts/ut/run_ut.sh +++ b/.azure-pipelines/scripts/ut/run_ut.sh @@ -22,7 +22,7 @@ function setup_environment() { git clone -b master --quiet --single-branch https://github.com/ggml-org/llama.cpp.git && cd llama.cpp/gguf-py && uv pip install . # install unit report dependencies - uv pip install pytest-cov + uv pip install pytest-cov pytest-timeout uv pip install -U chardet uv pip list @@ -91,7 +91,7 @@ function run_unit_test() { local ut_log_name=${LOG_DIR}/unittest_${test_basename}.log numactl --physcpubind="${NUMA_CPUSET:-0-15}" --membind="${NUMA_NODE:-0}" \ - pytest --cov=auto_round --cov-report= --cov-append \ + pytest --timeout=30 --session-timeout=600 --cov=auto_round --cov-report= --cov-append \ -vs --disable-warnings --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" done @@ -102,7 +102,7 @@ function run_inc_unit_test() { INC_PT_ONLY=1 uv pip install -r /auto-round/test/integration/test_cpu/requirements_inc.txt --extra-index-url https://download.pytorch.org/whl/cpu echo "##[endgroup]" - cd /auto-round/test || exit 1 + cd /auto-round/test/integration || exit 1 for test_file in $(find ./test_cpu -name "test_inc*.py" | sort); do echo "##[group]Running ${test_file}..." @@ -110,7 +110,7 @@ function run_inc_unit_test() { local ut_log_name=${LOG_DIR}/unittest_${test_basename}.log numactl --physcpubind="${NUMA_CPUSET:-0-15}" --membind="${NUMA_NODE:-0}" \ - pytest --cov=auto_round --cov-report= --cov-append \ + pytest --timeout=30 --session-timeout=600 --cov=auto_round --cov-report= --cov-append \ -vs --disable-warnings --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" done @@ -123,7 +123,7 @@ function run_llmc_unit_test() { cd /auto-round && uv pip install . echo "##[endgroup]" - cd /auto-round/test || exit 1 + cd /auto-round/test/integration || exit 1 for test_file in $(find ./test_cpu -name "test_llmc*.py" | sort); do echo "##[group]Running ${test_file}..." @@ -131,7 +131,7 @@ function run_llmc_unit_test() { local ut_log_name=${LOG_DIR}/unittest_${test_basename}.log numactl --physcpubind="${NUMA_CPUSET:-0-15}" --membind="${NUMA_NODE:-0}" \ - pytest --cov=auto_round --cov-report= --cov-append \ + pytest --timeout=30 --session-timeout=600 --cov=auto_round --cov-report= --cov-append \ -vs --disable-warnings --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" done @@ -147,6 +147,10 @@ function collect_log() { function main() { setup_environment run_unit_test + if [ "$test_part" -eq 5 ] && [ "$NIGHTLY_TEST" = 1 ]; then + run_inc_unit_test + run_llmc_unit_test + fi collect_log check_storage_usage print_summary diff --git a/.azure-pipelines/scripts/ut/run_ut_cuda.sh b/.azure-pipelines/scripts/ut/run_ut_cuda.sh index d37f804c16..4fb5cffa21 100644 --- a/.azure-pipelines/scripts/ut/run_ut_cuda.sh +++ b/.azure-pipelines/scripts/ut/run_ut_cuda.sh @@ -31,7 +31,7 @@ function create_conda_env() { export PATH=/usr/local/cuda/bin${PATH:+:${PATH}} export LD_LIBRARY_PATH=$(python -c "import site; print(site.getsitepackages()[0])")/nvidia/nvjitlink/lib:$LD_LIBRARY_PATH fi - uv pip install pytest-cov cmake requests ninja psutil + uv pip install pytest-cov pytest-timeout cmake requests ninja psutil uv cache prune } diff --git a/.azure-pipelines/scripts/ut/run_ut_hpu.sh b/.azure-pipelines/scripts/ut/run_ut_hpu.sh index 70399b1aed..2dc546f866 100644 --- a/.azure-pipelines/scripts/ut/run_ut_hpu.sh +++ b/.azure-pipelines/scripts/ut/run_ut_hpu.sh @@ -8,7 +8,7 @@ function setup_environment() { export TZ='Asia/Shanghai' export TQDM_MININTERVAL=60 export HF_HUB_DISABLE_PROGRESS_BARS=1 - pip install pytest-cov + pip install pytest-cov pytest-timeout pip list echo "##[endgroup]" @@ -34,6 +34,7 @@ function run_unit_test() { echo "##[group]Running ${test_file} in HPU lazy mode..." local ut_log_name="${LOG_DIR}/unittest_lazy_${test_basename}.log" PT_HPU_LAZY_MODE=1 pytest --cov="${auto_round_path}" \ + --timeout=30 --session-timeout=600 \ --cov-report= --cov-append -vs --disable-warnings \ --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" @@ -41,6 +42,7 @@ function run_unit_test() { echo "##[group]Running ${test_file} in HPU compile mode..." local ut_log_name="${LOG_DIR}/unittest_compile_${test_basename}.log" PT_HPU_LAZY_MODE=0 pytest --mode compile --cov="${auto_round_path}" \ + --timeout=30 --session-timeout=600 \ --cov-report= --cov-append -vs --disable-warnings \ --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" diff --git a/.azure-pipelines/scripts/ut/run_ut_xpu.sh b/.azure-pipelines/scripts/ut/run_ut_xpu.sh index ff3899d6e7..79d7067672 100644 --- a/.azure-pipelines/scripts/ut/run_ut_xpu.sh +++ b/.azure-pipelines/scripts/ut/run_ut_xpu.sh @@ -5,7 +5,7 @@ source /auto-round/.azure-pipelines/scripts/change_color.sh function setup_environment() { echo "##[group]set up UT env..." - uv pip install pytest-cov + uv pip install pytest-cov pytest-timeout uv pip list echo "##[endgroup]" @@ -39,8 +39,9 @@ function run_unit_test() { echo "##[group]Running ark ${test_file}..." local ut_log_name="${LOG_DIR}/unittest_ark_${test_basename}.log" numactl --physcpubind="${NUMA_CPUSET:-0-27}" --membind="${NUMA_NODE:-0}" \ - pytest --cov="${auto_round_path}" --cov-report= --cov-append -vs --disable-warnings \ - --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} + pytest --timeout=30 --session-timeout=600 \ + --cov="${auto_round_path}" --cov-report= --cov-append -vs --disable-warnings \ + --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" done @@ -50,8 +51,9 @@ function run_unit_test() { echo "##[group]Running xpu ${test_file}..." local ut_log_name="${LOG_DIR}/unittest_xpu_${test_basename}.log" numactl --physcpubind="${NUMA_CPUSET:-0-27}" --membind="${NUMA_NODE:-0}" \ - pytest --cov="${auto_round_path}" --cov-report= --cov-append -vs --disable-warnings \ - --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} + pytest --timeout=30 --session-timeout=600 \ + --cov="${auto_round_path}" --cov-report= --cov-append -vs --disable-warnings \ + --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" done } @@ -70,8 +72,9 @@ function run_unit_test_llmc() { echo "##[group]Running xpu llmc ${test_file}..." local ut_log_name="${LOG_DIR}/unittest_xpu_${test_basename}.log" numactl --physcpubind="${NUMA_CPUSET:-0-27}" --membind="${NUMA_NODE:-0}" \ - pytest --cov="${auto_round_path}" --cov-report= --cov-append -vs --disable-warnings \ - --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} + pytest --timeout=30 --session-timeout=600 \ + --cov="${auto_round_path}" --cov-report= --cov-append -vs --disable-warnings \ + --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" done } From 6261dabb8327d3e65e2a37ffe691a8590cbd4202 Mon Sep 17 00:00:00 2001 From: "Sun, Xuehao" Date: Thu, 6 Aug 2026 14:07:14 +0800 Subject: [PATCH 02/18] Add duration tracking to pytest commands and increase timeout for specific tests Signed-off-by: Sun, Xuehao --- .../scripts/cuda_unit_test/run_cuda_ut.sh | 8 ++++---- .azure-pipelines/scripts/ut/run_ut.sh | 9 ++++++--- .azure-pipelines/scripts/ut/run_ut_cuda.sh | 15 ++++++++++----- .azure-pipelines/scripts/ut/run_ut_hpu.sh | 4 ++-- .azure-pipelines/scripts/ut/run_ut_xpu.sh | 6 +++--- test/unit/test_cpu/export/test_gguf_format.py | 2 ++ test/unit/test_cpu/models/test_diffusion.py | 2 ++ 7 files changed, 29 insertions(+), 17 deletions(-) diff --git a/.azure-pipelines/scripts/cuda_unit_test/run_cuda_ut.sh b/.azure-pipelines/scripts/cuda_unit_test/run_cuda_ut.sh index d9ef90a033..68595f8caf 100644 --- a/.azure-pipelines/scripts/cuda_unit_test/run_cuda_ut.sh +++ b/.azure-pipelines/scripts/cuda_unit_test/run_cuda_ut.sh @@ -102,7 +102,7 @@ function run_unit_test() { pytest -m "not skip_ci" --timeout=30 --session-timeout=600 \ --cov=auto_round --cov-report= --cov-append \ - -vs --disable-warnings --junitxml="${ut_log_name%.log}.xml" \ + -vs --disable-warnings --durations=0 --junitxml="${ut_log_name%.log}.xml" \ ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" done @@ -134,7 +134,7 @@ function run_unit_test_llmc() { echo "##[group]Running ${test_file}..." local test_basename=$(basename ${test_file} .py) local ut_log_name=${LOG_DIR}/unittest_cuda_llmc_${test_basename}.log - pytest -m "not skip_ci" --cov=auto_round --cov-report= --cov-append -vs --disable-warnings --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} + pytest -m "not skip_ci" --cov=auto_round --cov-report= --cov-append -vs --disable-warnings --durations=0 --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" done [ -f .coverage ] && cp .coverage "${LOG_DIR}/.coverage.llmc" @@ -165,7 +165,7 @@ function run_unit_test_sglang() { echo "##[group]Running ${test_file}..." local test_basename=$(basename ${test_file} .py) local ut_log_name=${LOG_DIR}/unittest_cuda_sglang_${test_basename}.log - pytest -m "not skip_ci" --cov=auto_round --cov-report= --cov-append -vs --disable-warnings --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} + pytest -m "not skip_ci" --cov=auto_round --cov-report= --cov-append -vs --disable-warnings --durations=0 --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" done [ -f .coverage ] && cp .coverage "${LOG_DIR}/.coverage.sglang" @@ -196,7 +196,7 @@ function run_unit_test_vllm() { echo "##[group]Running ${test_file}..." local test_basename=$(basename ${test_file} .py) local ut_log_name=${LOG_DIR}/unittest_cuda_vllm_${test_basename}.log - pytest -m "not skip_ci" --cov=auto_round --cov-report= --cov-append -vs --disable-warnings --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} + pytest -m "not skip_ci" --cov=auto_round --cov-report= --cov-append -vs --disable-warnings --durations=0 --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" done [ -f .coverage ] && cp .coverage "${LOG_DIR}/.coverage.vllm" diff --git a/.azure-pipelines/scripts/ut/run_ut.sh b/.azure-pipelines/scripts/ut/run_ut.sh index e3e5c46124..4e38a60215 100644 --- a/.azure-pipelines/scripts/ut/run_ut.sh +++ b/.azure-pipelines/scripts/ut/run_ut.sh @@ -91,7 +91,8 @@ function run_unit_test() { local ut_log_name=${LOG_DIR}/unittest_${test_basename}.log numactl --physcpubind="${NUMA_CPUSET:-0-15}" --membind="${NUMA_NODE:-0}" \ - pytest --timeout=30 --session-timeout=600 --cov=auto_round --cov-report= --cov-append \ + pytest --timeout=30 --session-timeout=600 --durations=0 \ + --cov=auto_round --cov-report= --cov-append \ -vs --disable-warnings --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" done @@ -110,7 +111,8 @@ function run_inc_unit_test() { local ut_log_name=${LOG_DIR}/unittest_${test_basename}.log numactl --physcpubind="${NUMA_CPUSET:-0-15}" --membind="${NUMA_NODE:-0}" \ - pytest --timeout=30 --session-timeout=600 --cov=auto_round --cov-report= --cov-append \ + pytest --timeout=30 --session-timeout=600 --durations=0 \ + --cov=auto_round --cov-report= --cov-append \ -vs --disable-warnings --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" done @@ -131,7 +133,8 @@ function run_llmc_unit_test() { local ut_log_name=${LOG_DIR}/unittest_${test_basename}.log numactl --physcpubind="${NUMA_CPUSET:-0-15}" --membind="${NUMA_NODE:-0}" \ - pytest --timeout=30 --session-timeout=600 --cov=auto_round --cov-report= --cov-append \ + pytest --timeout=30 --session-timeout=600 --durations=0 \ + --cov=auto_round --cov-report= --cov-append \ -vs --disable-warnings --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" done diff --git a/.azure-pipelines/scripts/ut/run_ut_cuda.sh b/.azure-pipelines/scripts/ut/run_ut_cuda.sh index 4fb5cffa21..f729fc0885 100644 --- a/.azure-pipelines/scripts/ut/run_ut_cuda.sh +++ b/.azure-pipelines/scripts/ut/run_ut_cuda.sh @@ -111,7 +111,8 @@ function run_unit_test() { local ut_log_name=${LOG_DIR}/unittest_cuda_${test_basename}.log echo "Running ${test_file}..." - pytest --cov=auto_round --cov-report= --cov-append -vs --disable-warnings ${test_file} 2>&1 | tee ${ut_log_name} + pytest --cov=auto_round --cov-report= --cov-append \ + --durations=0 -vs --disable-warnings ${test_file} 2>&1 | tee ${ut_log_name} done [ -f .coverage ] && cp .coverage ${LOG_DIR}/.coverage.unit @@ -145,7 +146,8 @@ function run_unit_test_vlm() { local ut_log_name=${LOG_DIR}/unittest_cuda_vlm_${test_basename}.log echo "Running ${test_file}..." - pytest --cov=auto_round --cov-report= --cov-append -vs --disable-warnings ${test_file} 2>&1 | tee ${ut_log_name} + pytest --cov=auto_round --cov-report= --cov-append \ + --durations=0 -vs --disable-warnings ${test_file} 2>&1 | tee ${ut_log_name} done [ -f .coverage ] && cp .coverage ${LOG_DIR}/.coverage.vlm @@ -174,7 +176,8 @@ function run_unit_test_llmc() { local ut_log_name=${LOG_DIR}/unittest_cuda_llmc_${test_basename}.log echo "Running ${test_file}..." - pytest --cov=auto_round --cov-report= --cov-append -vs --disable-warnings ${test_file} 2>&1 | tee ${ut_log_name} + pytest --cov=auto_round --cov-report= --cov-append \ + --durations=0 -vs --disable-warnings ${test_file} 2>&1 | tee ${ut_log_name} done [ -f .coverage ] && cp .coverage ${LOG_DIR}/.coverage.llmc @@ -207,7 +210,8 @@ function run_unit_test_sglang() { local ut_log_name=${LOG_DIR}/unittest_cuda_sglang_${test_basename}.log echo "Running ${test_file}..." - pytest --cov=auto_round --cov-report= --cov-append -vs --disable-warnings ${test_file} 2>&1 | tee ${ut_log_name} + pytest --cov=auto_round --cov-report= --cov-append \ + --durations=0 -vs --disable-warnings ${test_file} 2>&1 | tee ${ut_log_name} done [ -f .coverage ] && cp .coverage ${LOG_DIR}/.coverage.sglang @@ -241,7 +245,8 @@ function run_unit_test_vllm() { local ut_log_name=${LOG_DIR}/unittest_cuda_vllm_${test_basename}.log echo "Running ${test_file}..." - pytest --cov=auto_round --cov-report= --cov-append -vs --disable-warnings ${test_file} 2>&1 | tee ${ut_log_name} + pytest --cov=auto_round --cov-report= --cov-append \ + --durations=0 -vs --disable-warnings ${test_file} 2>&1 | tee ${ut_log_name} done [ -f .coverage ] && cp .coverage ${LOG_DIR}/.coverage.vllm diff --git a/.azure-pipelines/scripts/ut/run_ut_hpu.sh b/.azure-pipelines/scripts/ut/run_ut_hpu.sh index 2dc546f866..0e5ee9c80e 100644 --- a/.azure-pipelines/scripts/ut/run_ut_hpu.sh +++ b/.azure-pipelines/scripts/ut/run_ut_hpu.sh @@ -34,7 +34,7 @@ function run_unit_test() { echo "##[group]Running ${test_file} in HPU lazy mode..." local ut_log_name="${LOG_DIR}/unittest_lazy_${test_basename}.log" PT_HPU_LAZY_MODE=1 pytest --cov="${auto_round_path}" \ - --timeout=30 --session-timeout=600 \ + --timeout=30 --session-timeout=600 --durations=0 \ --cov-report= --cov-append -vs --disable-warnings \ --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" @@ -42,7 +42,7 @@ function run_unit_test() { echo "##[group]Running ${test_file} in HPU compile mode..." local ut_log_name="${LOG_DIR}/unittest_compile_${test_basename}.log" PT_HPU_LAZY_MODE=0 pytest --mode compile --cov="${auto_round_path}" \ - --timeout=30 --session-timeout=600 \ + --timeout=30 --session-timeout=600 --durations=0 \ --cov-report= --cov-append -vs --disable-warnings \ --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" diff --git a/.azure-pipelines/scripts/ut/run_ut_xpu.sh b/.azure-pipelines/scripts/ut/run_ut_xpu.sh index 79d7067672..5cba44be8b 100644 --- a/.azure-pipelines/scripts/ut/run_ut_xpu.sh +++ b/.azure-pipelines/scripts/ut/run_ut_xpu.sh @@ -39,7 +39,7 @@ function run_unit_test() { echo "##[group]Running ark ${test_file}..." local ut_log_name="${LOG_DIR}/unittest_ark_${test_basename}.log" numactl --physcpubind="${NUMA_CPUSET:-0-27}" --membind="${NUMA_NODE:-0}" \ - pytest --timeout=30 --session-timeout=600 \ + pytest --timeout=30 --session-timeout=600 --durations=0 \ --cov="${auto_round_path}" --cov-report= --cov-append -vs --disable-warnings \ --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" @@ -51,7 +51,7 @@ function run_unit_test() { echo "##[group]Running xpu ${test_file}..." local ut_log_name="${LOG_DIR}/unittest_xpu_${test_basename}.log" numactl --physcpubind="${NUMA_CPUSET:-0-27}" --membind="${NUMA_NODE:-0}" \ - pytest --timeout=30 --session-timeout=600 \ + pytest --timeout=30 --session-timeout=600 --durations=0 \ --cov="${auto_round_path}" --cov-report= --cov-append -vs --disable-warnings \ --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" @@ -72,7 +72,7 @@ function run_unit_test_llmc() { echo "##[group]Running xpu llmc ${test_file}..." local ut_log_name="${LOG_DIR}/unittest_xpu_${test_basename}.log" numactl --physcpubind="${NUMA_CPUSET:-0-27}" --membind="${NUMA_NODE:-0}" \ - pytest --timeout=30 --session-timeout=600 \ + pytest --timeout=30 --session-timeout=600 --durations=0 \ --cov="${auto_round_path}" --cov-report= --cov-append -vs --disable-warnings \ --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" diff --git a/test/unit/test_cpu/export/test_gguf_format.py b/test/unit/test_cpu/export/test_gguf_format.py index 81ffdc3cfa..2e7db993f4 100644 --- a/test/unit/test_cpu/export/test_gguf_format.py +++ b/test/unit/test_cpu/export/test_gguf_format.py @@ -89,6 +89,7 @@ def test_q2_k_s_routes_data_driven(self, tiny_qwen_model_path): assert type(autoround).__name__ == "CompressionOrchestrator" assert isinstance(autoround.quantize_config, OptimizedRTNConfig) + @pytest.mark.timeout(60) def test_func(self): bits, group_size, sym = 4, 128, True autoround = AutoRound( @@ -106,6 +107,7 @@ def test_func(self): model = AutoModelForCausalLM.from_pretrained(quantized_model_path, gguf_file=gguf_file, device_map="auto") eval_generated_prompt(model, self.tokenizer) + @pytest.mark.timeout(60) def test_q4_k_m(self, dataloader, tiny_qwen_model_path): model_name = tiny_qwen_model_path layer_config = { diff --git a/test/unit/test_cpu/models/test_diffusion.py b/test/unit/test_cpu/models/test_diffusion.py index d6b45df26b..ef5807057b 100644 --- a/test/unit/test_cpu/models/test_diffusion.py +++ b/test/unit/test_cpu/models/test_diffusion.py @@ -23,6 +23,7 @@ def setup_flux(): return pipe, output_dir +@pytest.mark.timeout(120) def test_flux_saving(setup_flux): pipe, output_dir = setup_flux autoround = AutoRound( @@ -39,6 +40,7 @@ def test_flux_saving(setup_flux): shutil.rmtree(output_dir, ignore_errors=True) +@pytest.mark.timeout(120) def test_flux(setup_flux): pipe, output_dir = setup_flux autoround = AutoRound( From 84a1869654a73ef619750d75d0f52407eb7e8d6a Mon Sep 17 00:00:00 2001 From: "Sun, Xuehao" Date: Thu, 6 Aug 2026 14:10:48 +0800 Subject: [PATCH 03/18] Add disable_opt_rtn parameter to quantization in TestAutoRoundFP Signed-off-by: Sun, Xuehao --- test/unit/test_cpu/quantization/test_mxfp_nvfp.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/unit/test_cpu/quantization/test_mxfp_nvfp.py b/test/unit/test_cpu/quantization/test_mxfp_nvfp.py index a985d4e6c8..40037d82e3 100644 --- a/test/unit/test_cpu/quantization/test_mxfp_nvfp.py +++ b/test/unit/test_cpu/quantization/test_mxfp_nvfp.py @@ -55,6 +55,7 @@ def test_nvfp4_moe_actmax_rtn(self, tiny_deepseek_v2_model_path_cpu, dataloader) dataset=dataloader, layer_config=layer_config, trust_remote_code=False, + disable_opt_rtn=True, ) compressed_model, _ = autoround.quantize() moe = compressed_model.model.layers[1].mlp From aefe6afe83cec2968429b324f0d89d535a0fac4e Mon Sep 17 00:00:00 2001 From: "Sun, Xuehao" Date: Thu, 6 Aug 2026 14:20:23 +0800 Subject: [PATCH 04/18] Add COVERAGE_CORE=sysmon to pytest commands for improved coverage tracking Signed-off-by: Sun, Xuehao --- .azure-pipelines/scripts/cuda_unit_test/run_cuda_ut.sh | 8 ++++---- .azure-pipelines/scripts/ut/run_ark_ut.sh | 2 +- .azure-pipelines/scripts/ut/run_ut.sh | 6 +++--- .azure-pipelines/scripts/ut/run_ut_cuda.sh | 10 +++++----- .azure-pipelines/scripts/ut/run_ut_hpu.sh | 4 ++-- .azure-pipelines/scripts/ut/run_ut_xpu.sh | 6 +++--- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.azure-pipelines/scripts/cuda_unit_test/run_cuda_ut.sh b/.azure-pipelines/scripts/cuda_unit_test/run_cuda_ut.sh index 68595f8caf..ad248cf71c 100644 --- a/.azure-pipelines/scripts/cuda_unit_test/run_cuda_ut.sh +++ b/.azure-pipelines/scripts/cuda_unit_test/run_cuda_ut.sh @@ -100,7 +100,7 @@ function run_unit_test() { local test_basename=$(basename ${test_file} .py) local ut_log_name=${LOG_DIR}/unittest_cuda_${test_basename}.log - pytest -m "not skip_ci" --timeout=30 --session-timeout=600 \ + COVERAGE_CORE=sysmon pytest -m "not skip_ci" --timeout=30 --session-timeout=600 \ --cov=auto_round --cov-report= --cov-append \ -vs --disable-warnings --durations=0 --junitxml="${ut_log_name%.log}.xml" \ ${test_file} 2>&1 | tee ${ut_log_name} @@ -134,7 +134,7 @@ function run_unit_test_llmc() { echo "##[group]Running ${test_file}..." local test_basename=$(basename ${test_file} .py) local ut_log_name=${LOG_DIR}/unittest_cuda_llmc_${test_basename}.log - pytest -m "not skip_ci" --cov=auto_round --cov-report= --cov-append -vs --disable-warnings --durations=0 --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} + COVERAGE_CORE=sysmon pytest -m "not skip_ci" --cov=auto_round --cov-report= --cov-append -vs --disable-warnings --durations=0 --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" done [ -f .coverage ] && cp .coverage "${LOG_DIR}/.coverage.llmc" @@ -165,7 +165,7 @@ function run_unit_test_sglang() { echo "##[group]Running ${test_file}..." local test_basename=$(basename ${test_file} .py) local ut_log_name=${LOG_DIR}/unittest_cuda_sglang_${test_basename}.log - pytest -m "not skip_ci" --cov=auto_round --cov-report= --cov-append -vs --disable-warnings --durations=0 --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} + COVERAGE_CORE=sysmon pytest -m "not skip_ci" --cov=auto_round --cov-report= --cov-append -vs --disable-warnings --durations=0 --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" done [ -f .coverage ] && cp .coverage "${LOG_DIR}/.coverage.sglang" @@ -196,7 +196,7 @@ function run_unit_test_vllm() { echo "##[group]Running ${test_file}..." local test_basename=$(basename ${test_file} .py) local ut_log_name=${LOG_DIR}/unittest_cuda_vllm_${test_basename}.log - pytest -m "not skip_ci" --cov=auto_round --cov-report= --cov-append -vs --disable-warnings --durations=0 --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} + COVERAGE_CORE=sysmon pytest -m "not skip_ci" --cov=auto_round --cov-report= --cov-append -vs --disable-warnings --durations=0 --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" done [ -f .coverage ] && cp .coverage "${LOG_DIR}/.coverage.vllm" diff --git a/.azure-pipelines/scripts/ut/run_ark_ut.sh b/.azure-pipelines/scripts/ut/run_ark_ut.sh index e99e2c883f..b59accd5c2 100644 --- a/.azure-pipelines/scripts/ut/run_ark_ut.sh +++ b/.azure-pipelines/scripts/ut/run_ark_ut.sh @@ -25,7 +25,7 @@ function run_unit_test() { echo "##[group]Running ark ${test_file}..." local ut_log_name="${LOG_DIR}/unittest_ark_${test_basename}.log" - pytest -v ${test_file} 2>&1 | tee ${ut_log_name} + COVERAGE_CORE=sysmon pytest -v ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" done } diff --git a/.azure-pipelines/scripts/ut/run_ut.sh b/.azure-pipelines/scripts/ut/run_ut.sh index 4e38a60215..64a737805f 100644 --- a/.azure-pipelines/scripts/ut/run_ut.sh +++ b/.azure-pipelines/scripts/ut/run_ut.sh @@ -90,7 +90,7 @@ function run_unit_test() { local test_basename=$(basename ${test_file} .py) local ut_log_name=${LOG_DIR}/unittest_${test_basename}.log - numactl --physcpubind="${NUMA_CPUSET:-0-15}" --membind="${NUMA_NODE:-0}" \ + COVERAGE_CORE=sysmon numactl --physcpubind="${NUMA_CPUSET:-0-15}" --membind="${NUMA_NODE:-0}" \ pytest --timeout=30 --session-timeout=600 --durations=0 \ --cov=auto_round --cov-report= --cov-append \ -vs --disable-warnings --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} @@ -110,7 +110,7 @@ function run_inc_unit_test() { local test_basename=$(basename ${test_file} .py) local ut_log_name=${LOG_DIR}/unittest_${test_basename}.log - numactl --physcpubind="${NUMA_CPUSET:-0-15}" --membind="${NUMA_NODE:-0}" \ + COVERAGE_CORE=sysmon numactl --physcpubind="${NUMA_CPUSET:-0-15}" --membind="${NUMA_NODE:-0}" \ pytest --timeout=30 --session-timeout=600 --durations=0 \ --cov=auto_round --cov-report= --cov-append \ -vs --disable-warnings --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} @@ -132,7 +132,7 @@ function run_llmc_unit_test() { local test_basename=$(basename ${test_file} .py) local ut_log_name=${LOG_DIR}/unittest_${test_basename}.log - numactl --physcpubind="${NUMA_CPUSET:-0-15}" --membind="${NUMA_NODE:-0}" \ + COVERAGE_CORE=sysmon numactl --physcpubind="${NUMA_CPUSET:-0-15}" --membind="${NUMA_NODE:-0}" \ pytest --timeout=30 --session-timeout=600 --durations=0 \ --cov=auto_round --cov-report= --cov-append \ -vs --disable-warnings --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} diff --git a/.azure-pipelines/scripts/ut/run_ut_cuda.sh b/.azure-pipelines/scripts/ut/run_ut_cuda.sh index f729fc0885..617f4ea0d6 100644 --- a/.azure-pipelines/scripts/ut/run_ut_cuda.sh +++ b/.azure-pipelines/scripts/ut/run_ut_cuda.sh @@ -111,7 +111,7 @@ function run_unit_test() { local ut_log_name=${LOG_DIR}/unittest_cuda_${test_basename}.log echo "Running ${test_file}..." - pytest --cov=auto_round --cov-report= --cov-append \ + COVERAGE_CORE=sysmon pytest --cov=auto_round --cov-report= --cov-append \ --durations=0 -vs --disable-warnings ${test_file} 2>&1 | tee ${ut_log_name} done [ -f .coverage ] && cp .coverage ${LOG_DIR}/.coverage.unit @@ -146,7 +146,7 @@ function run_unit_test_vlm() { local ut_log_name=${LOG_DIR}/unittest_cuda_vlm_${test_basename}.log echo "Running ${test_file}..." - pytest --cov=auto_round --cov-report= --cov-append \ + COVERAGE_CORE=sysmon pytest --cov=auto_round --cov-report= --cov-append \ --durations=0 -vs --disable-warnings ${test_file} 2>&1 | tee ${ut_log_name} done [ -f .coverage ] && cp .coverage ${LOG_DIR}/.coverage.vlm @@ -176,7 +176,7 @@ function run_unit_test_llmc() { local ut_log_name=${LOG_DIR}/unittest_cuda_llmc_${test_basename}.log echo "Running ${test_file}..." - pytest --cov=auto_round --cov-report= --cov-append \ + COVERAGE_CORE=sysmon pytest --cov=auto_round --cov-report= --cov-append \ --durations=0 -vs --disable-warnings ${test_file} 2>&1 | tee ${ut_log_name} done [ -f .coverage ] && cp .coverage ${LOG_DIR}/.coverage.llmc @@ -210,7 +210,7 @@ function run_unit_test_sglang() { local ut_log_name=${LOG_DIR}/unittest_cuda_sglang_${test_basename}.log echo "Running ${test_file}..." - pytest --cov=auto_round --cov-report= --cov-append \ + COVERAGE_CORE=sysmon pytest --cov=auto_round --cov-report= --cov-append \ --durations=0 -vs --disable-warnings ${test_file} 2>&1 | tee ${ut_log_name} done [ -f .coverage ] && cp .coverage ${LOG_DIR}/.coverage.sglang @@ -245,7 +245,7 @@ function run_unit_test_vllm() { local ut_log_name=${LOG_DIR}/unittest_cuda_vllm_${test_basename}.log echo "Running ${test_file}..." - pytest --cov=auto_round --cov-report= --cov-append \ + COVERAGE_CORE=sysmon pytest --cov=auto_round --cov-report= --cov-append \ --durations=0 -vs --disable-warnings ${test_file} 2>&1 | tee ${ut_log_name} done [ -f .coverage ] && cp .coverage ${LOG_DIR}/.coverage.vllm diff --git a/.azure-pipelines/scripts/ut/run_ut_hpu.sh b/.azure-pipelines/scripts/ut/run_ut_hpu.sh index 0e5ee9c80e..03e0cff416 100644 --- a/.azure-pipelines/scripts/ut/run_ut_hpu.sh +++ b/.azure-pipelines/scripts/ut/run_ut_hpu.sh @@ -33,7 +33,7 @@ function run_unit_test() { echo "##[group]Running ${test_file} in HPU lazy mode..." local ut_log_name="${LOG_DIR}/unittest_lazy_${test_basename}.log" - PT_HPU_LAZY_MODE=1 pytest --cov="${auto_round_path}" \ + COVERAGE_CORE=sysmon PT_HPU_LAZY_MODE=1 pytest --cov="${auto_round_path}" \ --timeout=30 --session-timeout=600 --durations=0 \ --cov-report= --cov-append -vs --disable-warnings \ --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} @@ -41,7 +41,7 @@ function run_unit_test() { echo "##[group]Running ${test_file} in HPU compile mode..." local ut_log_name="${LOG_DIR}/unittest_compile_${test_basename}.log" - PT_HPU_LAZY_MODE=0 pytest --mode compile --cov="${auto_round_path}" \ + COVERAGE_CORE=sysmon PT_HPU_LAZY_MODE=0 pytest --mode compile --cov="${auto_round_path}" \ --timeout=30 --session-timeout=600 --durations=0 \ --cov-report= --cov-append -vs --disable-warnings \ --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} diff --git a/.azure-pipelines/scripts/ut/run_ut_xpu.sh b/.azure-pipelines/scripts/ut/run_ut_xpu.sh index 5cba44be8b..ef6c1ee08c 100644 --- a/.azure-pipelines/scripts/ut/run_ut_xpu.sh +++ b/.azure-pipelines/scripts/ut/run_ut_xpu.sh @@ -38,7 +38,7 @@ function run_unit_test() { echo "##[group]Running ark ${test_file}..." local ut_log_name="${LOG_DIR}/unittest_ark_${test_basename}.log" - numactl --physcpubind="${NUMA_CPUSET:-0-27}" --membind="${NUMA_NODE:-0}" \ + COVERAGE_CORE=sysmon numactl --physcpubind="${NUMA_CPUSET:-0-27}" --membind="${NUMA_NODE:-0}" \ pytest --timeout=30 --session-timeout=600 --durations=0 \ --cov="${auto_round_path}" --cov-report= --cov-append -vs --disable-warnings \ --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} @@ -50,7 +50,7 @@ function run_unit_test() { echo "##[group]Running xpu ${test_file}..." local ut_log_name="${LOG_DIR}/unittest_xpu_${test_basename}.log" - numactl --physcpubind="${NUMA_CPUSET:-0-27}" --membind="${NUMA_NODE:-0}" \ + COVERAGE_CORE=sysmon numactl --physcpubind="${NUMA_CPUSET:-0-27}" --membind="${NUMA_NODE:-0}" \ pytest --timeout=30 --session-timeout=600 --durations=0 \ --cov="${auto_round_path}" --cov-report= --cov-append -vs --disable-warnings \ --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} @@ -71,7 +71,7 @@ function run_unit_test_llmc() { echo "##[group]Running xpu llmc ${test_file}..." local ut_log_name="${LOG_DIR}/unittest_xpu_${test_basename}.log" - numactl --physcpubind="${NUMA_CPUSET:-0-27}" --membind="${NUMA_NODE:-0}" \ + COVERAGE_CORE=sysmon numactl --physcpubind="${NUMA_CPUSET:-0-27}" --membind="${NUMA_NODE:-0}" \ pytest --timeout=30 --session-timeout=600 --durations=0 \ --cov="${auto_round_path}" --cov-report= --cov-append -vs --disable-warnings \ --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} From 32b1088289d4c5f97d41d5f988faaeebd95e7b95 Mon Sep 17 00:00:00 2001 From: "Sun, Xuehao" Date: Thu, 6 Aug 2026 15:00:19 +0800 Subject: [PATCH 05/18] Update pytest duration settings to enforce minimum duration for test reporting Signed-off-by: Sun, Xuehao --- .../scripts/cuda_unit_test/run_cuda_ut.sh | 17 +++++++++++++---- .azure-pipelines/scripts/ut/run_ut.sh | 6 +++--- .azure-pipelines/scripts/ut/run_ut_cuda.sh | 10 +++++----- .azure-pipelines/scripts/ut/run_ut_hpu.sh | 4 ++-- .azure-pipelines/scripts/ut/run_ut_xpu.sh | 6 +++--- 5 files changed, 26 insertions(+), 17 deletions(-) diff --git a/.azure-pipelines/scripts/cuda_unit_test/run_cuda_ut.sh b/.azure-pipelines/scripts/cuda_unit_test/run_cuda_ut.sh index ad248cf71c..31412b09f9 100644 --- a/.azure-pipelines/scripts/cuda_unit_test/run_cuda_ut.sh +++ b/.azure-pipelines/scripts/cuda_unit_test/run_cuda_ut.sh @@ -102,7 +102,7 @@ function run_unit_test() { COVERAGE_CORE=sysmon pytest -m "not skip_ci" --timeout=30 --session-timeout=600 \ --cov=auto_round --cov-report= --cov-append \ - -vs --disable-warnings --durations=0 --junitxml="${ut_log_name%.log}.xml" \ + -vs --disable-warnings --durations=0 --durations-min=1 --junitxml="${ut_log_name%.log}.xml" \ ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" done @@ -134,7 +134,10 @@ function run_unit_test_llmc() { echo "##[group]Running ${test_file}..." local test_basename=$(basename ${test_file} .py) local ut_log_name=${LOG_DIR}/unittest_cuda_llmc_${test_basename}.log - COVERAGE_CORE=sysmon pytest -m "not skip_ci" --cov=auto_round --cov-report= --cov-append -vs --disable-warnings --durations=0 --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} + COVERAGE_CORE=sysmon pytest -m "not skip_ci" \ + --cov=auto_round --cov-report= --cov-append -vs --disable-warnings \ + --durations=0 --durations-min=1 --junitxml="${ut_log_name%.log}.xml" \ + ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" done [ -f .coverage ] && cp .coverage "${LOG_DIR}/.coverage.llmc" @@ -165,7 +168,10 @@ function run_unit_test_sglang() { echo "##[group]Running ${test_file}..." local test_basename=$(basename ${test_file} .py) local ut_log_name=${LOG_DIR}/unittest_cuda_sglang_${test_basename}.log - COVERAGE_CORE=sysmon pytest -m "not skip_ci" --cov=auto_round --cov-report= --cov-append -vs --disable-warnings --durations=0 --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} + COVERAGE_CORE=sysmon pytest -m "not skip_ci" \ + --cov=auto_round --cov-report= --cov-append -vs --disable-warnings \ + --durations=0 --durations-min=1 --junitxml="${ut_log_name%.log}.xml" \ + ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" done [ -f .coverage ] && cp .coverage "${LOG_DIR}/.coverage.sglang" @@ -196,7 +202,10 @@ function run_unit_test_vllm() { echo "##[group]Running ${test_file}..." local test_basename=$(basename ${test_file} .py) local ut_log_name=${LOG_DIR}/unittest_cuda_vllm_${test_basename}.log - COVERAGE_CORE=sysmon pytest -m "not skip_ci" --cov=auto_round --cov-report= --cov-append -vs --disable-warnings --durations=0 --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} + COVERAGE_CORE=sysmon pytest -m "not skip_ci" \ + --cov=auto_round --cov-report= --cov-append -vs --disable-warnings \ + --durations=0 --durations-min=1 --junitxml="${ut_log_name%.log}.xml" \ + ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" done [ -f .coverage ] && cp .coverage "${LOG_DIR}/.coverage.vllm" diff --git a/.azure-pipelines/scripts/ut/run_ut.sh b/.azure-pipelines/scripts/ut/run_ut.sh index 64a737805f..2c45df90e6 100644 --- a/.azure-pipelines/scripts/ut/run_ut.sh +++ b/.azure-pipelines/scripts/ut/run_ut.sh @@ -91,7 +91,7 @@ function run_unit_test() { local ut_log_name=${LOG_DIR}/unittest_${test_basename}.log COVERAGE_CORE=sysmon numactl --physcpubind="${NUMA_CPUSET:-0-15}" --membind="${NUMA_NODE:-0}" \ - pytest --timeout=30 --session-timeout=600 --durations=0 \ + pytest --timeout=30 --session-timeout=600 --durations=0 --durations-min=1 \ --cov=auto_round --cov-report= --cov-append \ -vs --disable-warnings --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" @@ -111,7 +111,7 @@ function run_inc_unit_test() { local ut_log_name=${LOG_DIR}/unittest_${test_basename}.log COVERAGE_CORE=sysmon numactl --physcpubind="${NUMA_CPUSET:-0-15}" --membind="${NUMA_NODE:-0}" \ - pytest --timeout=30 --session-timeout=600 --durations=0 \ + pytest --timeout=30 --session-timeout=600 --durations=0 --durations-min=1 \ --cov=auto_round --cov-report= --cov-append \ -vs --disable-warnings --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" @@ -133,7 +133,7 @@ function run_llmc_unit_test() { local ut_log_name=${LOG_DIR}/unittest_${test_basename}.log COVERAGE_CORE=sysmon numactl --physcpubind="${NUMA_CPUSET:-0-15}" --membind="${NUMA_NODE:-0}" \ - pytest --timeout=30 --session-timeout=600 --durations=0 \ + pytest --timeout=30 --session-timeout=600 --durations=0 --durations-min=1 \ --cov=auto_round --cov-report= --cov-append \ -vs --disable-warnings --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" diff --git a/.azure-pipelines/scripts/ut/run_ut_cuda.sh b/.azure-pipelines/scripts/ut/run_ut_cuda.sh index 617f4ea0d6..e9941c9338 100644 --- a/.azure-pipelines/scripts/ut/run_ut_cuda.sh +++ b/.azure-pipelines/scripts/ut/run_ut_cuda.sh @@ -112,7 +112,7 @@ function run_unit_test() { echo "Running ${test_file}..." COVERAGE_CORE=sysmon pytest --cov=auto_round --cov-report= --cov-append \ - --durations=0 -vs --disable-warnings ${test_file} 2>&1 | tee ${ut_log_name} + --durations=0 --durations-min=1 -vs --disable-warnings ${test_file} 2>&1 | tee ${ut_log_name} done [ -f .coverage ] && cp .coverage ${LOG_DIR}/.coverage.unit @@ -147,7 +147,7 @@ function run_unit_test_vlm() { echo "Running ${test_file}..." COVERAGE_CORE=sysmon pytest --cov=auto_round --cov-report= --cov-append \ - --durations=0 -vs --disable-warnings ${test_file} 2>&1 | tee ${ut_log_name} + --durations=0 --durations-min=1 -vs --disable-warnings ${test_file} 2>&1 | tee ${ut_log_name} done [ -f .coverage ] && cp .coverage ${LOG_DIR}/.coverage.vlm @@ -177,7 +177,7 @@ function run_unit_test_llmc() { echo "Running ${test_file}..." COVERAGE_CORE=sysmon pytest --cov=auto_round --cov-report= --cov-append \ - --durations=0 -vs --disable-warnings ${test_file} 2>&1 | tee ${ut_log_name} + --durations=0 --durations-min=1 -vs --disable-warnings ${test_file} 2>&1 | tee ${ut_log_name} done [ -f .coverage ] && cp .coverage ${LOG_DIR}/.coverage.llmc @@ -211,7 +211,7 @@ function run_unit_test_sglang() { echo "Running ${test_file}..." COVERAGE_CORE=sysmon pytest --cov=auto_round --cov-report= --cov-append \ - --durations=0 -vs --disable-warnings ${test_file} 2>&1 | tee ${ut_log_name} + --durations=0 --durations-min=1 -vs --disable-warnings ${test_file} 2>&1 | tee ${ut_log_name} done [ -f .coverage ] && cp .coverage ${LOG_DIR}/.coverage.sglang @@ -246,7 +246,7 @@ function run_unit_test_vllm() { echo "Running ${test_file}..." COVERAGE_CORE=sysmon pytest --cov=auto_round --cov-report= --cov-append \ - --durations=0 -vs --disable-warnings ${test_file} 2>&1 | tee ${ut_log_name} + --durations=0 --durations-min=1 -vs --disable-warnings ${test_file} 2>&1 | tee ${ut_log_name} done [ -f .coverage ] && cp .coverage ${LOG_DIR}/.coverage.vllm diff --git a/.azure-pipelines/scripts/ut/run_ut_hpu.sh b/.azure-pipelines/scripts/ut/run_ut_hpu.sh index 03e0cff416..67e5b91496 100644 --- a/.azure-pipelines/scripts/ut/run_ut_hpu.sh +++ b/.azure-pipelines/scripts/ut/run_ut_hpu.sh @@ -34,7 +34,7 @@ function run_unit_test() { echo "##[group]Running ${test_file} in HPU lazy mode..." local ut_log_name="${LOG_DIR}/unittest_lazy_${test_basename}.log" COVERAGE_CORE=sysmon PT_HPU_LAZY_MODE=1 pytest --cov="${auto_round_path}" \ - --timeout=30 --session-timeout=600 --durations=0 \ + --timeout=30 --session-timeout=600 --durations=0 --durations-min=1 \ --cov-report= --cov-append -vs --disable-warnings \ --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" @@ -42,7 +42,7 @@ function run_unit_test() { echo "##[group]Running ${test_file} in HPU compile mode..." local ut_log_name="${LOG_DIR}/unittest_compile_${test_basename}.log" COVERAGE_CORE=sysmon PT_HPU_LAZY_MODE=0 pytest --mode compile --cov="${auto_round_path}" \ - --timeout=30 --session-timeout=600 --durations=0 \ + --timeout=30 --session-timeout=600 --durations=0 --durations-min=1 \ --cov-report= --cov-append -vs --disable-warnings \ --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" diff --git a/.azure-pipelines/scripts/ut/run_ut_xpu.sh b/.azure-pipelines/scripts/ut/run_ut_xpu.sh index ef6c1ee08c..d69e6f563f 100644 --- a/.azure-pipelines/scripts/ut/run_ut_xpu.sh +++ b/.azure-pipelines/scripts/ut/run_ut_xpu.sh @@ -39,7 +39,7 @@ function run_unit_test() { echo "##[group]Running ark ${test_file}..." local ut_log_name="${LOG_DIR}/unittest_ark_${test_basename}.log" COVERAGE_CORE=sysmon numactl --physcpubind="${NUMA_CPUSET:-0-27}" --membind="${NUMA_NODE:-0}" \ - pytest --timeout=30 --session-timeout=600 --durations=0 \ + pytest --timeout=30 --session-timeout=600 --durations=0 --durations-min=1 \ --cov="${auto_round_path}" --cov-report= --cov-append -vs --disable-warnings \ --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" @@ -51,7 +51,7 @@ function run_unit_test() { echo "##[group]Running xpu ${test_file}..." local ut_log_name="${LOG_DIR}/unittest_xpu_${test_basename}.log" COVERAGE_CORE=sysmon numactl --physcpubind="${NUMA_CPUSET:-0-27}" --membind="${NUMA_NODE:-0}" \ - pytest --timeout=30 --session-timeout=600 --durations=0 \ + pytest --timeout=30 --session-timeout=600 --durations=0 --durations-min=1 \ --cov="${auto_round_path}" --cov-report= --cov-append -vs --disable-warnings \ --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" @@ -72,7 +72,7 @@ function run_unit_test_llmc() { echo "##[group]Running xpu llmc ${test_file}..." local ut_log_name="${LOG_DIR}/unittest_xpu_${test_basename}.log" COVERAGE_CORE=sysmon numactl --physcpubind="${NUMA_CPUSET:-0-27}" --membind="${NUMA_NODE:-0}" \ - pytest --timeout=30 --session-timeout=600 --durations=0 \ + pytest --timeout=30 --session-timeout=600 --durations=0 --durations-min=1 \ --cov="${auto_round_path}" --cov-report= --cov-append -vs --disable-warnings \ --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" From 0b44106ae842d45b1e0dcf32b5994c45e57e7b81 Mon Sep 17 00:00:00 2001 From: "Sun, Xuehao" Date: Thu, 6 Aug 2026 15:45:25 +0800 Subject: [PATCH 06/18] Add timeout markers to various test cases for improved stability Signed-off-by: Sun, Xuehao --- .../unit/test_cpu/advanced/test_low_precision_input_model.py | 1 + test/unit/test_cpu/algorithms/test_awq.py | 5 +++++ test/unit/test_cpu/backends/test_torch_backend.py | 2 ++ test/unit/test_cpu/core/test_autoround.py | 3 +++ test/unit/test_cpu/core/test_resume_integration.py | 1 + test/unit/test_cpu/export/test_export.py | 4 ++++ test/unit/test_cpu/export/test_gguf_format.py | 5 ++++- test/unit/test_cpu/export/test_llmc_format.py | 3 +++ test/unit/test_cpu/models/test_audio_model.py | 1 + test/unit/test_cpu/models/test_mllm.py | 1 + test/unit/test_cpu/models/test_moe_alignment.py | 1 + test/unit/test_cpu/models/test_moe_model.py | 2 ++ test/unit/test_cpu/quantization/test_asym.py | 1 + test/unit/test_cpu/quantization/test_model_free.py | 1 + test/unit/test_cpu/quantization/test_model_free_parity.py | 1 + test/unit/test_cpu/quantization/test_mxfp_nvfp.py | 1 + test/unit/test_cpu/quantization/test_static_attn.py | 2 ++ test/unit/test_cpu/schemes/test_auto_scheme.py | 1 + test/unit/test_cpu/schemes/test_scheme.py | 2 ++ test/unit/test_cpu/utils/test_alg_ext.py | 3 +++ test/unit/test_cpu/utils/test_calib_dataset.py | 3 +++ test/unit/test_cpu/utils/test_cli_usage.py | 4 ++++ test/unit/test_cpu/utils/test_model_scope.py | 2 ++ 23 files changed, 49 insertions(+), 1 deletion(-) diff --git a/test/unit/test_cpu/advanced/test_low_precision_input_model.py b/test/unit/test_cpu/advanced/test_low_precision_input_model.py index aadfcd6f8a..2a8fbdd4f4 100644 --- a/test/unit/test_cpu/advanced/test_low_precision_input_model.py +++ b/test/unit/test_cpu/advanced/test_low_precision_input_model.py @@ -86,6 +86,7 @@ def test_w4a16(self): model.model.layers[0].mlp.up_proj.weight.dtype == torch.bfloat16 ), "CompressedLinear layer was not converted to Linear" + @pytest.mark.timeout(60) def test_w4a16_to_mxfp4(self, tmp_path): model = get_tiny_model(get_model_path(self.w4a16_model_path)) model.config.name_or_path = None # Clear the name_or_path to avoid MTP copying issues diff --git a/test/unit/test_cpu/algorithms/test_awq.py b/test/unit/test_cpu/algorithms/test_awq.py index 100e0547b4..e36926ace8 100644 --- a/test/unit/test_cpu/algorithms/test_awq.py +++ b/test/unit/test_cpu/algorithms/test_awq.py @@ -44,6 +44,7 @@ def _save_dir(self, tmp_path): yield shutil.rmtree(self.save_dir, ignore_errors=True) + @pytest.mark.timeout(60) def test_awq_w4a16_quantize_and_inference(self, tiny_opt_model_path): """W4A16 AWQ quantization produces valid layer_config and model can generate.""" ar = AutoRound( @@ -68,6 +69,7 @@ def test_awq_w4a16_quantize_and_inference(self, tiny_opt_model_path): output = generate_prompt(model, tokenizer, device="cpu") assert len(output) > 0, "Model should produce non-empty output" + @pytest.mark.timeout(60) def test_awq_w4a16_export_auto_round_format(self, tiny_opt_model_path): """AWQ W4A16 export to auto_round format: verify quantization_config in saved config.""" ar = AutoRound( @@ -120,6 +122,7 @@ class TestAWQNonIntegerSchemes: under an MXFP/NVFP scheme. """ + @pytest.mark.timeout(60) @pytest.mark.parametrize("scheme", ["MXFP4", "NVFP4"]) def test_awq_non_integer_scheme_smoke(self, tiny_opt_model_path, scheme): ar = AutoRound( @@ -241,6 +244,7 @@ def test_awq_moe_dynamic_smoothing(self, tiny_qwen_moe_model_path): del model + @pytest.mark.timeout(360) def test_awq_moe_quantized_layers_check(self, tiny_qwen_moe_model_path): """AWQ on MoE: expert layers should be quantized, gates/routers stay FP.""" ar = AutoRound( @@ -275,6 +279,7 @@ def test_awq_moe_quantized_layers_check(self, tiny_qwen_moe_model_path): for name in fp_layers: assert name.endswith("gate"), f"Unexpected FP layer: {name}" + @pytest.mark.timeout(300) def test_awq_moe_save_quant_config(self, tiny_qwen_moe_model_path): """AWQ MoE: saved quantization_config should be consistent and loadable.""" ar = AutoRound( diff --git a/test/unit/test_cpu/backends/test_torch_backend.py b/test/unit/test_cpu/backends/test_torch_backend.py index bedc850c0b..fe3576bb85 100644 --- a/test/unit/test_cpu/backends/test_torch_backend.py +++ b/test/unit/test_cpu/backends/test_torch_backend.py @@ -26,6 +26,7 @@ def _save_dir(self, tmp_path): def teardown_class(self): shutil.rmtree("runs", ignore_errors=True) + @pytest.mark.timeout(60) def test_torch_4bits_asym(self, dataloader): model = AutoModelForCausalLM.from_pretrained(self.model_name, dtype="auto", trust_remote_code=True) tokenizer = AutoTokenizer.from_pretrained(self.model_name, trust_remote_code=True) @@ -64,6 +65,7 @@ def test_torch_4bits_asym(self, dataloader): evaluate_accuracy(model, tokenizer, threshold=0.35, batch_size=16, limit=10) torch.cuda.empty_cache() + @pytest.mark.timeout(60) def test_torch_4bits_sym(self, dataloader): model = AutoModelForCausalLM.from_pretrained(self.model_name, dtype="auto", trust_remote_code=True) tokenizer = AutoTokenizer.from_pretrained(self.model_name, trust_remote_code=True) diff --git a/test/unit/test_cpu/core/test_autoround.py b/test/unit/test_cpu/core/test_autoround.py index 70bc9c6d9f..eb538eb084 100644 --- a/test/unit/test_cpu/core/test_autoround.py +++ b/test/unit/test_cpu/core/test_autoround.py @@ -44,6 +44,7 @@ def test_bits_setting(self, tiny_opt_model_path): if module.bits != 8: raise ValueError(f"Expected bits to be 8, but got {module.bits}") + @pytest.mark.timeout(60) def test_layer_config(self, tiny_opt_model_path, dataloader): model_name = tiny_opt_model_path layer_config = {"self_attn": {"bits": 4, "data_type": "nv_fp", "act_bits": 16, "group_size": 16}} @@ -106,6 +107,7 @@ def test_consecutive_quant(self, tiny_opt_model_path, tiny_phi2_model_path, data ) autoround.quantize() + @pytest.mark.timeout(120) def test_mx_fp4(self, dataloader): model_name = opt_name_or_path bits, group_size, sym = 4, 32, False @@ -366,6 +368,7 @@ def test_tensor_reshape(self, dataloader): ) autoround.quantize() + @pytest.mark.timeout(60) def test_rtn(self, tiny_opt_model_path): model_name = tiny_opt_model_path model = AutoModelForCausalLM.from_pretrained(model_name, torch_dtype="auto", trust_remote_code=True) diff --git a/test/unit/test_cpu/core/test_resume_integration.py b/test/unit/test_cpu/core/test_resume_integration.py index 6396a65aa5..8bcedbb297 100644 --- a/test/unit/test_cpu/core/test_resume_integration.py +++ b/test/unit/test_cpu/core/test_resume_integration.py @@ -41,6 +41,7 @@ def _clean_resume_env(): class TestResumeIntegration: + @pytest.mark.timeout(60) def test_resume_skips_already_completed_blocks(self, tiny_opt_model_path, tmp_path): resume_dir = str(tmp_path / "resume") # AR_DISK_STREAM_MODEL keeps low_cpu_mem_usage active for this plain diff --git a/test/unit/test_cpu/export/test_export.py b/test/unit/test_cpu/export/test_export.py index 7b7ac3b3e2..c6ce3d43fc 100644 --- a/test/unit/test_cpu/export/test_export.py +++ b/test/unit/test_cpu/export/test_export.py @@ -202,6 +202,7 @@ def test_autoround_3bit_sym_format(self, dataloader): inputs = tokenizer(text, return_tensors="pt").to(model.device) print(tokenizer.decode(model.generate(**inputs, max_new_tokens=50)[0])) + @pytest.mark.timeout(120) @pytest.mark.parametrize("static_kv_dtype", ["fp8", "float16"]) def test_static_afp8_export(self, static_kv_dtype): import os @@ -321,6 +322,7 @@ def test_static_fp8_attn(self): assert f.get_tensor(weight_name).dtype == torch.float32 or f.get_tensor(weight_name).dtype == torch.bfloat16 assert "model.decoder.layers.8.self_attn.q_max" not in f.keys() + @pytest.mark.timeout(60) def test_awq_lmhead_export(self, dataloader): bits, sym, group_size = 4, False, 128 model_name = get_model_path("microsoft/phi-4") @@ -355,6 +357,7 @@ def test_awq_lmhead_export(self, dataloader): assert isinstance(lm_head, WQLinear_GEMM), "Illegal AWQ quantization for lm_head layer" + @pytest.mark.timeout(120) def test_gptq_lmhead_export(self, dataloader): bits, sym, group_size = 4, True, 128 # Note that, to save UT tuning time, the local model is intentionally kept lightweight, using only 2 hidden layers. @@ -527,6 +530,7 @@ def test_export_format_with_scheme(self, tiny_qwen_model_path): scale_dtype=ar.scale_dtype, ) + @pytest.mark.timeout(480) def test_autoawq_qwen3_vl_infer(self, dataloader): model_path = get_model_path("Qwen/Qwen3-VL-2B-Instruct") autoround = AutoRound( diff --git a/test/unit/test_cpu/export/test_gguf_format.py b/test/unit/test_cpu/export/test_gguf_format.py index 2e7db993f4..0a6f38606a 100644 --- a/test/unit/test_cpu/export/test_gguf_format.py +++ b/test/unit/test_cpu/export/test_gguf_format.py @@ -56,6 +56,7 @@ def _save_dir(self, tmp_path): yield shutil.rmtree(self.save_dir, ignore_errors=True) + @pytest.mark.timeout(60) def test_q4_0(self, tiny_qwen_model_path): bits, group_size, sym = 4, 32, True autoround = AutoRound( @@ -107,7 +108,7 @@ def test_func(self): model = AutoModelForCausalLM.from_pretrained(quantized_model_path, gguf_file=gguf_file, device_map="auto") eval_generated_prompt(model, self.tokenizer) - @pytest.mark.timeout(60) + @pytest.mark.timeout(120) def test_q4_k_m(self, dataloader, tiny_qwen_model_path): model_name = tiny_qwen_model_path layer_config = { @@ -147,6 +148,7 @@ def test_q4_k_m(self, dataloader, tiny_qwen_model_path): assert autoround.model.model.layers[0].mlp.gate_proj.bits == 8 assert autoround.layer_config["model.layers.0.mlp.gate_proj"]["mostly"] == "gguf:q8_0" + @pytest.mark.timeout(360) def test_all_format(self, tiny_qwen_model_path): model_name = tiny_qwen_model_path python_path = sys.executable @@ -206,6 +208,7 @@ def test_vlm_gguf(self, tiny_qwen_vl_model_path): else: assert file_size < 270, f"file size {file_size} MB is too large for non-quantized mmproj-model.gguf" + @pytest.mark.timeout(60) def test_vlm_gguf_wo_quant_nontext_module(self, tiny_qwen_vl_model_path): from auto_round import AutoRound diff --git a/test/unit/test_cpu/export/test_llmc_format.py b/test/unit/test_cpu/export/test_llmc_format.py index bc815408d3..cf83d8b9fd 100644 --- a/test/unit/test_cpu/export/test_llmc_format.py +++ b/test/unit/test_cpu/export/test_llmc_format.py @@ -47,6 +47,7 @@ def teardown_class(self): # autoround.quantize() # autoround.save_quantized("./saved", format="llm_compressor", inplace=True) + @pytest.mark.timeout(120) def test_llmcompressor_fp8(self, tmp_path): ## quantize the model model_name = opt_name_or_path @@ -129,6 +130,7 @@ def test_mxfp8_llmcompressor_format(self, tiny_opt_model_path, tmp_path): and quantization_config["ignore"] == ["lm_head"] ), f"Invalid MXFP8 quantization configuration: {quantization_config}" + @pytest.mark.timeout(60) def test_mxfp8_llmcompressor_kv_config(self, tiny_opt_model_path, tmp_path): ar = AutoRound( model=tiny_opt_model_path, @@ -192,6 +194,7 @@ def test_mxfp8_llmcompressor_attention_config(self, tiny_opt_model_path, tmp_pat assert any(key.endswith(".self_attn.q_scale") for key in keys), "q_scale not found in checkpoint" assert not any(key.endswith(".q_max") for key in keys), "q_max should not be exported" + @pytest.mark.timeout(60) def test_mixed_precision_llmcompressor_format(self, tiny_opt_model_path, tmp_path): scheme = AutoScheme( avg_bits=7, diff --git a/test/unit/test_cpu/models/test_audio_model.py b/test/unit/test_cpu/models/test_audio_model.py index 656ba5848a..98ffbb9337 100644 --- a/test/unit/test_cpu/models/test_audio_model.py +++ b/test/unit/test_cpu/models/test_audio_model.py @@ -162,6 +162,7 @@ def test_quantize_rtn(self, tiny_mimo_audio_model_path, tmp_path): has_quantlinear = any(m.__class__.__name__ == "QuantLinear" for m in quantized_model.modules()) assert has_quantlinear, "Quantized model should contain QuantLinear layers" + @pytest.mark.timeout(60) def test_quantize_with_tuning(self, tiny_mimo_audio_model_path, tmp_path): import transformers diff --git a/test/unit/test_cpu/models/test_mllm.py b/test/unit/test_cpu/models/test_mllm.py index 3ea8c72d50..4905680f64 100644 --- a/test/unit/test_cpu/models/test_mllm.py +++ b/test/unit/test_cpu/models/test_mllm.py @@ -147,6 +147,7 @@ def test_pure_text_model_check(self, tiny_qwen_vl_model_path): model = AutoModelForCausalLM.from_pretrained(opt_name_or_path, trust_remote_code=True) assert is_pure_text_model(model) + @pytest.mark.timeout(120) def test_str_input(self): tokenizer = AutoTokenizer.from_pretrained(self.model_name) processor = AutoProcessor.from_pretrained(self.model_name, trust_remote_code=True) diff --git a/test/unit/test_cpu/models/test_moe_alignment.py b/test/unit/test_cpu/models/test_moe_alignment.py index e1cacd48ed..995461b070 100644 --- a/test/unit/test_cpu/models/test_moe_alignment.py +++ b/test/unit/test_cpu/models/test_moe_alignment.py @@ -28,6 +28,7 @@ def setup_deepseek_v2_lite(): return model, tokenizer, output_dir, config +@pytest.mark.timeout(120) def test_moe_scale_alignment_fp8_static(setup_deepseek_v2_lite): """Test that FP8_STATIC quantization unifies gate/up input scales across experts.""" # Enable MoE scale unification explicitly diff --git a/test/unit/test_cpu/models/test_moe_model.py b/test/unit/test_cpu/models/test_moe_model.py index 91fcd71788..e608c8437c 100644 --- a/test/unit/test_cpu/models/test_moe_model.py +++ b/test/unit/test_cpu/models/test_moe_model.py @@ -41,6 +41,7 @@ def count_modules_by_type(model, target_module_name_or_class): return cnt +@pytest.mark.timeout(60) @pytest.mark.parametrize("scheme", ["MXFP4", "MXFP8"]) def test_gptoss(scheme, tiny_gpt_oss_model_path, tmp_path): config = AutoConfig.from_pretrained(tiny_gpt_oss_model_path, trust_remote_code=True) @@ -74,6 +75,7 @@ def test_gptoss(scheme, tiny_gpt_oss_model_path, tmp_path): loaded_out = loaded_model(inp) +@pytest.mark.timeout(120) def test_llama4(tiny_llama4_model_path): output_dir = "./tmp/test_quantized_llama4" quantized_model, save_folder = quantize_model( diff --git a/test/unit/test_cpu/quantization/test_asym.py b/test/unit/test_cpu/quantization/test_asym.py index 3d75ba5826..80fc58abf1 100644 --- a/test/unit/test_cpu/quantization/test_asym.py +++ b/test/unit/test_cpu/quantization/test_asym.py @@ -22,6 +22,7 @@ def teardown_class(cls): shutil.rmtree("runs", ignore_errors=True) # use parameters later + @pytest.mark.timeout(60) def test_asym_format(self, tiny_opt_model_path): for format in ["auto_round", "auto_round:auto_gptq", "auto_round:gptqmodel"]: bits, group_size, sym = 4, 128, False diff --git a/test/unit/test_cpu/quantization/test_model_free.py b/test/unit/test_cpu/quantization/test_model_free.py index 46ea0d35e9..9043a5b959 100644 --- a/test/unit/test_cpu/quantization/test_model_free.py +++ b/test/unit/test_cpu/quantization/test_model_free.py @@ -1526,6 +1526,7 @@ def test_convert_layer_config_infers_mxfp_bits_from_dtype_alias(self): assert base_scheme.data_type == "mx_fp" assert base_scheme.bits in (4, 8) + @pytest.mark.timeout(120) def test_e2e_int_auto_scheme(self, tmp_path, tiny_opt_model_path): from auto_round import AutoScheme diff --git a/test/unit/test_cpu/quantization/test_model_free_parity.py b/test/unit/test_cpu/quantization/test_model_free_parity.py index a82ed53c0f..9871edf42e 100644 --- a/test/unit/test_cpu/quantization/test_model_free_parity.py +++ b/test/unit/test_cpu/quantization/test_model_free_parity.py @@ -253,6 +253,7 @@ def test_disable_model_free_opt_out(tiny_opt_model_path): assert ar.model is not None +@pytest.mark.timeout(60) def test_mxfp_auto_scheme_quantization_config_parity(tmp_path, tiny_opt_model_path): """Mixed MXFP AutoScheme must serialize the same scheme metadata in both paths.""" pytest.importorskip("compressed_tensors") diff --git a/test/unit/test_cpu/quantization/test_mxfp_nvfp.py b/test/unit/test_cpu/quantization/test_mxfp_nvfp.py index 40037d82e3..c22575aa71 100644 --- a/test/unit/test_cpu/quantization/test_mxfp_nvfp.py +++ b/test/unit/test_cpu/quantization/test_mxfp_nvfp.py @@ -93,6 +93,7 @@ def test_nvfp4_moe_actmax_ar(self, tiny_deepseek_v2_model_path, dataloader): and lm_head.weight_scale.dtype is torch.float8_e4m3fn ), "Illegal NVFP4 packing for lm_head layer" + @pytest.mark.timeout(60) def test_mxfp4_moe_ar(self, tiny_deepseek_v2_model_path, dataloader): model_name = tiny_deepseek_v2_model_path layer_config = { diff --git a/test/unit/test_cpu/quantization/test_static_attn.py b/test/unit/test_cpu/quantization/test_static_attn.py index 9f99186ec8..307aa7dd75 100644 --- a/test/unit/test_cpu/quantization/test_static_attn.py +++ b/test/unit/test_cpu/quantization/test_static_attn.py @@ -37,6 +37,7 @@ def setup_deepseekv3(): return model, tokenizer, output_dir, config +@pytest.mark.timeout(120) def test_deepseek_v2(setup_deepseekv2): model, tokenizer, output_dir, config = setup_deepseekv2 autoround = AutoRound( @@ -59,6 +60,7 @@ def test_deepseek_v2(setup_deepseekv2): shutil.rmtree(output_dir, ignore_errors=True) +@pytest.mark.timeout(60) def test_deepseek_v3(setup_deepseekv3): model, tokenizer, output_dir, config = setup_deepseekv3 autoround = AutoRound( diff --git a/test/unit/test_cpu/schemes/test_auto_scheme.py b/test/unit/test_cpu/schemes/test_auto_scheme.py index d71ac0e01c..271bfbcedc 100644 --- a/test/unit/test_cpu/schemes/test_auto_scheme.py +++ b/test/unit/test_cpu/schemes/test_auto_scheme.py @@ -305,6 +305,7 @@ def test_auto_scheme_export(self, tiny_opt_model_path): assert mxfp_config["data_type"] == "mx_fp" assert os.path.exists(os.path.join(int_model_path, "config.json")) + @pytest.mark.timeout(120) def test_gguf_user_fixed_embedding_budget(self, tiny_qwen_model_path): """Regression test: a user-fixed embedding must be budget-priced at its fixed bits. diff --git a/test/unit/test_cpu/schemes/test_scheme.py b/test/unit/test_cpu/schemes/test_scheme.py index 482e30c917..cab978c0b6 100644 --- a/test/unit/test_cpu/schemes/test_scheme.py +++ b/test/unit/test_cpu/schemes/test_scheme.py @@ -45,6 +45,7 @@ def test_w2a16_rtn(self, tiny_opt_model_path, dataloader): ar.post_init() assert ar.bits == 2 + @pytest.mark.timeout(120) def test_w4a16_mixed(self, tiny_qwen_moe_model_path, dataloader): layer_config = { @@ -178,6 +179,7 @@ def test_parse_available_devices(self): device_list = parse_available_devices("0,1") assert len(device_list) == 1 and "cpu" in device_list + @pytest.mark.timeout(60) def test_set_scheme(self, tiny_qwen_model_path): ar = AutoRound( tiny_qwen_model_path, diff --git a/test/unit/test_cpu/utils/test_alg_ext.py b/test/unit/test_cpu/utils/test_alg_ext.py index 60b199f07e..4926f69fab 100644 --- a/test/unit/test_cpu/utils/test_alg_ext.py +++ b/test/unit/test_cpu/utils/test_alg_ext.py @@ -1,9 +1,12 @@ from test.helpers import qwen_name_or_path +import pytest + from auto_round import AutoRound class TestAlgExt: + @pytest.mark.timeout(60) def test_alg_ext(self, tiny_opt_model_path, tiny_qwen_model_path): model_name = tiny_opt_model_path ar = AutoRound(model_name, scheme="W2A16", iters=1, nsamples=1, enable_alg_ext=True) diff --git a/test/unit/test_cpu/utils/test_calib_dataset.py b/test/unit/test_cpu/utils/test_calib_dataset.py index bfb401fbe5..d707d36df5 100644 --- a/test/unit/test_cpu/utils/test_calib_dataset.py +++ b/test/unit/test_cpu/utils/test_calib_dataset.py @@ -98,6 +98,7 @@ def test_jsonl(self, tiny_opt_model_path): ) autoround.quantize() + @pytest.mark.timeout(60) def test_apply_chat_template(self, tiny_qwen_model_path): model_name = tiny_qwen_model_path model = AutoModelForCausalLM.from_pretrained(model_name, torch_dtype="auto", trust_remote_code=True) @@ -117,6 +118,7 @@ def test_apply_chat_template(self, tiny_qwen_model_path): ) autoround.quantize() + @pytest.mark.timeout(180) def test_combine_dataset(self, tiny_qwen_model_path): dataset = "NeelNanda/pile-10k" + "," + "madao33/new-title-chinese" + "," + "mbpp" + "," + "opencode-instruct" bits, group_size, sym = 4, 128, True @@ -132,6 +134,7 @@ def test_combine_dataset(self, tiny_qwen_model_path): ) autoround.quantize() + @pytest.mark.timeout(60) def test_combine_dataset2(self, tiny_opt_model_path): dataset = "NeelNanda/pile-10k:num=256,mbpp:num=256" bits, group_size, sym = 4, 128, True diff --git a/test/unit/test_cpu/utils/test_cli_usage.py b/test/unit/test_cpu/utils/test_cli_usage.py index 27b9749edc..7e42d6a455 100644 --- a/test/unit/test_cpu/utils/test_cli_usage.py +++ b/test/unit/test_cpu/utils/test_cli_usage.py @@ -30,6 +30,7 @@ def test_auto_round_cmd(self, tiny_opt_model_path, tiny_qwen_vl_model_path): if res > 0 or res == -1: assert False, "cmd line test fail, please have a check" + @pytest.mark.timeout(60) def test_auto_round_cmd2(self, tiny_opt_model_path, tiny_qwen_vl_model_path): python_path = sys.executable res = os.system( @@ -38,6 +39,7 @@ def test_auto_round_cmd2(self, tiny_opt_model_path, tiny_qwen_vl_model_path): if res > 0 or res == -1: assert False, "cmd line test fail, please have a check" + @pytest.mark.timeout(60) def test_auto_round_cmd3(self, tiny_opt_model_path, tiny_qwen_vl_model_path): python_path = sys.executable res = os.system( @@ -46,6 +48,7 @@ def test_auto_round_cmd3(self, tiny_opt_model_path, tiny_qwen_vl_model_path): if res > 0 or res == -1: assert False, "cmd line test fail, please have a check" + @pytest.mark.timeout(60) def test_auto_round_cmd4(self, tiny_opt_model_path, tiny_qwen_vl_model_path): python_path = sys.executable res = os.system( @@ -66,6 +69,7 @@ def test_auto_round_cmd6(self, tiny_opt_model_path, tiny_qwen_vl_model_path): if res > 0 or res == -1: assert False, "cmd line test fail, please have a check" + @pytest.mark.timeout(60) def test_auto_round_cmd7(self, tiny_opt_model_path, tiny_qwen_vl_model_path): python_path = sys.executable res = os.system( diff --git a/test/unit/test_cpu/utils/test_model_scope.py b/test/unit/test_cpu/utils/test_model_scope.py index b93d9346b4..3b7d96eea2 100644 --- a/test/unit/test_cpu/utils/test_model_scope.py +++ b/test/unit/test_cpu/utils/test_model_scope.py @@ -30,11 +30,13 @@ def teardown_class(self): if os.path.exists(self.cache_path): shutil.rmtree(self.cache_path, ignore_errors=True) + @pytest.mark.timeout(120) def test_llm(self, dataloader): model_name = get_model_path("Qwen/Qwen2.5-0.5B-Instruct") autoround = AutoRound(model_name, platform="model_scope", scheme="w4a16", iters=0, seqlen=2, dataset=dataloader) autoround.quantize_and_save() + @pytest.mark.timeout(360) def test_mllm(self, dataloader): model_name = get_model_path("Qwen/Qwen2-VL-2B-Instruct") autoround = AutoRound( From 272dfee6f03fd4bac9b5f58ae194718c72e4ea30 Mon Sep 17 00:00:00 2001 From: "Sun, Xuehao" Date: Thu, 6 Aug 2026 15:52:29 +0800 Subject: [PATCH 07/18] Remove session timeout and default timeout from pytest commands in unit test scripts Signed-off-by: Sun, Xuehao --- .azure-pipelines/scripts/cuda_unit_test/run_cuda_ut.sh | 2 +- .azure-pipelines/scripts/ut/run_ut.sh | 2 +- .azure-pipelines/scripts/ut/run_ut_hpu.sh | 4 ++-- .azure-pipelines/scripts/ut/run_ut_xpu.sh | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.azure-pipelines/scripts/cuda_unit_test/run_cuda_ut.sh b/.azure-pipelines/scripts/cuda_unit_test/run_cuda_ut.sh index 31412b09f9..19bd84ad6a 100644 --- a/.azure-pipelines/scripts/cuda_unit_test/run_cuda_ut.sh +++ b/.azure-pipelines/scripts/cuda_unit_test/run_cuda_ut.sh @@ -100,7 +100,7 @@ function run_unit_test() { local test_basename=$(basename ${test_file} .py) local ut_log_name=${LOG_DIR}/unittest_cuda_${test_basename}.log - COVERAGE_CORE=sysmon pytest -m "not skip_ci" --timeout=30 --session-timeout=600 \ + COVERAGE_CORE=sysmon pytest -m "not skip_ci" \ --cov=auto_round --cov-report= --cov-append \ -vs --disable-warnings --durations=0 --durations-min=1 --junitxml="${ut_log_name%.log}.xml" \ ${test_file} 2>&1 | tee ${ut_log_name} diff --git a/.azure-pipelines/scripts/ut/run_ut.sh b/.azure-pipelines/scripts/ut/run_ut.sh index 2c45df90e6..3fb0357388 100644 --- a/.azure-pipelines/scripts/ut/run_ut.sh +++ b/.azure-pipelines/scripts/ut/run_ut.sh @@ -91,7 +91,7 @@ function run_unit_test() { local ut_log_name=${LOG_DIR}/unittest_${test_basename}.log COVERAGE_CORE=sysmon numactl --physcpubind="${NUMA_CPUSET:-0-15}" --membind="${NUMA_NODE:-0}" \ - pytest --timeout=30 --session-timeout=600 --durations=0 --durations-min=1 \ + pytest --durations=0 --durations-min=1 \ --cov=auto_round --cov-report= --cov-append \ -vs --disable-warnings --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" diff --git a/.azure-pipelines/scripts/ut/run_ut_hpu.sh b/.azure-pipelines/scripts/ut/run_ut_hpu.sh index 67e5b91496..0e47cb95d4 100644 --- a/.azure-pipelines/scripts/ut/run_ut_hpu.sh +++ b/.azure-pipelines/scripts/ut/run_ut_hpu.sh @@ -34,7 +34,7 @@ function run_unit_test() { echo "##[group]Running ${test_file} in HPU lazy mode..." local ut_log_name="${LOG_DIR}/unittest_lazy_${test_basename}.log" COVERAGE_CORE=sysmon PT_HPU_LAZY_MODE=1 pytest --cov="${auto_round_path}" \ - --timeout=30 --session-timeout=600 --durations=0 --durations-min=1 \ + --durations=0 --durations-min=1 \ --cov-report= --cov-append -vs --disable-warnings \ --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" @@ -42,7 +42,7 @@ function run_unit_test() { echo "##[group]Running ${test_file} in HPU compile mode..." local ut_log_name="${LOG_DIR}/unittest_compile_${test_basename}.log" COVERAGE_CORE=sysmon PT_HPU_LAZY_MODE=0 pytest --mode compile --cov="${auto_round_path}" \ - --timeout=30 --session-timeout=600 --durations=0 --durations-min=1 \ + --durations=0 --durations-min=1 \ --cov-report= --cov-append -vs --disable-warnings \ --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" diff --git a/.azure-pipelines/scripts/ut/run_ut_xpu.sh b/.azure-pipelines/scripts/ut/run_ut_xpu.sh index d69e6f563f..ce109efce7 100644 --- a/.azure-pipelines/scripts/ut/run_ut_xpu.sh +++ b/.azure-pipelines/scripts/ut/run_ut_xpu.sh @@ -39,7 +39,7 @@ function run_unit_test() { echo "##[group]Running ark ${test_file}..." local ut_log_name="${LOG_DIR}/unittest_ark_${test_basename}.log" COVERAGE_CORE=sysmon numactl --physcpubind="${NUMA_CPUSET:-0-27}" --membind="${NUMA_NODE:-0}" \ - pytest --timeout=30 --session-timeout=600 --durations=0 --durations-min=1 \ + pytest --durations=0 --durations-min=1 \ --cov="${auto_round_path}" --cov-report= --cov-append -vs --disable-warnings \ --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" @@ -51,7 +51,7 @@ function run_unit_test() { echo "##[group]Running xpu ${test_file}..." local ut_log_name="${LOG_DIR}/unittest_xpu_${test_basename}.log" COVERAGE_CORE=sysmon numactl --physcpubind="${NUMA_CPUSET:-0-27}" --membind="${NUMA_NODE:-0}" \ - pytest --timeout=30 --session-timeout=600 --durations=0 --durations-min=1 \ + pytest --durations=0 --durations-min=1 \ --cov="${auto_round_path}" --cov-report= --cov-append -vs --disable-warnings \ --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" @@ -72,7 +72,7 @@ function run_unit_test_llmc() { echo "##[group]Running xpu llmc ${test_file}..." local ut_log_name="${LOG_DIR}/unittest_xpu_${test_basename}.log" COVERAGE_CORE=sysmon numactl --physcpubind="${NUMA_CPUSET:-0-27}" --membind="${NUMA_NODE:-0}" \ - pytest --timeout=30 --session-timeout=600 --durations=0 --durations-min=1 \ + pytest --durations=0 --durations-min=1 \ --cov="${auto_round_path}" --cov-report= --cov-append -vs --disable-warnings \ --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" From 3f04d7ce9662c6ac9f1e8d97ed482f5a81a181e5 Mon Sep 17 00:00:00 2001 From: "Sun, Xuehao" Date: Thu, 6 Aug 2026 16:56:20 +0800 Subject: [PATCH 08/18] Add timeout markers to various test cases for improved stability Signed-off-by: Sun, Xuehao --- test/integration/test_xpu/test_llmc_integration.py | 1 + test/unit/test_ark/test_model.py | 3 +++ test/unit/test_cpu/export/test_export.py | 2 +- test/unit/test_cpu/quantization/test_mxfp_nvfp.py | 1 + test/unit/test_cpu/quantization/test_static_attn.py | 2 +- test/unit/test_cuda/algorithms/test_alg_ext.py | 2 ++ test/unit/test_cuda/algorithms/test_auto_scheme.py | 4 ++++ test/unit/test_cuda/algorithms/test_awq.py | 6 ++++++ test/unit/test_cuda/backends/test_exllamav2_backend.py | 2 ++ test/unit/test_cuda/backends/test_marlin_backend.py | 2 ++ test/unit/test_cuda/backends/test_torch_backend.py | 1 + test/unit/test_cuda/backends/test_triton_backend.py | 1 + test/unit/test_cuda/calibration/test_calib_dataset.py | 1 + test/unit/test_cuda/export/test_auto_round_format.py | 1 + test/unit/test_cuda/export/test_fp8_format.py | 1 + test/unit/test_cuda/export/test_gguf_format.py | 4 ++++ test/unit/test_cuda/models/test_audio_model.py | 1 + test/unit/test_cuda/models/test_conv1d.py | 1 + test/unit/test_cuda/models/test_fp8_model.py | 2 ++ test/unit/test_cuda/models/test_moe_model.py | 1 + test/unit/test_cuda/models/test_omni_model.py | 1 + test/unit/test_cuda/quantization/test_asym.py | 1 + test/unit/test_cuda/quantization/test_mxfp_nvfp.py | 1 + test/unit/test_cuda/quantization/test_torch_compile.py | 2 ++ test/unit/test_cuda/transform/test_mxfp4_transform.py | 3 +++ test/unit/test_cuda/transform/test_spinquant.py | 3 +++ test/unit/test_hpu/test_auto_round.py | 1 + test/unit/test_hpu/test_quant_fp8.py | 1 + test/unit/test_hpu/test_static_attn.py | 1 + test/unit/test_xpu/test_autoround.py | 2 ++ 30 files changed, 53 insertions(+), 2 deletions(-) diff --git a/test/integration/test_xpu/test_llmc_integration.py b/test/integration/test_xpu/test_llmc_integration.py index cb0471a65b..8022835f52 100644 --- a/test/integration/test_xpu/test_llmc_integration.py +++ b/test/integration/test_xpu/test_llmc_integration.py @@ -77,6 +77,7 @@ # TODO: remove xfail once the issue is resolved. @pytest.mark.xfail(reason="skip this case temporarily due to issue https://github.com/intel/auto-round/issues/2112") @pytest.mark.skipif(torch.xpu.device_count() < 1, reason="test requires at least 1 XPU") +@pytest.mark.timeout(60) @pytest.mark.parametrize( "recipe", [ diff --git a/test/unit/test_ark/test_model.py b/test/unit/test_ark/test_model.py index 823da1e616..6c35da38b0 100644 --- a/test/unit/test_ark/test_model.py +++ b/test/unit/test_ark/test_model.py @@ -58,6 +58,7 @@ def main_op(self, format, bits, group_size, sym, dtype, device, fast_cfg=True, t evaluate_accuracy(model, tokenizer, threshold=tar_acc, batch_size=32, limit=limit) torch.xpu.empty_cache() + @pytest.mark.timeout(60) @pytest.mark.parametrize("format", ["auto_round", "auto_round:gptqmodel"]) @pytest.mark.parametrize("bits, group_size, sym", [(4, 128, True), (8, 128, True)]) @pytest.mark.parametrize("dtype", [torch.bfloat16]) @@ -65,6 +66,7 @@ def main_op(self, format, bits, group_size, sym, dtype, device, fast_cfg=True, t def test_formats(self, format, bits, group_size, sym, dtype, device): self.main_op(format, bits, group_size, sym, dtype, device) + @pytest.mark.timeout(60) @pytest.mark.parametrize("format", ["auto_round:auto_awq"]) @pytest.mark.parametrize("bits, group_size, sym", [(4, 32, True)]) @pytest.mark.parametrize("dtype", [torch.float16]) @@ -72,6 +74,7 @@ def test_formats(self, format, bits, group_size, sym, dtype, device): def test_awq_fp16(self, format, bits, group_size, sym, dtype, device): self.main_op(format, bits, group_size, sym, dtype, device) + @pytest.mark.timeout(300) @pytest.mark.parametrize("format", ["auto_round"]) @pytest.mark.parametrize("bits, group_size, sym", [(2, 32, False)]) @pytest.mark.parametrize("dtype", [torch.bfloat16]) diff --git a/test/unit/test_cpu/export/test_export.py b/test/unit/test_cpu/export/test_export.py index c6ce3d43fc..805e68675d 100644 --- a/test/unit/test_cpu/export/test_export.py +++ b/test/unit/test_cpu/export/test_export.py @@ -322,7 +322,7 @@ def test_static_fp8_attn(self): assert f.get_tensor(weight_name).dtype == torch.float32 or f.get_tensor(weight_name).dtype == torch.bfloat16 assert "model.decoder.layers.8.self_attn.q_max" not in f.keys() - @pytest.mark.timeout(60) + @pytest.mark.timeout(120) def test_awq_lmhead_export(self, dataloader): bits, sym, group_size = 4, False, 128 model_name = get_model_path("microsoft/phi-4") diff --git a/test/unit/test_cpu/quantization/test_mxfp_nvfp.py b/test/unit/test_cpu/quantization/test_mxfp_nvfp.py index c22575aa71..685d6fbe50 100644 --- a/test/unit/test_cpu/quantization/test_mxfp_nvfp.py +++ b/test/unit/test_cpu/quantization/test_mxfp_nvfp.py @@ -61,6 +61,7 @@ def test_nvfp4_moe_actmax_rtn(self, tiny_deepseek_v2_model_path_cpu, dataloader) moe = compressed_model.model.layers[1].mlp assert hasattr(moe.experts[0].gate_proj.orig_layer, "act_max") + @pytest.mark.timeout(60) def test_nvfp4_moe_actmax_ar(self, tiny_deepseek_v2_model_path, dataloader): model_name = tiny_deepseek_v2_model_path layer_config = { diff --git a/test/unit/test_cpu/quantization/test_static_attn.py b/test/unit/test_cpu/quantization/test_static_attn.py index 307aa7dd75..e6c3f006b0 100644 --- a/test/unit/test_cpu/quantization/test_static_attn.py +++ b/test/unit/test_cpu/quantization/test_static_attn.py @@ -60,7 +60,7 @@ def test_deepseek_v2(setup_deepseekv2): shutil.rmtree(output_dir, ignore_errors=True) -@pytest.mark.timeout(60) +@pytest.mark.timeout(90) def test_deepseek_v3(setup_deepseekv3): model, tokenizer, output_dir, config = setup_deepseekv3 autoround = AutoRound( diff --git a/test/unit/test_cuda/algorithms/test_alg_ext.py b/test/unit/test_cuda/algorithms/test_alg_ext.py index a97f6efe37..ee62a8e1c4 100644 --- a/test/unit/test_cuda/algorithms/test_alg_ext.py +++ b/test/unit/test_cuda/algorithms/test_alg_ext.py @@ -57,6 +57,7 @@ def setup_and_teardown_class(self): # "overrides were applied (data_type was not yet 'int_asym_dq')." # ) + @pytest.mark.timeout(60) def test_int2_g64_asym_enable_alg_ext_keeps_config(self, tiny_qwen_model_path): """Regression test: asym int2/g64 keeps the requested tuning config.""" @@ -90,6 +91,7 @@ def test_int2_g64_asym_enable_alg_ext_keeps_config(self, tiny_qwen_model_path): assert quantizer.enable_norm_bias_tuning is True assert quantizer.enable_quanted_input is False + @pytest.mark.timeout(90) @pytest.mark.parametrize("scheme", ["MXFP4", "NVFP4", "W2A16G64", "gguf:q2_k_s,gguf:q4_k_s"]) def test_all_support_dtype(self, scheme, tiny_qwen_model_path): from auto_round.auto_scheme import AutoScheme diff --git a/test/unit/test_cuda/algorithms/test_auto_scheme.py b/test/unit/test_cuda/algorithms/test_auto_scheme.py index 70b286550b..b48327cc2b 100644 --- a/test/unit/test_cuda/algorithms/test_auto_scheme.py +++ b/test/unit/test_cuda/algorithms/test_auto_scheme.py @@ -28,6 +28,7 @@ def setup_and_teardown_class(self): yield shutil.rmtree("runs", ignore_errors=True) + @pytest.mark.timeout(30) def test_gguf_k_0(self, tiny_qwen_model_path): target_bits = 5.5 scheme = AutoScheme(avg_bits=target_bits, options=("GGUF:Q4_K_M", "GGUF:Q8_0")) @@ -75,6 +76,7 @@ def test_gguf(self): # Due to the tiny model and embedding, the actual number of bits of gguf format will be larger than the target bits. assert target_bits - 0.1 < avg_bits <= target_bits + 0.3 + @pytest.mark.timeout(120) def test_shared_layers(self, tiny_opt_model_path): model_name = tiny_opt_model_path from transformers import AutoModelForCausalLM, AutoTokenizer @@ -247,6 +249,7 @@ def test_layer_config(self): print(avg_bits) assert target_bits - 0.1 < avg_bits <= target_bits + 1e-3 + @pytest.mark.timeout(120) def test_lm_head_and_mix_dtype(self, tiny_untied_qwen_model_path): target_bits = 5 scheme = AutoScheme(avg_bits=target_bits, options=("MXFP4", "MXFP8")) @@ -311,6 +314,7 @@ def test_enable_torch_compile(self): _, quantized_model_path = ar.quantize_and_save(output_dir=self.save_dir) evaluate_accuracy(quantized_model_path, threshold=0.10) + @pytest.mark.timeout(180) def test_mixed_bits_get_scoring(self): """Verify that AutoScheme scoring produces accuracy above a known reference threshold for mixed-bit quantization. diff --git a/test/unit/test_cuda/algorithms/test_awq.py b/test/unit/test_cuda/algorithms/test_awq.py index d5faecb454..f7bc376d8e 100644 --- a/test/unit/test_cuda/algorithms/test_awq.py +++ b/test/unit/test_cuda/algorithms/test_awq.py @@ -46,6 +46,7 @@ def _save_dir(self, tmp_path): yield shutil.rmtree(self.save_dir, ignore_errors=True) + @pytest.mark.timeout(60) def test_awq_w4a16_quantize_and_inference(self, tiny_opt_model_path): """W4A16 AWQ quantization and CUDA inference smoke test.""" ar = AutoRound( @@ -92,6 +93,7 @@ def test_awq_w4a16_export_auto_round_args(self, tiny_opt_model_path): assert qconfig["sym"] == sym assert "auto-round" in qconfig["quant_method"] + @pytest.mark.timeout(90) def test_awq_w4a16_load_and_generate(self): """Quantize, save, reload, and generate on CUDA to verify round-trip.""" model_name = get_model_path("facebook/opt-125m") @@ -121,6 +123,7 @@ def _save_dir(self, tmp_path): yield shutil.rmtree(self.save_dir, ignore_errors=True) + @pytest.mark.timeout(90) def test_awq_moe_dynamic_smoothing(self, tiny_qwen_moe_model_path): """AWQ mapping resolution works on MoE model.""" from auto_round.algorithms.transforms.awq.mappings import resolve_mappings @@ -153,6 +156,7 @@ def test_awq_moe_dynamic_smoothing(self, tiny_qwen_moe_model_path): del model + @pytest.mark.timeout(120) def test_awq_moe_quantized_layers_check(self, tiny_qwen_moe_model_path): """Expert layers quantized to W4, gates/routers stay fp.""" ar = AutoRound( @@ -189,6 +193,7 @@ def test_awq_moe_quantized_layers_check(self, tiny_qwen_moe_model_path): for name in fp_layers: assert name.endswith("gate"), f"Unexpected FP layer: {name}" + @pytest.mark.timeout(90) def test_awq_moe_save_compressed_size(self, tiny_qwen_moe_model_path): """AWQ MoE W4: quantized safetensors should be smaller than original.""" ar = AutoRound( @@ -233,6 +238,7 @@ def setup_class(cls): def teardown_class(cls): shutil.rmtree("runs", ignore_errors=True) + @pytest.mark.timeout(150) def test_awq_w4a16_lmeval(self): """AWQ W4A16 on OPT-125m: lambada_openai accuracy check.""" ar = AutoRound( diff --git a/test/unit/test_cuda/backends/test_exllamav2_backend.py b/test/unit/test_cuda/backends/test_exllamav2_backend.py index 25be1425ab..738279e216 100644 --- a/test/unit/test_cuda/backends/test_exllamav2_backend.py +++ b/test/unit/test_cuda/backends/test_exllamav2_backend.py @@ -34,6 +34,7 @@ def setup_and_teardown_class(self): # @pytest.mark.skip_ci(reason="Only tiny model is suggested") # @pytest.mark.skip_ci(reason="Time-consuming; Accuracy evaluation") @require_gptqmodel + @pytest.mark.timeout(120) def test_gptqmodel_exllmav2_4bits_asym(self, dataloader): model_path = get_model_path("facebook/opt-125m") bits, group_size, sym = 4, 128, False @@ -127,6 +128,7 @@ def test_gptq_exllamav2_4bits_sym_group_size(self, group_size): torch.cuda.empty_cache() @require_gptqmodel + @pytest.mark.timeout(60) def test_gptqmodel_awq_exllamav2_4bits_asym(self, dataloader): """Test AWQ quantization with gptqmodel:awq_exllamav2 backend (bfloat16 inference).""" model_path = get_model_path("facebook/opt-125m") diff --git a/test/unit/test_cuda/backends/test_marlin_backend.py b/test/unit/test_cuda/backends/test_marlin_backend.py index d13507be47..7f631fc622 100644 --- a/test/unit/test_cuda/backends/test_marlin_backend.py +++ b/test/unit/test_cuda/backends/test_marlin_backend.py @@ -34,6 +34,7 @@ def setup_and_teardown_class(self): # Keep one CI test for marlin backend and skip others to save time. # @pytest.mark.skip_ci(reason="Only tiny model is suggested") # @pytest.mark.skip_ci(reason="Time-consuming; Accuracy evaluation") + @pytest.mark.timeout(150) def test_marlin_4bits_sym_with_zp_m_1(self, dataloader): model = AutoModelForCausalLM.from_pretrained(self.model_name, torch_dtype="auto", trust_remote_code=True) tokenizer = AutoTokenizer.from_pretrained(self.model_name, trust_remote_code=True) @@ -172,6 +173,7 @@ def test_marlin_group_size(self, dataloader): # shutil.rmtree("./saved", ignore_errors=True) @require_gptqmodel + @pytest.mark.timeout(60) def test_gptqmodel_awq_marlin_4bits_sym(self): """Test AWQ quantization with gptqmodel:awq_marlin backend (sym-only, float16).""" model_path = get_model_path("facebook/opt-125m") diff --git a/test/unit/test_cuda/backends/test_torch_backend.py b/test/unit/test_cuda/backends/test_torch_backend.py index f4127fb2cc..bcfa4ec1a9 100644 --- a/test/unit/test_cuda/backends/test_torch_backend.py +++ b/test/unit/test_cuda/backends/test_torch_backend.py @@ -33,6 +33,7 @@ def setup_and_teardown_class(self): # Keep one CI test for torch backend and skip others to save time. # @pytest.mark.skip_ci(reason="Only tiny model is suggested") # @pytest.mark.skip_ci(reason="Time-consuming; Accuracy evaluation") + @pytest.mark.timeout(60) def test_torch_4bits_asym(self, dataloader): model_path = get_model_path("facebook/opt-125m") model = AutoModelForCausalLM.from_pretrained(model_path, torch_dtype="auto", trust_remote_code=True) diff --git a/test/unit/test_cuda/backends/test_triton_backend.py b/test/unit/test_cuda/backends/test_triton_backend.py index 159e06f8d5..04f33ebb1c 100644 --- a/test/unit/test_cuda/backends/test_triton_backend.py +++ b/test/unit/test_cuda/backends/test_triton_backend.py @@ -29,6 +29,7 @@ def teardown_class(self): # @pytest.mark.skip_ci(reason="Only tiny model is suggested") # @pytest.mark.skip_ci(reason="Time-consuming; Accuracy evaluation") @require_greater_than_050 + @pytest.mark.timeout(150) def test_tritonv2_2bits_asym(self): model = AutoModelForCausalLM.from_pretrained(self.model_name, torch_dtype="auto", trust_remote_code=True) tokenizer = AutoTokenizer.from_pretrained(self.model_name, trust_remote_code=True) diff --git a/test/unit/test_cuda/calibration/test_calib_dataset.py b/test/unit/test_cuda/calibration/test_calib_dataset.py index bdee2ebebb..93dbccfda1 100644 --- a/test/unit/test_cuda/calibration/test_calib_dataset.py +++ b/test/unit/test_cuda/calibration/test_calib_dataset.py @@ -10,6 +10,7 @@ class TestLocalCalibDataset: + @pytest.mark.timeout(120) def test_combine_dataset(self, tiny_opt_model_path): dataset = "NeelNanda/pile-10k" + ",BAAI/CCI3-HQ" + ",madao33/new-title-chinese" bits, group_size, sym = 4, 128, True diff --git a/test/unit/test_cuda/export/test_auto_round_format.py b/test/unit/test_cuda/export/test_auto_round_format.py index d3c729ffaa..722643ff30 100644 --- a/test/unit/test_cuda/export/test_auto_round_format.py +++ b/test/unit/test_cuda/export/test_auto_round_format.py @@ -153,6 +153,7 @@ def test_tritonv2_bf16(self): eval_generated_prompt(model, tokenizer) torch.cuda.empty_cache() + @pytest.mark.timeout(90) def test_fp8_block_fp8_format(self): model_name = "Qwen/Qwen3-0.6B" diff --git a/test/unit/test_cuda/export/test_fp8_format.py b/test/unit/test_cuda/export/test_fp8_format.py index 8d2cec59c1..72a7e84264 100644 --- a/test/unit/test_cuda/export/test_fp8_format.py +++ b/test/unit/test_cuda/export/test_fp8_format.py @@ -22,6 +22,7 @@ def _save_dir(self, tmp_path): yield shutil.rmtree(self.save_dir, ignore_errors=True) + @pytest.mark.timeout(60) def test_fp8_block_fp8_format(self): model_name = self.model_name diff --git a/test/unit/test_cuda/export/test_gguf_format.py b/test/unit/test_cuda/export/test_gguf_format.py index 0435a61c84..0279de6c4c 100644 --- a/test/unit/test_cuda/export/test_gguf_format.py +++ b/test/unit/test_cuda/export/test_gguf_format.py @@ -102,6 +102,7 @@ def _export_qwen35_moe_gguf(self, tiny_qwen35_moe_model_path): @pytest.mark.skipif(not check_version("transformers>=5.2.0"), reason="requires transformers >= 5.2.0") @pytest.mark.skipif(not torch.cuda.is_available(), reason="requires CUDA") @require_gguf + @pytest.mark.timeout(120) def test_qwen35_moe_gguf(self, tiny_qwen35_moe_model_path): self._export_qwen35_moe_gguf(tiny_qwen35_moe_model_path) @@ -138,6 +139,7 @@ def test_gguf_format(self, tiny_qwen_model_path, dataloader): autoround.save_quantized(output_dir=quantized_model_path, format="gguf:q4_1") @require_gguf + @pytest.mark.timeout(150) def test_q4_0_accuracy(self): model_name = get_model_path("Qwen/Qwen2.5-0.5B-Instruct") bits, group_size, sym = 4, 32, True @@ -222,6 +224,7 @@ def test_special_model(self): shutil.rmtree(tiny_model_path, ignore_errors=True) @require_gguf + @pytest.mark.timeout(90) def test_vlm_gguf(self): from test.helpers import save_tiny_model @@ -296,6 +299,7 @@ def test_q2k_mixed(self): shutil.rmtree(saved_tiny_model_path, ignore_errors=True) @require_gguf + @pytest.mark.timeout(60) def test_q2_k_s_ffn_down_q4k(self): """Verify blk.0.ffn_down.weight is Q4_K in gguf:q2_k_s format. Blocks where i_layer < n_layer/8 should use Q4_K instead of Q2_K for ffn_down.""" diff --git a/test/unit/test_cuda/models/test_audio_model.py b/test/unit/test_cuda/models/test_audio_model.py index 929326b313..16c114df7b 100644 --- a/test/unit/test_cuda/models/test_audio_model.py +++ b/test/unit/test_cuda/models/test_audio_model.py @@ -327,6 +327,7 @@ def test_quantize_rtn(self, tiny_mimo_audio_model_path, tmp_path): has_quantlinear = any(m.__class__.__name__ == "QuantLinear" for m in quantized_model.modules()) assert has_quantlinear, "Quantized model should contain QuantLinear layers" + @pytest.mark.timeout(60) def test_quantize_with_tuning(self, tiny_mimo_audio_model_path, tmp_path): import transformers diff --git a/test/unit/test_cuda/models/test_conv1d.py b/test/unit/test_cuda/models/test_conv1d.py index bf8ecd8ca0..8cf1bf0656 100644 --- a/test/unit/test_cuda/models/test_conv1d.py +++ b/test/unit/test_cuda/models/test_conv1d.py @@ -25,6 +25,7 @@ def setup_and_teardown_class(self): shutil.rmtree("runs", ignore_errors=True) @require_gptqmodel + @pytest.mark.timeout(150) def test_quant(self, dataloader): model_name = get_model_path("MBZUAI/LaMini-GPT-124M") model = get_tiny_model(model_name) diff --git a/test/unit/test_cuda/models/test_fp8_model.py b/test/unit/test_cuda/models/test_fp8_model.py index f4444ab0a4..ad280a6b90 100644 --- a/test/unit/test_cuda/models/test_fp8_model.py +++ b/test/unit/test_cuda/models/test_fp8_model.py @@ -76,6 +76,7 @@ def test_small_model_rtn_generation(self, mock_fp8_capable_device, tiny_fp8_qwen tokenizer = AutoTokenizer.from_pretrained(quantized_model_path) generate_prompt(model, tokenizer) + @pytest.mark.timeout(60) def test_gguf_imatrix(self, mock_fp8_capable_device, tiny_fp8_qwen_model_path): ar = AutoRound(tiny_fp8_qwen_model_path, iters=0) _, quantized_model_path = ar.quantize_and_save(format="gguf:q2_k_s", output_dir=self.save_dir) @@ -108,6 +109,7 @@ def test_small_model_iters1(self, mock_fp8_capable_device): with patch("torch.cuda.get_device_capability", return_value=DEVICE_CAPABILITY): # revert DEVICE_CAPABILITY evaluate_accuracy(folder, threshold=0.25) + @pytest.mark.timeout(150) def test_small_model_opt_rtn(self, mock_fp8_capable_device): model_name = get_model_path("Qwen/Qwen3-0.6B-FP8") ar = AutoRound(model=model_name, iters=0) diff --git a/test/unit/test_cuda/models/test_moe_model.py b/test/unit/test_cuda/models/test_moe_model.py index 4ccf66256a..91e621be55 100644 --- a/test/unit/test_cuda/models/test_moe_model.py +++ b/test/unit/test_cuda/models/test_moe_model.py @@ -11,6 +11,7 @@ @pytest.mark.skipif(not check_version("transformers>=5.2.0"), reason="requires transformers >= 5.2.0") +@pytest.mark.timeout(120) def test_qwen3_5_moe(tiny_qwen35_moe_model_path): from transformers import Qwen3_5MoeForConditionalGeneration diff --git a/test/unit/test_cuda/models/test_omni_model.py b/test/unit/test_cuda/models/test_omni_model.py index 04f1cbaf9d..f3888d3156 100644 --- a/test/unit/test_cuda/models/test_omni_model.py +++ b/test/unit/test_cuda/models/test_omni_model.py @@ -96,6 +96,7 @@ def _save_dir(self, tmp_path): yield shutil.rmtree(self.save_dir, ignore_errors=True) + @pytest.mark.timeout(60) def test_quantize_and_reload(self, tiny_qwen3_omni_moe_model_path): """Quantize, save, reload, verify weights, and run inference.""" # Quantize diff --git a/test/unit/test_cuda/quantization/test_asym.py b/test/unit/test_cuda/quantization/test_asym.py index 7be120fdd5..97e5ed60f4 100644 --- a/test/unit/test_cuda/quantization/test_asym.py +++ b/test/unit/test_cuda/quantization/test_asym.py @@ -24,6 +24,7 @@ def setup_and_teardown_class(self): yield shutil.rmtree("runs", ignore_errors=True) + @pytest.mark.timeout(90) @pytest.mark.parametrize("group_size", [32, 64, 128]) def test_asym_group_size_with_tuning(self, group_size, tiny_opt_model_path): bits, sym = 4, False diff --git a/test/unit/test_cuda/quantization/test_mxfp_nvfp.py b/test/unit/test_cuda/quantization/test_mxfp_nvfp.py index aade7aa344..f7958ba787 100644 --- a/test/unit/test_cuda/quantization/test_mxfp_nvfp.py +++ b/test/unit/test_cuda/quantization/test_mxfp_nvfp.py @@ -28,6 +28,7 @@ } +@pytest.mark.timeout(90) @pytest.mark.parametrize("scheme", testing_schemes) @torch.inference_mode() def test_e2e_quant_and_infer(scheme, tiny_qwen_model_path): diff --git a/test/unit/test_cuda/quantization/test_torch_compile.py b/test/unit/test_cuda/quantization/test_torch_compile.py index 0fc4620e91..042e6abb9b 100644 --- a/test/unit/test_cuda/quantization/test_torch_compile.py +++ b/test/unit/test_cuda/quantization/test_torch_compile.py @@ -28,6 +28,7 @@ def setup_and_teardown_class(self): shutil.rmtree("runs", ignore_errors=True) @require_gguf + @pytest.mark.timeout(180) def test_gguf_q2ks_torch_compile(self, dataloader): """Test GGUF Q2_K_S quantization with torch.compile enabled. @@ -56,6 +57,7 @@ def test_gguf_q2ks_torch_compile(self, dataloader): shutil.rmtree(self.save_dir, ignore_errors=True) @require_gguf + @pytest.mark.timeout(60) def test_gguf_q2ks_torch_compile_iters0(self, tiny_qwen_model_path): """Test GGUF Q2_K_S with torch.compile and iters=0 (RTN mode). diff --git a/test/unit/test_cuda/transform/test_mxfp4_transform.py b/test/unit/test_cuda/transform/test_mxfp4_transform.py index 631d20c85f..60475adf2d 100644 --- a/test/unit/test_cuda/transform/test_mxfp4_transform.py +++ b/test/unit/test_cuda/transform/test_mxfp4_transform.py @@ -26,6 +26,7 @@ def setup_and_teardown_class(self): shutil.rmtree("./saved", ignore_errors=True) shutil.rmtree("runs", ignore_errors=True) + @pytest.mark.timeout(90) def test_transform_mxfp4_quant_infer(self): model_name = get_model_path("qwen/Qwen3-0.6B") scheme = "MXFP4" @@ -45,6 +46,7 @@ def test_transform_mxfp4_quant_infer(self): generate_prompt(model, tokenizer) + @pytest.mark.timeout(60) def test_transform_mxfp4_tuning_quant_infer(self): model_name = get_model_path("qwen/Qwen3-0.6B") scheme = "MXFP4" @@ -64,6 +66,7 @@ def test_transform_mxfp4_tuning_quant_infer(self): generate_prompt(model, tokenizer) + @pytest.mark.timeout(60) def test_random_transform_mxfp4_quant_infer(self): model_name = get_model_path("qwen/Qwen3-0.6B") scheme = "MXFP4" diff --git a/test/unit/test_cuda/transform/test_spinquant.py b/test/unit/test_cuda/transform/test_spinquant.py index b5d841b6cf..13aef1582b 100644 --- a/test/unit/test_cuda/transform/test_spinquant.py +++ b/test/unit/test_cuda/transform/test_spinquant.py @@ -303,6 +303,7 @@ def setup_and_teardown_class(self): yield shutil.rmtree(self.save_dir, ignore_errors=True) + @pytest.mark.timeout(90) def test_pipeline_quarot_string(self): """AutoRound(rotation_config='quarot') should work end-to-end.""" model_name = get_model_path("Qwen/Qwen3-0.6B") @@ -319,6 +320,7 @@ def test_pipeline_quarot_string(self): tokenizer = AutoTokenizer.from_pretrained(quantized_model_path) generate_prompt(model, tokenizer) + @pytest.mark.timeout(60) def test_pipeline_spinquant_config(self): """AutoRound(rotation_config=SpinQuantConfig(...)) should work.""" model_name = get_model_path("Qwen/Qwen3-0.6B") @@ -343,6 +345,7 @@ def test_pipeline_spinquant_config(self): ) shutil.rmtree(self.save_dir + "_cfg", ignore_errors=True) + @pytest.mark.timeout(60) def test_pipeline_dict_config(self): """AutoRound(rotation_config={...}) should work.""" model_name = get_model_path("Qwen/Qwen3-0.6B") diff --git a/test/unit/test_hpu/test_auto_round.py b/test/unit/test_hpu/test_auto_round.py index 90850c1233..fea7941770 100644 --- a/test/unit/test_hpu/test_auto_round.py +++ b/test/unit/test_hpu/test_auto_round.py @@ -31,6 +31,7 @@ def run_opt_125m_on_hpu(): @pytest.mark.skipif(not is_hpex_available(), reason="HPU is not supported") @pytest.mark.skipif(not is_pytest_mode_lazy(), reason="Only for lazy mode") +@pytest.mark.timeout(90) def test_opt_125m_lazy_mode(): run_opt_125m_on_hpu() diff --git a/test/unit/test_hpu/test_quant_fp8.py b/test/unit/test_hpu/test_quant_fp8.py index 39f25fa373..274e479052 100644 --- a/test/unit/test_hpu/test_quant_fp8.py +++ b/test/unit/test_hpu/test_quant_fp8.py @@ -23,6 +23,7 @@ def _save_dir(self, tmp_path): def check_nan_inf_in_tensor(self, tensor, name=""): return torch.isnan(tensor).any() or torch.isinf(tensor).any() + @pytest.mark.timeout(120) @pytest.mark.parametrize("model_name", MODEL_LIST) def test_small_model_rtn_generation(self, model_name): ar = AutoRound(model_name, iters=0, scheme="FP8_STATIC", nsamples=16) diff --git a/test/unit/test_hpu/test_static_attn.py b/test/unit/test_hpu/test_static_attn.py index 6f2c5cacfa..6a5b97b322 100644 --- a/test/unit/test_hpu/test_static_attn.py +++ b/test/unit/test_hpu/test_static_attn.py @@ -26,6 +26,7 @@ def setup_deepseekv2(): @pytest.mark.skipif(not is_hpex_available(), reason="HPU is not supported") @pytest.mark.skipif(not is_pytest_mode_lazy(), reason="Only for lazy mode") +@pytest.mark.timeout(60) def test_deepseek_v2_on_hpu(setup_deepseekv2): model, tokenizer, output_dir, config = setup_deepseekv2 autoround = AutoRound( diff --git a/test/unit/test_xpu/test_autoround.py b/test/unit/test_xpu/test_autoround.py index da32e35a63..77f43b1278 100644 --- a/test/unit/test_xpu/test_autoround.py +++ b/test/unit/test_xpu/test_autoround.py @@ -125,6 +125,7 @@ def test_scheme(self, scheme, dataloader): shutil.rmtree(quantized_model_path, ignore_errors=True) + @pytest.mark.timeout(120) def test_vlm_model(self, dataloader): scheme = "W4A16" model_name = get_model_path("Qwen/Qwen2-VL-2B-Instruct") @@ -192,6 +193,7 @@ def test_vlm_model(self, dataloader): ) print(output_text[0]) + @pytest.mark.timeout(90) def test_quant_lm_head(self, dataloader): bits, sym, group_size = 4, True, 128 # Note that, to save UT tuning time, the local model is intentionally kept lightweight, using only 2 hidden layers. From d6c556bdedb5ebf834ec224f04968a54160c3037 Mon Sep 17 00:00:00 2001 From: "Sun, Xuehao" Date: Fri, 7 Aug 2026 09:39:55 +0800 Subject: [PATCH 09/18] Increase timeout values for various tests to enhance stability and prevent premature failures Signed-off-by: Sun, Xuehao --- .../scripts/cuda_unit_test/run_cuda_ut.sh | 2 +- .azure-pipelines/scripts/ut/run_ut.sh | 2 +- .azure-pipelines/scripts/ut/run_ut_hpu.sh | 4 ++-- .azure-pipelines/scripts/ut/run_ut_xpu.sh | 6 +++--- test/unit/test_cuda/algorithms/test_alg_ext.py | 4 ++-- test/unit/test_cuda/algorithms/test_auto_scheme.py | 8 ++++---- test/unit/test_cuda/algorithms/test_awq.py | 12 ++++++------ .../test_cuda/backends/test_exllamav2_backend.py | 4 ++-- test/unit/test_cuda/backends/test_marlin_backend.py | 4 ++-- test/unit/test_cuda/backends/test_torch_backend.py | 2 +- test/unit/test_cuda/backends/test_triton_backend.py | 2 +- .../unit/test_cuda/calibration/test_calib_dataset.py | 2 +- test/unit/test_cuda/export/test_auto_round_format.py | 2 +- test/unit/test_cuda/export/test_fp8_format.py | 2 +- test/unit/test_cuda/export/test_gguf_format.py | 8 ++++---- test/unit/test_cuda/models/test_audio_model.py | 2 +- test/unit/test_cuda/models/test_conv1d.py | 2 +- test/unit/test_cuda/models/test_fp8_model.py | 4 ++-- test/unit/test_cuda/models/test_moe_model.py | 2 +- test/unit/test_cuda/models/test_omni_model.py | 2 +- test/unit/test_cuda/quantization/test_asym.py | 2 +- test/unit/test_cuda/quantization/test_mxfp_nvfp.py | 2 +- .../test_cuda/quantization/test_torch_compile.py | 4 ++-- .../unit/test_cuda/transform/test_mxfp4_transform.py | 6 +++--- test/unit/test_cuda/transform/test_spinquant.py | 6 +++--- 25 files changed, 48 insertions(+), 48 deletions(-) diff --git a/.azure-pipelines/scripts/cuda_unit_test/run_cuda_ut.sh b/.azure-pipelines/scripts/cuda_unit_test/run_cuda_ut.sh index 19bd84ad6a..80fa680db9 100644 --- a/.azure-pipelines/scripts/cuda_unit_test/run_cuda_ut.sh +++ b/.azure-pipelines/scripts/cuda_unit_test/run_cuda_ut.sh @@ -101,7 +101,7 @@ function run_unit_test() { local ut_log_name=${LOG_DIR}/unittest_cuda_${test_basename}.log COVERAGE_CORE=sysmon pytest -m "not skip_ci" \ - --cov=auto_round --cov-report= --cov-append \ + --cov=auto_round --cov-report= --cov-append --timeout=60 --session-timeout=720 \ -vs --disable-warnings --durations=0 --durations-min=1 --junitxml="${ut_log_name%.log}.xml" \ ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" diff --git a/.azure-pipelines/scripts/ut/run_ut.sh b/.azure-pipelines/scripts/ut/run_ut.sh index 3fb0357388..2c45df90e6 100644 --- a/.azure-pipelines/scripts/ut/run_ut.sh +++ b/.azure-pipelines/scripts/ut/run_ut.sh @@ -91,7 +91,7 @@ function run_unit_test() { local ut_log_name=${LOG_DIR}/unittest_${test_basename}.log COVERAGE_CORE=sysmon numactl --physcpubind="${NUMA_CPUSET:-0-15}" --membind="${NUMA_NODE:-0}" \ - pytest --durations=0 --durations-min=1 \ + pytest --timeout=30 --session-timeout=600 --durations=0 --durations-min=1 \ --cov=auto_round --cov-report= --cov-append \ -vs --disable-warnings --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" diff --git a/.azure-pipelines/scripts/ut/run_ut_hpu.sh b/.azure-pipelines/scripts/ut/run_ut_hpu.sh index 0e47cb95d4..67e5b91496 100644 --- a/.azure-pipelines/scripts/ut/run_ut_hpu.sh +++ b/.azure-pipelines/scripts/ut/run_ut_hpu.sh @@ -34,7 +34,7 @@ function run_unit_test() { echo "##[group]Running ${test_file} in HPU lazy mode..." local ut_log_name="${LOG_DIR}/unittest_lazy_${test_basename}.log" COVERAGE_CORE=sysmon PT_HPU_LAZY_MODE=1 pytest --cov="${auto_round_path}" \ - --durations=0 --durations-min=1 \ + --timeout=30 --session-timeout=600 --durations=0 --durations-min=1 \ --cov-report= --cov-append -vs --disable-warnings \ --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" @@ -42,7 +42,7 @@ function run_unit_test() { echo "##[group]Running ${test_file} in HPU compile mode..." local ut_log_name="${LOG_DIR}/unittest_compile_${test_basename}.log" COVERAGE_CORE=sysmon PT_HPU_LAZY_MODE=0 pytest --mode compile --cov="${auto_round_path}" \ - --durations=0 --durations-min=1 \ + --timeout=30 --session-timeout=600 --durations=0 --durations-min=1 \ --cov-report= --cov-append -vs --disable-warnings \ --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" diff --git a/.azure-pipelines/scripts/ut/run_ut_xpu.sh b/.azure-pipelines/scripts/ut/run_ut_xpu.sh index ce109efce7..d69e6f563f 100644 --- a/.azure-pipelines/scripts/ut/run_ut_xpu.sh +++ b/.azure-pipelines/scripts/ut/run_ut_xpu.sh @@ -39,7 +39,7 @@ function run_unit_test() { echo "##[group]Running ark ${test_file}..." local ut_log_name="${LOG_DIR}/unittest_ark_${test_basename}.log" COVERAGE_CORE=sysmon numactl --physcpubind="${NUMA_CPUSET:-0-27}" --membind="${NUMA_NODE:-0}" \ - pytest --durations=0 --durations-min=1 \ + pytest --timeout=30 --session-timeout=600 --durations=0 --durations-min=1 \ --cov="${auto_round_path}" --cov-report= --cov-append -vs --disable-warnings \ --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" @@ -51,7 +51,7 @@ function run_unit_test() { echo "##[group]Running xpu ${test_file}..." local ut_log_name="${LOG_DIR}/unittest_xpu_${test_basename}.log" COVERAGE_CORE=sysmon numactl --physcpubind="${NUMA_CPUSET:-0-27}" --membind="${NUMA_NODE:-0}" \ - pytest --durations=0 --durations-min=1 \ + pytest --timeout=30 --session-timeout=600 --durations=0 --durations-min=1 \ --cov="${auto_round_path}" --cov-report= --cov-append -vs --disable-warnings \ --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" @@ -72,7 +72,7 @@ function run_unit_test_llmc() { echo "##[group]Running xpu llmc ${test_file}..." local ut_log_name="${LOG_DIR}/unittest_xpu_${test_basename}.log" COVERAGE_CORE=sysmon numactl --physcpubind="${NUMA_CPUSET:-0-27}" --membind="${NUMA_NODE:-0}" \ - pytest --durations=0 --durations-min=1 \ + pytest --timeout=30 --session-timeout=600 --durations=0 --durations-min=1 \ --cov="${auto_round_path}" --cov-report= --cov-append -vs --disable-warnings \ --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" diff --git a/test/unit/test_cuda/algorithms/test_alg_ext.py b/test/unit/test_cuda/algorithms/test_alg_ext.py index ee62a8e1c4..8b61e251a4 100644 --- a/test/unit/test_cuda/algorithms/test_alg_ext.py +++ b/test/unit/test_cuda/algorithms/test_alg_ext.py @@ -57,7 +57,7 @@ def setup_and_teardown_class(self): # "overrides were applied (data_type was not yet 'int_asym_dq')." # ) - @pytest.mark.timeout(60) + @pytest.mark.timeout(90) def test_int2_g64_asym_enable_alg_ext_keeps_config(self, tiny_qwen_model_path): """Regression test: asym int2/g64 keeps the requested tuning config.""" @@ -91,7 +91,7 @@ def test_int2_g64_asym_enable_alg_ext_keeps_config(self, tiny_qwen_model_path): assert quantizer.enable_norm_bias_tuning is True assert quantizer.enable_quanted_input is False - @pytest.mark.timeout(90) + @pytest.mark.timeout(120) @pytest.mark.parametrize("scheme", ["MXFP4", "NVFP4", "W2A16G64", "gguf:q2_k_s,gguf:q4_k_s"]) def test_all_support_dtype(self, scheme, tiny_qwen_model_path): from auto_round.auto_scheme import AutoScheme diff --git a/test/unit/test_cuda/algorithms/test_auto_scheme.py b/test/unit/test_cuda/algorithms/test_auto_scheme.py index b48327cc2b..6d8549149f 100644 --- a/test/unit/test_cuda/algorithms/test_auto_scheme.py +++ b/test/unit/test_cuda/algorithms/test_auto_scheme.py @@ -28,7 +28,7 @@ def setup_and_teardown_class(self): yield shutil.rmtree("runs", ignore_errors=True) - @pytest.mark.timeout(30) + @pytest.mark.timeout(60) def test_gguf_k_0(self, tiny_qwen_model_path): target_bits = 5.5 scheme = AutoScheme(avg_bits=target_bits, options=("GGUF:Q4_K_M", "GGUF:Q8_0")) @@ -76,7 +76,7 @@ def test_gguf(self): # Due to the tiny model and embedding, the actual number of bits of gguf format will be larger than the target bits. assert target_bits - 0.1 < avg_bits <= target_bits + 0.3 - @pytest.mark.timeout(120) + @pytest.mark.timeout(150) def test_shared_layers(self, tiny_opt_model_path): model_name = tiny_opt_model_path from transformers import AutoModelForCausalLM, AutoTokenizer @@ -249,7 +249,7 @@ def test_layer_config(self): print(avg_bits) assert target_bits - 0.1 < avg_bits <= target_bits + 1e-3 - @pytest.mark.timeout(120) + @pytest.mark.timeout(150) def test_lm_head_and_mix_dtype(self, tiny_untied_qwen_model_path): target_bits = 5 scheme = AutoScheme(avg_bits=target_bits, options=("MXFP4", "MXFP8")) @@ -314,7 +314,7 @@ def test_enable_torch_compile(self): _, quantized_model_path = ar.quantize_and_save(output_dir=self.save_dir) evaluate_accuracy(quantized_model_path, threshold=0.10) - @pytest.mark.timeout(180) + @pytest.mark.timeout(210) def test_mixed_bits_get_scoring(self): """Verify that AutoScheme scoring produces accuracy above a known reference threshold for mixed-bit quantization. diff --git a/test/unit/test_cuda/algorithms/test_awq.py b/test/unit/test_cuda/algorithms/test_awq.py index f7bc376d8e..95a9fba26c 100644 --- a/test/unit/test_cuda/algorithms/test_awq.py +++ b/test/unit/test_cuda/algorithms/test_awq.py @@ -46,7 +46,7 @@ def _save_dir(self, tmp_path): yield shutil.rmtree(self.save_dir, ignore_errors=True) - @pytest.mark.timeout(60) + @pytest.mark.timeout(90) def test_awq_w4a16_quantize_and_inference(self, tiny_opt_model_path): """W4A16 AWQ quantization and CUDA inference smoke test.""" ar = AutoRound( @@ -93,7 +93,7 @@ def test_awq_w4a16_export_auto_round_args(self, tiny_opt_model_path): assert qconfig["sym"] == sym assert "auto-round" in qconfig["quant_method"] - @pytest.mark.timeout(90) + @pytest.mark.timeout(120) def test_awq_w4a16_load_and_generate(self): """Quantize, save, reload, and generate on CUDA to verify round-trip.""" model_name = get_model_path("facebook/opt-125m") @@ -123,7 +123,7 @@ def _save_dir(self, tmp_path): yield shutil.rmtree(self.save_dir, ignore_errors=True) - @pytest.mark.timeout(90) + @pytest.mark.timeout(120) def test_awq_moe_dynamic_smoothing(self, tiny_qwen_moe_model_path): """AWQ mapping resolution works on MoE model.""" from auto_round.algorithms.transforms.awq.mappings import resolve_mappings @@ -156,7 +156,7 @@ def test_awq_moe_dynamic_smoothing(self, tiny_qwen_moe_model_path): del model - @pytest.mark.timeout(120) + @pytest.mark.timeout(150) def test_awq_moe_quantized_layers_check(self, tiny_qwen_moe_model_path): """Expert layers quantized to W4, gates/routers stay fp.""" ar = AutoRound( @@ -193,7 +193,7 @@ def test_awq_moe_quantized_layers_check(self, tiny_qwen_moe_model_path): for name in fp_layers: assert name.endswith("gate"), f"Unexpected FP layer: {name}" - @pytest.mark.timeout(90) + @pytest.mark.timeout(120) def test_awq_moe_save_compressed_size(self, tiny_qwen_moe_model_path): """AWQ MoE W4: quantized safetensors should be smaller than original.""" ar = AutoRound( @@ -238,7 +238,7 @@ def setup_class(cls): def teardown_class(cls): shutil.rmtree("runs", ignore_errors=True) - @pytest.mark.timeout(150) + @pytest.mark.timeout(180) def test_awq_w4a16_lmeval(self): """AWQ W4A16 on OPT-125m: lambada_openai accuracy check.""" ar = AutoRound( diff --git a/test/unit/test_cuda/backends/test_exllamav2_backend.py b/test/unit/test_cuda/backends/test_exllamav2_backend.py index 738279e216..597c11cf41 100644 --- a/test/unit/test_cuda/backends/test_exllamav2_backend.py +++ b/test/unit/test_cuda/backends/test_exllamav2_backend.py @@ -34,7 +34,7 @@ def setup_and_teardown_class(self): # @pytest.mark.skip_ci(reason="Only tiny model is suggested") # @pytest.mark.skip_ci(reason="Time-consuming; Accuracy evaluation") @require_gptqmodel - @pytest.mark.timeout(120) + @pytest.mark.timeout(150) def test_gptqmodel_exllmav2_4bits_asym(self, dataloader): model_path = get_model_path("facebook/opt-125m") bits, group_size, sym = 4, 128, False @@ -128,7 +128,7 @@ def test_gptq_exllamav2_4bits_sym_group_size(self, group_size): torch.cuda.empty_cache() @require_gptqmodel - @pytest.mark.timeout(60) + @pytest.mark.timeout(90) def test_gptqmodel_awq_exllamav2_4bits_asym(self, dataloader): """Test AWQ quantization with gptqmodel:awq_exllamav2 backend (bfloat16 inference).""" model_path = get_model_path("facebook/opt-125m") diff --git a/test/unit/test_cuda/backends/test_marlin_backend.py b/test/unit/test_cuda/backends/test_marlin_backend.py index 7f631fc622..39fed05da9 100644 --- a/test/unit/test_cuda/backends/test_marlin_backend.py +++ b/test/unit/test_cuda/backends/test_marlin_backend.py @@ -34,7 +34,7 @@ def setup_and_teardown_class(self): # Keep one CI test for marlin backend and skip others to save time. # @pytest.mark.skip_ci(reason="Only tiny model is suggested") # @pytest.mark.skip_ci(reason="Time-consuming; Accuracy evaluation") - @pytest.mark.timeout(150) + @pytest.mark.timeout(180) def test_marlin_4bits_sym_with_zp_m_1(self, dataloader): model = AutoModelForCausalLM.from_pretrained(self.model_name, torch_dtype="auto", trust_remote_code=True) tokenizer = AutoTokenizer.from_pretrained(self.model_name, trust_remote_code=True) @@ -173,7 +173,7 @@ def test_marlin_group_size(self, dataloader): # shutil.rmtree("./saved", ignore_errors=True) @require_gptqmodel - @pytest.mark.timeout(60) + @pytest.mark.timeout(90) def test_gptqmodel_awq_marlin_4bits_sym(self): """Test AWQ quantization with gptqmodel:awq_marlin backend (sym-only, float16).""" model_path = get_model_path("facebook/opt-125m") diff --git a/test/unit/test_cuda/backends/test_torch_backend.py b/test/unit/test_cuda/backends/test_torch_backend.py index bcfa4ec1a9..dd03cd87b8 100644 --- a/test/unit/test_cuda/backends/test_torch_backend.py +++ b/test/unit/test_cuda/backends/test_torch_backend.py @@ -33,7 +33,7 @@ def setup_and_teardown_class(self): # Keep one CI test for torch backend and skip others to save time. # @pytest.mark.skip_ci(reason="Only tiny model is suggested") # @pytest.mark.skip_ci(reason="Time-consuming; Accuracy evaluation") - @pytest.mark.timeout(60) + @pytest.mark.timeout(90) def test_torch_4bits_asym(self, dataloader): model_path = get_model_path("facebook/opt-125m") model = AutoModelForCausalLM.from_pretrained(model_path, torch_dtype="auto", trust_remote_code=True) diff --git a/test/unit/test_cuda/backends/test_triton_backend.py b/test/unit/test_cuda/backends/test_triton_backend.py index 04f33ebb1c..1620a34bf7 100644 --- a/test/unit/test_cuda/backends/test_triton_backend.py +++ b/test/unit/test_cuda/backends/test_triton_backend.py @@ -29,7 +29,7 @@ def teardown_class(self): # @pytest.mark.skip_ci(reason="Only tiny model is suggested") # @pytest.mark.skip_ci(reason="Time-consuming; Accuracy evaluation") @require_greater_than_050 - @pytest.mark.timeout(150) + @pytest.mark.timeout(180) def test_tritonv2_2bits_asym(self): model = AutoModelForCausalLM.from_pretrained(self.model_name, torch_dtype="auto", trust_remote_code=True) tokenizer = AutoTokenizer.from_pretrained(self.model_name, trust_remote_code=True) diff --git a/test/unit/test_cuda/calibration/test_calib_dataset.py b/test/unit/test_cuda/calibration/test_calib_dataset.py index 93dbccfda1..fd90cdfeca 100644 --- a/test/unit/test_cuda/calibration/test_calib_dataset.py +++ b/test/unit/test_cuda/calibration/test_calib_dataset.py @@ -10,7 +10,7 @@ class TestLocalCalibDataset: - @pytest.mark.timeout(120) + @pytest.mark.timeout(150) def test_combine_dataset(self, tiny_opt_model_path): dataset = "NeelNanda/pile-10k" + ",BAAI/CCI3-HQ" + ",madao33/new-title-chinese" bits, group_size, sym = 4, 128, True diff --git a/test/unit/test_cuda/export/test_auto_round_format.py b/test/unit/test_cuda/export/test_auto_round_format.py index 722643ff30..0f8427e32b 100644 --- a/test/unit/test_cuda/export/test_auto_round_format.py +++ b/test/unit/test_cuda/export/test_auto_round_format.py @@ -153,7 +153,7 @@ def test_tritonv2_bf16(self): eval_generated_prompt(model, tokenizer) torch.cuda.empty_cache() - @pytest.mark.timeout(90) + @pytest.mark.timeout(120) def test_fp8_block_fp8_format(self): model_name = "Qwen/Qwen3-0.6B" diff --git a/test/unit/test_cuda/export/test_fp8_format.py b/test/unit/test_cuda/export/test_fp8_format.py index 72a7e84264..7b76188857 100644 --- a/test/unit/test_cuda/export/test_fp8_format.py +++ b/test/unit/test_cuda/export/test_fp8_format.py @@ -22,7 +22,7 @@ def _save_dir(self, tmp_path): yield shutil.rmtree(self.save_dir, ignore_errors=True) - @pytest.mark.timeout(60) + @pytest.mark.timeout(90) def test_fp8_block_fp8_format(self): model_name = self.model_name diff --git a/test/unit/test_cuda/export/test_gguf_format.py b/test/unit/test_cuda/export/test_gguf_format.py index 0279de6c4c..65dd3baa63 100644 --- a/test/unit/test_cuda/export/test_gguf_format.py +++ b/test/unit/test_cuda/export/test_gguf_format.py @@ -102,7 +102,7 @@ def _export_qwen35_moe_gguf(self, tiny_qwen35_moe_model_path): @pytest.mark.skipif(not check_version("transformers>=5.2.0"), reason="requires transformers >= 5.2.0") @pytest.mark.skipif(not torch.cuda.is_available(), reason="requires CUDA") @require_gguf - @pytest.mark.timeout(120) + @pytest.mark.timeout(150) def test_qwen35_moe_gguf(self, tiny_qwen35_moe_model_path): self._export_qwen35_moe_gguf(tiny_qwen35_moe_model_path) @@ -139,7 +139,7 @@ def test_gguf_format(self, tiny_qwen_model_path, dataloader): autoround.save_quantized(output_dir=quantized_model_path, format="gguf:q4_1") @require_gguf - @pytest.mark.timeout(150) + @pytest.mark.timeout(180) def test_q4_0_accuracy(self): model_name = get_model_path("Qwen/Qwen2.5-0.5B-Instruct") bits, group_size, sym = 4, 32, True @@ -224,7 +224,7 @@ def test_special_model(self): shutil.rmtree(tiny_model_path, ignore_errors=True) @require_gguf - @pytest.mark.timeout(90) + @pytest.mark.timeout(120) def test_vlm_gguf(self): from test.helpers import save_tiny_model @@ -299,7 +299,7 @@ def test_q2k_mixed(self): shutil.rmtree(saved_tiny_model_path, ignore_errors=True) @require_gguf - @pytest.mark.timeout(60) + @pytest.mark.timeout(90) def test_q2_k_s_ffn_down_q4k(self): """Verify blk.0.ffn_down.weight is Q4_K in gguf:q2_k_s format. Blocks where i_layer < n_layer/8 should use Q4_K instead of Q2_K for ffn_down.""" diff --git a/test/unit/test_cuda/models/test_audio_model.py b/test/unit/test_cuda/models/test_audio_model.py index 16c114df7b..578f1c8ebd 100644 --- a/test/unit/test_cuda/models/test_audio_model.py +++ b/test/unit/test_cuda/models/test_audio_model.py @@ -327,7 +327,7 @@ def test_quantize_rtn(self, tiny_mimo_audio_model_path, tmp_path): has_quantlinear = any(m.__class__.__name__ == "QuantLinear" for m in quantized_model.modules()) assert has_quantlinear, "Quantized model should contain QuantLinear layers" - @pytest.mark.timeout(60) + @pytest.mark.timeout(90) def test_quantize_with_tuning(self, tiny_mimo_audio_model_path, tmp_path): import transformers diff --git a/test/unit/test_cuda/models/test_conv1d.py b/test/unit/test_cuda/models/test_conv1d.py index 8cf1bf0656..343f3aad72 100644 --- a/test/unit/test_cuda/models/test_conv1d.py +++ b/test/unit/test_cuda/models/test_conv1d.py @@ -25,7 +25,7 @@ def setup_and_teardown_class(self): shutil.rmtree("runs", ignore_errors=True) @require_gptqmodel - @pytest.mark.timeout(150) + @pytest.mark.timeout(180) def test_quant(self, dataloader): model_name = get_model_path("MBZUAI/LaMini-GPT-124M") model = get_tiny_model(model_name) diff --git a/test/unit/test_cuda/models/test_fp8_model.py b/test/unit/test_cuda/models/test_fp8_model.py index ad280a6b90..3d1693ca44 100644 --- a/test/unit/test_cuda/models/test_fp8_model.py +++ b/test/unit/test_cuda/models/test_fp8_model.py @@ -76,7 +76,7 @@ def test_small_model_rtn_generation(self, mock_fp8_capable_device, tiny_fp8_qwen tokenizer = AutoTokenizer.from_pretrained(quantized_model_path) generate_prompt(model, tokenizer) - @pytest.mark.timeout(60) + @pytest.mark.timeout(90) def test_gguf_imatrix(self, mock_fp8_capable_device, tiny_fp8_qwen_model_path): ar = AutoRound(tiny_fp8_qwen_model_path, iters=0) _, quantized_model_path = ar.quantize_and_save(format="gguf:q2_k_s", output_dir=self.save_dir) @@ -109,7 +109,7 @@ def test_small_model_iters1(self, mock_fp8_capable_device): with patch("torch.cuda.get_device_capability", return_value=DEVICE_CAPABILITY): # revert DEVICE_CAPABILITY evaluate_accuracy(folder, threshold=0.25) - @pytest.mark.timeout(150) + @pytest.mark.timeout(180) def test_small_model_opt_rtn(self, mock_fp8_capable_device): model_name = get_model_path("Qwen/Qwen3-0.6B-FP8") ar = AutoRound(model=model_name, iters=0) diff --git a/test/unit/test_cuda/models/test_moe_model.py b/test/unit/test_cuda/models/test_moe_model.py index 91e621be55..fd04231313 100644 --- a/test/unit/test_cuda/models/test_moe_model.py +++ b/test/unit/test_cuda/models/test_moe_model.py @@ -11,7 +11,7 @@ @pytest.mark.skipif(not check_version("transformers>=5.2.0"), reason="requires transformers >= 5.2.0") -@pytest.mark.timeout(120) +@pytest.mark.timeout(150) def test_qwen3_5_moe(tiny_qwen35_moe_model_path): from transformers import Qwen3_5MoeForConditionalGeneration diff --git a/test/unit/test_cuda/models/test_omni_model.py b/test/unit/test_cuda/models/test_omni_model.py index f3888d3156..672a2a99fe 100644 --- a/test/unit/test_cuda/models/test_omni_model.py +++ b/test/unit/test_cuda/models/test_omni_model.py @@ -96,7 +96,7 @@ def _save_dir(self, tmp_path): yield shutil.rmtree(self.save_dir, ignore_errors=True) - @pytest.mark.timeout(60) + @pytest.mark.timeout(90) def test_quantize_and_reload(self, tiny_qwen3_omni_moe_model_path): """Quantize, save, reload, verify weights, and run inference.""" # Quantize diff --git a/test/unit/test_cuda/quantization/test_asym.py b/test/unit/test_cuda/quantization/test_asym.py index 97e5ed60f4..f305b30ca0 100644 --- a/test/unit/test_cuda/quantization/test_asym.py +++ b/test/unit/test_cuda/quantization/test_asym.py @@ -24,7 +24,7 @@ def setup_and_teardown_class(self): yield shutil.rmtree("runs", ignore_errors=True) - @pytest.mark.timeout(90) + @pytest.mark.timeout(120) @pytest.mark.parametrize("group_size", [32, 64, 128]) def test_asym_group_size_with_tuning(self, group_size, tiny_opt_model_path): bits, sym = 4, False diff --git a/test/unit/test_cuda/quantization/test_mxfp_nvfp.py b/test/unit/test_cuda/quantization/test_mxfp_nvfp.py index f7958ba787..dbbcd63000 100644 --- a/test/unit/test_cuda/quantization/test_mxfp_nvfp.py +++ b/test/unit/test_cuda/quantization/test_mxfp_nvfp.py @@ -28,7 +28,7 @@ } -@pytest.mark.timeout(90) +@pytest.mark.timeout(120) @pytest.mark.parametrize("scheme", testing_schemes) @torch.inference_mode() def test_e2e_quant_and_infer(scheme, tiny_qwen_model_path): diff --git a/test/unit/test_cuda/quantization/test_torch_compile.py b/test/unit/test_cuda/quantization/test_torch_compile.py index 042e6abb9b..6f9df8cae6 100644 --- a/test/unit/test_cuda/quantization/test_torch_compile.py +++ b/test/unit/test_cuda/quantization/test_torch_compile.py @@ -28,7 +28,7 @@ def setup_and_teardown_class(self): shutil.rmtree("runs", ignore_errors=True) @require_gguf - @pytest.mark.timeout(180) + @pytest.mark.timeout(210) def test_gguf_q2ks_torch_compile(self, dataloader): """Test GGUF Q2_K_S quantization with torch.compile enabled. @@ -57,7 +57,7 @@ def test_gguf_q2ks_torch_compile(self, dataloader): shutil.rmtree(self.save_dir, ignore_errors=True) @require_gguf - @pytest.mark.timeout(60) + @pytest.mark.timeout(90) def test_gguf_q2ks_torch_compile_iters0(self, tiny_qwen_model_path): """Test GGUF Q2_K_S with torch.compile and iters=0 (RTN mode). diff --git a/test/unit/test_cuda/transform/test_mxfp4_transform.py b/test/unit/test_cuda/transform/test_mxfp4_transform.py index 60475adf2d..0996e2ffaf 100644 --- a/test/unit/test_cuda/transform/test_mxfp4_transform.py +++ b/test/unit/test_cuda/transform/test_mxfp4_transform.py @@ -26,7 +26,7 @@ def setup_and_teardown_class(self): shutil.rmtree("./saved", ignore_errors=True) shutil.rmtree("runs", ignore_errors=True) - @pytest.mark.timeout(90) + @pytest.mark.timeout(120) def test_transform_mxfp4_quant_infer(self): model_name = get_model_path("qwen/Qwen3-0.6B") scheme = "MXFP4" @@ -46,7 +46,7 @@ def test_transform_mxfp4_quant_infer(self): generate_prompt(model, tokenizer) - @pytest.mark.timeout(60) + @pytest.mark.timeout(90) def test_transform_mxfp4_tuning_quant_infer(self): model_name = get_model_path("qwen/Qwen3-0.6B") scheme = "MXFP4" @@ -66,7 +66,7 @@ def test_transform_mxfp4_tuning_quant_infer(self): generate_prompt(model, tokenizer) - @pytest.mark.timeout(60) + @pytest.mark.timeout(90) def test_random_transform_mxfp4_quant_infer(self): model_name = get_model_path("qwen/Qwen3-0.6B") scheme = "MXFP4" diff --git a/test/unit/test_cuda/transform/test_spinquant.py b/test/unit/test_cuda/transform/test_spinquant.py index 13aef1582b..5c635a2f20 100644 --- a/test/unit/test_cuda/transform/test_spinquant.py +++ b/test/unit/test_cuda/transform/test_spinquant.py @@ -303,7 +303,7 @@ def setup_and_teardown_class(self): yield shutil.rmtree(self.save_dir, ignore_errors=True) - @pytest.mark.timeout(90) + @pytest.mark.timeout(120) def test_pipeline_quarot_string(self): """AutoRound(rotation_config='quarot') should work end-to-end.""" model_name = get_model_path("Qwen/Qwen3-0.6B") @@ -320,7 +320,7 @@ def test_pipeline_quarot_string(self): tokenizer = AutoTokenizer.from_pretrained(quantized_model_path) generate_prompt(model, tokenizer) - @pytest.mark.timeout(60) + @pytest.mark.timeout(90) def test_pipeline_spinquant_config(self): """AutoRound(rotation_config=SpinQuantConfig(...)) should work.""" model_name = get_model_path("Qwen/Qwen3-0.6B") @@ -345,7 +345,7 @@ def test_pipeline_spinquant_config(self): ) shutil.rmtree(self.save_dir + "_cfg", ignore_errors=True) - @pytest.mark.timeout(60) + @pytest.mark.timeout(90) def test_pipeline_dict_config(self): """AutoRound(rotation_config={...}) should work.""" model_name = get_model_path("Qwen/Qwen3-0.6B") From ef0f569545b19de6ddb89a964e761e1ba8fcb690 Mon Sep 17 00:00:00 2001 From: "Sun, Xuehao" Date: Fri, 7 Aug 2026 11:36:32 +0800 Subject: [PATCH 10/18] Increase timeout values for various tests to improve stability and prevent premature failures Signed-off-by: Sun, Xuehao --- .azure-pipelines/scripts/ut/run_ut.sh | 2 +- test/unit/test_cpu/utils/test_cli_usage.py | 8 ++++---- test/unit/test_cpu/utils/test_model_scope.py | 2 ++ test/unit/test_cuda/algorithms/test_awq.py | 6 +++--- test/unit/test_cuda/backends/test_exllamav2_backend.py | 2 +- test/unit/test_cuda/export/test_gguf_format.py | 2 +- test/unit/test_cuda/models/test_conv1d.py | 2 +- test/unit/test_cuda/models/test_fp8_model.py | 2 +- test/unit/test_cuda/models/test_moe_model.py | 2 +- test/unit/test_cuda/models/test_omni_model.py | 2 +- test/unit/test_cuda/transform/test_spinquant.py | 2 +- test/unit/test_hpu/test_static_attn.py | 2 +- 12 files changed, 18 insertions(+), 16 deletions(-) diff --git a/.azure-pipelines/scripts/ut/run_ut.sh b/.azure-pipelines/scripts/ut/run_ut.sh index 2c45df90e6..67aaec68d1 100644 --- a/.azure-pipelines/scripts/ut/run_ut.sh +++ b/.azure-pipelines/scripts/ut/run_ut.sh @@ -91,7 +91,7 @@ function run_unit_test() { local ut_log_name=${LOG_DIR}/unittest_${test_basename}.log COVERAGE_CORE=sysmon numactl --physcpubind="${NUMA_CPUSET:-0-15}" --membind="${NUMA_NODE:-0}" \ - pytest --timeout=30 --session-timeout=600 --durations=0 --durations-min=1 \ + pytest -m "not skip_ci" --timeout=30 --session-timeout=600 --durations=0 --durations-min=1 \ --cov=auto_round --cov-report= --cov-append \ -vs --disable-warnings --junitxml="${ut_log_name%.log}.xml" ${test_file} 2>&1 | tee ${ut_log_name} echo "##[endgroup]" diff --git a/test/unit/test_cpu/utils/test_cli_usage.py b/test/unit/test_cpu/utils/test_cli_usage.py index 7e42d6a455..0be2b0052f 100644 --- a/test/unit/test_cpu/utils/test_cli_usage.py +++ b/test/unit/test_cpu/utils/test_cli_usage.py @@ -30,7 +30,7 @@ def test_auto_round_cmd(self, tiny_opt_model_path, tiny_qwen_vl_model_path): if res > 0 or res == -1: assert False, "cmd line test fail, please have a check" - @pytest.mark.timeout(60) + @pytest.mark.timeout(90) def test_auto_round_cmd2(self, tiny_opt_model_path, tiny_qwen_vl_model_path): python_path = sys.executable res = os.system( @@ -39,7 +39,7 @@ def test_auto_round_cmd2(self, tiny_opt_model_path, tiny_qwen_vl_model_path): if res > 0 or res == -1: assert False, "cmd line test fail, please have a check" - @pytest.mark.timeout(60) + @pytest.mark.timeout(90) def test_auto_round_cmd3(self, tiny_opt_model_path, tiny_qwen_vl_model_path): python_path = sys.executable res = os.system( @@ -48,7 +48,7 @@ def test_auto_round_cmd3(self, tiny_opt_model_path, tiny_qwen_vl_model_path): if res > 0 or res == -1: assert False, "cmd line test fail, please have a check" - @pytest.mark.timeout(60) + @pytest.mark.timeout(90) def test_auto_round_cmd4(self, tiny_opt_model_path, tiny_qwen_vl_model_path): python_path = sys.executable res = os.system( @@ -69,7 +69,7 @@ def test_auto_round_cmd6(self, tiny_opt_model_path, tiny_qwen_vl_model_path): if res > 0 or res == -1: assert False, "cmd line test fail, please have a check" - @pytest.mark.timeout(60) + @pytest.mark.timeout(90) def test_auto_round_cmd7(self, tiny_opt_model_path, tiny_qwen_vl_model_path): python_path = sys.executable res = os.system( diff --git a/test/unit/test_cpu/utils/test_model_scope.py b/test/unit/test_cpu/utils/test_model_scope.py index 3b7d96eea2..17cfd497ba 100644 --- a/test/unit/test_cpu/utils/test_model_scope.py +++ b/test/unit/test_cpu/utils/test_model_scope.py @@ -30,12 +30,14 @@ def teardown_class(self): if os.path.exists(self.cache_path): shutil.rmtree(self.cache_path, ignore_errors=True) + @pytest.mark.skip_ci(reason="https://github.com/intel/auto-round/issues/2127") @pytest.mark.timeout(120) def test_llm(self, dataloader): model_name = get_model_path("Qwen/Qwen2.5-0.5B-Instruct") autoround = AutoRound(model_name, platform="model_scope", scheme="w4a16", iters=0, seqlen=2, dataset=dataloader) autoround.quantize_and_save() + @pytest.mark.skip_ci(reason="https://github.com/intel/auto-round/issues/2127") @pytest.mark.timeout(360) def test_mllm(self, dataloader): model_name = get_model_path("Qwen/Qwen2-VL-2B-Instruct") diff --git a/test/unit/test_cuda/algorithms/test_awq.py b/test/unit/test_cuda/algorithms/test_awq.py index 95a9fba26c..ddc4371ebe 100644 --- a/test/unit/test_cuda/algorithms/test_awq.py +++ b/test/unit/test_cuda/algorithms/test_awq.py @@ -156,7 +156,7 @@ def test_awq_moe_dynamic_smoothing(self, tiny_qwen_moe_model_path): del model - @pytest.mark.timeout(150) + @pytest.mark.timeout(240) def test_awq_moe_quantized_layers_check(self, tiny_qwen_moe_model_path): """Expert layers quantized to W4, gates/routers stay fp.""" ar = AutoRound( @@ -193,7 +193,7 @@ def test_awq_moe_quantized_layers_check(self, tiny_qwen_moe_model_path): for name in fp_layers: assert name.endswith("gate"), f"Unexpected FP layer: {name}" - @pytest.mark.timeout(120) + @pytest.mark.timeout(180) def test_awq_moe_save_compressed_size(self, tiny_qwen_moe_model_path): """AWQ MoE W4: quantized safetensors should be smaller than original.""" ar = AutoRound( @@ -238,7 +238,7 @@ def setup_class(cls): def teardown_class(cls): shutil.rmtree("runs", ignore_errors=True) - @pytest.mark.timeout(180) + @pytest.mark.timeout(240) def test_awq_w4a16_lmeval(self): """AWQ W4A16 on OPT-125m: lambada_openai accuracy check.""" ar = AutoRound( diff --git a/test/unit/test_cuda/backends/test_exllamav2_backend.py b/test/unit/test_cuda/backends/test_exllamav2_backend.py index 597c11cf41..7ca321b20a 100644 --- a/test/unit/test_cuda/backends/test_exllamav2_backend.py +++ b/test/unit/test_cuda/backends/test_exllamav2_backend.py @@ -34,7 +34,7 @@ def setup_and_teardown_class(self): # @pytest.mark.skip_ci(reason="Only tiny model is suggested") # @pytest.mark.skip_ci(reason="Time-consuming; Accuracy evaluation") @require_gptqmodel - @pytest.mark.timeout(150) + @pytest.mark.timeout(240) def test_gptqmodel_exllmav2_4bits_asym(self, dataloader): model_path = get_model_path("facebook/opt-125m") bits, group_size, sym = 4, 128, False diff --git a/test/unit/test_cuda/export/test_gguf_format.py b/test/unit/test_cuda/export/test_gguf_format.py index 65dd3baa63..5cb71ea4d0 100644 --- a/test/unit/test_cuda/export/test_gguf_format.py +++ b/test/unit/test_cuda/export/test_gguf_format.py @@ -102,7 +102,7 @@ def _export_qwen35_moe_gguf(self, tiny_qwen35_moe_model_path): @pytest.mark.skipif(not check_version("transformers>=5.2.0"), reason="requires transformers >= 5.2.0") @pytest.mark.skipif(not torch.cuda.is_available(), reason="requires CUDA") @require_gguf - @pytest.mark.timeout(150) + @pytest.mark.timeout(240) def test_qwen35_moe_gguf(self, tiny_qwen35_moe_model_path): self._export_qwen35_moe_gguf(tiny_qwen35_moe_model_path) diff --git a/test/unit/test_cuda/models/test_conv1d.py b/test/unit/test_cuda/models/test_conv1d.py index 343f3aad72..e58a612062 100644 --- a/test/unit/test_cuda/models/test_conv1d.py +++ b/test/unit/test_cuda/models/test_conv1d.py @@ -25,7 +25,7 @@ def setup_and_teardown_class(self): shutil.rmtree("runs", ignore_errors=True) @require_gptqmodel - @pytest.mark.timeout(180) + @pytest.mark.timeout(300) def test_quant(self, dataloader): model_name = get_model_path("MBZUAI/LaMini-GPT-124M") model = get_tiny_model(model_name) diff --git a/test/unit/test_cuda/models/test_fp8_model.py b/test/unit/test_cuda/models/test_fp8_model.py index 3d1693ca44..4c6887fac4 100644 --- a/test/unit/test_cuda/models/test_fp8_model.py +++ b/test/unit/test_cuda/models/test_fp8_model.py @@ -109,7 +109,7 @@ def test_small_model_iters1(self, mock_fp8_capable_device): with patch("torch.cuda.get_device_capability", return_value=DEVICE_CAPABILITY): # revert DEVICE_CAPABILITY evaluate_accuracy(folder, threshold=0.25) - @pytest.mark.timeout(180) + @pytest.mark.timeout(300) def test_small_model_opt_rtn(self, mock_fp8_capable_device): model_name = get_model_path("Qwen/Qwen3-0.6B-FP8") ar = AutoRound(model=model_name, iters=0) diff --git a/test/unit/test_cuda/models/test_moe_model.py b/test/unit/test_cuda/models/test_moe_model.py index fd04231313..fca22284d2 100644 --- a/test/unit/test_cuda/models/test_moe_model.py +++ b/test/unit/test_cuda/models/test_moe_model.py @@ -11,7 +11,7 @@ @pytest.mark.skipif(not check_version("transformers>=5.2.0"), reason="requires transformers >= 5.2.0") -@pytest.mark.timeout(150) +@pytest.mark.timeout(240) def test_qwen3_5_moe(tiny_qwen35_moe_model_path): from transformers import Qwen3_5MoeForConditionalGeneration diff --git a/test/unit/test_cuda/models/test_omni_model.py b/test/unit/test_cuda/models/test_omni_model.py index 672a2a99fe..85cacee4c2 100644 --- a/test/unit/test_cuda/models/test_omni_model.py +++ b/test/unit/test_cuda/models/test_omni_model.py @@ -96,7 +96,7 @@ def _save_dir(self, tmp_path): yield shutil.rmtree(self.save_dir, ignore_errors=True) - @pytest.mark.timeout(90) + @pytest.mark.timeout(180) def test_quantize_and_reload(self, tiny_qwen3_omni_moe_model_path): """Quantize, save, reload, verify weights, and run inference.""" # Quantize diff --git a/test/unit/test_cuda/transform/test_spinquant.py b/test/unit/test_cuda/transform/test_spinquant.py index 5c635a2f20..2e692c97ca 100644 --- a/test/unit/test_cuda/transform/test_spinquant.py +++ b/test/unit/test_cuda/transform/test_spinquant.py @@ -303,7 +303,7 @@ def setup_and_teardown_class(self): yield shutil.rmtree(self.save_dir, ignore_errors=True) - @pytest.mark.timeout(120) + @pytest.mark.timeout(180) def test_pipeline_quarot_string(self): """AutoRound(rotation_config='quarot') should work end-to-end.""" model_name = get_model_path("Qwen/Qwen3-0.6B") diff --git a/test/unit/test_hpu/test_static_attn.py b/test/unit/test_hpu/test_static_attn.py index 6a5b97b322..2a06a8a44c 100644 --- a/test/unit/test_hpu/test_static_attn.py +++ b/test/unit/test_hpu/test_static_attn.py @@ -26,7 +26,7 @@ def setup_deepseekv2(): @pytest.mark.skipif(not is_hpex_available(), reason="HPU is not supported") @pytest.mark.skipif(not is_pytest_mode_lazy(), reason="Only for lazy mode") -@pytest.mark.timeout(60) +@pytest.mark.timeout(90) def test_deepseek_v2_on_hpu(setup_deepseekv2): model, tokenizer, output_dir, config = setup_deepseekv2 autoround = AutoRound( From a90e07550f56a78e0bbf173f8142919c07f9fa45 Mon Sep 17 00:00:00 2001 From: "Sun, Xuehao" Date: Fri, 7 Aug 2026 11:58:36 +0800 Subject: [PATCH 11/18] Refactor CLI test execution to use in-process calls for improved coverage and stability Signed-off-by: Sun, Xuehao --- test/unit/test_cpu/export/test_gguf_format.py | 52 ++--- test/unit/test_cpu/utils/test_cli_usage.py | 200 +++++++++++++----- .../test_cuda/advanced/test_evaluation.py | 56 ++--- 3 files changed, 202 insertions(+), 106 deletions(-) diff --git a/test/unit/test_cpu/export/test_gguf_format.py b/test/unit/test_cpu/export/test_gguf_format.py index 0a6f38606a..5912a4ac84 100644 --- a/test/unit/test_cpu/export/test_gguf_format.py +++ b/test/unit/test_cpu/export/test_gguf_format.py @@ -11,8 +11,21 @@ from auto_round import AutoRound from auto_round.algorithms.quantization.rtn.config import OptimizedRTNConfig -AUTO_ROUND_PATH = __file__.split("/") -AUTO_ROUND_PATH = "/".join(AUTO_ROUND_PATH[: AUTO_ROUND_PATH.index("test")]) + +def _run_auto_round_cli(monkeypatch, cmd): + """Run the auto_round CLI in-process by patching ``sys.argv``. + + ``cmd`` contains only the CLI arguments (everything after ``-m auto_round``). + This replaces the previous ``os.system('python -m auto_round ...')`` calls so + the code runs in the test process and is measured by coverage. + """ + from auto_round.cli.main import run + + monkeypatch.setattr(sys, "argv", ["auto_round", *cmd.split()]) + try: + run() + except SystemExit as exc: # argparse help/errors exit; only 0/None is success + assert exc.code in (0, None), f"cmd line test fail, exit code {exc.code}" def test_update_module_applies_replacements_for_gguf(monkeypatch): @@ -149,43 +162,34 @@ def test_q4_k_m(self, dataloader, tiny_qwen_model_path): assert autoround.layer_config["model.layers.0.mlp.gate_proj"]["mostly"] == "gguf:q8_0" @pytest.mark.timeout(360) - def test_all_format(self, tiny_qwen_model_path): + def test_all_format(self, monkeypatch, tiny_qwen_model_path): model_name = tiny_qwen_model_path - python_path = sys.executable # for gguf_format in ["gguf:q4_0", "gguf:q4_1", "gguf:q4_k_m", "gguf:q6_k"]: for gguf_format in ["gguf:q4_k_m"]: - res = os.system( - f"PYTHONPATH='{AUTO_ROUND_PATH}:$PYTHONPATH' {python_path} -m auto_round --model {model_name} " - f" --bs 16 --iters 1 --nsamples 1 --seqlen 16 --format {gguf_format}" + _run_auto_round_cli( + monkeypatch, + f"--model {model_name} --bs 16 --iters 1 --nsamples 1 --seqlen 16 --format {gguf_format}", ) - if res > 0 or res == -1: - assert False, "cmd line test fail, please have a check" shutil.rmtree("../../tmp_autoround", ignore_errors=True) - res = os.system( - f"PYTHONPATH='{AUTO_ROUND_PATH}:$PYTHONPATH' {python_path} -m auto_round --model {model_name}" - f" --bs 16 --iters 0 --nsamples 1 --seqlen 16 --format fake,{gguf_format}" + _run_auto_round_cli( + monkeypatch, + f"--model {model_name} --bs 16 --iters 0 --nsamples 1 --seqlen 16 --format fake,{gguf_format}", ) - if res > 0 or res == -1: - assert False, "cmd line test fail, please have a check" shutil.rmtree("../../tmp_autoround", ignore_errors=True) # test q2_k_mixed with iters=0 (RTN) on non-MoE model — should still work - res = os.system( - f"PYTHONPATH='{AUTO_ROUND_PATH}:$PYTHONPATH' {python_path} -m auto_round --model {model_name}" - f" --bs 16 --iters 0 --disable_opt_rtn --nsamples 1 --seqlen 16 --scheme GGUF:Q2_K_MIXED" + _run_auto_round_cli( + monkeypatch, + f"--model {model_name} --bs 16 --iters 0 --disable_opt_rtn --nsamples 1 --seqlen 16 --scheme GGUF:Q2_K_MIXED", ) - if res > 0 or res == -1: - assert False, "cmd line test fail, please have a check" shutil.rmtree("../../tmp_autoround", ignore_errors=True) # test q2_k_mixed with iters=1 on non-MoE model — should fallback to q4_k_m - res = os.system( - f"PYTHONPATH='{AUTO_ROUND_PATH}:$PYTHONPATH' {python_path} -m auto_round --model {model_name}" - f" --bs 16 --iters 1 --nsamples 1 --seqlen 16 --format gguf:q2_k_mixed" + _run_auto_round_cli( + monkeypatch, + f"--model {model_name} --bs 16 --iters 1 --nsamples 1 --seqlen 16 --format gguf:q2_k_mixed", ) - if res > 0 or res == -1: - assert False, "cmd line test fail, please have a check" shutil.rmtree("../../tmp_autoround", ignore_errors=True) def test_vlm_gguf(self, tiny_qwen_vl_model_path): diff --git a/test/unit/test_cpu/utils/test_cli_usage.py b/test/unit/test_cpu/utils/test_cli_usage.py index 0be2b0052f..9e251c371c 100644 --- a/test/unit/test_cpu/utils/test_cli_usage.py +++ b/test/unit/test_cpu/utils/test_cli_usage.py @@ -1,14 +1,26 @@ -import os import shutil import sys from test.helpers import get_model_path import pytest +from auto_round.cli.main import run, run_light from auto_round.utils import parse_layer_config_arg -AUTO_ROUND_PATH = __file__.split("/") -AUTO_ROUND_PATH = "/".join(AUTO_ROUND_PATH[: AUTO_ROUND_PATH.index("test")]) + +def _assert_cli_ok(monkeypatch, argv, entry=run): + """Run an in-process CLI entry point and assert it succeeds. + + ``argv`` is the full argv (including argv[0]); it replaces ``sys.argv`` so + the entry point parses it exactly like a real command line invocation. + Help/eval paths exit via argparse with code 0, while quantization paths + return normally. Any non-zero ``SystemExit`` indicates a CLI failure. + """ + monkeypatch.setattr(sys, "argv", list(argv)) + try: + entry() + except SystemExit as exc: # argparse help/version exits with code 0 + assert exc.code in (0, None), f"cmd line test fail, exit code {exc.code}" class TestAutoRoundCmd: @@ -24,80 +36,152 @@ def teardown_class(self): shutil.rmtree("runs", ignore_errors=True) shutil.rmtree("../../tmp_autoround", ignore_errors=True) - def test_auto_round_cmd(self, tiny_opt_model_path, tiny_qwen_vl_model_path): - python_path = sys.executable - res = os.system(f"PYTHONPATH='{AUTO_ROUND_PATH}:$PYTHONPATH' {python_path} -m auto_round -h") - if res > 0 or res == -1: - assert False, "cmd line test fail, please have a check" + def test_auto_round_cmd(self, monkeypatch, tiny_opt_model_path, tiny_qwen_vl_model_path): + _assert_cli_ok(monkeypatch, ["auto_round", "-h"]) @pytest.mark.timeout(90) - def test_auto_round_cmd2(self, tiny_opt_model_path, tiny_qwen_vl_model_path): - python_path = sys.executable - res = os.system( - f"PYTHONPATH='{AUTO_ROUND_PATH}:$PYTHONPATH' {python_path} -m auto_round --model {tiny_opt_model_path} --seqlen 32 --iter 2 --nsamples 1 --format auto_gptq,auto_round --output_dir {self.save_dir} --tasks piqa --limit 2" + def test_auto_round_cmd2(self, monkeypatch, tiny_opt_model_path, tiny_qwen_vl_model_path): + _assert_cli_ok( + monkeypatch, + [ + "auto_round", + "--model", + tiny_opt_model_path, + "--seqlen", + "32", + "--iter", + "2", + "--nsamples", + "1", + "--format", + "auto_gptq,auto_round", + "--output_dir", + self.save_dir, + "--tasks", + "piqa", + "--limit", + "2", + ], ) - if res > 0 or res == -1: - assert False, "cmd line test fail, please have a check" @pytest.mark.timeout(90) - def test_auto_round_cmd3(self, tiny_opt_model_path, tiny_qwen_vl_model_path): - python_path = sys.executable - res = os.system( - f"PYTHONPATH='{AUTO_ROUND_PATH}:$PYTHONPATH' {python_path} -m auto_round --model {tiny_opt_model_path} --seqlen 8 --iter 1 --nsamples 1 --eval_task_by_task --tasks openbookqa --bs 32 --limit 2" + def test_auto_round_cmd3(self, monkeypatch, tiny_opt_model_path, tiny_qwen_vl_model_path): + _assert_cli_ok( + monkeypatch, + [ + "auto_round", + "--model", + tiny_opt_model_path, + "--seqlen", + "8", + "--iter", + "1", + "--nsamples", + "1", + "--eval_task_by_task", + "--tasks", + "openbookqa", + "--bs", + "32", + "--limit", + "2", + ], ) - if res > 0 or res == -1: - assert False, "cmd line test fail, please have a check" @pytest.mark.timeout(90) - def test_auto_round_cmd4(self, tiny_opt_model_path, tiny_qwen_vl_model_path): - python_path = sys.executable - res = os.system( - f"PYTHONPATH='{AUTO_ROUND_PATH}:$PYTHONPATH' {python_path} -c 'from auto_round.__main__ import run_light; run_light()' --seqlen 8 --iter 2 --nsamples 8 --output_dir {self.save_dir} --tasks lambada_openai --limit 2" + def test_auto_round_cmd4(self, monkeypatch, tiny_opt_model_path, tiny_qwen_vl_model_path): + _assert_cli_ok( + monkeypatch, + [ + "auto_round", + "--seqlen", + "8", + "--iter", + "2", + "--nsamples", + "8", + "--output_dir", + self.save_dir, + "--tasks", + "lambada_openai", + "--limit", + "2", + ], + entry=run_light, ) - if res > 0 or res == -1: - assert False, "cmd line test fail, please have a check" - def test_auto_round_cmd5(self, tiny_opt_model_path, tiny_qwen_vl_model_path): - python_path = sys.executable - res = os.system(f"PYTHONPATH='{AUTO_ROUND_PATH}:$PYTHONPATH' {python_path} -m auto_round --eval -h") - if res > 0 or res == -1: - assert False, "cmd line test fail, please have a check" + def test_auto_round_cmd5(self, monkeypatch, tiny_opt_model_path, tiny_qwen_vl_model_path): + _assert_cli_ok(monkeypatch, ["auto_round", "--eval", "-h"]) - def test_auto_round_cmd6(self, tiny_opt_model_path, tiny_qwen_vl_model_path): - python_path = sys.executable - res = os.system(f"PYTHONPATH='{AUTO_ROUND_PATH}:$PYTHONPATH' {python_path} -m auto_round --eval --lmms -h") - if res > 0 or res == -1: - assert False, "cmd line test fail, please have a check" + def test_auto_round_cmd6(self, monkeypatch, tiny_opt_model_path, tiny_qwen_vl_model_path): + _assert_cli_ok(monkeypatch, ["auto_round", "--eval", "--lmms", "-h"]) @pytest.mark.timeout(90) - def test_auto_round_cmd7(self, tiny_opt_model_path, tiny_qwen_vl_model_path): - python_path = sys.executable - res = os.system( - f"PYTHONPATH='{AUTO_ROUND_PATH}:$PYTHONPATH' {python_path} -m auto_round --mllm --model {tiny_qwen_vl_model_path} --iter 2 --nsamples 2 --seqlen 32 --format auto_round --output_dir {self.save_dir}" + def test_auto_round_cmd7(self, monkeypatch, tiny_opt_model_path, tiny_qwen_vl_model_path): + _assert_cli_ok( + monkeypatch, + [ + "auto_round", + "--mllm", + "--model", + tiny_qwen_vl_model_path, + "--iter", + "2", + "--nsamples", + "2", + "--seqlen", + "32", + "--format", + "auto_round", + "--output_dir", + self.save_dir, + ], ) - if res > 0 or res == -1: - assert False, "cmd line test fail, please have a check" - - def test_auto_round_cmd8(self, tiny_opt_model_path, tiny_qwen_vl_model_path): - python_path = sys.executable - res = os.system( - f"PYTHONPATH='{AUTO_ROUND_PATH}:$PYTHONPATH' {python_path} -m auto_round --mllm --iter 2 --nsamples 2 --model {tiny_qwen_vl_model_path} --seqlen 32 --format auto_round" - f" --quant_nontext_module --output_dir {self.save_dir}" + + def test_auto_round_cmd8(self, monkeypatch, tiny_opt_model_path, tiny_qwen_vl_model_path): + _assert_cli_ok( + monkeypatch, + [ + "auto_round", + "--mllm", + "--iter", + "2", + "--nsamples", + "2", + "--model", + tiny_qwen_vl_model_path, + "--seqlen", + "32", + "--format", + "auto_round", + "--quant_nontext_module", + "--output_dir", + self.save_dir, + ], ) - if res > 0 or res == -1: - assert False, "cmd line test fail, please have a check" - def test_layer_config(self, tiny_opt_model_path): + def test_layer_config(self, monkeypatch, tiny_opt_model_path): """Test --layer_config with unquoted JSON-like syntax.""" - python_path = sys.executable layer_cfg = r"{fc1:{bits:8,data_type:int},fc2:{bits:16,data_type:int}}" - res = os.system( - f"PYTHONPATH='{AUTO_ROUND_PATH}:$PYTHONPATH' {python_path} -m auto_round" - f" --model {tiny_opt_model_path} --seqlen 8 --iter 0 --disable_opt_rtn" - f" --layer_config '{layer_cfg}' --format auto_round --output_dir {self.save_dir}" + _assert_cli_ok( + monkeypatch, + [ + "auto_round", + "--model", + tiny_opt_model_path, + "--seqlen", + "8", + "--iter", + "0", + "--disable_opt_rtn", + "--layer_config", + layer_cfg, + "--format", + "auto_round", + "--output_dir", + self.save_dir, + ], ) - if res > 0 or res == -1: - assert False, "cmd line test with --layer_config fail, please have a check" def test_parse_layer_config(): diff --git a/test/unit/test_cuda/advanced/test_evaluation.py b/test/unit/test_cuda/advanced/test_evaluation.py index bcac8740cd..31a87a84f7 100644 --- a/test/unit/test_cuda/advanced/test_evaluation.py +++ b/test/unit/test_cuda/advanced/test_evaluation.py @@ -19,40 +19,48 @@ import pytest +def _run_auto_round_cli(monkeypatch, cmd): + """Run the auto_round CLI in-process by patching ``sys.argv``. + + ``cmd`` contains only the CLI arguments (everything after ``-m auto_round``). + This replaces the previous ``os.system('python -m auto_round ...')`` calls so + the code runs in the test process and is measured by coverage. + """ + from auto_round.cli.main import run + + monkeypatch.setattr(sys, "argv", ["auto_round", *cmd.split()]) + try: + run() + except SystemExit as exc: # argparse help/errors exit; only 0/None is success + assert exc.code in (0, None), f"cmd line test fail, exit code {exc.code}" + + @pytest.mark.skipif( not os.path.exists("/usr/bin/nvidia-smi") and not os.path.exists("/usr/local/cuda"), reason="CUDA not available" ) class TestHFEvaluation: """Test different evaluation modes: --eval and --eval_backend.""" - def test_eval_mode_hf_backend(self, tiny_opt_model_path): + def test_eval_mode_hf_backend(self, monkeypatch, tiny_opt_model_path): """Test --eval flag: evaluate model without quantization (HF backend default).""" - python_path = sys.executable - - cmd = f"{python_path} -m auto_round --model {tiny_opt_model_path} --eval --tasks lambada_openai --limit 10" - - ret = os.system(cmd) - - assert ret == 0, f"HF backend evaluation failed (rc={ret})" + _run_auto_round_cli( + monkeypatch, + f"--model {tiny_opt_model_path} --eval --tasks lambada_openai --limit 10", + ) @pytest.mark.skip_ci(reason="The evaluation is time-consuming") - def test_iters_0_hf_backend(self, tiny_opt_model_path): + def test_iters_0_hf_backend(self, monkeypatch, tiny_opt_model_path): """Test quantization with iters=0 and HF backend evaluation.""" - python_path = sys.executable - - cmd = f"{python_path} -m auto_round --model {tiny_opt_model_path} --iters 0 --disable_opt_rtn --tasks lambada_openai --limit 10" - - ret = os.system(cmd) - - assert ret == 0, f"HF backend with iters=0 failed (rc={ret})" + _run_auto_round_cli( + monkeypatch, + f"--model {tiny_opt_model_path} --iters 0 --disable_opt_rtn --tasks lambada_openai --limit 10", + ) @pytest.mark.skip_ci(reason="The evaluation is time-consuming") - def test_iters_0_task_by_task(self, tiny_opt_model_path): + def test_iters_0_task_by_task(self, monkeypatch, tiny_opt_model_path): """Test quantization with iters=0 and task-by-task evaluation.""" - python_path = sys.executable - - cmd = f"{python_path} -m auto_round --model {tiny_opt_model_path} --iters 0 --disable_opt_rtn --eval_task_by_task --tasks lambada_openai,piqa --limit 10" - - ret = os.system(cmd) - - assert ret == 0, f"Task-by-task with iters=0 failed (rc={ret})" + _run_auto_round_cli( + monkeypatch, + f"--model {tiny_opt_model_path} --iters 0 --disable_opt_rtn " + f"--eval_task_by_task --tasks lambada_openai,piqa --limit 10", + ) From 1a7ff8bfb9a47ec6bba92db180f3132a5edc684c Mon Sep 17 00:00:00 2001 From: "Sun, Xuehao" Date: Fri, 7 Aug 2026 13:54:27 +0800 Subject: [PATCH 12/18] Increase timeout values for various tests to enhance stability and prevent premature failures Signed-off-by: Sun, Xuehao --- test/unit/test_cpu/core/test_autoround.py | 3 ++- test/unit/test_cpu/export/test_gguf_format.py | 1 + test/unit/test_cpu/models/test_diffusion.py | 2 +- test/unit/test_cpu/quantization/test_block_fp.py | 1 + test/unit/test_cuda/algorithms/test_awq.py | 2 +- test/unit/test_cuda/backends/test_marlin_backend.py | 2 +- test/unit/test_cuda/models/test_moe_model.py | 2 +- 7 files changed, 8 insertions(+), 5 deletions(-) diff --git a/test/unit/test_cpu/core/test_autoround.py b/test/unit/test_cpu/core/test_autoround.py index eb538eb084..e9c4c11d24 100644 --- a/test/unit/test_cpu/core/test_autoround.py +++ b/test/unit/test_cpu/core/test_autoround.py @@ -36,6 +36,7 @@ def _save_dir(self, tmp_path): def teardown_class(self): shutil.rmtree("runs", ignore_errors=True) + @pytest.mark.timeout(90) def test_bits_setting(self, tiny_opt_model_path): layer_config = {"model.decoder.layers.0.self_attn.k_proj": {"data_type": "mx_fp8", "group_size": 32}} autoround = AutoRound(tiny_opt_model_path, iters=2, seqlen=2, nsamples=1, layer_config=layer_config) @@ -44,7 +45,7 @@ def test_bits_setting(self, tiny_opt_model_path): if module.bits != 8: raise ValueError(f"Expected bits to be 8, but got {module.bits}") - @pytest.mark.timeout(60) + @pytest.mark.timeout(90) def test_layer_config(self, tiny_opt_model_path, dataloader): model_name = tiny_opt_model_path layer_config = {"self_attn": {"bits": 4, "data_type": "nv_fp", "act_bits": 16, "group_size": 16}} diff --git a/test/unit/test_cpu/export/test_gguf_format.py b/test/unit/test_cpu/export/test_gguf_format.py index 5912a4ac84..9f6b4f062e 100644 --- a/test/unit/test_cpu/export/test_gguf_format.py +++ b/test/unit/test_cpu/export/test_gguf_format.py @@ -192,6 +192,7 @@ def test_all_format(self, monkeypatch, tiny_qwen_model_path): ) shutil.rmtree("../../tmp_autoround", ignore_errors=True) + @pytest.mark.timeout(90) def test_vlm_gguf(self, tiny_qwen_vl_model_path): from auto_round import AutoRound diff --git a/test/unit/test_cpu/models/test_diffusion.py b/test/unit/test_cpu/models/test_diffusion.py index ef5807057b..d61100f976 100644 --- a/test/unit/test_cpu/models/test_diffusion.py +++ b/test/unit/test_cpu/models/test_diffusion.py @@ -40,7 +40,7 @@ def test_flux_saving(setup_flux): shutil.rmtree(output_dir, ignore_errors=True) -@pytest.mark.timeout(120) +@pytest.mark.timeout(150) def test_flux(setup_flux): pipe, output_dir = setup_flux autoround = AutoRound( diff --git a/test/unit/test_cpu/quantization/test_block_fp.py b/test/unit/test_cpu/quantization/test_block_fp.py index 151d06012f..a224758a6f 100644 --- a/test/unit/test_cpu/quantization/test_block_fp.py +++ b/test/unit/test_cpu/quantization/test_block_fp.py @@ -92,6 +92,7 @@ def test_block_fp8_quant(self): scale_ref[i, j] = data[i * 128 : (i + 1) * 128, j * 128 : (j + 1) * 128].abs().max() / max_val assert (scale == scale_ref).all() + @pytest.mark.timeout(60) def test_group_size_handler(self, tiny_qwen_model_path): scheme = { "data_type": "int", diff --git a/test/unit/test_cuda/algorithms/test_awq.py b/test/unit/test_cuda/algorithms/test_awq.py index ddc4371ebe..247742be91 100644 --- a/test/unit/test_cuda/algorithms/test_awq.py +++ b/test/unit/test_cuda/algorithms/test_awq.py @@ -238,7 +238,7 @@ def setup_class(cls): def teardown_class(cls): shutil.rmtree("runs", ignore_errors=True) - @pytest.mark.timeout(240) + @pytest.mark.timeout(360) def test_awq_w4a16_lmeval(self): """AWQ W4A16 on OPT-125m: lambada_openai accuracy check.""" ar = AutoRound( diff --git a/test/unit/test_cuda/backends/test_marlin_backend.py b/test/unit/test_cuda/backends/test_marlin_backend.py index 39fed05da9..a00350eeaa 100644 --- a/test/unit/test_cuda/backends/test_marlin_backend.py +++ b/test/unit/test_cuda/backends/test_marlin_backend.py @@ -34,7 +34,7 @@ def setup_and_teardown_class(self): # Keep one CI test for marlin backend and skip others to save time. # @pytest.mark.skip_ci(reason="Only tiny model is suggested") # @pytest.mark.skip_ci(reason="Time-consuming; Accuracy evaluation") - @pytest.mark.timeout(180) + @pytest.mark.timeout(240) def test_marlin_4bits_sym_with_zp_m_1(self, dataloader): model = AutoModelForCausalLM.from_pretrained(self.model_name, torch_dtype="auto", trust_remote_code=True) tokenizer = AutoTokenizer.from_pretrained(self.model_name, trust_remote_code=True) diff --git a/test/unit/test_cuda/models/test_moe_model.py b/test/unit/test_cuda/models/test_moe_model.py index fca22284d2..04c37a319b 100644 --- a/test/unit/test_cuda/models/test_moe_model.py +++ b/test/unit/test_cuda/models/test_moe_model.py @@ -11,7 +11,7 @@ @pytest.mark.skipif(not check_version("transformers>=5.2.0"), reason="requires transformers >= 5.2.0") -@pytest.mark.timeout(240) +@pytest.mark.timeout(300) def test_qwen3_5_moe(tiny_qwen35_moe_model_path): from transformers import Qwen3_5MoeForConditionalGeneration From f7165f9ce9ae6f5ceb41a8e9c62eb38d72f135fc Mon Sep 17 00:00:00 2001 From: "Sun, Xuehao" Date: Fri, 7 Aug 2026 14:57:11 +0800 Subject: [PATCH 13/18] Increase timeout values for specific tests to enhance stability and prevent premature failures Signed-off-by: Sun, Xuehao --- test/unit/test_cpu/export/test_gguf_format.py | 2 ++ test/unit/test_cpu/quantization/test_block_fp.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/test/unit/test_cpu/export/test_gguf_format.py b/test/unit/test_cpu/export/test_gguf_format.py index 9f6b4f062e..1f9b3956eb 100644 --- a/test/unit/test_cpu/export/test_gguf_format.py +++ b/test/unit/test_cpu/export/test_gguf_format.py @@ -472,6 +472,7 @@ def test_qtype_setting(self, tiny_qwen_vl_model_path): assert ar.layer_config["model.language_model.embed_tokens"]["bits"] == 6 assert ar.layer_config["model.language_model.embed_tokens"]["super_bits"] == 8 + @pytest.mark.timeout(60) def test_q2k_mixed(self, tiny_qwen_moe_model_path): model_name = tiny_qwen_moe_model_path autoround = AutoRound( @@ -494,6 +495,7 @@ def test_q2k_mixed(self, tiny_qwen_moe_model_path): tensor_types = {tensor.name: tensor.tensor_type.name for tensor in gguf_model.tensors} assert tensor_types["blk.0.ffn_up_exps.weight"] == "Q2_K" + @pytest.mark.timeout(60) def test_q2k_mixed_keeps_only_three_dim_expert_weights_at_q2k(self, tiny_qwen_moe_model_path): model_name = tiny_qwen_moe_model_path autoround = AutoRound( diff --git a/test/unit/test_cpu/quantization/test_block_fp.py b/test/unit/test_cpu/quantization/test_block_fp.py index a224758a6f..7fb6695c27 100644 --- a/test/unit/test_cpu/quantization/test_block_fp.py +++ b/test/unit/test_cpu/quantization/test_block_fp.py @@ -92,7 +92,7 @@ def test_block_fp8_quant(self): scale_ref[i, j] = data[i * 128 : (i + 1) * 128, j * 128 : (j + 1) * 128].abs().max() / max_val assert (scale == scale_ref).all() - @pytest.mark.timeout(60) + @pytest.mark.timeout(120) def test_group_size_handler(self, tiny_qwen_model_path): scheme = { "data_type": "int", From dc9115da3b29dace57010594d6d4352f54b796ee Mon Sep 17 00:00:00 2001 From: "Sun, Xuehao" Date: Fri, 7 Aug 2026 15:12:54 +0800 Subject: [PATCH 14/18] Skip CI for time-consuming tests and adjust timeout values for improved stability Signed-off-by: Sun, Xuehao --- test/unit/test_cuda/algorithms/test_auto_scheme.py | 2 +- test/unit/test_cuda/algorithms/test_awq.py | 4 ++-- test/unit/test_cuda/backends/test_triton_backend.py | 2 +- test/unit/test_cuda/export/test_gguf_format.py | 2 +- test/unit/test_cuda/quantization/test_torch_compile.py | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/unit/test_cuda/algorithms/test_auto_scheme.py b/test/unit/test_cuda/algorithms/test_auto_scheme.py index 6d8549149f..73945bd1e0 100644 --- a/test/unit/test_cuda/algorithms/test_auto_scheme.py +++ b/test/unit/test_cuda/algorithms/test_auto_scheme.py @@ -314,7 +314,7 @@ def test_enable_torch_compile(self): _, quantized_model_path = ar.quantize_and_save(output_dir=self.save_dir) evaluate_accuracy(quantized_model_path, threshold=0.10) - @pytest.mark.timeout(210) + @pytest.mark.skip_ci(reason="Time-consuming: two quantizations plus two lm_eval runs; covered by nightly") def test_mixed_bits_get_scoring(self): """Verify that AutoScheme scoring produces accuracy above a known reference threshold for mixed-bit quantization. diff --git a/test/unit/test_cuda/algorithms/test_awq.py b/test/unit/test_cuda/algorithms/test_awq.py index 247742be91..15b7f3038c 100644 --- a/test/unit/test_cuda/algorithms/test_awq.py +++ b/test/unit/test_cuda/algorithms/test_awq.py @@ -193,7 +193,7 @@ def test_awq_moe_quantized_layers_check(self, tiny_qwen_moe_model_path): for name in fp_layers: assert name.endswith("gate"), f"Unexpected FP layer: {name}" - @pytest.mark.timeout(180) + @pytest.mark.skip_ci(reason="Redundant MoE quantize only to check file-size ratio; layer check already covers it") def test_awq_moe_save_compressed_size(self, tiny_qwen_moe_model_path): """AWQ MoE W4: quantized safetensors should be smaller than original.""" ar = AutoRound( @@ -238,7 +238,7 @@ def setup_class(cls): def teardown_class(cls): shutil.rmtree("runs", ignore_errors=True) - @pytest.mark.timeout(360) + @pytest.mark.skip_ci(reason="Time-consuming lm_eval accuracy check; covered by nightly") def test_awq_w4a16_lmeval(self): """AWQ W4A16 on OPT-125m: lambada_openai accuracy check.""" ar = AutoRound( diff --git a/test/unit/test_cuda/backends/test_triton_backend.py b/test/unit/test_cuda/backends/test_triton_backend.py index 1620a34bf7..95d57937cd 100644 --- a/test/unit/test_cuda/backends/test_triton_backend.py +++ b/test/unit/test_cuda/backends/test_triton_backend.py @@ -29,7 +29,7 @@ def teardown_class(self): # @pytest.mark.skip_ci(reason="Only tiny model is suggested") # @pytest.mark.skip_ci(reason="Time-consuming; Accuracy evaluation") @require_greater_than_050 - @pytest.mark.timeout(180) + @pytest.mark.timeout(300) def test_tritonv2_2bits_asym(self): model = AutoModelForCausalLM.from_pretrained(self.model_name, torch_dtype="auto", trust_remote_code=True) tokenizer = AutoTokenizer.from_pretrained(self.model_name, trust_remote_code=True) diff --git a/test/unit/test_cuda/export/test_gguf_format.py b/test/unit/test_cuda/export/test_gguf_format.py index 5cb71ea4d0..5c929db143 100644 --- a/test/unit/test_cuda/export/test_gguf_format.py +++ b/test/unit/test_cuda/export/test_gguf_format.py @@ -138,8 +138,8 @@ def test_gguf_format(self, tiny_qwen_model_path, dataloader): quantized_model_path = self.save_dir autoround.save_quantized(output_dir=quantized_model_path, format="gguf:q4_1") + @pytest.mark.skip_ci(reason="Time-consuming accuracy evaluation; covered by nightly") @require_gguf - @pytest.mark.timeout(180) def test_q4_0_accuracy(self): model_name = get_model_path("Qwen/Qwen2.5-0.5B-Instruct") bits, group_size, sym = 4, 32, True diff --git a/test/unit/test_cuda/quantization/test_torch_compile.py b/test/unit/test_cuda/quantization/test_torch_compile.py index 6f9df8cae6..6c6cd4ecb1 100644 --- a/test/unit/test_cuda/quantization/test_torch_compile.py +++ b/test/unit/test_cuda/quantization/test_torch_compile.py @@ -27,8 +27,8 @@ def setup_and_teardown_class(self): shutil.rmtree("./saved", ignore_errors=True) shutil.rmtree("runs", ignore_errors=True) + @pytest.mark.skip_ci(reason="torch.compile warmup with iters=2 is slow") @require_gguf - @pytest.mark.timeout(210) def test_gguf_q2ks_torch_compile(self, dataloader): """Test GGUF Q2_K_S quantization with torch.compile enabled. From 9b5f69b6a9c6a081720c75c4d9e0a54823912e8c Mon Sep 17 00:00:00 2001 From: "Sun, Xuehao" Date: Fri, 7 Aug 2026 16:06:44 +0800 Subject: [PATCH 15/18] Add CI markers and timeout guidelines for long-running tests in README Signed-off-by: Sun, Xuehao --- test/README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/README.md b/test/README.md index 61583a51ae..28947fb10f 100644 --- a/test/README.md +++ b/test/README.md @@ -140,6 +140,25 @@ def test_model_inference(tiny_opt_model_path): - **CPU-specific** → `*/test_cpu/`, **CUDA-specific** → `*/test_cuda/` - Import from parent: `from test.helpers import ...` +### CI Markers and Timeouts + +- For long-running or non-critical tests under `test_cuda/`, use + `@pytest.mark.skip_ci(reason="...")` and provide a clear reason why the test should not run in CI. +- In CI, each test function has a default timeout of **30 seconds**, while each test file has a timeout of + **10 minutes**. +- Prefer simplifying a test so that it completes within the default timeout. If the test cannot be reduced further, + extend its timeout with `@pytest.mark.timeout(seconds)`. If a test file exceeds the 10-minute limit, split its tests + into smaller files whenever possible. + +```python +@pytest.mark.timeout(120) +def test_long_running_case(): ... + + +@pytest.mark.skip_ci(reason="Time-consuming accuracy evaluation; covered by nightly tests") +def test_optional_accuracy_evaluation(): ... +``` + ## 5. Running Tests ```sh From ec6179fda4f137acd05db885ca2e5dbdf1738b7b Mon Sep 17 00:00:00 2001 From: "Sun, Xuehao" Date: Fri, 7 Aug 2026 16:25:32 +0800 Subject: [PATCH 16/18] Add timeout marker for mixed MXFP autoround format loading test Signed-off-by: Sun, Xuehao --- test/unit/test_cpu/quantization/test_mix_bits.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/unit/test_cpu/quantization/test_mix_bits.py b/test/unit/test_cpu/quantization/test_mix_bits.py index ee3f227007..8ba18fdbd5 100644 --- a/test/unit/test_cpu/quantization/test_mix_bits.py +++ b/test/unit/test_cpu/quantization/test_mix_bits.py @@ -175,6 +175,7 @@ def test_mixed_ar_format_part_name_hf_loading(self, dataloader): inputs = tokenizer(text, return_tensors="pt").to(model.device) print(tokenizer.decode(model.generate(**inputs, max_new_tokens=50)[0])) + @pytest.mark.timeout(60) def test_mixed_MXFP_autoround_format_loading(self, dataloader): layer_config = { "k_proj": {"bits": 8, "act_bits": 8}, From 8691098639a154e3d71f750675192e184be01417 Mon Sep 17 00:00:00 2001 From: "Sun, Xuehao" Date: Fri, 7 Aug 2026 16:39:04 +0800 Subject: [PATCH 17/18] Remove redundant 'disable_opt_rtn' parameter in quantization call Signed-off-by: Sun, Xuehao --- test/unit/test_cpu/quantization/test_mxfp_nvfp.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/unit/test_cpu/quantization/test_mxfp_nvfp.py b/test/unit/test_cpu/quantization/test_mxfp_nvfp.py index 669e9708ab..e701f0c987 100644 --- a/test/unit/test_cpu/quantization/test_mxfp_nvfp.py +++ b/test/unit/test_cpu/quantization/test_mxfp_nvfp.py @@ -56,7 +56,6 @@ def test_nvfp4_moe_actmax_rtn(self, tiny_deepseek_v2_model_path_cpu, dataloader) layer_config=layer_config, disable_opt_rtn=True, trust_remote_code=False, - disable_opt_rtn=True, ) compressed_model, _ = autoround.quantize() moe = compressed_model.model.layers[1].mlp From de0bddbd73006b445624fa867a00e2b7f6f2df87 Mon Sep 17 00:00:00 2001 From: "Sun, Xuehao" Date: Fri, 7 Aug 2026 19:59:47 +0800 Subject: [PATCH 18/18] Increase timeout for AWQ MoE quantized layers check and add timeout for test_g128 Signed-off-by: Sun, Xuehao --- test/unit/test_cpu/algorithms/test_awq.py | 2 +- test/unit/test_cpu/core/test_autoround.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/test/unit/test_cpu/algorithms/test_awq.py b/test/unit/test_cpu/algorithms/test_awq.py index e36926ace8..4b5569d0fb 100644 --- a/test/unit/test_cpu/algorithms/test_awq.py +++ b/test/unit/test_cpu/algorithms/test_awq.py @@ -244,7 +244,7 @@ def test_awq_moe_dynamic_smoothing(self, tiny_qwen_moe_model_path): del model - @pytest.mark.timeout(360) + @pytest.mark.timeout(420) def test_awq_moe_quantized_layers_check(self, tiny_qwen_moe_model_path): """AWQ on MoE: expert layers should be quantized, gates/routers stay FP.""" ar = AutoRound( diff --git a/test/unit/test_cpu/core/test_autoround.py b/test/unit/test_cpu/core/test_autoround.py index e9c4c11d24..9eb4be7dfd 100644 --- a/test/unit/test_cpu/core/test_autoround.py +++ b/test/unit/test_cpu/core/test_autoround.py @@ -157,6 +157,7 @@ def test_w4g1(self, tiny_opt_model_path, dataloader): ) autoround.quantize() + @pytest.mark.timeout(60) @pytest.mark.parametrize("bits", [2, 3, 4]) def test_g128(self, bits, dataloader): model_name = opt_name_or_path