diff --git a/.github/workflows/build-llamacpp-binaries.yml b/.github/workflows/build-llamacpp-binaries.yml index 0f46c69b6..18834dd83 100644 --- a/.github/workflows/build-llamacpp-binaries.yml +++ b/.github/workflows/build-llamacpp-binaries.yml @@ -82,13 +82,48 @@ jobs: -DGGML_FMA=ON -DGGML_F16C=ON -DGGML_BMI2=ON + - os: windows-latest + name: windows-x64-cuda + cuda: true + cuda_version: '13.2.0' + cuda_architectures: '86' + build_target: llama-funasr-sensevoice + timeout_minutes: 90 + cmake_flags: >- + -DGGML_NATIVE=OFF + -DGGML_CUDA=ON + -DGGML_CUDA_FORCE_CUBLAS=ON + -DGGML_CUDA_FA=OFF + -DGGML_CUDA_NCCL=OFF + -DGGML_CUDA_GRAPHS=OFF + -DGGML_AVX=OFF + -DGGML_AVX2=OFF + -DGGML_AVX_VNNI=OFF + -DGGML_AVX512=OFF + -DGGML_AVX512_VBMI=OFF + -DGGML_AVX512_VNNI=OFF + -DGGML_AVX512_BF16=OFF + -DGGML_FMA=OFF + -DGGML_F16C=OFF + -DGGML_BMI2=OFF runs-on: ${{ matrix.os }} + timeout-minutes: ${{ matrix.timeout_minutes || 30 }} defaults: run: shell: bash working-directory: runtime/llama.cpp steps: - uses: actions/checkout@v4 + - name: Install CUDA Toolkit + if: matrix.cuda + uses: Jimver/cuda-toolkit@v0.2.35 + with: + cuda: ${{ matrix.cuda_version }} + method: network + log-file-suffix: ${{ matrix.name }}.txt + - name: Show CUDA compiler + if: matrix.cuda + run: nvcc --version - name: Configure and build run: | # Release binaries must be portable across user machines, not tuned to @@ -96,8 +131,23 @@ jobs: # AVX-VNNI instructions and then crash with SIGILL on ordinary CPUs. # Keep the default x64 package conservative, and publish explicit # x64-avx2 assets for machines that support AVX2/FMA/F16C/BMI2. - cmake -B build -DCMAKE_BUILD_TYPE=Release ${{ matrix.cmake_flags }} - cmake --build build --config Release -j 2 + # The CUDA release asset is SenseVoiceSmall-specific for now; building + # only that target keeps the Windows CUDA job bounded and matches the + # backend currently exposed by `--backend cuda`. + cmake_args=( + -B build + -DCMAKE_BUILD_TYPE=Release + ${{ matrix.cmake_flags }} + ) + if [ -n "${{ matrix.cuda_architectures }}" ]; then + cmake_args+=("-DCMAKE_CUDA_ARCHITECTURES=${{ matrix.cuda_architectures }}") + fi + cmake "${cmake_args[@]}" + if [ -n "${{ matrix.build_target }}" ]; then + cmake --build build --config Release -j 2 --target "${{ matrix.build_target }}" + else + cmake --build build --config Release -j 2 + fi - name: Package run: | mkdir -p pkg @@ -135,4 +185,4 @@ jobs: gh release create "$tag" dist/* \ --repo "${{ github.repository }}" \ --title "FunASR llama.cpp runtime $version" \ - --notes "Prebuilt self-contained binaries for the FunASR llama.cpp / GGUF runtime: SenseVoice, Paraformer and Fun-ASR-Nano with built-in FSMN-VAD. Download the default quantized model with \`bash download-funasr-model.sh \` (the helper requires the Hugging Face CLI: \`pip install -U huggingface_hub\`), then run \`llama-funasr-cli\` / \`llama-funasr-sensevoice\` / \`llama-funasr-paraformer\`. Use the default x64 asset for maximum CPU compatibility; use the x64-avx2 asset on CPUs with AVX2/FMA/F16C/BMI2 for higher throughput. No Python ASR runtime or local build is required. Docs: $docs" + --notes "Prebuilt self-contained binaries for the FunASR llama.cpp / GGUF runtime: SenseVoice, Paraformer and Fun-ASR-Nano with built-in FSMN-VAD. Download the default quantized model with \`bash download-funasr-model.sh \` (the helper requires the Hugging Face CLI: \`pip install -U huggingface_hub\`), then run \`llama-funasr-cli\` / \`llama-funasr-sensevoice\` / \`llama-funasr-paraformer\`. Use the default x64 asset for maximum CPU compatibility; use the x64-avx2 asset on CPUs with AVX2/FMA/F16C/BMI2 for higher throughput. The Windows CUDA asset is \`windows-x64-cuda\`; it requires an NVIDIA driver compatible with the CUDA Toolkit version configured by the release workflow, targets CUDA architecture 86, and enables SenseVoiceSmall graph execution with \`llama-funasr-sensevoice ... --backend cuda\`. Build from source for other GPU architectures. No Python ASR runtime or local build is required. Docs: $docs" diff --git a/runtime/llama.cpp/CMakeLists.txt b/runtime/llama.cpp/CMakeLists.txt index 64ebad851..66fa28fd9 100644 --- a/runtime/llama.cpp/CMakeLists.txt +++ b/runtime/llama.cpp/CMakeLists.txt @@ -24,6 +24,9 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) endif() include(FetchContent) +if(POLICY CMP0169) + cmake_policy(SET CMP0169 OLD) +endif() set(LLAMA_BUILD_TESTS OFF CACHE BOOL "" FORCE) set(LLAMA_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) set(LLAMA_BUILD_TOOLS OFF CACHE BOOL "" FORCE) @@ -32,7 +35,11 @@ set(LLAMA_CURL OFF CACHE BOOL "" FORCE) FetchContent_Declare(llama GIT_REPOSITORY https://github.com/ggml-org/llama.cpp.git GIT_TAG 8086439a4cea94c71a5dfb8fe4ad1546aebd640f) -FetchContent_MakeAvailable(llama) +FetchContent_GetProperties(llama) +if(NOT llama_POPULATED) + FetchContent_Populate(llama) + add_subdirectory(${llama_SOURCE_DIR} ${llama_BINARY_DIR}) +endif() find_package(Threads REQUIRED) set(FUNASR_COMMON ${CMAKE_CURRENT_SOURCE_DIR}/funasr-common) diff --git a/runtime/llama.cpp/README.md b/runtime/llama.cpp/README.md index 1004000c0..c71605e32 100644 --- a/runtime/llama.cpp/README.md +++ b/runtime/llama.cpp/README.md @@ -72,9 +72,13 @@ cmake --build build-cuda -j --target llama-funasr-sensevoice -m sensevoice-small-f16.gguf -a sample.wav --backend cuda ``` -`--backend cpu` remains the default and is what the current cross-platform -prebuilt binaries use. A binary built without `-DGGML_CUDA=ON` exits with a clear -message if `--backend cuda` is requested. +`--backend cpu` remains the default and is what the portable cross-platform +prebuilt binaries use. Tagged runtime releases also publish a +`funasr-llamacpp-windows-x64-cuda.zip` package when the Windows CUDA release job +passes; it requires an NVIDIA driver compatible with the CUDA Toolkit version +configured by that release job and targets CUDA architecture 86. Build from source +for other GPU architectures. A binary built without `-DGGML_CUDA=ON` exits with a +clear message if `--backend cuda` is requested. ## Build (shared) ```bash diff --git a/runtime/llama.cpp/tests/test_release_workflow.py b/runtime/llama.cpp/tests/test_release_workflow.py new file mode 100644 index 000000000..18f749952 --- /dev/null +++ b/runtime/llama.cpp/tests/test_release_workflow.py @@ -0,0 +1,41 @@ +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[3] +WORKFLOW = ROOT / ".github" / "workflows" / "build-llamacpp-binaries.yml" + + +def test_windows_cuda_release_asset_is_in_matrix(): + workflow = WORKFLOW.read_text(encoding="utf-8") + + assert "name: windows-x64-cuda" in workflow + assert "cuda: true" in workflow + assert "windows-x64-cuda" in workflow + assert "cuda_architectures: '86'" in workflow + assert "build_target: llama-funasr-sensevoice" in workflow + assert "timeout_minutes: 90" in workflow + + +def test_windows_cuda_build_uses_cuda_toolkit_and_flags(): + workflow = WORKFLOW.read_text(encoding="utf-8") + + assert "Jimver/cuda-toolkit" in workflow + assert "if: matrix.cuda" in workflow + assert "-DGGML_CUDA=ON" in workflow + assert "-DGGML_CUDA_FORCE_CUBLAS=ON" in workflow + assert "-DGGML_CUDA_FA=OFF" in workflow + assert "-DGGML_CUDA_NCCL=OFF" in workflow + assert "CMAKE_CUDA_ARCHITECTURES=${{ matrix.cuda_architectures }}" in workflow + assert "cmake \"${cmake_args[@]}\"" in workflow + assert "--target \"${{ matrix.build_target }}\"" in workflow + + +def test_release_notes_explain_cpu_and_cuda_windows_assets(): + readme = (ROOT / "runtime" / "llama.cpp" / "README.md").read_text(encoding="utf-8") + + assert "windows-x64-cuda" in readme + assert "--backend cuda" in readme + assert "Windows CUDA" in readme + assert "CUDA architecture 86" in readme + assert "Build from source" in readme + assert "other GPU architectures" in readme