Skip to content

Commit 26651fc

Browse files
Michael YuanMichael Yuan
authored andcommitted
Use libtorch-releases for all Linux builds, add ARM64 CUDA (Jetson)
- All Linux variants download libtorch from second-state/libtorch-releases - All release tarballs bundle libtorch/ — no separate download at install time - Added ARM64 CUDA/Jetson build job (build-linux-arm-cuda) - x86 CUDA build now bundles libtorch instead of skipping it - install.sh: removed download_cuda_libtorch(), added ARM CUDA detection - README.md: updated build instructions with libtorch-releases URLs
1 parent 6a52223 commit 26651fc

4 files changed

Lines changed: 147 additions & 113 deletions

File tree

.github/workflows/ci-rust.yml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ jobs:
1010
timeout-minutes: 120
1111

1212
env:
13-
LIBTORCH_VERSION: "2.7.0"
1413
LIBTORCH_BYPASS_VERSION_CHECK: "1"
1514

1615
steps:
@@ -26,9 +25,9 @@ jobs:
2625
2726
- name: Download libtorch
2827
run: |
29-
wget -q "https://download.pytorch.org/libtorch/cpu/libtorch-cxx11-abi-shared-with-deps-${LIBTORCH_VERSION}%2Bcpu.zip" -O libtorch.zip
30-
unzip -q libtorch.zip
31-
rm libtorch.zip
28+
curl -Lo libtorch.tar.gz "https://github.com/second-state/libtorch-releases/releases/download/v2.7.1/libtorch-cxx11-abi-x86_64-2.7.1.tar.gz"
29+
tar xzf libtorch.tar.gz
30+
rm libtorch.tar.gz
3231
3332
- name: Set libtorch environment
3433
run: |

.github/workflows/release-rust.yml

Lines changed: 95 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ jobs:
1414
timeout-minutes: 60
1515

1616
env:
17-
LIBTORCH_VERSION: "2.7.0"
1817
LIBTORCH_BYPASS_VERSION_CHECK: "1"
1918

2019
steps:
@@ -30,9 +29,9 @@ jobs:
3029
3130
- name: Download libtorch
3231
run: |
33-
wget -q "https://download.pytorch.org/libtorch/cpu/libtorch-cxx11-abi-shared-with-deps-${LIBTORCH_VERSION}%2Bcpu.zip" -O libtorch.zip
34-
unzip -q libtorch.zip
35-
rm libtorch.zip
32+
curl -Lo libtorch.tar.gz "https://github.com/second-state/libtorch-releases/releases/download/v2.7.1/libtorch-cxx11-abi-x86_64-2.7.1.tar.gz"
33+
tar xzf libtorch.tar.gz
34+
rm libtorch.tar.gz
3635
3736
- name: Set libtorch environment
3837
run: |
@@ -51,13 +50,9 @@ jobs:
5150
run: |
5251
mkdir -p staging/qwen3-audio-api-linux-x86_64/lib
5352
54-
# Copy binary
5553
cp rust/target/release/qwen3-audio-api staging/qwen3-audio-api-linux-x86_64/
56-
57-
# Bundle libtorch
5854
cp -r libtorch staging/qwen3-audio-api-linux-x86_64/
5955
60-
# Bundle lame/opus shared libraries if dynamically linked
6156
for lib in mp3lame opus; do
6257
so_file=$(ldd rust/target/release/qwen3-audio-api | grep "lib${lib}" | awk '{print $3}')
6358
if [ -n "$so_file" ] && [ -f "$so_file" ]; then
@@ -66,16 +61,9 @@ jobs:
6661
fi
6762
done
6863
69-
# Set RPATH so binary finds bundled libs at runtime
7064
patchelf --set-rpath '$ORIGIN/lib:$ORIGIN/libtorch/lib' \
7165
staging/qwen3-audio-api-linux-x86_64/qwen3-audio-api
7266
73-
# Verify
74-
echo "=== Bundled libraries ==="
75-
ls -la staging/qwen3-audio-api-linux-x86_64/lib/ || echo "(no extra libs needed)"
76-
echo "=== RPATH ==="
77-
patchelf --print-rpath staging/qwen3-audio-api-linux-x86_64/qwen3-audio-api
78-
7967
tar -czf qwen3-audio-api-linux-x86_64.tar.gz -C staging qwen3-audio-api-linux-x86_64
8068
8169
- name: Upload artifact
@@ -89,9 +77,7 @@ jobs:
8977
timeout-minutes: 90
9078

