build.yml 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. name: CI
  2. on:
  3. push:
  4. branches: [main, master]
  5. paths:
  6. - '**/*.cpp'
  7. - '**/*.h'
  8. - '**/*.hpp'
  9. - '**/CMakeLists.txt'
  10. - '.github/workflows/**'
  11. pull_request:
  12. types: [opened, synchronize, reopened]
  13. workflow_dispatch:
  14. concurrency:
  15. group: ${{ github.workflow }}-${{ github.head_ref && github.ref || github.run_id }}
  16. cancel-in-progress: true
  17. env:
  18. # HuggingFace model info
  19. HF_MODEL_REPO: GaboxR67/MelBandRoformers
  20. HF_CHECKPOINT_PATH: melbandroformers/vocals/voc_fv6.ckpt
  21. HF_CONFIG_PATH: melbandroformers/vocals/voc_gabox.yaml
  22. # Music-Source-Separation-Training repo
  23. MSST_REPO: https://github.com/ZFTurbo/Music-Source-Separation-Training.git
  24. jobs:
  25. # ===========================================================================
  26. # Prepare: Generate test data (runs once, shared via artifacts)
  27. # ===========================================================================
  28. prepare-test-data:
  29. runs-on: ubuntu-latest
  30. steps:
  31. - name: Checkout
  32. uses: actions/checkout@v4
  33. - name: Setup Python
  34. uses: actions/setup-python@v5
  35. with:
  36. python-version: '3.11'
  37. - name: Clone MSST Repository
  38. run: git clone --depth 1 ${{ env.MSST_REPO }} msst
  39. - name: Install Dependencies
  40. run: |
  41. pip install torch torchaudio --index-url https://download.pytorch.org/whl/cpu
  42. pip install huggingface_hub scipy soundfile gguf librosa ml_collections einops pyyaml numpy tqdm beartype rotary_embedding_torch
  43. - name: Download Model from HuggingFace
  44. env:
  45. HF_TOKEN: ${{ secrets.HF_TOKEN }}
  46. run: |
  47. python -c "
  48. from huggingface_hub import hf_hub_download
  49. import os
  50. token = os.environ.get('HF_TOKEN') or None
  51. hf_hub_download('${{ env.HF_MODEL_REPO }}', '${{ env.HF_CHECKPOINT_PATH }}',
  52. local_dir='./model', token=token)
  53. hf_hub_download('${{ env.HF_MODEL_REPO }}', '${{ env.HF_CONFIG_PATH }}',
  54. local_dir='./model', token=token)
  55. "
  56. - name: Generate Test Audio
  57. run: |
  58. python scripts/generate_test_audio.py --output test_audio.wav --duration 5.0 --sample-rate 44100
  59. - name: Generate Test Data
  60. run: |
  61. python scripts/generate_test_data.py \
  62. --model-repo msst \
  63. --audio test_audio.wav \
  64. --checkpoint model/${{ env.HF_CHECKPOINT_PATH }} \
  65. --config model/${{ env.HF_CONFIG_PATH }} \
  66. --output test_data
  67. - name: Convert Model to GGUF
  68. run: |
  69. python scripts/convert_to_gguf.py \
  70. --ckpt model/${{ env.HF_CHECKPOINT_PATH }} \
  71. --config model/${{ env.HF_CONFIG_PATH }} \
  72. --out model.gguf \
  73. --dtype fp32
  74. - name: Upload Test Data Artifact
  75. uses: actions/upload-artifact@v4
  76. with:
  77. name: test-data
  78. path: |
  79. test_data/
  80. model.gguf
  81. test_audio.wav
  82. retention-days: 1
  83. # ===========================================================================
  84. # Build Matrix: Core Platforms + Vulkan
  85. # ===========================================================================
  86. build:
  87. needs: prepare-test-data
  88. strategy:
  89. fail-fast: false
  90. matrix:
  91. include:
  92. # Tier 1: Core Platforms (CPU)
  93. - { name: linux-x64-cpu, os: ubuntu-22.04, backend: cpu, test: true }
  94. - { name: linux-arm64-cpu, os: ubuntu-22.04-arm, backend: cpu, test: true }
  95. - { name: macos-arm64, os: macos-latest, backend: cpu, test: true }
  96. - { name: macos-x64, os: macos-15-intel, backend: cpu, test: true }
  97. - { name: windows-x64-msvc, os: windows-2025, backend: cpu, test: true }
  98. # Tier 2: Vulkan Backend
  99. - { name: linux-vulkan, os: ubuntu-24.04, backend: vulkan, test: true }
  100. - { name: windows-vulkan, os: windows-2025, backend: vulkan, test: true }
  101. runs-on: ${{ matrix.os }}
  102. steps:
  103. - name: Checkout
  104. uses: actions/checkout@v4
  105. - name: Clone GGML
  106. run: git clone --depth 1 https://github.com/ggerganov/ggml.git ggml
  107. - name: Download Test Data
  108. uses: actions/download-artifact@v4
  109. with:
  110. name: test-data
  111. - name: Setup Python
  112. uses: actions/setup-python@v5
  113. with:
  114. python-version: '3.11'
  115. - name: Install Python Dependencies
  116. run: pip install numpy scipy
  117. # ----- Linux Dependencies -----
  118. - name: Install Dependencies (Linux)
  119. if: runner.os == 'Linux'
  120. run: |
  121. sudo apt-get update
  122. sudo apt-get install -y build-essential cmake
  123. - name: Install Vulkan SDK (Linux)
  124. if: matrix.backend == 'vulkan' && runner.os == 'Linux'
  125. run: |
  126. sudo apt-get install -y libvulkan-dev glslc mesa-vulkan-drivers
  127. # ----- macOS Dependencies -----
  128. - name: Install Dependencies (macOS)
  129. if: runner.os == 'macOS'
  130. run: brew install cmake
  131. # ----- Windows Dependencies -----
  132. - name: Install Dependencies (Windows)
  133. if: runner.os == 'Windows'
  134. run: choco install ninja -y
  135. - name: Install Vulkan SDK (Windows)
  136. if: matrix.backend == 'vulkan' && runner.os == 'Windows'
  137. run: |
  138. $VK_VERSION = "1.4.313.2"
  139. curl.exe -o VulkanSDK.exe -L "https://sdk.lunarg.com/sdk/download/${VK_VERSION}/windows/vulkansdk-windows-X64-${VK_VERSION}.exe"
  140. Start-Process -FilePath .\VulkanSDK.exe -ArgumentList "--accept-licenses --default-answer --confirm-command install" -Wait
  141. Add-Content $env:GITHUB_ENV "VULKAN_SDK=C:\VulkanSDK\${VK_VERSION}"
  142. Add-Content $env:GITHUB_PATH "C:\VulkanSDK\${VK_VERSION}\bin"
  143. # ----- Configure -----
  144. - name: Configure (Unix)
  145. if: runner.os != 'Windows'
  146. run: |
  147. cmake -B build \
  148. -DCMAKE_BUILD_TYPE=Release \
  149. -DGGML_DIR=ggml \
  150. -DGGML_CUDA=OFF \
  151. -DGGML_VULKAN=${{ matrix.backend == 'vulkan' && 'ON' || 'OFF' }} \
  152. -DMBR_BUILD_TESTS=ON \
  153. -DMBR_BUILD_CLI=ON
  154. - name: Configure (Windows)
  155. if: runner.os == 'Windows'
  156. run: |
  157. cmake -B build -G "Ninja Multi-Config" `
  158. -DGGML_DIR=ggml `
  159. -DGGML_CUDA=OFF `
  160. -DGGML_VULKAN=${{ matrix.backend == 'vulkan' && 'ON' || 'OFF' }} `
  161. -DMBR_BUILD_TESTS=ON `
  162. -DMBR_BUILD_CLI=ON
  163. # ----- Build -----
  164. - name: Build (Unix)
  165. if: runner.os != 'Windows'
  166. run: cmake --build build --config Release -j $(nproc 2>/dev/null || sysctl -n hw.logicalcpu)
  167. - name: Build (Windows)
  168. if: runner.os == 'Windows'
  169. run: cmake --build build --config Release -j $env:NUMBER_OF_PROCESSORS
  170. # ----- Unit Tests -----
  171. - name: Run Unit Tests
  172. if: matrix.test
  173. env:
  174. MBR_MODEL_PATH: ${{ github.workspace }}/model.gguf
  175. MBR_TEST_DATA_DIR: ${{ github.workspace }}/test_data
  176. MBR_FORCE_CPU: ${{ runner.os == 'macOS' && '1' || '' }}
  177. run: ctest --test-dir build -C Release --output-on-failure --timeout 300
  178. # ----- CLI Tests -----
  179. - name: Test CLI
  180. if: matrix.test
  181. shell: bash
  182. env:
  183. MBR_MODEL_PATH: ${{ github.workspace }}/model.gguf
  184. MBR_FORCE_CPU: ${{ runner.os == 'macOS' && '1' || '' }}
  185. run: |
  186. echo "=== CLI Test Suite ==="
  187. # Dynamically find CLI executable
  188. CLI_NAME="mel_band_roformer-cli"
  189. if [[ "$RUNNER_OS" == "Windows" ]]; then CLI_NAME="mel_band_roformer-cli.exe"; fi
  190. echo "Searching for $CLI_NAME..."
  191. CLI_PATH=$(find build -name "$CLI_NAME" | head -n 1)
  192. if [[ -z "$CLI_PATH" ]]; then
  193. echo "Error: CLI executable not found!"
  194. find build
  195. exit 1
  196. fi
  197. echo "Found CLI at: $CLI_PATH"
  198. chmod +x "$CLI_PATH"
  199. # Setup execution variables
  200. CLI_DIR=$(dirname "$CLI_PATH")
  201. CLI_EXE="./$CLI_NAME"
  202. # Debug Info
  203. echo "Debug: Listing directory $CLI_DIR"
  204. ls -l "$CLI_DIR"
  205. echo "Debug: Checking dependencies"
  206. if command -v ldd >/dev/null; then
  207. ldd "$CLI_PATH" || echo "ldd returned error"
  208. fi
  209. # Define runner helper
  210. run_cli() {
  211. if [[ "$RUNNER_OS" == "Windows" ]]; then
  212. WIN_EXE=$(cygpath -w "$CLI_PATH")
  213. cmd //c "$WIN_EXE" "$@"
  214. else
  215. (cd "$CLI_DIR" && ./$CLI_NAME "$@")
  216. fi
  217. }
  218. # 1. Test --help
  219. echo "[1/4] Testing --help..."
  220. run_cli --help
  221. # 2. Test with missing arguments (should fail)
  222. echo "[2/4] Testing error handling..."
  223. if run_cli 2>/dev/null; then
  224. echo "ERROR: CLI should fail without arguments"
  225. exit 1
  226. fi
  227. # 3. Use existing test audio
  228. echo "[3/4] Using generated test audio..."
  229. cp test_audio.wav cli_test_input.wav
  230. # 4. Run full inference
  231. echo "[4/4] Running inference..."
  232. # Use absolute paths for input/output to avoid directory issues
  233. ABS_MODEL=$(readlink -f "$MBR_MODEL_PATH" || echo "$(pwd)/model.gguf")
  234. ABS_INPUT=$(readlink -f cli_test_input.wav || echo "$(pwd)/cli_test_input.wav")
  235. ABS_OUTPUT=$(readlink -f cli_test_output.wav || echo "$(pwd)/cli_test_output.wav")
  236. # Convert paths for Windows MSVC executables
  237. if [[ "$RUNNER_OS" == "Windows" ]]; then
  238. ABS_MODEL=$(cygpath -w "$ABS_MODEL")
  239. ABS_INPUT=$(cygpath -w "$ABS_INPUT")
  240. ABS_OUTPUT=$(cygpath -w "$ABS_OUTPUT")
  241. fi
  242. echo "Running with model: $ABS_MODEL"
  243. run_cli "$ABS_MODEL" "$ABS_INPUT" "$ABS_OUTPUT" --chunk-size 88200 --overlap 2
  244. # Verify output exists and has reasonable size
  245. if [[ ! -f cli_test_output.wav ]]; then
  246. echo "ERROR: Output file not created"
  247. exit 1
  248. fi
  249. OUTPUT_SIZE=$(stat -c%s cli_test_output.wav 2>/dev/null || stat -f%z cli_test_output.wav)
  250. if [[ $OUTPUT_SIZE -lt 1000 ]]; then
  251. echo "ERROR: Output file too small: $OUTPUT_SIZE bytes"
  252. exit 1
  253. fi
  254. echo "=== CLI Tests Passed ==="
  255. # ----- Upload Artifacts -----
  256. - name: Upload Build Artifacts
  257. uses: actions/upload-artifact@v4
  258. with:
  259. name: build-${{ matrix.name }}
  260. path: |
  261. build/bin/
  262. build/lib*/
  263. build/*.dll
  264. build/*.so
  265. build/*.dylib
  266. build/mel_band_roformer-cli*
  267. build/Release/
  268. retention-days: 7
  269. # ===========================================================================
  270. # CUDA Build: Linux (Compile Only - No GPU for testing)
  271. # ===========================================================================
  272. build-cuda-linux:
  273. runs-on: ubuntu-latest
  274. container: nvidia/cuda:12.6.2-devel-ubuntu24.04
  275. steps:
  276. - name: Install Git
  277. run: |
  278. apt-get update
  279. apt-get install -y git
  280. - name: Checkout
  281. uses: actions/checkout@v4
  282. - name: Clone GGML
  283. run: git clone --depth 1 https://github.com/ggerganov/ggml.git ggml
  284. - name: Install Dependencies
  285. run: |
  286. apt-get install -y cmake build-essential ninja-build
  287. - name: Configure
  288. run: |
  289. ls -ld ggml
  290. cmake -B build -G Ninja \
  291. -DCMAKE_BUILD_TYPE=Release \
  292. -DGGML_DIR=ggml \
  293. -DGGML_CUDA=ON \
  294. -DCMAKE_CUDA_ARCHITECTURES="75;80;86;89" \
  295. -DMBR_BUILD_TESTS=OFF \
  296. -DMBR_BUILD_CLI=ON
  297. - name: Build
  298. run: cmake --build build --config Release -j $(nproc)
  299. - name: Upload Artifacts
  300. uses: actions/upload-artifact@v4
  301. with:
  302. name: build-linux-cuda
  303. path: |
  304. build/bin/
  305. build/lib*/
  306. build/*.so
  307. retention-days: 7
  308. # ===========================================================================
  309. # CUDA Build: Windows (Compile Only - No GPU for testing)
  310. # ===========================================================================
  311. build-cuda-windows:
  312. runs-on: windows-2022
  313. env:
  314. CUDA_VERSION: '12.4'
  315. steps:
  316. - name: Checkout
  317. uses: actions/checkout@v4
  318. - name: Clone GGML
  319. run: git clone --depth 1 https://github.com/ggerganov/ggml.git ggml
  320. - name: Install CUDA Toolkit
  321. run: |
  322. # For CI, use the official CUDA installer approach
  323. curl.exe -o cuda_installer.exe -L "https://developer.download.nvidia.com/compute/cuda/12.4.0/network_installers/cuda_12.4.0_windows_network.exe"
  324. Start-Process -FilePath .\cuda_installer.exe -ArgumentList "-s nvcc_12.4 cudart_12.4 cublas_12.4 cublas_dev_12.4 cufft_12.4 cufft_dev_12.4" -Wait -NoNewWindow
  325. Add-Content $env:GITHUB_ENV "CUDA_PATH=C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.4"
  326. Add-Content $env:GITHUB_PATH "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.4\bin"
  327. - name: Install Ninja
  328. run: choco install ninja -y
  329. - name: Configure and Build
  330. shell: cmd
  331. run: |
  332. call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
  333. cmake -B build -G "Ninja Multi-Config" ^
  334. -DGGML_DIR=ggml ^
  335. -DGGML_CUDA=ON ^
  336. -DCMAKE_CUDA_ARCHITECTURES="75;80;86;89" ^
  337. -DMBR_BUILD_TESTS=OFF ^
  338. -DMBR_BUILD_CLI=ON
  339. cmake --build build --config Release -j %NUMBER_OF_PROCESSORS%
  340. - name: Upload Artifacts
  341. uses: actions/upload-artifact@v4
  342. with:
  343. name: build-windows-cuda
  344. path: |
  345. build/bin/
  346. build/Release/
  347. build/*.dll
  348. retention-days: 7