Skip to content

Commit 03b71a1

Browse files
committed
[CICD] Consolidate platform CI updates and Qwen3.6 configs
Unify Qwen3.6 model test configs across platforms and consolidate pending MUSA S5000, MetaX graph serving, and Ascend 910C CI updates.
1 parent 0268a16 commit 03b71a1

57 files changed

Lines changed: 1315 additions & 317 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/configs/ascend.yml

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,11 @@
1818
platform: ascend
1919

2020
# Docker image for this hardware
21-
ci_image: harbor.baai.ac.cn/flagscale/vllm-plugin-fl:v0.2.0-ascend-ci
21+
ci_image: harbor.baai.ac.cn/flagscale/vllm-plugin-fl:ascend-vllm0.20.2-a3-ci
2222

2323
# Runner labels for this hardware
2424
runner_labels:
25-
- self-hosted
26-
- Linux
27-
- ARM64
28-
- ascend
29-
- npu-16
25+
- flagcicd-910c
3026

3127
# Container volumes (hardware-specific paths)
3228
container_volumes:
@@ -44,6 +40,8 @@ container_options: >-
4440
--hostname vllm-plugin-fl
4541
--ipc=host
4642
--privileged
43+
--env ASCEND_RT_VISIBLE_DEVICES=14,15
44+
--env VLLM_EXECUTE_MODEL_TIMEOUT_SECONDS=1800
4745
--device /dev/davinci0
4846
--device /dev/davinci1
4947
--device /dev/davinci2

.github/configs/musa.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Copyright 2026 FlagOS Contributors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# MUSA Hardware Configuration
16+
# This file defines CI/CD settings for MUSA testing.
17+
18+
platform: musa
19+
20+
ci_image: harbor.baai.ac.cn/flagos-dev/vllm-plugin-fl:v0.20.2-musa-ci
21+
22+
runner_labels:
23+
- mt-cicd-vllm-plugin
24+
25+
container_volumes:
26+
- /data:/data
27+
28+
container_options: >-
29+
--hostname vllm-plugin-fl
30+
--privileged
31+
--ipc=host
32+
--shm-size=64g
33+
--env GEMS_VENDOR=mthreads
34+
--env VLLM_PLUGINS=fl
35+
--env MTHREADS_VISIBLE_DEVICES=all

.github/configs/platforms.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,12 @@ platforms:
2323
cuda:
2424
enabled: true
2525
ascend:
26-
enabled: false
26+
# Ascend uses a scarce self-hosted NPU runner; keep it enabled when
27+
# validating Ascend changes in PR CI.
28+
enabled: true
2729
hygon:
2830
enabled: true
2931
metax:
3032
enabled: true
33+
musa:
34+
enabled: true