9179
env:
92-
LIBTORCH_VERSION: "2.7.0"
9380
LIBTORCH_BYPASS_VERSION_CHECK: "1"
94-
CUDA_VERSION: "cu126"
9581

9682
steps:
9783
- uses: actions/checkout@v4
@@ -104,16 +90,24 @@ jobs:
10490
sudo apt-get update && sudo apt-get install -y cmake pkg-config \
10591
nasm libclang-dev libmp3lame-dev libopus-dev patchelf
10692
93+
- name: Install CUDA toolkit (for linking)
94+
run: |
95+
wget -q https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2404/x86_64/cuda-keyring_1.1-1_all.deb
96+
sudo dpkg -i cuda-keyring_1.1-1_all.deb
97+
sudo apt-get update
98+
sudo apt-get install -y cuda-toolkit-12-6
99+
107100
- name: Download libtorch (CUDA)
108101
run: |
109-
wget -q "https://download.pytorch.org/libtorch/${CUDA_VERSION}/libtorch-cxx11-abi-shared-with-deps-${LIBTORCH_VERSION}%2B${CUDA_VERSION}.zip" -O libtorch.zip
110-
unzip -q libtorch.zip
111-
rm libtorch.zip
102+
curl -Lo libtorch.tar.gz "https://github.com/second-state/libtorch-releases/releases/download/v2.7.1/libtorch-cxx11-abi-x86_64-cuda12.6-2.7.1.tar.gz"
103+
tar xzf libtorch.tar.gz
104+
rm libtorch.tar.gz
112105
113106
- name: Set libtorch environment
114107
run: |
115108
echo "LIBTORCH=$(pwd)/libtorch" >> $GITHUB_ENV
116-
echo "LD_LIBRARY_PATH=$(pwd)/libtorch/lib:$LD_LIBRARY_PATH" >> $GITHUB_ENV
109+
echo "LD_LIBRARY_PATH=$(pwd)/libtorch/lib:/usr/local/cuda/lib64:$LD_LIBRARY_PATH" >> $GITHUB_ENV
110+
echo "RUSTFLAGS=-C link-arg=-Wl,-rpath-link,$(pwd)/libtorch/lib -C link-arg=-Wl,-rpath-link,/usr/local/cuda/lib64" >> $GITHUB_ENV
117111
118112
- name: Force latest qwen3_tts and qwen3_asr from HEAD
119113
working-directory: rust
@@ -127,12 +121,9 @@ jobs:
127121
run: |
128122
mkdir -p staging/qwen3-audio-api-linux-x86_64-cuda/lib
129123
130-
# Copy binary
131124
cp rust/target/release/qwen3-audio-api staging/qwen3-audio-api-linux-x86_64-cuda/
125+
cp -r libtorch staging/qwen3-audio-api-linux-x86_64-cuda/
132126
133-
# Do NOT bundle libtorch — users provide their own CUDA libtorch at runtime
134-
135-
# Bundle lame/opus shared libraries if dynamically linked
136127
for lib in mp3lame opus; do
137128
so_file=$(ldd rust/target/release/qwen3-audio-api | grep "lib${lib}" | awk '{print $3}')
138129
if [ -n "$so_file" ] && [ -f "$so_file" ]; then
@@ -141,16 +132,9 @@ jobs:
141132
fi
142133
done
143134
144-
# Set RPATH so binary finds libtorch in a sibling directory at runtime
145135
patchelf --set-rpath '$ORIGIN/lib:$ORIGIN/libtorch/lib' \
146136
staging/qwen3-audio-api-linux-x86_64-cuda/qwen3-audio-api
147137
148-
# Verify
149-
echo "=== Bundled libraries ==="
150-
ls -la staging/qwen3-audio-api-linux-x86_64-cuda/lib/ || echo "(no extra libs needed)"
151-
echo "=== RPATH ==="
152-
patchelf --print-rpath staging/qwen3-audio-api-linux-x86_64-cuda/qwen3-audio-api
153-
154138
tar -czf qwen3-audio-api-linux-x86_64-cuda.tar.gz -C staging qwen3-audio-api-linux-x86_64-cuda
155139
156140
- name: Upload artifact
@@ -164,7 +148,6 @@ jobs:
164148
timeout-minutes: 60
165149

