Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 19 additions & 11 deletions .azure_pipelines/olive-ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,20 @@ variables:
skipComponentGovernanceDetection: true

jobs:
- job: Olive_CI_NoOp
displayName: "Olive CI moved to GitHub Actions"
pool:
vmImage: "ubuntu-latest"
steps:
- script: echo "No Azure Pipelines jobs configured for this pipeline."
displayName: "No-op placeholder"

# Linux unit tests
- template: job_templates/olive-test-cpu-template.yaml
parameters:
name: Linux_CPU_CI_Unit_Test
pool: $(OLIVE_POOL_UBUNTU2004)
pytest_marker: 'not openvino and not amd'
# - template: job_templates/olive-test-cpu-template.yaml
Comment thread
xiaoyu-work marked this conversation as resolved.
# parameters:
# name: Linux_CPU_CI_Unit_Test
# pool: $(OLIVE_POOL_UBUNTU2004)
# pytest_marker: 'not openvino and not amd'

# Skip the GPU CI until the pool issue is resolved (not able to allocate GPU resources).
# - template: job_templates/olive-test-linux-gpu-template.yaml
Expand All @@ -48,9 +56,9 @@ jobs:
# pytest_marker: 'not openvino and not amd'

# Windows unit tests
- template: job_templates/olive-test-cpu-template.yaml
parameters:
name: Windows_CPU_CI_Unit_Test
pool: $(OLIVE_POOL_WIN2019)
windows: True
pytest_marker: 'not openvino and not amd'
# - template: job_templates/olive-test-cpu-template.yaml
# parameters:
# name: Windows_CPU_CI_Unit_Test
# pool: $(OLIVE_POOL_WIN2019)
# windows: True
# pytest_marker: 'not openvino and not amd'
128 changes: 128 additions & 0 deletions .github/workflows/cpu-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
name: Olive CPU CI

on:
workflow_dispatch:
push:
branches:
- main
pull_request:
branches:
- main
issue_comment:
types:
- created

concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'issue_comment' && format('pr-{0}-{1}', github.event.issue.number, github.event.comment.id) || github.ref }}
cancel-in-progress: true

permissions:
contents: read
pull-requests: read
issues: read

jobs:
cpu_tests:
if: >-
github.event_name == 'push' ||
github.event_name == 'workflow_dispatch' ||
(github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false) ||
(
github.event_name == 'issue_comment' &&
github.event.issue.pull_request != null &&
contains(github.event.comment.body, '/ci run') &&
(
github.event.comment.author_association == 'OWNER' ||
github.event.comment.author_association == 'MEMBER' ||
github.event.comment.author_association == 'COLLABORATOR'
)
)
name: ${{ matrix.name }} CPU unit tests
strategy:
fail-fast: false
matrix:
include:
- name: Linux
os: ubuntu-22.04
platform: linux
- name: Windows
os: windows-2022
platform: windows
runs-on: ${{ matrix.os }}
timeout-minutes: 300
env:
HF_HOME: ${{ github.workspace }}/.cache/huggingface
PYTHONIOENCODING: utf-8
PYTHONUTF8: "1"

steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event_name == 'issue_comment' && format('refs/pull/{0}/merge', github.event.issue.number) || github.ref }}

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip
cache-dependency-path: |
requirements.txt
test/requirements-test.txt
test/requirements-test-cpu.txt

- name: Install PyTorch
run: python -m pip install torch

- name: Install Olive
run: python -m pip install .

- name: Install ONNX Runtime
run: python -m pip install onnxruntime

- name: Install pytest
run: python -m pip install pytest

- name: Install test dependencies
run: python -m pip install -r test/requirements-test-cpu.txt

- name: List installed packages
run: python -m pip list

- name: Log in to Hugging Face
env:
HF_TOKEN: ${{ secrets.HUGGING_FACE_HUB_TOKEN }}
run: >-
python -c "import os; from huggingface_hub import login;
login(token=os.environ['HF_TOKEN'])"

- name: Create test output directory
run: python -c "from pathlib import Path; Path('logs').mkdir(exist_ok=True)"

