Nightly CI Test¶
This document explains how to trigger nightly hardware CI tests against your own PR code on Ascend NPU hardware (A2/A3), without waiting for the scheduled nightly run.
Background¶
By default, nightly CI tests run on a fixed schedule using pre-built nightly images. Contributors can self-service trigger these tests directly against their PR changes by combining a GitHub label with a comment command.
How to Trigger¶
1. Post a comment¶
Post one of the following comments in the PR to specify which tests to run. The comment itself triggers the workflow — no label is required.
| Comment | Effect |
|---|---|
/nightly |
Run all nightly tests |
/nightly all |
Run all nightly tests (same as above) |
/nightly test1 test2 ... |
Run only the named tests |
Note
Only repository Contributors (Triage role) and Maintainers (Write role) can
trigger the /nightly command. If you do not have this permission, ask a maintainer
to post the comment for you. You can find the list of maintainers and contributors in
the project's Governance page or by checking the
CODEOWNERS
file.
2. Wait for results¶
GitHub Actions will trigger the Nightly-A2 or Nightly-A3 workflow. Only tests
matching the filter will be dispatched, which saves hardware resources.
Differences Between PR and Scheduled Runs¶
| Scheduled / Manual Dispatch | PR-triggered | |
|---|---|---|
| Trigger | Cron (daily) or workflow_dispatch |
/nightly comment |
| Code tested | Pre-built nightly image | Your PR's HEAD commit (source installed fresh) |
| Test scope | All tests | Configurable via /nightly <names> |
| vLLM + vllm-ascend | From image | Checked out and installed from source |
| Test matrix | From main branch's matrix YAML | From PR branch's matrix YAML |
When a PR run is detected (is_pr_test: true), the workflow additionally:
- Uninstalls any existing vllm packages in the container.
- Checks out the specific vllm version and your PR's vllm-ascend commit from source.
- Installs all dependencies from source.
- Installs the
aisbenchbenchmark suite.
Test Matrix Data Source¶
The set of nightly test cases (their names, runners, test paths, model configs) is declared in a single data file:
The file is organized as a2: and a3: top-level keys (one per SoC). Under each
SoC, tests are grouped by execution shape (single-node, multi-node, double-node,
multi-card, accuracy) and each group holds a test_config (or nightly / pr_only
for accuracy) list whose entries carry a name plus the fields consumed by the
downstream reusable workflows (os, tests, config_file_path, size, etc.).
Both the Nightly-A2 and Nightly-A3 workflows dynamically read this file at run
time — there is no hardcoded test matrix in the workflow YAMLs. The
/nightly <name> slash command resolves names by walking the same file from the
PR branch, so newly added entries can be exercised on a PR before they land on
main.
Adding a New Nightly Test Case¶
To add a new test case (no need to touch the workflow YAMLs):
- Append an entry under the appropriate section in
.github/workflows/configs/nightly_config.yaml. Each entry needs at least: name: unique identifier used in/nightly <name>filtersos(for single-node / multi-card pytest+yaml tests) orrunneris inferred- one of
tests:(pytest directory) orconfig_file_path:(YAML-driven model config) size(multi-node / double-node only)- Add the actual test files (pytest modules under
tests/e2e/nightly/...or YAML model configs intests/e2e/nightly/.../configs/). - Open a PR. Once CI is green, you can validate the new entry against real NPU hardware without merging the PR — see Examples below.
Available Test Names¶
The test names you can pass to /nightly correspond to the name fields under
the matching section in .github/workflows/configs/nightly_config.yaml. The
tables below mirror the current contents of that file.
A2 workflow (.github/workflows/schedule_nightly_test_a2.yaml)¶
Single-node tests (a2.single_node.test_config):
| Test name | Description |
|---|---|
test_custom_op_multi_card |
Custom operator tests (multi card) |
qwen3-vl-32b-instruct-w8a8 |
Qwen3-VL-32B-Instruct W8A8 |
qwen3-32b-int8 |
Qwen3-32B INT8 quantization |
Qwen3.5-27B-w8a8-A2 |
Qwen3.5-27B W8A8 |
Qwen3.5-397B-A17B-w4a8-mtp |
Qwen3.5-397B-A17B W4A8 + MTP |
Multi-node tests (a2.multi_node.test_config):
| Test name | Description |
|---|---|
multi-node-qwen3-235b-dp |
Qwen3-235B-A22B, 2-node DP |
multi-node-GLM-5.1-w8a8-A2 |
GLM-5.1 W8A8, 2 nodes |
multi-node-Kimi-K2.5-W4A8-A2 |
Kimi-K2.5 W4A8, 2 nodes |
Accuracy tests (a2.accuracy.nightly and a2.accuracy.pr_only):
| Test name | Description | Scope |
|---|---|---|
accuracy-group-1 |
Qwen3-VL-8B, Qwen3-8B, Qwen2-Audio-7B, etc. | nightly |
accuracy-group-2 |
ERNIE-4.5, Molmo-7B, Llama-3.2-3B, etc. | nightly |
accuracy-group-3 |
Qwen3-30B-A3B, Qwen3-VL-30B-A3B, etc. | nightly |
accuracy-group-4 |
Qwen3-Next-80B-A3B, Qwen3-Omni-30B-A3B, etc. | nightly |
pr-accuracy-group-1 |
gemma-3-4b-it, internlm3-8b-instruct, etc. | pr_only |
pr-accuracy-group-2 |
Qwen2.5-Math-RM-72B, Hunyuan-A13B-Instruct | pr_only |
The pr-accuracy-group-* entries only run on /nightly (PR-triggered) runs;
/nightly all on the schedule skips them.
A3 workflow (.github/workflows/schedule_nightly_test_a3.yaml)¶
Multi-node tests (a3.multi_node.test_config, 4-node):
| Test name | Description |
|---|---|
multi-node-deepseek-v3.2-W8A8-EP |
DeepSeek-V3.2-W8A8 with EP, 4-node |
Double-node tests (a3.double_node.test_config, 2-node, run after multi-node):
| Test name | Description |
|---|---|
multi-node-deepseek-r1-w8a8-longseq |
DeepSeek-R1-W8A8 long sequence, 2-node |
multi-node-qwen3-dp |
Qwen3-235B-A22B, 2-node DP |
multi-node-qwenw8a8-2node-eplb |
Qwen3-235B-W8A8 with EPLB, 2-node |
multi-node-dpsk3.2-2node |
DeepSeek-V3.2-W8A8, 2-node |
multi-node-qwenw8a8-2node-longseq |
Qwen3-235B-W8A8 long sequence, 2-node |
multi-node-qwen-disagg-pd |
Qwen3-235B disaggregated PD, 2-node |
multi-node-qwen-vl-disagg-pd |
Qwen3-VL-235B disaggregated PD, 2-node |
multi-node-deepseek-v3.1 |
DeepSeek-V3.1-BF16, 2-node |
multi-node-deepseek-v3.2-W8A8-EP |
DeepSeek-V3.2-W8A8 with EP, 4-node |
multi-node-glm-5.2 |
GLM-5.1-W8A8, 2-node |
Single-node tests (a3.single_node.test_config):
| Test name | Description |
|---|---|
mtpx-deepseek-r1-0528-w8a8 |
MTP-X + DeepSeek-R1-0528-W8A8 |
deepseek-r1-0528-w8a8 |
DeepSeek-R1-0528-W8A8 |
kimi-k2-thinking |
Kimi-K2-Thinking |
qwen3-vl-235b-a22b-instruct-w8a8 |
Qwen3-VL-235B-A22B-Instruct-W8A8 |
deepseek-r1-0528-w8a8-prefix-cache |
DeepSeek-R1-0528-W8A8 prefix cache |
deepseek-v3-2-w8a8 |
DeepSeek-V3.2-W8A8 |
glm-4.7-w8a8 |
GLM-4.7 W8A8 |
kimi-k2.5 |
Kimi-K2.5 |
qwen3-235b-a22b-w8a8 |
Qwen3-235B-A22B-W8A8 |
Qwen3.5-397B-A17B-w8a8-mtp |
Qwen3.5-397B-A17B W8A8 + MTP |
MiniMax-M2.5-w8a8-QuaRot-A3 |
MiniMax-M2.5 W8A8 + QuaRot |
Qwen3.5-27B-w8a8-A3 |
Qwen3.5-27B W8A8 |
Qwen3.5-122B-A10B-W8A8-A3 |
Qwen3.5-122B-A10B W8A8 |
DeepSeek-V4-Flash-W8A8-A3 |
DeepSeek-V4-Flash W8A8 |
Multi-card tests (a3.multi_card.test_config):
| Test name | Description |
|---|---|
qwen3-30b-acc |
Qwen3-30B accuracy test |
qwen3-30b-a3b-w8a8 |
Qwen3-30B-A3B-W8A8 |
qwen3-32b-int8 |
Qwen3-32B-Int8 |
qwen3-32b-int8-prefix-cache |
Qwen3-32B-Int8 prefix cache |
Qwen3-30B-A3B-W4A8-llm-compressor |
Qwen3-30B-A3B W4A8 via llm-compressor |
Qwen3-30B-QuaRot |
Qwen3-30B QuaRot + eagle3 |
Qwen3-32B-QuaRot |
Qwen3-32B QuaRot + eagle3 |
Warning
The A3 resource pool has a maximum concurrency of 5×16 NPUs. Multi-node tests
run with max-parallel: 2 to avoid resource exhaustion. Running /nightly all on
A3 will queue a large number of jobs — prefer targeting specific test names when
possible.
Examples¶
Run all available nightly tests against your PR:
Run only the custom operator multi-card test:
Run two specific tests at once (one per SoC):
Run a single accuracy group (with all of its models):
Run a single accuracy model (only that model from a group):
Re-trigger after fixing an issue: just push a new commit. The synchronize event
re-runs the workflow and picks up the existing /nightly comment automatically — no
need to post a new comment.
Adding a New Test Case — Worked Example¶
To add my-new-test to the A2 single-node section:
- Edit
.github/workflows/configs/nightly_config.yaml, append undera2.single_node.test_config:
- name: my-new-test
os: linux-aarch64-a2b3-4
tests: tests/e2e/nightly/single_node/ops/multicard_ops_a2/test_my_new.py
-
Commit the new pytest file (
test_my_new.py) in the same PR. -
Trigger from the PR:
The workflow will:
pr_nightly_command.ymlreads your PR'snightly_config.yamland resolvesmy-new-test→ dispatch A2 only.Nightly-A2is dispatched atmain, butgenerate-a2-matrixchecks out your PR commit and reads the new entry from the matrix.single-node-testsruns one matrix job formy-new-test, withshould_run=true. The reusable workflow checks out your PR code (viavllm_ascend_ref) and runs your pytest.
Troubleshooting¶
The workflow didn't start after I posted the comment.
- Check that the comment starts exactly with
/nightlywith no leading spaces or extra characters before the slash. - Confirm you have at least Triage permission on the repository; unauthorized users' comments are ignored.
- To re-trigger after fixing an issue, simply push a new commit — the workflow will
reuse the existing
/nightlycomment automatically.
Only some tests ran, not the ones I expected.
- Test names are case-sensitive and must match the
namefield in.github/workflows/configs/nightly_config.yamlexactly (see the tables above). - For a PR-triggered run, the matrix is loaded from your PR's
nightly_config.yaml, not main. If a name isn't in your PR's file, it won't be recognized and the dispatch will be skipped. - Check the
parse-triggerjob output in GitHub Actions for the resolvedtest_filtervalue.
The workflow ran with the scheduled image, not my PR code.
- Confirm the workflow was triggered by
repository_dispatch(slash command), not bareworkflow_dispatch. Thepr_nightly_command.ymlworkflow is what actually dispatchesschedule_nightly_test_a2.yaml/_a3.yamlwithvllm_ascend_refpointing at your PR SHA.
A new test I added isn't being recognized.
- Confirm the entry is well-formed YAML under
.github/workflows/configs/nightly_config.yaml. Thenamefield is required and must be unique within the SoC's section. - The matrix is loaded from your PR branch, so make sure the file is committed
to the same branch the
/nightlycomment was posted on.
How to obtain more detailed logs to pinpoint problems for multi-node tests
- For most issues, the stdout pop-up logs from GitHub actions are sufficient (this log always represents the logs from the first node).
- If the logs from a first node are no longer sufficient to provide effective logging information, see the summary of your jobs to download log archive for the corresponding test, which includes the framework-side logs and plog information for each node, structured as follows: