(#6) ci: wire CPU/GPU/multi-GPU/nightly + docs - #61
Conversation
13f33cb to
1a6c400
Compare
Wire the four canonical test suites (plan §3 / Phase 6) into GitHub Actions
and document them.
- pyproject.toml: register the `nightly` marker (plan open-question 1) so the
full-sweep command `-m "slow or nightly"` resolves without an unknown-marker
error.
- .github/actions/setup-dmi: composite action shared by every job -- installs
Python deps + the Transformers fork, builds the ClickHouse C++ client and the
DMI native backend (.so), optionally installs the vLLM fork, and smoke-checks
that `monitoring` imports. The native backend must be built even for the CPU
suite because importing `monitoring` loads the prebuilt .so at import time
(JIT disabled); building needs nvcc but no GPU at runtime.
- .github/workflows/tests.yml: four jobs mapping 1:1 to the canonical commands.
* cpu (push/PR) -> not gpu and not e2e and not manual
* gpu-smoke (push/PR, after cpu) -> gpu and not multi_gpu and not slow
* multi-gpu (push/PR, after cpu) -> multi_gpu
* nightly (07:00 UTC / dispatch) -> slow or nightly
GPU-tier jobs run on self-hosted runners labelled by capability and tolerate
pytest exit code 5 (empty selection on a tier with nothing marked yet); the
_requirements.py skip-guards let a runner missing ClickHouse/weights skip with
a reason instead of failing.
- docs/testing.md: the four commands, the marker taxonomy, the skip-guards, and
the CI job map.
Acceptance (CPU): python -m pytest -m "not gpu and not e2e and not manual" -q
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
10629af to
563d4bc
Compare
Samfisheryu
left a comment
There was a problem hiding this comment.
I rebased this PR onto main and removed the stale chained-branch state. The PR is now cleanly based on the current test-marker work, and the accidental submodule pointer changes are gone.
The CI design still needs to be realigned with #55. Please restructure it around the intended three-stage plan:
-
Stage 1: lightweight CPU PR gate
This should be a true CPU-only gate using the currentcpumarker. It should stay dependency-light and should not require the native backend build or self-hosted GPU infrastructure. -
Stage 2: GPU / native regression
The heavier native backend build, GPU tests, multi-GPU tests, ClickHouse, vLLM, and model-cache-dependent checks should run on the GPU/self-hosted tier. This likely requires setting up the self-hosted runner environment on the Frootlab server, including runner labels, CUDA/toolchain availability, ClickHouse/model-cache assumptions, and trigger policy. -
Stage 3: packaging
The native backend build should be wired into the install/package flow, so the workflow is not just manually runningmakein CI. If this PR does not implement that stage yet, please scope the documentation accordingly.
In short, please redesign this PR to follow the CPU gate → GPU/native regression on the Frootlab self-hosted server → packaging split from #55. Right now those responsibilities are still mixed together, especially in the shared setup path.
| on: | ||
| push: | ||
| branches: [main] | ||
| pull_request: |
There was a problem hiding this comment.
This is a security blocker from #55. With pull_request enabled here and the jobs below running on self-hosted runners, a fork PR can execute untrusted checked-out code on the Frootlab runner (checkout with recursive submodules, pip install -e, make, and the composite action). Docker would only be defense in depth; the primary fix is to avoid auto-running self-hosted jobs for untrusted fork PRs. The PR path should be GitHub-hosted CPU-only, and self-hosted jobs should be limited to trusted triggers such as schedule, workflow_dispatch, or internal PRs with a maintainer-controlled label.
| # ---- Single-GPU smoke ---------------------------------------------------- | ||
| gpu-smoke: | ||
| if: github.event_name != 'schedule' | ||
| needs: cpu | ||
| runs-on: [self-hosted, linux, gpu] | ||
| timeout-minutes: 60 | ||
| env: | ||
| CUDA_VISIBLE_DEVICES: "0" | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| submodules: recursive | ||
| - uses: ./.github/actions/setup-dmi | ||
| with: | ||
| install-vllm: "true" | ||
| - name: Single-GPU smoke suite | ||
| # Exit code 5 ("no tests collected") is tolerated: a hardware tier with | ||
| # nothing marked for it yet is not a failure. | ||
| run: | | ||
| set +e | ||
| python -m pytest -m "gpu and not multi_gpu and not slow" -q | ||
| rc=$? | ||
| if [ "$rc" -eq 5 ]; then echo "::notice::no single-GPU tests collected"; exit 0; fi | ||
| exit $rc | ||
|
|
||
| # ---- Multi-GPU / TP ------------------------------------------------------ | ||
| multi-gpu: | ||
| if: github.event_name != 'schedule' | ||
| needs: cpu | ||
| runs-on: [self-hosted, linux, multi-gpu] |
There was a problem hiding this comment.
These GPU-tier jobs should not run on every PR/push. if: github.event_name != 'schedule' means they run for normal PR updates and pushes after CPU, which conflicts with #55 Stage 2: GPU/native regression should be nightly plus explicit/manual maintainer opt-in, for example workflow_dispatch or a run-gpu label on trusted internal PRs. Please gate gpu-smoke and multi-gpu accordingly instead of making every PR consume self-hosted GPU resources.
|
@XbzOnGit Any comment on CICD design? |
…module pointer - CPU gate command now excludes `native_backend` marked tests which require the compiled .so; they were passing collection but failing at runtime with NameError on HOOK_TYPE_* constants absent without the native backend. - Restore integration/transformers submodule to ce5095aa (DMI fork) from 3aa21543 (upstream HF). The wrong pointer was set during rebase conflict resolution; ce5095aa is the commit that contains gpt2_compare, llama_compare, and qwen3_compare model files required by test_per_hook_isolation.py. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Issue 1 — Restructure around the three-stage plan
Issue 2 — Security blocker (fork PRs on self-hosted runners)
Issue 3 — GPU jobs firing on every PR/push
Additional fixes (from CI test runs)
|
Summary
This PR implements the CI infrastructure and testing workflow described in the project plan, introducing a standardized test matrix, reusable setup action, and testing documentation.
Merge the PR #56 first.Key Changes
Registered the
nightlypytest markerAdded the
nightlymarker inpyproject.toml(matching the assumption made in the plan's open question).Enables the full sweep command:
pytest -m "slow or nightly"without triggering unknown-marker warnings or errors.
Introduced a shared CI setup action
.github/actions/setup-dmi/action.yml, a composite action used across all CI jobs..so)Added the CI test workflow
.github/workflows/tests.ymlwith four jobs corresponding directly to the canonical test commands.Deliverables
pyproject.tomlnightlypytest marker.pytest -m "slow or nightly"executes cleanly without unknown-marker errors..github/actions/setup-dmi/action.ymlReusable composite action responsible for environment setup across all CI jobs.
Responsibilities:
.github/workflows/tests.ymlDefines four CI jobs mapping 1:1 to the canonical test commands:
[self-hosted, linux, dmi-cpu]not gpu and not e2e and not manualcpu)[self-hosted, linux, gpu]gpu and not multi_gpu and not slowcpu)[self-hosted, linux, multi-gpu]multi_gpu[self-hosted, linux, gpu]slow or nightlydocs/testing.mdAdds testing documentation covering:
Key Decisions
Native backend build in CPU jobs
.soat import time (JIT disabled), so CPU tests require the backend to be compiled.nvccduring setup, but does not require GPU hardware at runtime.setup-dmiaction handles this automatically, and the rationale is documented intesting.md.Self-hosted GPU runners
gpu-smoke,multi-gpu, andnightly) therefore target capability-labelled self-hosted runners appropriate for this lab repository.Exit-code-5 tolerance on GPU-tier jobs
multi_gpucurrently selects zero tests because tensor-parallel tests are introduced in later phases.5when no tests are collected, which would incorrectly fail the workflow.5is therefore tolerated for:gpu-smokemulti-gpunightlyVerification
nightlymarker registers correctly:pytest --markersMarker Selection Validation
not gpu and not e2e and not manualgpu and not multi_gpu and not slowmulti_gpuslow or nightlyAdditional validation:
monitoring/Makefilelibs/clickhouse-cppintegration/*