166150
env:
167-
LIBTORCH_VERSION: "2.7.1"
168151
LIBTORCH_BYPASS_VERSION_CHECK: "1"
169152

170153
steps:
@@ -180,7 +163,7 @@ jobs:
180163
181164
- name: Download libtorch
182165
run: |
183-
wget -q "https://github.com/second-state/libtorch-releases/releases/download/v${LIBTORCH_VERSION}/libtorch-cxx11-abi-aarch64-${LIBTORCH_VERSION}.tar.gz" -O libtorch.tar.gz
166+
curl -Lo libtorch.tar.gz "https://github.com/second-state/libtorch-releases/releases/download/v2.7.1/libtorch-cxx11-abi-aarch64-2.7.1.tar.gz"
184167
tar xzf libtorch.tar.gz
185168
rm libtorch.tar.gz
186169
@@ -201,13 +184,9 @@ jobs:
201184
run: |
202185
mkdir -p staging/qwen3-audio-api-linux-aarch64/lib
203186
204-
# Copy binary
205187
cp rust/target/release/qwen3-audio-api staging/qwen3-audio-api-linux-aarch64/
206-
207-
# Bundle libtorch
208188
cp -r libtorch staging/qwen3-audio-api-linux-aarch64/
209189
210-
# Bundle lame/opus shared libraries if dynamically linked
211190
for lib in mp3lame opus; do
212191
so_file=$(ldd rust/target/release/qwen3-audio-api | grep "lib${lib}" | awk '{print $3}')
213192
if [ -n "$so_file" ] && [ -f "$so_file" ]; then
@@ -216,16 +195,9 @@ jobs:
216195
fi
217196
done
218197
219-
# Set RPATH so binary finds bundled libs at runtime
220198
patchelf --set-rpath '$ORIGIN/lib:$ORIGIN/libtorch/lib' \
221199
staging/qwen3-audio-api-linux-aarch64/qwen3-audio-api
222200
223-
# Verify
224-
echo "=== Bundled libraries ==="
225-
ls -la staging/qwen3-audio-api-linux-aarch64/lib/ || echo "(no extra libs needed)"
226-
echo "=== RPATH ==="
227-
patchelf --print-rpath staging/qwen3-audio-api-linux-aarch64/qwen3-audio-api
228-
229201
tar -czf qwen3-audio-api-linux-aarch64.tar.gz -C staging qwen3-audio-api-linux-aarch64
230202
231203
- name: Upload artifact
@@ -234,6 +206,77 @@ jobs:
234206
name: linux-aarch64
235207
path: qwen3-audio-api-linux-aarch64.tar.gz
236208

