build.yml 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
  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. # Enable sccache GitHub Actions cache
  25. SCCACHE_GHA_ENABLED: "true"
  26. jobs:
  27. # ===========================================================================
  28. # Prepare: Generate test data (runs once, shared via artifacts)
  29. # ===========================================================================
  30. prepare-test-data:
  31. runs-on: ubuntu-latest
  32. steps:
  33. - name: Checkout
  34. uses: actions/checkout@v4
  35. - name: Setup Python
  36. uses: actions/setup-python@v5
  37. with:
  38. python-version: '3.11'
  39. - name: Clone MSST Repository
  40. run: git clone --depth 1 ${{ env.MSST_REPO }} msst
  41. - name: Install Dependencies
  42. run: |
  43. pip install torch torchaudio --index-url https://download.pytorch.org/whl/cpu
  44. pip install huggingface_hub scipy soundfile gguf librosa ml_collections einops pyyaml numpy tqdm beartype rotary_embedding_torch
  45. - name: Download Model from HuggingFace
  46. env:
  47. HF_TOKEN: ${{ secrets.HF_TOKEN }}
  48. run: |
  49. python -c "
  50. from huggingface_hub import hf_hub_download
  51. import os
  52. token = os.environ.get('HF_TOKEN') or None
  53. hf_hub_download('${{ env.HF_MODEL_REPO }}', '${{ env.HF_CHECKPOINT_PATH }}',
  54. local_dir='./model', token=token)
  55. hf_hub_download('${{ env.HF_MODEL_REPO }}', '${{ env.HF_CONFIG_PATH }}',
  56. local_dir='./model', token=token)
  57. "
  58. - name: Generate Test Audio
  59. run: |
  60. python scripts/generate_test_audio.py --output test_audio.wav --duration 5.0 --sample-rate 44100
  61. - name: Generate Test Data
  62. run: |
  63. python scripts/generate_test_data.py \
  64. --model-repo msst \
  65. --audio test_audio.wav \
  66. --checkpoint model/${{ env.HF_CHECKPOINT_PATH }} \
  67. --config model/${{ env.HF_CONFIG_PATH }} \
  68. --output test_data
  69. - name: Convert Model to GGUF
  70. run: |
  71. python scripts/convert_to_gguf.py \
  72. --ckpt model/${{ env.HF_CHECKPOINT_PATH }} \
  73. --config model/${{ env.HF_CONFIG_PATH }} \
  74. --out model.gguf \
  75. --dtype fp32
  76. - name: Upload Test Data Artifact
  77. uses: actions/upload-artifact@v4
  78. with:
  79. name: test-data
  80. path: |
  81. test_data/
  82. model.gguf
  83. test_audio.wav
  84. retention-days: 1
  85. # ===========================================================================
  86. # Build Matrix: Core Platforms + Vulkan
  87. # ===========================================================================
  88. build:
  89. needs: prepare-test-data
  90. strategy:
  91. fail-fast: false
  92. matrix:
  93. include:
  94. # Tier 1: Core Platforms (CPU)
  95. - { name: linux-x64-cpu, os: ubuntu-22.04, backend: cpu, test: true }
  96. - { name: linux-arm64-cpu, os: ubuntu-22.04-arm, backend: cpu, test: true }
  97. - { name: macos-arm64, os: macos-latest, backend: cpu, test: true }
  98. - { name: macos-x64, os: macos-15-intel, backend: cpu, test: true }
  99. - { name: windows-x64-msvc, os: windows-2025, backend: cpu, test: true }
  100. # Tier 2: Vulkan Backend
  101. - { name: linux-vulkan, os: ubuntu-24.04, backend: vulkan, test: true }
  102. - { name: windows-vulkan, os: windows-2025, backend: vulkan, test: true }
  103. runs-on: ${{ matrix.os }}
  104. steps:
  105. - name: Checkout
  106. uses: actions/checkout@v4
  107. - name: Clone GGML
  108. run: git clone --depth 1 https://github.com/ggerganov/ggml.git ggml
  109. - name: Download Test Data
  110. uses: actions/download-artifact@v4
  111. with:
  112. name: test-data
  113. - name: Setup Python
  114. uses: actions/setup-python@v5
  115. with:
  116. python-version: '3.11'
  117. - name: Setup MSVC
  118. if: runner.os == 'Windows'
  119. uses: ilammy/msvc-dev-cmd@v1
  120. - name: Install Python Dependencies
  121. run: pip install numpy scipy
  122. - name: Setup sccache
  123. uses: mozilla-actions/sccache-action@v0.0.9
  124. # ----- Linux Dependencies -----
  125. - name: Install Dependencies (Linux)
  126. if: runner.os == 'Linux'
  127. run: |
  128. sudo apt-get update
  129. sudo apt-get install -y build-essential cmake
  130. - name: Install Vulkan SDK (Linux)
  131. if: matrix.backend == 'vulkan' && runner.os == 'Linux'
  132. run: |
  133. sudo apt-get install -y libvulkan-dev glslc mesa-vulkan-drivers
  134. # ----- macOS Dependencies -----
  135. - name: Install Dependencies (macOS)
  136. if: runner.os == 'macOS'
  137. run: brew install cmake
  138. # ----- Windows Dependencies -----
  139. - name: Install Dependencies (Windows)
  140. if: runner.os == 'Windows'
  141. run: choco install ninja -y
  142. - name: Install Vulkan SDK (Windows)
  143. if: matrix.backend == 'vulkan' && runner.os == 'Windows'
  144. run: |
  145. $VK_VERSION = "1.4.313.2"
  146. curl.exe -o VulkanSDK.exe -L "https://sdk.lunarg.com/sdk/download/${VK_VERSION}/windows/vulkansdk-windows-X64-${VK_VERSION}.exe"
  147. Start-Process -FilePath .\VulkanSDK.exe -ArgumentList "--accept-licenses --default-answer --confirm-command install" -Wait
  148. Add-Content $env:GITHUB_ENV "VULKAN_SDK=C:\VulkanSDK\${VK_VERSION}"
  149. Add-Content $env:GITHUB_PATH "C:\VulkanSDK\${VK_VERSION}\bin"
  150. # ----- Configure -----
  151. - name: Configure (Unix)
  152. if: runner.os != 'Windows'
  153. run: |
  154. cmake -B build \
  155. -DCMAKE_BUILD_TYPE=Release \
  156. -DGGML_DIR=ggml \
  157. -DGGML_CUDA=OFF \
  158. -DGGML_VULKAN=${{ matrix.backend == 'vulkan' && 'ON' || 'OFF' }} \
  159. -DCMAKE_C_COMPILER_LAUNCHER=sccache \
  160. -DCMAKE_CXX_COMPILER_LAUNCHER=sccache \
  161. -DMBR_BUILD_TESTS=ON \
  162. -DMBR_BUILD_CLI=ON
  163. - name: Configure (Windows)
  164. if: runner.os == 'Windows'
  165. run: |
  166. cmake -B build -G "Ninja Multi-Config" `
  167. -DGGML_DIR=ggml `
  168. -DGGML_CUDA=OFF `
  169. -DGGML_VULKAN=${{ matrix.backend == 'vulkan' && 'ON' || 'OFF' }} `
  170. -DCMAKE_C_COMPILER_LAUNCHER=sccache `
  171. -DCMAKE_CXX_COMPILER_LAUNCHER=sccache `
  172. -DMBR_BUILD_TESTS=ON `
  173. -DMBR_BUILD_CLI=ON
  174. # ----- Build -----
  175. - name: Build (Unix)
  176. if: runner.os != 'Windows'
  177. run: cmake --build build --config Release -j $(nproc 2>/dev/null || sysctl -n hw.logicalcpu)
  178. - name: Build (Windows)
  179. if: runner.os == 'Windows'
  180. run: cmake --build build --config Release -j $env:NUMBER_OF_PROCESSORS
  181. # ----- Unit Tests -----
  182. - name: Run Unit Tests
  183. if: matrix.test
  184. env:
  185. MBR_MODEL_PATH: ${{ github.workspace }}/model.gguf
  186. MBR_TEST_DATA_DIR: ${{ github.workspace }}/test_data
  187. MBR_FORCE_CPU: ${{ runner.os == 'macOS' && '1' || '' }}
  188. run: ctest --test-dir build -C Release -V --output-on-failure --timeout 300
  189. # ----- CLI Tests -----
  190. - name: Test CLI
  191. if: matrix.test
  192. shell: bash
  193. env:
  194. MBR_MODEL_PATH: ${{ github.workspace }}/model.gguf
  195. MBR_FORCE_CPU: ${{ runner.os == 'macOS' && '1' || '' }}
  196. run: |
  197. echo "=== CLI Test Suite ==="
  198. # Dynamically find CLI executable
  199. CLI_NAME="mel_band_roformer-cli"
  200. if [[ "$RUNNER_OS" == "Windows" ]]; then CLI_NAME="mel_band_roformer-cli.exe"; fi
  201. echo "Searching for $CLI_NAME..."
  202. CLI_PATH=$(find build -name "$CLI_NAME" | head -n 1)
  203. if [[ -z "$CLI_PATH" ]]; then
  204. echo "Error: CLI executable not found!"
  205. find build
  206. exit 1
  207. fi
  208. echo "Found CLI at: $CLI_PATH"
  209. chmod +x "$CLI_PATH"
  210. # Setup execution variables
  211. CLI_DIR=$(dirname "$CLI_PATH")
  212. CLI_EXE="./$CLI_NAME"
  213. # Debug Info
  214. echo "Debug: Listing directory $CLI_DIR"
  215. ls -l "$CLI_DIR"
  216. echo "Debug: Checking dependencies"
  217. if command -v ldd >/dev/null; then
  218. ldd "$CLI_PATH" || echo "ldd returned error"
  219. fi
  220. # Define runner helper
  221. run_cli() {
  222. echo "Executing: ./$CLI_NAME $@"
  223. (cd "$CLI_DIR" && ./$CLI_NAME "$@")
  224. }
  225. # Debug PATH
  226. echo "PATH: $PATH"
  227. # 1. Test --help
  228. echo "[1/4] Testing --help..."
  229. run_cli --help
  230. # 2. Test with missing arguments (should fail)
  231. echo "[2/4] Testing error handling..."
  232. if run_cli 2>/dev/null; then
  233. echo "ERROR: CLI should fail without arguments"
  234. exit 1
  235. fi
  236. # 3. Use existing test audio
  237. echo "[3/4] Using generated test audio..."
  238. cp test_audio.wav cli_test_input.wav
  239. # 4. Run full inference
  240. echo "[4/4] Running inference..."
  241. # Use absolute paths for input/output to avoid directory issues
  242. ABS_MODEL=$(readlink -f "$MBR_MODEL_PATH" || echo "$(pwd)/model.gguf")
  243. ABS_INPUT=$(readlink -f cli_test_input.wav || echo "$(pwd)/cli_test_input.wav")
  244. ABS_OUTPUT=$(readlink -f cli_test_output.wav || echo "$(pwd)/cli_test_output.wav")
  245. # Convert paths for Windows MSVC executables
  246. if [[ "$RUNNER_OS" == "Windows" ]]; then
  247. ABS_MODEL=$(cygpath -w "$ABS_MODEL")
  248. ABS_INPUT=$(cygpath -w "$ABS_INPUT")
  249. ABS_OUTPUT=$(cygpath -w "$ABS_OUTPUT")
  250. fi
  251. echo "Running with model: $ABS_MODEL"
  252. run_cli "$ABS_MODEL" "$ABS_INPUT" "$ABS_OUTPUT" --chunk-size 88200 --overlap 2
  253. # Verify output exists and has reasonable size
  254. if [[ ! -f cli_test_output.wav ]]; then
  255. echo "ERROR: Output file not created"
  256. exit 1
  257. fi
  258. OUTPUT_SIZE=$(stat -c%s cli_test_output.wav 2>/dev/null || stat -f%z cli_test_output.wav)
  259. if [[ $OUTPUT_SIZE -lt 1000 ]]; then
  260. echo "ERROR: Output file too small: $OUTPUT_SIZE bytes"
  261. exit 1
  262. fi
  263. echo "=== CLI Tests Passed ==="
  264. # ----- Upload Artifacts -----
  265. - name: Upload Build Artifacts
  266. uses: actions/upload-artifact@v4
  267. with:
  268. name: build-${{ matrix.name }}
  269. path: |
  270. build/bin/
  271. build/lib*/
  272. build/*.dll
  273. build/*.so
  274. build/*.dylib
  275. build/mel_band_roformer-cli*
  276. build/Release/
  277. retention-days: 7
  278. # ----- Prepare Release Artifact -----
  279. - name: Prepare Release Artifact (Unix)
  280. if: runner.os != 'Windows'
  281. shell: bash
  282. run: |
  283. # Create release directory
  284. mkdir -p release/mel-band-roformer
  285. # Find and copy CLI executable
  286. CLI_PATH=$(find build -name "mel_band_roformer-cli" -type f | head -n 1)
  287. if [[ -n "$CLI_PATH" ]]; then
  288. cp "$CLI_PATH" release/mel-band-roformer/
  289. chmod +x release/mel-band-roformer/mel_band_roformer-cli
  290. fi
  291. # Copy shared libraries if exist (only real files, not symlinks)
  292. find build \( -name "*.so*" -o -name "*.dylib" \) -type f ! -type l | while read lib; do
  293. cp "$lib" release/mel-band-roformer/ 2>/dev/null || true
  294. done
  295. # List contents
  296. echo "Release artifact contents:"
  297. ls -lh release/mel-band-roformer/
  298. - name: Prepare Release Artifact (Windows)
  299. if: runner.os == 'Windows'
  300. shell: pwsh
  301. run: |
  302. # Create release directory
  303. New-Item -ItemType Directory -Force -Path "release\mel-band-roformer"
  304. # Find and copy CLI executable
  305. $CliPath = Get-ChildItem -Path build -Filter "mel_band_roformer-cli.exe" -Recurse -File | Select-Object -First 1
  306. if ($CliPath) {
  307. Copy-Item $CliPath.FullName "release\mel-band-roformer\"
  308. }
  309. # Copy DLL files
  310. Get-ChildItem -Path build -Filter "*.dll" -Recurse -File | ForEach-Object {
  311. Copy-Item $_.FullName "release\mel-band-roformer\" -ErrorAction SilentlyContinue
  312. }
  313. # List contents
  314. Write-Host "Release artifact contents:"
  315. Get-ChildItem "release\mel-band-roformer" | Format-Table Name, Length
  316. - name: Upload Release Artifact
  317. uses: actions/upload-artifact@v4
  318. with:
  319. name: MelBandRoformer-${{ matrix.name }}
  320. path: release/mel-band-roformer/
  321. retention-days: 30
  322. # ===========================================================================
  323. # CUDA Build: Linux (Compile Verification Only)
  324. # ===========================================================================
  325. build-cuda-linux:
  326. name: build-cuda-linux-${{ matrix.cuda_version }}
  327. runs-on: ${{ matrix.os }}
  328. strategy:
  329. fail-fast: false
  330. matrix:
  331. include:
  332. - { cuda_version: "11.8.0", os: ubuntu-22.04 }
  333. - { cuda_version: "12.9.1", os: ubuntu-latest }
  334. - { cuda_version: "13.1.0", os: ubuntu-latest }
  335. steps:
  336. - name: Checkout
  337. uses: actions/checkout@v4
  338. - name: Clone GGML
  339. run: git clone --depth 1 https://github.com/ggerganov/ggml.git ggml
  340. - name: Install CUDA Toolkit
  341. uses: Jimver/cuda-toolkit@master
  342. with:
  343. cuda: ${{ matrix.cuda_version }}
  344. method: network
  345. sub-packages: '["nvcc", "cudart", "thrust"]'
  346. non-cuda-sub-packages: '["libcublas", "libcublas-dev"]'
  347. - name: Install Dependencies
  348. run: |
  349. sudo apt-get install -y cmake build-essential ninja-build
  350. - name: Setup sccache
  351. uses: mozilla-actions/sccache-action@v0.0.9
  352. - name: Configure
  353. run: |
  354. ls -ld ggml
  355. # Minimal architectures for compile verification
  356. # Just verify compilation works, not for distribution
  357. CUDA_ARCHS="75;86"
  358. echo "Verifying build for CUDA architectures: $CUDA_ARCHS"
  359. cmake -B build -G Ninja \
  360. -DCMAKE_BUILD_TYPE=Release \
  361. -DGGML_DIR=ggml \
  362. -DGGML_CUDA=ON \
  363. -DGGML_CUDA_FORCE_MMQ=ON \
  364. -DCMAKE_CUDA_ARCHITECTURES="$CUDA_ARCHS" \
  365. -DCMAKE_C_COMPILER_LAUNCHER=sccache \
  366. -DCMAKE_CXX_COMPILER_LAUNCHER=sccache \
  367. -DCMAKE_CUDA_COMPILER_LAUNCHER=sccache \
  368. -DMBR_BUILD_TESTS=OFF \
  369. -DMBR_BUILD_CLI=ON
  370. - name: Build
  371. run: cmake --build build --config Release -j $(nproc)
  372. - name: Upload Artifacts
  373. uses: actions/upload-artifact@v4
  374. with:
  375. name: build-linux-cuda-${{ matrix.cuda_version }}
  376. path: |
  377. build/bin/
  378. build/lib*/
  379. build/*.so
  380. retention-days: 7
  381. # ----- Prepare Release Artifact -----
  382. - name: Prepare Release Artifact
  383. run: |
  384. # Create release directory
  385. mkdir -p release/mel-band-roformer
  386. # Find and copy CLI executable
  387. CLI_PATH=$(find build -name "mel_band_roformer-cli" -type f | head -n 1)
  388. if [[ -n "$CLI_PATH" ]]; then
  389. cp "$CLI_PATH" release/mel-band-roformer/
  390. chmod +x release/mel-band-roformer/mel_band_roformer-cli
  391. fi
  392. # Copy shared libraries
  393. find build -name "*.so*" | while read lib; do
  394. cp "$lib" release/mel-band-roformer/ 2>/dev/null || true
  395. done
  396. # List contents
  397. echo "Release artifact contents:"
  398. ls -lh release/mel-band-roformer/
  399. - name: Upload Release Artifact
  400. uses: actions/upload-artifact@v4
  401. with:
  402. name: MelBandRoformer-linux-cuda-${{ matrix.cuda_version }}
  403. path: release/mel-band-roformer/
  404. retention-days: 30
  405. # ===========================================================================
  406. # CUDA Build: Windows (Compile Only - No GPU for testing)
  407. # ===========================================================================
  408. build-cuda-windows:
  409. name: build-cuda-windows-${{ matrix.cuda_version }}
  410. runs-on: windows-2022
  411. strategy:
  412. fail-fast: false
  413. matrix:
  414. cuda_version: ["11.8.0", "12.9.1", "13.1.0"]
  415. env:
  416. CUDA_VERSION: ${{ matrix.cuda_version }}
  417. steps:
  418. - name: Checkout
  419. uses: actions/checkout@v4
  420. - name: Setup MSVC
  421. if: runner.os == 'Windows'
  422. uses: ilammy/msvc-dev-cmd@v1
  423. - name: Clone GGML
  424. run: git clone --depth 1 https://github.com/ggerganov/ggml.git ggml
  425. - name: Install CUDA Toolkit
  426. if: ${{ matrix.cuda_version != '13.1.0' }}
  427. uses: Jimver/cuda-toolkit@master
  428. with:
  429. cuda: ${{ matrix.cuda_version }}
  430. method: network
  431. sub-packages: '["nvcc", "cudart", "cublas", "cublas_dev", "thrust", "visual_studio_integration"]'
  432. - name: Install CUDA Toolkit(13.1.0)
  433. if: ${{ matrix.cuda_version == '13.1.0' }}
  434. uses: Jimver/cuda-toolkit@master
  435. with:
  436. cuda: ${{ matrix.cuda_version }}
  437. method: network
  438. sub-packages: '["nvcc", "cudart", "cublas", "cublas_dev", "nvrtc", "nvrtc_dev", "crt", "nvvm", "visual_studio_integration"]'
  439. - name: Install Ninja
  440. run: choco install ninja -y
  441. - name: Setup sccache
  442. uses: mozilla-actions/sccache-action@v0.0.9
  443. - name: Configure and Build
  444. shell: pwsh
  445. run: |
  446. # Consumer GPU architectures:
  447. # 61=Pascal (GTX 10), 75=Turing (RTX 20/GTX 16), 86=Ampere (RTX 30), 89=Ada (RTX 40), 120=Blackwell (RTX 50)
  448. $cudaVersion = "${{ matrix.cuda_version }}"
  449. if ($cudaVersion -match "^11\.") {
  450. # CUDA 11.x doesn't support arch 120
  451. $cudaArchs = "61;75;86;89"
  452. $env:CUDAFLAGS = "-allow-unsupported-compiler -D_ALLOW_COMPILER_AND_STL_VERSION_MISMATCH -D_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR"
  453. } else {
  454. # CUDA 12+: Add RTX 50 (Blackwell)
  455. $cudaArchs = "61;75;86;89;120"
  456. $env:CUDAFLAGS = ""
  457. }
  458. Write-Host "Building for CUDA architectures: $cudaArchs"
  459. cmake -B build -G "Ninja Multi-Config" `
  460. -DGGML_DIR=ggml `
  461. -DGGML_CUDA=ON `
  462. -DGGML_CUDA_FORCE_MMQ=ON `
  463. "-DCMAKE_CUDA_ARCHITECTURES=$cudaArchs" `
  464. -DCMAKE_C_COMPILER_LAUNCHER=sccache `
  465. -DCMAKE_CXX_COMPILER_LAUNCHER=sccache `
  466. -DCMAKE_CUDA_COMPILER_LAUNCHER=sccache `
  467. -DMBR_BUILD_TESTS=OFF `
  468. -DMBR_BUILD_CLI=ON
  469. cmake --build build --config Release -j $env:NUMBER_OF_PROCESSORS
  470. - name: Upload Artifacts
  471. uses: actions/upload-artifact@v4
  472. with:
  473. name: build-windows-cuda-${{ matrix.cuda_version }}
  474. path: |
  475. build/bin/
  476. build/Release/
  477. build/*.dll
  478. retention-days: 7
  479. # ----- Prepare Release Artifact -----
  480. - name: Prepare Release Artifact
  481. shell: pwsh
  482. run: |
  483. # Create release directory
  484. New-Item -ItemType Directory -Force -Path "release\mel-band-roformer"
  485. # Find and copy CLI executable
  486. $CliPath = Get-ChildItem -Path build -Filter "mel_band_roformer-cli.exe" -Recurse -File | Select-Object -First 1
  487. if ($CliPath) {
  488. Copy-Item $CliPath.FullName "release\mel-band-roformer\"
  489. }
  490. # Copy DLL files
  491. Get-ChildItem -Path build -Filter "*.dll" -Recurse -File | ForEach-Object {
  492. Copy-Item $_.FullName "release\mel-band-roformer\" -ErrorAction SilentlyContinue
  493. }
  494. # List contents
  495. Write-Host "Release artifact contents:"
  496. Get-ChildItem "release\mel-band-roformer" | Format-Table Name, Length
  497. - name: Upload Release Artifact
  498. uses: actions/upload-artifact@v4
  499. with:
  500. name: MelBandRoformer-windows-cuda-${{ matrix.cuda_version }}
  501. path: release\mel-band-roformer\
  502. retention-days: 30