.github/scripts/ascend/check.sh

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,40 @@
22
# Copyright (c) 2025 BAAI. All rights reserved.
33
# Check Huawei Ascend NPU availability.
44
set -euo pipefail
5+
56
echo "=== Checking Ascend NPU availability ==="
6-
# TODO: Replace with actual Ascend device check command.
7-
npu-smi info || echo "WARNING: npu-smi not found. Ascend device check skipped."
7+
8+
if ! command -v npu-smi >/dev/null 2>&1; then
9+
echo "::error::npu-smi is required but was not found in PATH."
10+
exit 1
11+
fi
12+
13+
if [[ -z "${ASCEND_RT_VISIBLE_DEVICES:-}" ]]; then
14+
echo "::error::ASCEND_RT_VISIBLE_DEVICES is not set."
15+
exit 1
16+
fi
17+
18+
required_devices=(
19+
"/dev/davinci_manager"
20+
"/dev/devmm_svm"
21+
"/dev/hisi_hdc"
22+
)
23+
24+
IFS=',' read -r -a visible_devices <<< "${ASCEND_RT_VISIBLE_DEVICES}"
25+
for device_id in "${visible_devices[@]}"; do
26+
device_id="${device_id//[[:space:]]/}"
27+
if [[ -z "${device_id}" ]]; then
28+
continue
29+
fi
30+
required_devices+=("/dev/davinci${device_id}")
31+
done
32+
33+
for device_path in "${required_devices[@]}"; do
34+
if [[ ! -e "${device_path}" ]]; then
35+
echo "::error::Missing Ascend device path: ${device_path}"
36+
exit 1
37+
fi
38+
done
39+
40+
npu-smi info
41+
echo "Ascend device check passed."
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#!/bin/bash
2+
# Copyright 2026 FlagOS Contributors
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
# Provision models on the host-mounted /data volume. Images must not contain
17+
# model weights; every platform test refers to the same host path convention.
18+
set -euo pipefail
19+
20+
export FL_MODEL_BASE_PATH="${FL_MODEL_BASE_PATH:-/data/models}"
21+
export HF_ENDPOINT="${HF_ENDPOINT:-https://hf-mirror.com}"
22+
23+
QWEN_ROOT="${FL_MODEL_BASE_PATH}/Qwen"
24+
HF_MODEL_ID="Qwen/Qwen3-0.6B"
25+
MODELSCOPE_MODEL_IDS=(
26+
"Qwen/Qwen3.6-27B"
27+
"Qwen/Qwen3.6-35B-A3B"
28+
)
29+
30+
mkdir -p "${QWEN_ROOT}"
31+
32+
MODEL_DIR="${QWEN_ROOT}/${HF_MODEL_ID#Qwen/}"
33+
if [[ -f "${MODEL_DIR}/config.json" ]]; then
34+
echo "Model already available: ${MODEL_DIR}"
35+
else
36+
export MODEL_ID="${HF_MODEL_ID}" MODEL_DIR
37+
echo "Downloading ${MODEL_ID} from ${HF_ENDPOINT} to ${MODEL_DIR}"
38+
python - <<'PY'
39+
import os
40+
41+
from huggingface_hub import snapshot_download
42+
43+
44+
snapshot_download(
45+
repo_id=os.environ["MODEL_ID"],
46+
local_dir=os.environ["MODEL_DIR"],
47+
endpoint=os.environ["HF_ENDPOINT"],
48+
)
49+
PY
50+
test -f "${MODEL_DIR}/config.json"
51+
echo "Model ready: ${MODEL_DIR}"
52+
fi
53+
54+
if ! command -v modelscope >/dev/null 2>&1; then
55+
pip install modelscope --break-system-packages
56+
fi
57+
58+
for MODEL_ID in "${MODELSCOPE_MODEL_IDS[@]}"; do
59+
MODEL_DIR="${QWEN_ROOT}/${MODEL_ID#Qwen/}"
60+
if [[ -f "${MODEL_DIR}/config.json" ]]; then
61+
echo "Model already available: ${MODEL_DIR}"
62+
continue
63+
fi
64+
65+
echo "Downloading ${MODEL_ID} from ModelScope to ${MODEL_DIR}"
66+
modelscope download --model "${MODEL_ID}" --local_dir "${MODEL_DIR}"
67+
test -f "${MODEL_DIR}/config.json"
68+
echo "Model ready: ${MODEL_DIR}"
69+
done

.github/scripts/ascend/setup.sh

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,19 @@ set -euo pipefail
66
git config --global --add safe.directory "$(pwd)"
77

88
pip install --upgrade pip "setuptools>=77.0.3"
9-
pip install --no-build-isolation -e ".[test]"
9+
pip install \
10+
--constraint requirements/ascend.txt \
11+
--no-build-isolation \
12+
--no-deps \
13+
-e .
14+
15+
python - <<'PY'
16+
import numpy
17+
18+
expected = "1.26.4"
19+
if numpy.__version__ != expected:
20+
raise RuntimeError(
21+
f"Unexpected NumPy version: {numpy.__version__}; expected {expected}"
22+
)
23+
print(f"NumPy version: {numpy.__version__}")
24+
PY

.github/scripts/generate_matrix.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,16 @@ def resolve_task_dir(task_key: str) -> str:
5858
return TASK_DIR_MAP.get(task_key, task_key)
5959

6060