209+
build-linux-arm-cuda:
210+
runs-on: ubuntu-24.04-arm
211+
timeout-minutes: 90
212+
213+
env:
214+
LIBTORCH_BYPASS_VERSION_CHECK: "1"
215+
216+
steps:
217+
- uses: actions/checkout@v4
218+
219+
- name: Install Rust toolchain
220+
uses: dtolnay/rust-toolchain@stable
221+
222+
- name: Install system dependencies
223+
run: |
224+
sudo apt-get update && sudo apt-get install -y cmake pkg-config \
225+
nasm libclang-dev libmp3lame-dev libopus-dev patchelf
226+
227+
- name: Install CUDA toolkit and BLAS (for linking)
228+
run: |
229+
wget -q https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2404/sbsa/cuda-keyring_1.1-1_all.deb
230+
sudo dpkg -i cuda-keyring_1.1-1_all.deb
231+
sudo apt-get update
232+
sudo apt-get install -y cuda-toolkit-12-6 libopenblas-dev
233+
234+
- name: Download libtorch (CUDA)
235+
run: |
236+
curl -Lo libtorch.tar.gz "https://github.com/second-state/libtorch-releases/releases/download/v2.7.1/libtorch-cxx11-abi-aarch64-cuda12.6-2.7.1.tar.gz"
237+
tar xzf libtorch.tar.gz
238+
rm libtorch.tar.gz
239+
240+
- name: Set libtorch environment
241+
run: |
242+
echo "LIBTORCH=$(pwd)/libtorch" >> $GITHUB_ENV
243+
echo "LD_LIBRARY_PATH=$(pwd)/libtorch/lib:/usr/local/cuda/lib64:$LD_LIBRARY_PATH" >> $GITHUB_ENV
244+
echo "RUSTFLAGS=-C link-arg=-Wl,-rpath-link,$(pwd)/libtorch/lib -C link-arg=-Wl,-rpath-link,/usr/local/cuda/lib64" >> $GITHUB_ENV
245+
246+
- name: Force latest qwen3_tts and qwen3_asr from HEAD
247+
working-directory: rust
248+
run: rm Cargo.lock
249+
250+
- name: Build
251+
working-directory: rust
252+
run: cargo build --release
253+
254+
- name: Package archive
255+
run: |
256+
mkdir -p staging/qwen3-audio-api-linux-aarch64-cuda/lib
257+
258+
cp rust/target/release/qwen3-audio-api staging/qwen3-audio-api-linux-aarch64-cuda/
259+
cp -r libtorch staging/qwen3-audio-api-linux-aarch64-cuda/
260+
261+
for lib in mp3lame opus; do
262+
so_file=$(ldd rust/target/release/qwen3-audio-api | grep "lib${lib}" | awk '{print $3}')
263+
if [ -n "$so_file" ] && [ -f "$so_file" ]; then
264+
echo "Bundling $so_file"
265+
cp "$so_file" staging/qwen3-audio-api-linux-aarch64-cuda/lib/
266+
fi
267+
done
268+
269+
patchelf --set-rpath '$ORIGIN/lib:$ORIGIN/libtorch/lib' \
270+
staging/qwen3-audio-api-linux-aarch64-cuda/qwen3-audio-api
271+
272+
tar -czf qwen3-audio-api-linux-aarch64-cuda.tar.gz -C staging qwen3-audio-api-linux-aarch64-cuda
273+
274+
- name: Upload artifact
275+
uses: actions/upload-artifact@v4
276+
with:
277+
name: linux-aarch64-cuda
278+
path: qwen3-audio-api-linux-aarch64-cuda.tar.gz
279+
237280
build-macos:
238281
runs-on: macos-14
239282
timeout-minutes: 60
@@ -271,11 +314,9 @@ jobs:
271314
272315
mkdir -p staging/qwen3-audio-api-macos-arm64/lib
273316
274-
# Bundle any dynamically linked lame/opus libs and fix paths
275317
for lib in mp3lame opus; do
276318
dylib_ref=$(otool -L "$BINARY" | grep "lib${lib}" | awk '{print $1}')
277319
if [ -n "$dylib_ref" ]; then
278-
# Find the actual dylib file
279320
dylib_file=$(echo "$dylib_ref" | sed 's|@rpath/||')
280321
if [ -f "$dylib_ref" ]; then
281322
dylib_file="$dylib_ref"
@@ -284,7 +325,6 @@ jobs:
284325
fi
285326
echo "Bundling $dylib_file (ref: $dylib_ref)"
286327
cp "$dylib_file" staging/qwen3-audio-api-macos-arm64/lib/
287-
# Rewrite the reference to use @executable_path/lib/
288328
install_name_tool -change "$dylib_ref" \
289329
"@executable_path/lib/$(basename $dylib_file)" "$BINARY"
290330
fi
@@ -293,12 +333,6 @@ jobs:
293333
cp "$BINARY" staging/qwen3-audio-api-macos-arm64/
294334
cp "$METALLIB" staging/qwen3-audio-api-macos-arm64/
295335
296-
# Verify
297-
echo "=== Final otool -L ==="
298-
otool -L staging/qwen3-audio-api-macos-arm64/qwen3-audio-api
299-
echo "=== Bundled libraries ==="
300-
ls -la staging/qwen3-audio-api-macos-arm64/lib/ || echo "(no extra libs needed)"
301-
302336
tar -czf qwen3-audio-api-macos-arm64.tar.gz -C staging qwen3-audio-api-macos-arm64
303337
304338
- name: Upload artifact
@@ -350,7 +384,7 @@ jobs:
350384
path: tokenizer-*.json
351385

