ci: unblock the release job's artifact download, parallelize xz, and slim the CUDA install - #25
Merged
Conversation
The release job has been cancelling mid-"Download artifacts" more often than not, which reads as a CUDA timeout but isn't: in runs 30341691913 and 30364671144 every build job succeeded and only `release` died, both times ~14 minutes into the download with 4 of 28 artifacts complete. Two causes: - `ubuntu-slim` is a container runner (the log reports "VM Image - Source: Docker, Name: ubuntu:24.04"), and it was being asked to hold ~14 GB of artifacts plus the transient zip each download extracts from. Move to a full ubuntu-24.04 VM. - actions/download-artifact starts every matched artifact concurrently. Its PARALLEL_DOWNLOADS chunking is ineffective because the promises are constructed eagerly in .map() before chunk() runs, so all 28 downloads begin within half a second. There is no concurrency input, so split the call into four pattern-scoped steps. The patterns partition the artifact list exactly: no unmatched and no double-matched names. A pattern matching nothing does not throw (only the `name` and `artifact-ids` paths do), so a dropped backend family still degrades into the existing completeness checks. Separately, `tar -cJf` drives a single-threaded xz and was the largest cost in the Linux CUDA jobs at ~6.8 min/leg, ~112 min per run across the 16 legs. Switch to `tar -I 'xz -T0'`. Measured on a 2.9 GB binary payload: 12m41s single-threaded vs 47.7s on 32 cores, with the archive 1.8% larger because threaded mode compresses independent blocks. The runners are 4-core, so expect roughly 3-4x there. This does not address the real long pole: ubuntu-22-rocm still runs 93-144 min while every CUDA leg finishes in 15-20, and `release` cannot start until it is done. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The Linux CUDA jobs installed the cuda-toolkit-12-9 metapackage, which pulls Nsight Systems, Nsight Compute, cuFFT, cuSPARSE, cuSOLVER and NPP along with the pieces ggml-cuda is actually compiled against. That is "Need to get 3935 MB of archives" on every one of the 16 Linux CUDA legs, none of it cached. Resolve the dependency closure by hand instead: nvcc, cudart-dev (which also supplies the libcuda.so stub behind CUDA::cuda_driver), cccl for the thrust/cub headers, and cublas/curand/nvjitlink -dev. That is 16 packages and ~1.2 GB against 61 packages and ~3.9 GB, and it still satisfies the Build, Bundle CUDA runtime libraries and Validate steps. None of the subset declares Recommends, so nothing sneaks back in. Add a post-install existence check over nvcc and the specific headers and libraries the later steps consume, so a repackaging upstream fails at the install step naming the missing file rather than partway through a compile. This matches what windows-cuda already does, where Jimver/cuda-toolkit is invoked with an explicit sub-packages list. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
kenvandine
commented
Jul 29, 2026
kenvandine
left a comment
Member
Author
There was a problem hiding this comment.
Summary of Review
This PR directly addresses the primary bottlenecks causing release job timeouts and cancellations in .github/workflows/release.yml.
Key Fixes Reviewed:
-
Release Job Environment & Download Batching:
- Moving
releasefromubuntu-slim(container runner) toubuntu-24.04provides dedicated disk space and avoids IO saturation during extraction. - Partitioning artifact downloads into 4 pattern-scoped steps (
llama-bin-*,llama-ubuntu-cuda-*-x64.tar.xz,llama-ubuntu-cuda-*-arm64.tar.xz,llama-windows-cuda-*) preventsactions/download-artifact@v7from launching 28 parallel extractions simultaneously. - Added
ls -laanddf -hdiagnostics for troubleshooting.
- Moving
-
Multithreaded xz Compression:
- Switching
tar -cJftotar -I 'xz -T0'drivesxzacross all available cores on the runner, cutting compression time per leg significantly.
- Switching
-
CUDA Toolkit Slimming:
- Replacing
cuda-toolkit-12-9(~3.9 GB) with the 6-package subset (cuda-nvcc-12-9,cuda-cudart-dev-12-9,cuda-cccl-12-9,libcublas-dev-12-9,libcurand-dev-12-9,libnvjitlink-dev-12-9) reduces apt payload size by ~70% (~1.2 GB). - The explicit post-install loop ensures compiler (
nvcc), headers (cublas_v2.h,cub/cub.cuh), and runtime shared objects exist before starting the build.
- Replacing
LGTM!
superm1
approved these changes
Jul 29, 2026
superm1
left a comment
Member
There was a problem hiding this comment.
Why even download and hash artifacts? Seems pretty expensive in first place.
Anyway lgtm
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Release runs have been cancelling more often than not, and it looks like CUDA timing out. It isn't. In runs 30341691913 and 30364671144, every build job succeeded and only
releasedied — both times ~14 minutes intoDownload artifacts, with 4 of 28 artifacts complete:Successful runs finish that same step in 3.5–4.5 min. CUDA itself is healthy: all 24 legs restore their ccache (76.8% hit rate, 0.13/0.50 GB), and warm
Buildsteps are 2.5–5.1 min.Fix 1 — the release job
Runner.
ubuntu-slimis a container runner — the log reportsVM Image — Source: Docker, Name: ubuntu:24.04— and it was being asked to hold ~14 GB of artifacts plus the transient zip each download extracts from. Moved to a fullubuntu-24.04VM.Concurrency.
actions/download-artifact@v7starts every matched artifact at once. Its chunking is ineffective:The promises are constructed eagerly in
.map()beforechunk()runs, soPARALLEL_DOWNLOADSonly paces how results are awaited. The log confirms it — all 28Starting downloadlines land within 0.5 s. There is no concurrency input, so the only lever is separatepattern-scoped steps.Verified the four patterns partition the real artifact list from run
30364671144:A
patternthat matches nothing does not throw (only thenameandartifact-idspaths do), so a dropped backend family still degrades gracefully into the existing completeness checks rather than failing the job.Also added a
ls -la/df -hstep so the next stall is diagnosable instead of a silent 14-minute hang.Fix 2 — xz threading
tar -cJfdrives a single-threaded xz, and it was the single largest cost in the Linux CUDA jobs — larger than the compile:Switched to
tar -I 'xz -T0'. Measured on a 2.9 GB binary payload:xz -T1(runner default)xz -T0(32 cores)Round-trip verified —
xz -tpasses,diff -ron the extracted tree is clean.Two caveats: the archive is 1.8% larger, because threaded mode compresses independent blocks. And the runners are 4-core, not 32, so expect roughly 3–4× rather than 16× — about 6.8 min → ~2 min per leg, ~112 min → ~30 min of runner time per run.
Fix 3 — stop installing three quarters of the CUDA toolkit
The other column in that table. Both Linux CUDA jobs installed the
cuda-toolkit-12-9metapackage, which isNeed to get 3935 MB of archiveson every leg, ×16 legs, uncached.Almost none of it is used. The build is
-DGGML_STATIC=OFF, soggml-cudalinksCUDA::cudart,CUDA::cublasandCUDA::cuda_driver; theBundle CUDA runtime librariesandValidate CUDA package contentssteps additionally wantlibcurandandlibnvJitLink. The metapackage also drags in Nsight Systems, Nsight Compute, cuFFT, cuSPARSE, cuSOLVER and NPP, which are neither compiled against nor shipped.So the install is now a hand-resolved subset. I walked the dependency closure against the repo's own
Packages.gzfor both architectures:cuda-toolkit-12-9(x86_64)cuda-toolkit-12-9(sbsa)(3,885 MB against the observed 3935 MB — the gap is the handful of deps that come from Ubuntu's own archive rather than NVIDIA's.)
The six roots, and why each is there:
cuda-nvcc-12-9cuda-crt,cuda-nvvmcuda-cudart-dev-12-9libcudart, and viacuda-driver-devthelibcuda.sostub behindCUDA::cuda_drivercuda-cccl-12-9libcublas-dev-12-9libcublas+libcublasLt— 944 MB of the remaining 1.2 GB, and unavoidablelibcurand-dev-12-9Validatelibnvjitlink-dev-12-9ValidateTwo things worth confirming rather than assuming:
/usr/local/cudastill exists. It is an alternative installed bycuda-toolkit-12-9-config-common's postinst (update-alternatives --install /usr/local/cuda cuda /usr/local/cuda-12.9 129), and that package is a transitive dep of the subset. Unpacked the.debto check.apt-get installbehaves the same as--no-install-recommendshere.Since this is a hand-picked list, I also added a post-install existence check over
nvccand the exact headers and libraries the later steps consume. If NVIDIA ever repackages one of these, the job fails at the install step naming the missing file, rather than partway through a compile or — worse — atValidateafter 20 minutes of work.This also brings Linux in line with
windows-cuda, which has always passed an explicitsub-packageslist toJimver/cuda-toolkit.Expected effect: the ~61 min/run those two families currently spend in
Install CUDA Toolkitshould land in roughly the 20 min range. Bytes drop 70%; unpack time won't scale quite linearly, so I'd rather state the measured number and let the run confirm the rest.Considered and rejected: caching the
.debs withactions/cache. It would work, but the repo's Actions cache is already at 8.96 GiB of the 10 GiB limit — adding ~2.3 GiB of apt archives would evict the ccache entries that keepBuildat 2.5–5.1 min. Not installing the bytes is strictly better than caching bytes we never needed.What this does not fix
The real long pole is untouched.
ubuntu-22-rocmruns 93–144 min while every CUDA leg finishes in 15–20, andreleasecannot start until it's done. Shaving the pack and install steps won't shorten a run that's gated on ROCm.One other thing surfaced while investigating, not addressed here:
rocm-wheelsblob). Each run writes ~3 GiB of fresh entries, so GitHub is silently LRU-evicting. Hasn't bitten the CUDA legs yet, but there's no headroom.Separately: run
30390684307was cancelled by hand at20:05:49and re-dispatched 11 minutes later. That one isn't a bug.Testing
Workflow YAML parses, the
releasejob's step list is as expected, and both rewrittenInstall CUDA Toolkitscripts passbash -n. The package subset was verified by dependency-closure resolution against the liveubuntu2204/x86_64andubuntu2204/sbsaPackages.gz, not by eyeballing names — but the install itself only proves out on a real runner, so the CUDA legs of this PR's run are the actual check. The download-path change only exercises onschedule/workflow_dispatchand still needs a manual dispatch to confirm end to end; the xz change is covered by PR runs.🤖 Generated with Claude Code