61+
def resolve_e2e_timeout(config: dict, device: str, task_dir: str) -> int:
62+
"""Return timeout for an E2E task, allowing platform YAML overrides."""
63+
default = DEFAULT_TIMEOUT.get(task_dir, 60)
64+
timeouts = (
65+
config.get(device, {}).get("tests", {}).get("timeouts", {}).get("e2e", {})
66+
)
67+
value = timeouts.get(task_dir, default)
68+
return int(value)
69+
70+
6171
def get_device_sections(config: dict) -> list[str]:
6272
"""Return device section names present in the config.
6373
@@ -108,7 +118,7 @@ def build_e2e_matrix(
108118
# Build one matrix entry per (task, device) group
109119
entries = []
110120
for (task_dir, device), case_list in groups.items():
111-
timeout = DEFAULT_TIMEOUT.get(task_dir, 60)
121+
timeout = resolve_e2e_timeout(config, device, task_dir)
112122
entries.append(
113123
{
114124
"task": task_dir,

.github/scripts/musa/check.sh

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/bin/bash
2+
# Copyright (c) 2026 BAAI. All rights reserved.
3+
# Check Moore Threads MUSA availability.
4+
set -euo pipefail
5+
6+
echo "Current time: $(date '+%Y-%m-%d %H:%M:%S')"
7+
echo "=== Checking Moore Threads MUSA availability ==="
8+
9+
if command -v mthreads-gmi >/dev/null 2>&1; then
10+
mthreads-gmi
11+
else
12+
echo "::warning::mthreads-gmi not found; checking through torch_musa."
13+
fi
14+
15+
python - <<'PY'
16+
import torch
17+
import torch_musa
18+
19+
assert torch.musa.is_available(), "MUSA accelerator is unavailable"
20+
count = torch.musa.device_count()
21+
assert count > 0, "No MUSA devices detected"
22+
23+
tensor = torch.ones((32, 32), device="musa:0")
24+
torch.musa.synchronize()
25+
26+
print(f"MUSA devices: {count}")
27+
print(f"Tensor smoke: {tensor.device} {tuple(tensor.shape)}")
28+
PY

.github/scripts/musa/setup.sh

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#!/bin/bash
2+
# Copyright (c) 2026 BAAI. All rights reserved.
3+
# Setup script for Moore Threads MUSA CI environment.
4+
set -euo pipefail
5+
6+
git config --global --add safe.directory "$(pwd)"
7+
8+
: "${GEMS_VENDOR:?GEMS_VENDOR is not set}"
9+
: "${VLLM_PLUGINS:?VLLM_PLUGINS is not set}"
10+
: "${MTHREADS_VISIBLE_DEVICES:?MTHREADS_VISIBLE_DEVICES is not set}"
11+
12+
python -m pip install --no-build-isolation --no-deps -e .
13+
14+
python - <<'PY'
15+
import flag_gems
16+
import torch
17+
import torch_musa
18+
import vllm
19+
import vllm_fl
20+
from vllm.platforms import current_platform
21+
22+
assert torch.musa.is_available(), "MUSA accelerator is unavailable"
23+
assert torch.musa.device_count() > 0, "No MUSA devices detected"
24+
assert current_platform.device_type == "musa", current_platform.device_type
25+
26+
print(f"vLLM import ok: {vllm.__version__}")
27+
print(f"vLLM-FL import ok: {vllm_fl.__file__}")
28+
print(f"FlagGems import ok: {getattr(flag_gems, '__version__', 'unknown')}")
29+
print(f"Torch import ok: {torch.__version__}")
30+
print(f"MUSA available: {torch.musa.is_available()}")
31+
print(f"MUSA devices: {torch.musa.device_count()}")
32+
print(f"Platform: {current_platform}")
33+
PY

.github/workflows/_e2e_test.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,13 @@ jobs:
9393
- name: Check device availability
9494
run: bash .github/scripts/${{ inputs.platform }}/check.sh
9595

96+
- name: Prepare host models
97+
run: |
98+
model_script=".github/scripts/${{ inputs.platform }}/download_models.sh"
99+
if [ -f "${model_script}" ]; then
100+
bash "${model_script}"
101+
fi
102+
96103
- name: Install project
97104
run: bash .github/scripts/${{ inputs.platform }}/setup.sh
98105

0 commit comments

Comments
 (0)