From 11bdc2ba42525b32b969fe051e5b612c30bca73d Mon Sep 17 00:00:00 2001 From: mccxadmin Date: Thu, 20 Aug 2026 18:43:12 +0800 Subject: [PATCH 01/14] build: add MUSA CI workflow and launcher. --- .github/workflows/build_x86_64_musa.yaml | 147 +++++++++++++++++++++++ cibuild/build_musa.sh | 108 +++++++++++++++++ 2 files changed, 255 insertions(+) create mode 100644 .github/workflows/build_x86_64_musa.yaml create mode 100755 cibuild/build_musa.sh diff --git a/.github/workflows/build_x86_64_musa.yaml b/.github/workflows/build_x86_64_musa.yaml new file mode 100644 index 0000000000..d2c3e36c34 --- /dev/null +++ b/.github/workflows/build_x86_64_musa.yaml @@ -0,0 +1,147 @@ +# Copyright 2026 The xLLM Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: xLLM Build x86_64 MUSA + +on: + workflow_dispatch: + push: + branches: [main] + paths-ignore: + - 'docs/**' + - 'tools/**' + - '*.md' + - '*.txt' + - '*.yml' + pull_request: + branches: [main] + types: [opened, synchronize, reopened] + paths-ignore: + - 'docs/**' + - 'tools/**' + - '*.md' + - '*.txt' + - '*.yml' + pull_request_review: + types: [submitted] + +permissions: + contents: read + +env: + JOBNAME: xllm-x86_64-musa-cibuild-${{ github.run_id }} + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} + +jobs: + # Review changes to executable CI inputs before using the privileged runner. + check-sensitive: + runs-on: [xllm-cpu-only-cicd] + outputs: + requires_approval: ${{ steps.check_sensitive.outputs.requires_approval }} + do_build: ${{ steps.decide.outputs.do_build }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + persist-credentials: false + ref: ${{ github.event.pull_request.head.sha || github.sha }} + + - name: Check if sensitive files were changed + id: check_sensitive + shell: bash + run: | + requires_approval=false + event="${{ github.event_name }}" + if [[ "${event}" == "pull_request" || + "${event}" == "pull_request_review" ]]; then + while IFS= read -r changed_file; do + case "${changed_file}" in + .github/**|cibuild/**|setup.py|examples/generate.py) + requires_approval=true + break + ;; + esac + done < <( + git diff --name-only \ + "${{ github.event.pull_request.base.sha }}" \ + "${{ github.event.pull_request.head.sha }}" + ) + fi + echo "requires_approval=${requires_approval}" >> "${GITHUB_OUTPUT}" + + - name: Decide whether to build + id: decide + shell: bash + run: | + event="${{ github.event_name }}" + if [[ "${event}" == "workflow_dispatch" || "${event}" == "push" ]]; then + echo "do_build=true" >> "${GITHUB_OUTPUT}" + elif [[ "${event}" == "pull_request" ]]; then + if [[ "${{ steps.check_sensitive.outputs.requires_approval }}" == "true" ]]; then + echo "do_build=false" >> "${GITHUB_OUTPUT}" + else + echo "do_build=true" >> "${GITHUB_OUTPUT}" + fi + elif [[ "${event}" == "pull_request_review" ]]; then + association="${{ github.event.review.author_association }}" + if [[ "${{ steps.check_sensitive.outputs.requires_approval }}" == "true" && + "${{ github.event.review.state }}" == "approved" && + "${{ github.event.review.commit_id }}" == + "${{ github.event.pull_request.head.sha }}" && + ("${association}" == "OWNER" || + "${association}" == "MEMBER" || + "${association}" == "COLLABORATOR") ]]; then + echo "do_build=true" >> "${GITHUB_OUTPUT}" + else + echo "do_build=false" >> "${GITHUB_OUTPUT}" + fi + else + echo "do_build=false" >> "${GITHUB_OUTPUT}" + fi + + build: + needs: check-sensitive + if: > + (github.event_name == 'workflow_dispatch' || github.event_name == 'push') || + needs.check-sensitive.outputs.do_build == 'true' + runs-on: [self-hosted, xllm-musa-x86-cicd] + timeout-minutes: 120 + steps: + - name: Prepare submodule checkout + run: | + if [ -d .git/modules ]; then + find .git/modules -type f -name '*.lock' -print -delete || true + fi + + - name: Checkout code + uses: actions/checkout@v4 + timeout-minutes: 10 + with: + clean: true + fetch-depth: 1 + persist-credentials: false + ref: ${{ github.event.pull_request.merge_commit_sha || github.sha }} + submodules: recursive + + - name: Clean submodules + run: git submodule foreach --recursive git clean -ffdx + + - name: Build Python package + run: | + bash ./cibuild/build_musa.sh \ + 'python setup.py build --device musa' diff --git a/cibuild/build_musa.sh b/cibuild/build_musa.sh new file mode 100755 index 0000000000..07736ce5a7 --- /dev/null +++ b/cibuild/build_musa.sh @@ -0,0 +1,108 @@ +#!/bin/bash +# Copyright 2026 The xLLM Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -Eeuo pipefail + +readonly IMAGE="${XLLM_MUSA_IMAGE:-registry.mthreads.com/presale/devtech/xllm:musa-cicd-20260820}" +readonly WORKDIR="${GITHUB_WORKSPACE:-$(pwd)}" +readonly CCACHE_CACHE="${XLLM_MUSA_CCACHE:-}" + +error() { + echo "Require one build command, e.g. python setup.py build --device musa" >&2 + exit 1 +} + +if [[ $# -ne 1 || -z "$1" ]]; then + error +fi + +if ! command -v docker >/dev/null 2>&1; then + echo "ERROR: 'docker' command is missing." >&2 + exit 1 +fi + +if [[ ! -d "${WORKDIR}" ]]; then + echo "ERROR: workspace does not exist: ${WORKDIR}" >&2 + exit 1 +fi + +DOCKER_RUNTIMES="$(docker info --format '{{json .Runtimes}}')" +readonly DOCKER_RUNTIMES +if [[ "${DOCKER_RUNTIMES}" != *'"mthreads"'* ]]; then + echo "ERROR: Docker runtime 'mthreads' is unavailable." >&2 + exit 1 +fi + +readonly COMMAND="$1" +readonly BUILD_JOBS="${MAX_JOBS:-16}" +readonly MUSA_DEVICE_MASK="${MUSA_VISIBLE_DEVICES:-0}" +container_name="${JOBNAME:-xllm-musa-cibuild}-${BASHPID}" +container_name="${container_name//[^a-zA-Z0-9_.-]/-}" +readonly container_name +docker_pid="" + +RUN_OPTS=( + --rm + --name "${container_name}" + --privileged + --runtime=mthreads + --ipc=host + --network=host + --shm-size=128g + --ulimit memlock=-1 + --env "GITHUB_WORKSPACE=${WORKDIR}" + --env "MAX_JOBS=${BUILD_JOBS}" + --env "MUSA_VISIBLE_DEVICES=${MUSA_DEVICE_MASK}" + --env "XLLM_HOST_GID=$(id -g)" + --env "XLLM_HOST_UID=$(id -u)" + --volume "${WORKDIR}:${WORKDIR}" + --workdir "${WORKDIR}" + --entrypoint /usr/local/bin/run-xllm-musa-ci +) + +if [[ -n "${CCACHE_CACHE}" ]]; then + if [[ ! -d "${CCACHE_CACHE}" ]]; then + echo "ERROR: configured ccache directory does not exist: ${CCACHE_CACHE}" >&2 + exit 1 + fi + RUN_OPTS+=( + --env "CCACHE_DIR=/root/.cache/ccache" + --volume "${CCACHE_CACHE}:/root/.cache/ccache" + ) +fi + +cleanup() { + local status=$? + trap - EXIT INT TERM + set +e + docker rm --force "${container_name}" >/dev/null 2>&1 + if [[ -n "${docker_pid}" ]]; then + wait "${docker_pid}" >/dev/null 2>&1 + docker_pid="" + fi + exit "${status}" +} +trap cleanup EXIT +trap 'exit 130' INT +trap 'exit 143' TERM + +docker run "${RUN_OPTS[@]}" "${IMAGE}" run "${COMMAND}" & +docker_pid=$! +set +e +wait "${docker_pid}" +docker_status=$? +set -e +docker_pid="" +exit "${docker_status}" From 97bbd66c2e62662496a5e00e7d341ed4eaa580e7 Mon Sep 17 00:00:00 2001 From: mccxadmin Date: Thu, 20 Aug 2026 20:43:47 +0800 Subject: [PATCH 02/14] build: align MUSA CI cache with NPU. --- .github/workflows/build_x86_64_musa.yaml | 14 +++++++++----- cibuild/build_musa.sh | 19 +++++++++++++++++-- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build_x86_64_musa.yaml b/.github/workflows/build_x86_64_musa.yaml index d2c3e36c34..460fb78b15 100644 --- a/.github/workflows/build_x86_64_musa.yaml +++ b/.github/workflows/build_x86_64_musa.yaml @@ -69,6 +69,11 @@ jobs: event="${{ github.event_name }}" if [[ "${event}" == "pull_request" || "${event}" == "pull_request_review" ]]; then + changed_files="$( + git diff --name-only \ + "${{ github.event.pull_request.base.sha }}" \ + "${{ github.event.pull_request.head.sha }}" + )" while IFS= read -r changed_file; do case "${changed_file}" in .github/**|cibuild/**|setup.py|examples/generate.py) @@ -76,11 +81,7 @@ jobs: break ;; esac - done < <( - git diff --name-only \ - "${{ github.event.pull_request.base.sha }}" \ - "${{ github.event.pull_request.head.sha }}" - ) + done <<< "${changed_files}" fi echo "requires_approval=${requires_approval}" >> "${GITHUB_OUTPUT}" @@ -142,6 +143,9 @@ jobs: run: git submodule foreach --recursive git clean -ffdx - name: Build Python package + if: ${{ success() }} + timeout-minutes: 120 run: | + chmod +x ./cibuild/build_musa.sh bash ./cibuild/build_musa.sh \ 'python setup.py build --device musa' diff --git a/cibuild/build_musa.sh b/cibuild/build_musa.sh index 07736ce5a7..7e9b785675 100755 --- a/cibuild/build_musa.sh +++ b/cibuild/build_musa.sh @@ -18,6 +18,7 @@ set -Eeuo pipefail readonly IMAGE="${XLLM_MUSA_IMAGE:-registry.mthreads.com/presale/devtech/xllm:musa-cicd-20260820}" readonly WORKDIR="${GITHUB_WORKSPACE:-$(pwd)}" readonly CCACHE_CACHE="${XLLM_MUSA_CCACHE:-}" +readonly VCPKG_CACHE="${XLLM_MUSA_VCPKG_CACHE:-/export/home/musa_vcpkg_cache}" error() { echo "Require one build command, e.g. python setup.py build --device musa" >&2 @@ -38,6 +39,11 @@ if [[ ! -d "${WORKDIR}" ]]; then exit 1 fi +if ! mkdir -p "${VCPKG_CACHE}/archives" "${VCPKG_CACHE}/downloads"; then + echo "ERROR: cannot create vcpkg cache directories: ${VCPKG_CACHE}" >&2 + exit 1 +fi + DOCKER_RUNTIMES="$(docker info --format '{{json .Runtimes}}')" readonly DOCKER_RUNTIMES if [[ "${DOCKER_RUNTIMES}" != *'"mthreads"'* ]]; then @@ -45,7 +51,13 @@ if [[ "${DOCKER_RUNTIMES}" != *'"mthreads"'* ]]; then exit 1 fi -readonly COMMAND="$1" +# Keep vcpkg source selection tied to CMake while reusing host downloads and +# binary archives. +readonly COMMAND="unset VCPKG_ROOT VCPKG_BINARY_SOURCES \ + DEPENDENCES_ROOT FETCHCONTENT_SOURCE_DIR_VCPKG CMAKE_TOOLCHAIN_FILE +export VCPKG_DEFAULT_BINARY_CACHE=/root/.cache/vcpkg/archives +export VCPKG_DOWNLOADS=/root/.cache/vcpkg/downloads +$1" readonly BUILD_JOBS="${MAX_JOBS:-16}" readonly MUSA_DEVICE_MASK="${MUSA_VISIBLE_DEVICES:-0}" container_name="${JOBNAME:-xllm-musa-cibuild}-${BASHPID}" @@ -68,6 +80,7 @@ RUN_OPTS=( --env "XLLM_HOST_GID=$(id -g)" --env "XLLM_HOST_UID=$(id -u)" --volume "${WORKDIR}:${WORKDIR}" + --volume "${VCPKG_CACHE}:/root/.cache/vcpkg" --workdir "${WORKDIR}" --entrypoint /usr/local/bin/run-xllm-musa-ci ) @@ -87,11 +100,13 @@ cleanup() { local status=$? trap - EXIT INT TERM set +e - docker rm --force "${container_name}" >/dev/null 2>&1 if [[ -n "${docker_pid}" ]]; then + docker stop --time 40 "${container_name}" >/dev/null 2>&1 + kill -TERM "${docker_pid}" >/dev/null 2>&1 wait "${docker_pid}" >/dev/null 2>&1 docker_pid="" fi + docker rm --force "${container_name}" >/dev/null 2>&1 exit "${status}" } trap cleanup EXIT From 0167d88b4ee4b5d6a3a1eba747ff52841d0e79c3 Mon Sep 17 00:00:00 2001 From: mccxadmin Date: Thu, 20 Aug 2026 21:17:32 +0800 Subject: [PATCH 03/14] build: fix MUSA approval gate syntax. --- .github/workflows/build_x86_64_musa.yaml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build_x86_64_musa.yaml b/.github/workflows/build_x86_64_musa.yaml index 460fb78b15..0ff88b84fd 100644 --- a/.github/workflows/build_x86_64_musa.yaml +++ b/.github/workflows/build_x86_64_musa.yaml @@ -100,10 +100,12 @@ jobs: fi elif [[ "${event}" == "pull_request_review" ]]; then association="${{ github.event.review.author_association }}" + review_state="${{ github.event.review.state }}" + review_commit="${{ github.event.review.commit_id }}" + head_sha="${{ github.event.pull_request.head.sha }}" if [[ "${{ steps.check_sensitive.outputs.requires_approval }}" == "true" && - "${{ github.event.review.state }}" == "approved" && - "${{ github.event.review.commit_id }}" == - "${{ github.event.pull_request.head.sha }}" && + "${review_state}" == "approved" && + "${review_commit}" == "${head_sha}" && ("${association}" == "OWNER" || "${association}" == "MEMBER" || "${association}" == "COLLABORATOR") ]]; then From a0216d5c908c40b46817c0505d6bd658fb924415 Mon Sep 17 00:00:00 2001 From: mccxadmin Date: Fri, 21 Aug 2026 14:07:39 +0800 Subject: [PATCH 04/14] build(musa): simplify CI launcher Align the MUSA host launcher with the existing NPU build script. Keep only the MUSA runtime, workspace and vcpkg mounts, device/build environment, UID/GID handoff, and image entrypoint. Remove redundant runtime/workspace probes, ccache branching, container-name bookkeeping, and duplicate outer cleanup while preserving vcpkg source isolation and child-shell failure propagation. --- cibuild/build_musa.sh | 90 ++++++++----------------------------------- 1 file changed, 15 insertions(+), 75 deletions(-) diff --git a/cibuild/build_musa.sh b/cibuild/build_musa.sh index 7e9b785675..3a24e929da 100755 --- a/cibuild/build_musa.sh +++ b/cibuild/build_musa.sh @@ -13,61 +13,36 @@ # See the License for the specific language governing permissions and # limitations under the License. -set -Eeuo pipefail +set -e -readonly IMAGE="${XLLM_MUSA_IMAGE:-registry.mthreads.com/presale/devtech/xllm:musa-cicd-20260820}" -readonly WORKDIR="${GITHUB_WORKSPACE:-$(pwd)}" -readonly CCACHE_CACHE="${XLLM_MUSA_CCACHE:-}" -readonly VCPKG_CACHE="${XLLM_MUSA_VCPKG_CACHE:-/export/home/musa_vcpkg_cache}" +IMAGE="${XLLM_MUSA_IMAGE:-registry.mthreads.com/presale/devtech/xllm:musa-cicd-20260820}" +WORKDIR="$(pwd)" +VCPKG_CACHE="${XLLM_MUSA_VCPKG_CACHE:-/export/home/musa_vcpkg_cache}" error() { echo "Require one build command, e.g. python setup.py build --device musa" >&2 exit 1 } -if [[ $# -ne 1 || -z "$1" ]]; then - error -fi - -if ! command -v docker >/dev/null 2>&1; then - echo "ERROR: 'docker' command is missing." >&2 - exit 1 -fi +CMD="$*" +[[ -z "${CMD}" ]] && error -if [[ ! -d "${WORKDIR}" ]]; then - echo "ERROR: workspace does not exist: ${WORKDIR}" >&2 - exit 1 -fi +mkdir -p "${VCPKG_CACHE}" -if ! mkdir -p "${VCPKG_CACHE}/archives" "${VCPKG_CACHE}/downloads"; then - echo "ERROR: cannot create vcpkg cache directories: ${VCPKG_CACHE}" >&2 - exit 1 -fi +[[ ! -x $(command -v docker) ]] && \ + echo "ERROR: 'docker' command is missing." && exit 1 -DOCKER_RUNTIMES="$(docker info --format '{{json .Runtimes}}')" -readonly DOCKER_RUNTIMES -if [[ "${DOCKER_RUNTIMES}" != *'"mthreads"'* ]]; then - echo "ERROR: Docker runtime 'mthreads' is unavailable." >&2 - exit 1 -fi - -# Keep vcpkg source selection tied to CMake while reusing host downloads and -# binary archives. -readonly COMMAND="unset VCPKG_ROOT VCPKG_BINARY_SOURCES \ +COMMAND="set -euo pipefail; \ +unset VCPKG_ROOT VCPKG_BINARY_SOURCES \ DEPENDENCES_ROOT FETCHCONTENT_SOURCE_DIR_VCPKG CMAKE_TOOLCHAIN_FILE export VCPKG_DEFAULT_BINARY_CACHE=/root/.cache/vcpkg/archives export VCPKG_DOWNLOADS=/root/.cache/vcpkg/downloads -$1" -readonly BUILD_JOBS="${MAX_JOBS:-16}" -readonly MUSA_DEVICE_MASK="${MUSA_VISIBLE_DEVICES:-0}" -container_name="${JOBNAME:-xllm-musa-cibuild}-${BASHPID}" -container_name="${container_name//[^a-zA-Z0-9_.-]/-}" -readonly container_name -docker_pid="" +${CMD}" +BUILD_JOBS="${MAX_JOBS:-16}" +MUSA_DEVICE_MASK="${MUSA_VISIBLE_DEVICES:-0}" RUN_OPTS=( --rm - --name "${container_name}" --privileged --runtime=mthreads --ipc=host @@ -85,39 +60,4 @@ RUN_OPTS=( --entrypoint /usr/local/bin/run-xllm-musa-ci ) -if [[ -n "${CCACHE_CACHE}" ]]; then - if [[ ! -d "${CCACHE_CACHE}" ]]; then - echo "ERROR: configured ccache directory does not exist: ${CCACHE_CACHE}" >&2 - exit 1 - fi - RUN_OPTS+=( - --env "CCACHE_DIR=/root/.cache/ccache" - --volume "${CCACHE_CACHE}:/root/.cache/ccache" - ) -fi - -cleanup() { - local status=$? - trap - EXIT INT TERM - set +e - if [[ -n "${docker_pid}" ]]; then - docker stop --time 40 "${container_name}" >/dev/null 2>&1 - kill -TERM "${docker_pid}" >/dev/null 2>&1 - wait "${docker_pid}" >/dev/null 2>&1 - docker_pid="" - fi - docker rm --force "${container_name}" >/dev/null 2>&1 - exit "${status}" -} -trap cleanup EXIT -trap 'exit 130' INT -trap 'exit 143' TERM - -docker run "${RUN_OPTS[@]}" "${IMAGE}" run "${COMMAND}" & -docker_pid=$! -set +e -wait "${docker_pid}" -docker_status=$? -set -e -docker_pid="" -exit "${docker_status}" +docker run "${RUN_OPTS[@]}" "${IMAGE}" run "${COMMAND}" From d19740ed9562acda49dfd6f5d43bb635caec3f69 Mon Sep 17 00:00:00 2001 From: mccxadmin Date: Fri, 21 Aug 2026 14:11:31 +0800 Subject: [PATCH 05/14] build(musa): drop ineffective shm override The launcher already uses the host IPC namespace, so Docker shm-size does not affect the container. Keep the MUSA-specific memlock limit required by the runtime while matching the NPU launcher more closely. --- cibuild/build_musa.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/cibuild/build_musa.sh b/cibuild/build_musa.sh index 3a24e929da..00681a89a0 100755 --- a/cibuild/build_musa.sh +++ b/cibuild/build_musa.sh @@ -47,7 +47,6 @@ RUN_OPTS=( --runtime=mthreads --ipc=host --network=host - --shm-size=128g --ulimit memlock=-1 --env "GITHUB_WORKSPACE=${WORKDIR}" --env "MAX_JOBS=${BUILD_JOBS}" From eab2dc2cd2e34d9b65c147bfbb30c487d3105acd Mon Sep 17 00:00:00 2001 From: mccxadmin Date: Fri, 21 Aug 2026 14:18:05 +0800 Subject: [PATCH 06/14] build(musa): inline command guard Remove the single-use error helper and keep the empty-command check as one direct NPU-style guard. --- cibuild/build_musa.sh | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/cibuild/build_musa.sh b/cibuild/build_musa.sh index 00681a89a0..b49905d612 100755 --- a/cibuild/build_musa.sh +++ b/cibuild/build_musa.sh @@ -19,13 +19,8 @@ IMAGE="${XLLM_MUSA_IMAGE:-registry.mthreads.com/presale/devtech/xllm:musa-cicd-2 WORKDIR="$(pwd)" VCPKG_CACHE="${XLLM_MUSA_VCPKG_CACHE:-/export/home/musa_vcpkg_cache}" -error() { - echo "Require one build command, e.g. python setup.py build --device musa" >&2 - exit 1 -} - CMD="$*" -[[ -z "${CMD}" ]] && error +[[ -z "${CMD}" ]] && echo "Require build command" && exit 1 mkdir -p "${VCPKG_CACHE}" From ce5d04d39c2f3c8434a99a6122bfb3c4da250790 Mon Sep 17 00:00:00 2001 From: mccxadmin Date: Fri, 21 Aug 2026 14:20:00 +0800 Subject: [PATCH 07/14] build(musa): remove redundant command guard The workflow always passes the fixed MUSA build command, so the launcher only needs to forward it to the image entrypoint. --- cibuild/build_musa.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/cibuild/build_musa.sh b/cibuild/build_musa.sh index b49905d612..0f453c6a3d 100755 --- a/cibuild/build_musa.sh +++ b/cibuild/build_musa.sh @@ -20,7 +20,6 @@ WORKDIR="$(pwd)" VCPKG_CACHE="${XLLM_MUSA_VCPKG_CACHE:-/export/home/musa_vcpkg_cache}" CMD="$*" -[[ -z "${CMD}" ]] && echo "Require build command" && exit 1 mkdir -p "${VCPKG_CACHE}" From 887f8ef0e4e81ab7f0383346d9a0114dc92aa276 Mon Sep 17 00:00:00 2001 From: mccxadmin Date: Fri, 21 Aug 2026 14:23:53 +0800 Subject: [PATCH 08/14] build(musa): remove redundant Docker probe Let the required docker run invocation report Docker availability and runtime failures directly, matching the minimal NPU launcher flow. --- cibuild/build_musa.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/cibuild/build_musa.sh b/cibuild/build_musa.sh index 0f453c6a3d..fbd959084a 100755 --- a/cibuild/build_musa.sh +++ b/cibuild/build_musa.sh @@ -23,9 +23,6 @@ CMD="$*" mkdir -p "${VCPKG_CACHE}" -[[ ! -x $(command -v docker) ]] && \ - echo "ERROR: 'docker' command is missing." && exit 1 - COMMAND="set -euo pipefail; \ unset VCPKG_ROOT VCPKG_BINARY_SOURCES \ DEPENDENCES_ROOT FETCHCONTENT_SOURCE_DIR_VCPKG CMAKE_TOOLCHAIN_FILE From 2acc722e5bce778b9940107241b9969dd2956ec0 Mon Sep 17 00:00:00 2001 From: mccxadmin Date: Fri, 21 Aug 2026 14:30:48 +0800 Subject: [PATCH 09/14] build(musa): remove command alias Forward the fixed workflow command directly into the container command instead of storing it in a single-use variable. --- cibuild/build_musa.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cibuild/build_musa.sh b/cibuild/build_musa.sh index fbd959084a..8006a9e094 100755 --- a/cibuild/build_musa.sh +++ b/cibuild/build_musa.sh @@ -19,8 +19,6 @@ IMAGE="${XLLM_MUSA_IMAGE:-registry.mthreads.com/presale/devtech/xllm:musa-cicd-2 WORKDIR="$(pwd)" VCPKG_CACHE="${XLLM_MUSA_VCPKG_CACHE:-/export/home/musa_vcpkg_cache}" -CMD="$*" - mkdir -p "${VCPKG_CACHE}" COMMAND="set -euo pipefail; \ @@ -28,7 +26,7 @@ unset VCPKG_ROOT VCPKG_BINARY_SOURCES \ DEPENDENCES_ROOT FETCHCONTENT_SOURCE_DIR_VCPKG CMAKE_TOOLCHAIN_FILE export VCPKG_DEFAULT_BINARY_CACHE=/root/.cache/vcpkg/archives export VCPKG_DOWNLOADS=/root/.cache/vcpkg/downloads -${CMD}" +$*" BUILD_JOBS="${MAX_JOBS:-16}" MUSA_DEVICE_MASK="${MUSA_VISIBLE_DEVICES:-0}" From b35ff5c78c13c704b0af48577af2bbe493fabf62 Mon Sep 17 00:00:00 2001 From: mccxadmin Date: Fri, 21 Aug 2026 14:41:39 +0800 Subject: [PATCH 10/14] build(musa): keep only required launcher actions Reduce the compile-only launcher to the fixed image and one foreground docker run. Keep only the MUSA runtime, host network required for GitCode access, bounded build parallelism, workspace/cache mounts, ownership handoff, and the image entrypoint. --- cibuild/build_musa.sh | 49 +++++++++++++------------------------------ 1 file changed, 14 insertions(+), 35 deletions(-) diff --git a/cibuild/build_musa.sh b/cibuild/build_musa.sh index 8006a9e094..b2102e3842 100755 --- a/cibuild/build_musa.sh +++ b/cibuild/build_musa.sh @@ -13,39 +13,18 @@ # See the License for the specific language governing permissions and # limitations under the License. -set -e +IMAGE="registry.mthreads.com/presale/devtech/xllm:musa-cicd-20260820" -IMAGE="${XLLM_MUSA_IMAGE:-registry.mthreads.com/presale/devtech/xllm:musa-cicd-20260820}" -WORKDIR="$(pwd)" -VCPKG_CACHE="${XLLM_MUSA_VCPKG_CACHE:-/export/home/musa_vcpkg_cache}" - -mkdir -p "${VCPKG_CACHE}" - -COMMAND="set -euo pipefail; \ -unset VCPKG_ROOT VCPKG_BINARY_SOURCES \ - DEPENDENCES_ROOT FETCHCONTENT_SOURCE_DIR_VCPKG CMAKE_TOOLCHAIN_FILE -export VCPKG_DEFAULT_BINARY_CACHE=/root/.cache/vcpkg/archives -export VCPKG_DOWNLOADS=/root/.cache/vcpkg/downloads -$*" -BUILD_JOBS="${MAX_JOBS:-16}" -MUSA_DEVICE_MASK="${MUSA_VISIBLE_DEVICES:-0}" - -RUN_OPTS=( - --rm - --privileged - --runtime=mthreads - --ipc=host - --network=host - --ulimit memlock=-1 - --env "GITHUB_WORKSPACE=${WORKDIR}" - --env "MAX_JOBS=${BUILD_JOBS}" - --env "MUSA_VISIBLE_DEVICES=${MUSA_DEVICE_MASK}" - --env "XLLM_HOST_GID=$(id -g)" - --env "XLLM_HOST_UID=$(id -u)" - --volume "${WORKDIR}:${WORKDIR}" - --volume "${VCPKG_CACHE}:/root/.cache/vcpkg" - --workdir "${WORKDIR}" - --entrypoint /usr/local/bin/run-xllm-musa-ci -) - -docker run "${RUN_OPTS[@]}" "${IMAGE}" run "${COMMAND}" +docker run \ + --rm \ + --runtime=mthreads \ + --network=host \ + --env "GITHUB_WORKSPACE=${PWD}" \ + --env MAX_JOBS=16 \ + --env "XLLM_HOST_GID=$(id -g)" \ + --env "XLLM_HOST_UID=$(id -u)" \ + --volume "${PWD}:${PWD}" \ + --volume /export/home/musa_vcpkg_cache:/root/.cache/vcpkg \ + --workdir "${PWD}" \ + --entrypoint /usr/local/bin/run-xllm-musa-ci \ + "${IMAGE}" run "$*" From 3f589ddf12b991b3fcd6b673ef71979d732784e2 Mon Sep 17 00:00:00 2001 From: mccxadmin Date: Fri, 21 Aug 2026 14:53:48 +0800 Subject: [PATCH 11/14] build(musa): simplify CI workflow Remove unused job state, default checkout options, duplicate build conditions and timeouts, and no-op setup commands. Skip the diff checkout for trusted push and manual events while retaining the sensitive-file approval gate, current-head review validation, persistent-runner submodule cleanup, and recursive checkout. --- .github/workflows/build_x86_64_musa.yaml | 77 ++++++++---------------- 1 file changed, 26 insertions(+), 51 deletions(-) diff --git a/.github/workflows/build_x86_64_musa.yaml b/.github/workflows/build_x86_64_musa.yaml index 0ff88b84fd..5e02296b2d 100644 --- a/.github/workflows/build_x86_64_musa.yaml +++ b/.github/workflows/build_x86_64_musa.yaml @@ -26,7 +26,6 @@ on: - '*.yml' pull_request: branches: [main] - types: [opened, synchronize, reopened] paths-ignore: - 'docs/**' - 'tools/**' @@ -39,22 +38,18 @@ on: permissions: contents: read -env: - JOBNAME: xllm-x86_64-musa-cibuild-${{ github.run_id }} - concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} jobs: - # Review changes to executable CI inputs before using the privileged runner. check-sensitive: runs-on: [xllm-cpu-only-cicd] outputs: - requires_approval: ${{ steps.check_sensitive.outputs.requires_approval }} do_build: ${{ steps.decide.outputs.do_build }} steps: - name: Checkout code + if: github.event_name == 'pull_request' || github.event_name == 'pull_request_review' uses: actions/checkout@v4 with: fetch-depth: 0 @@ -63,66 +58,54 @@ jobs: - name: Check if sensitive files were changed id: check_sensitive - shell: bash + if: github.event_name == 'pull_request' || github.event_name == 'pull_request_review' run: | requires_approval=false - event="${{ github.event_name }}" - if [[ "${event}" == "pull_request" || - "${event}" == "pull_request_review" ]]; then - changed_files="$( - git diff --name-only \ - "${{ github.event.pull_request.base.sha }}" \ - "${{ github.event.pull_request.head.sha }}" - )" - while IFS= read -r changed_file; do - case "${changed_file}" in - .github/**|cibuild/**|setup.py|examples/generate.py) - requires_approval=true - break - ;; - esac - done <<< "${changed_files}" - fi + while IFS= read -r changed_file; do + case "${changed_file}" in + .github/**|cibuild/**|setup.py|examples/generate.py) + requires_approval=true + break + ;; + esac + done < <( + git diff --name-only \ + "${{ github.event.pull_request.base.sha }}" \ + "${{ github.event.pull_request.head.sha }}" + ) echo "requires_approval=${requires_approval}" >> "${GITHUB_OUTPUT}" - name: Decide whether to build id: decide - shell: bash run: | event="${{ github.event_name }}" + requires_approval="${{ steps.check_sensitive.outputs.requires_approval }}" + do_build=false if [[ "${event}" == "workflow_dispatch" || "${event}" == "push" ]]; then - echo "do_build=true" >> "${GITHUB_OUTPUT}" - elif [[ "${event}" == "pull_request" ]]; then - if [[ "${{ steps.check_sensitive.outputs.requires_approval }}" == "true" ]]; then - echo "do_build=false" >> "${GITHUB_OUTPUT}" - else - echo "do_build=true" >> "${GITHUB_OUTPUT}" - fi + do_build=true + elif [[ "${event}" == "pull_request" && + "${requires_approval}" != "true" ]]; then + do_build=true elif [[ "${event}" == "pull_request_review" ]]; then association="${{ github.event.review.author_association }}" review_state="${{ github.event.review.state }}" review_commit="${{ github.event.review.commit_id }}" head_sha="${{ github.event.pull_request.head.sha }}" - if [[ "${{ steps.check_sensitive.outputs.requires_approval }}" == "true" && + if [[ "${requires_approval}" == "true" && "${review_state}" == "approved" && "${review_commit}" == "${head_sha}" && ("${association}" == "OWNER" || "${association}" == "MEMBER" || "${association}" == "COLLABORATOR") ]]; then - echo "do_build=true" >> "${GITHUB_OUTPUT}" - else - echo "do_build=false" >> "${GITHUB_OUTPUT}" + do_build=true fi - else - echo "do_build=false" >> "${GITHUB_OUTPUT}" fi + echo "do_build=${do_build}" >> "${GITHUB_OUTPUT}" build: needs: check-sensitive - if: > - (github.event_name == 'workflow_dispatch' || github.event_name == 'push') || - needs.check-sensitive.outputs.do_build == 'true' - runs-on: [self-hosted, xllm-musa-x86-cicd] + if: needs.check-sensitive.outputs.do_build == 'true' + runs-on: [xllm-musa-x86-cicd] timeout-minutes: 120 steps: - name: Prepare submodule checkout @@ -135,19 +118,11 @@ jobs: uses: actions/checkout@v4 timeout-minutes: 10 with: - clean: true - fetch-depth: 1 persist-credentials: false - ref: ${{ github.event.pull_request.merge_commit_sha || github.sha }} submodules: recursive - name: Clean submodules run: git submodule foreach --recursive git clean -ffdx - name: Build Python package - if: ${{ success() }} - timeout-minutes: 120 - run: | - chmod +x ./cibuild/build_musa.sh - bash ./cibuild/build_musa.sh \ - 'python setup.py build --device musa' + run: bash ./cibuild/build_musa.sh 'python setup.py build --device musa' From c3b20c28929a9dbb062400a2fce4dae1347230dc Mon Sep 17 00:00:00 2001 From: mccxadmin Date: Fri, 21 Aug 2026 16:12:36 +0800 Subject: [PATCH 12/14] build(musa): wire CMake to mcc_wrapper --- cibuild/build_musa.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/cibuild/build_musa.sh b/cibuild/build_musa.sh index b2102e3842..eccf8074f3 100755 --- a/cibuild/build_musa.sh +++ b/cibuild/build_musa.sh @@ -21,6 +21,7 @@ docker run \ --network=host \ --env "GITHUB_WORKSPACE=${PWD}" \ --env MAX_JOBS=16 \ + --env "CMAKE_ARGS=-DCMAKE_CUDA_COMPILER=/usr/local/musa/tools/musamapping/mcc_wrapper -DCMAKE_MODULE_PATH=/usr/local/musa/tools/musamapping/cmake/Modules" \ --env "XLLM_HOST_GID=$(id -g)" \ --env "XLLM_HOST_UID=$(id -u)" \ --volume "${PWD}:${PWD}" \ From 1643bfbb91035b51bb6d9f1010067337f6e2cd0e Mon Sep 17 00:00:00 2001 From: mccxadmin Date: Fri, 21 Aug 2026 20:46:56 +0800 Subject: [PATCH 13/14] build-musa-vcpkg-cache --- .github/workflows/build_x86_64_musa.yaml | 3 +++ cibuild/build_musa.sh | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_x86_64_musa.yaml b/.github/workflows/build_x86_64_musa.yaml index 5e02296b2d..1b458f748f 100644 --- a/.github/workflows/build_x86_64_musa.yaml +++ b/.github/workflows/build_x86_64_musa.yaml @@ -108,6 +108,9 @@ jobs: runs-on: [xllm-musa-x86-cicd] timeout-minutes: 120 steps: + - name: Prepare vcpkg cache + run: mkdir -p /export/home/musa_vcpkg_cache/archives /export/home/musa_vcpkg_cache/downloads + - name: Prepare submodule checkout run: | if [ -d .git/modules ]; then diff --git a/cibuild/build_musa.sh b/cibuild/build_musa.sh index eccf8074f3..f0478a09d1 100755 --- a/cibuild/build_musa.sh +++ b/cibuild/build_musa.sh @@ -13,7 +13,13 @@ # See the License for the specific language governing permissions and # limitations under the License. +set -e + IMAGE="registry.mthreads.com/presale/devtech/xllm:musa-cicd-20260820" +COMMAND="unset VCPKG_ROOT VCPKG_BINARY_SOURCES DEPENDENCES_ROOT FETCHCONTENT_SOURCE_DIR_VCPKG CMAKE_TOOLCHAIN_FILE +export VCPKG_DEFAULT_BINARY_CACHE=/root/.cache/vcpkg/archives +export VCPKG_DOWNLOADS=/root/.cache/vcpkg/downloads +$*" docker run \ --rm \ @@ -28,4 +34,4 @@ docker run \ --volume /export/home/musa_vcpkg_cache:/root/.cache/vcpkg \ --workdir "${PWD}" \ --entrypoint /usr/local/bin/run-xllm-musa-ci \ - "${IMAGE}" run "$*" + "${IMAGE}" run "${COMMAND}" From c981234de7f4cd15630377479b6d34b03de8c641 Mon Sep 17 00:00:00 2001 From: mccxadmin Date: Fri, 21 Aug 2026 21:03:25 +0800 Subject: [PATCH 14/14] build-musa-smhasher-warning --- third_party/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt index 6571ff2c58..5e4ca1598d 100644 --- a/third_party/CMakeLists.txt +++ b/third_party/CMakeLists.txt @@ -4,6 +4,10 @@ add_subdirectory(sentencepiece) add_subdirectory(minja) add_subdirectory(brpc) add_subdirectory(smhasher/src) +if(USE_MUSA AND TARGET SMHasherSupport) + # SMHasher uses the deprecated register storage class in SpeedTest.cpp. + target_compile_options(SMHasherSupport PRIVATE -Wno-register) +endif() add_subdirectory(cpprestsdk) if(USE_MUSA AND TARGET cpprest) # mcc_wrapper diagnoses signed conversions in cpprestsdk headers more