352386
release:
353-
needs: [build-linux, build-linux-cuda, build-linux-arm, build-macos, generate-tokenizers]
387+
needs: [build-linux, build-linux-cuda, build-linux-arm, build-linux-arm-cuda, build-macos, generate-tokenizers]
354388
runs-on: ubuntu-latest
355389
permissions:
356390
contents: write
@@ -371,6 +405,11 @@ jobs:
371405
with:
372406
name: linux-aarch64
373407

408+
- name: Download Linux ARM CUDA artifact
409+
uses: actions/download-artifact@v4
410+
with:
411+
name: linux-aarch64-cuda
412+
374413
- name: Download macOS artifact
375414
uses: actions/download-artifact@v4
376415
with:
@@ -389,5 +428,6 @@ jobs:
389428
qwen3-audio-api-linux-x86_64.tar.gz
390429
qwen3-audio-api-linux-x86_64-cuda.tar.gz
391430
qwen3-audio-api-linux-aarch64.tar.gz
431+
qwen3-audio-api-linux-aarch64-cuda.tar.gz
392432
qwen3-audio-api-macos-arm64.tar.gz
393433
tokenizer-*.json

rust/README.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -293,20 +293,24 @@ cp target/release/build/qwen3_tts-*/out/lib/mlx.metallib target/release/
293293

294294
#### Download libtorch
295295

296-
Download and extract libtorch for your platform:
296+
Download and extract libtorch for your platform from [libtorch-releases](https://github.com/second-state/libtorch-releases/releases/tag/v2.7.1):
297297

298298
```bash
299299
# Linux x86_64 (CPU)
300-
curl -LO https://download.pytorch.org/libtorch/cpu/libtorch-cxx11-abi-shared-with-deps-2.7.1%2Bcpu.zip
301-
unzip libtorch-cxx11-abi-shared-with-deps-2.7.1+cpu.zip
300+
curl -LO https://github.com/second-state/libtorch-releases/releases/download/v2.7.1/libtorch-cxx11-abi-x86_64-2.7.1.tar.gz
301+
tar xzf libtorch-cxx11-abi-x86_64-2.7.1.tar.gz
302302

303303
# Linux x86_64 (CUDA 12.6)
304-
curl -LO https://download.pytorch.org/libtorch/cu126/libtorch-cxx11-abi-shared-with-deps-2.7.0%2Bcu126.zip
305-
unzip libtorch-cxx11-abi-shared-with-deps-2.7.0+cu126.zip
304+
curl -LO https://github.com/second-state/libtorch-releases/releases/download/v2.7.1/libtorch-cxx11-abi-x86_64-cuda12.6-2.7.1.tar.gz
305+
tar xzf libtorch-cxx11-abi-x86_64-cuda12.6-2.7.1.tar.gz
306306

307307
# Linux aarch64 (CPU)
308308
curl -LO https://github.com/second-state/libtorch-releases/releases/download/v2.7.1/libtorch-cxx11-abi-aarch64-2.7.1.tar.gz
309309
tar xzf libtorch-cxx11-abi-aarch64-2.7.1.tar.gz
310+
311+
# Linux aarch64 (CUDA 12.6 / Jetson)
312+
curl -LO https://github.com/second-state/libtorch-releases/releases/download/v2.7.1/libtorch-cxx11-abi-aarch64-cuda12.6-2.7.1.tar.gz
313+
tar xzf libtorch-cxx11-abi-aarch64-cuda12.6-2.7.1.tar.gz
310314
```
311315

312316
#### Set environment variables

0 commit comments

Comments
 (0)