- name: Run tests
run: >-
python -m coverage run --source=olive -m pytest -v -s -p no:warnings
--disable-warnings --log-cli-level=WARNING
--junitxml=logs/test-TestOlive-${{ matrix.platform }}.xml
-m "not openvino and not amd" test
--basetemp "${{ runner.temp }}/pytest"

- name: Show coverage report
if: always()
continue-on-error: true
run: python -m coverage report -m

- name: Generate coverage report
Comment thread
xiaoyu-work marked this conversation as resolved.
if: always()
continue-on-error: true
run: python -m coverage xml -o coverage-${{ matrix.platform }}.xml

- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: cpu-test-results-${{ matrix.platform }}
path: |
logs/*.xml
coverage-${{ matrix.platform }}.xml
if-no-files-found: warn
retention-days: 14
6 changes: 3 additions & 3 deletions test/cli/test_cli_test_model_smoke.py
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ class TestCliTestModelSmoke(unittest.TestCase):

def test_documented_test_model_smoke_flow(self):
if self.workdir is None:
with tempfile.TemporaryDirectory() as temp_dir:
with tempfile.TemporaryDirectory(ignore_cleanup_errors=True) as temp_dir:
self._assert_smoke_flows(Path(temp_dir))
else:
workdir = Path(self.workdir)
Expand Down Expand Up @@ -352,7 +352,7 @@ def test_save_local_tiny_qwen2_5_vl_supports_image_processor(self):
self.skipTest("Pillow is required for VLM processor smoke test.")
from transformers import AutoProcessor

with tempfile.TemporaryDirectory() as temp_dir:
with tempfile.TemporaryDirectory(ignore_cleanup_errors=True) as temp_dir:
model_path = Path(temp_dir) / "qwen2_5_vl"
_save_local_tiny_qwen2_5_vl(model_path)

Expand All @@ -376,7 +376,7 @@ def test_save_local_tiny_qwen2_5_vl_supports_image_processor(self):
def test_model_discrepancy(self):
"""Verify that OnnxDiscrepancyCheck runs successfully with the configured exporter."""
if self.workdir is None:
with tempfile.TemporaryDirectory() as temp_dir:
with tempfile.TemporaryDirectory(ignore_cleanup_errors=True) as temp_dir:
self._assert_discrepancy(Path(temp_dir))
else:
workdir = Path(self.workdir)
Expand Down
2 changes: 1 addition & 1 deletion test/cli/test_cli_whisper_smoke.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ class TestCliWhisperSmoke(unittest.TestCase):
def test_whisper_capture_onnx_graph(self):
"""Verify that Whisper encoder and decoder are exported to ONNX successfully."""
if self.workdir is None:
with tempfile.TemporaryDirectory() as temp_dir:
with tempfile.TemporaryDirectory(ignore_cleanup_errors=True) as temp_dir:
self._assert_whisper_export(Path(temp_dir))
else:
workdir = Path(self.workdir)
Expand Down
14 changes: 10 additions & 4 deletions test/passes/onnx/test_mnb_to_qdq.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,16 @@ def test_mnb_to_qdq(create_mnb_model, nodes_to_exclude, add_zero_point, use_sign
# disable qdq to mnb fusion so we can test the output of the DQ nodes directly
disabled_optimizers = ["QDQSelectorActionTransformer"]
if is_symmetric and use_signed_int and not add_zero_point and use_transpose_op:
# there seems to be a bug in ORT graph optimization which changes the int4 DQ to uint8 DQ
with pytest.raises(Exception, match="uint8"):
onnxruntime.InferenceSession(str(qdq_model.model_path), disabled_optimizers=disabled_optimizers)
return
# Some ORT builds fail here because graph optimization changes signed sub-byte DQ to uint8 DQ.
try:
qdq_session = onnxruntime.InferenceSession(
str(qdq_model.model_path), disabled_optimizers=disabled_optimizers
)
qdq_session.disable_fallback()
except Exception as e:
if "uint8" in str(e):
return
raise
else:
qdq_session = onnxruntime.InferenceSession(str(qdq_model.model_path), disabled_optimizers=disabled_optimizers)
qdq_session.disable_fallback()
Expand Down
Loading