Selective CUDA repository mirror for GPU servers. Install NVIDIA driver,
CUDA toolkit, and companion libraries directly from
mirrors.siam.ai.
Pick your driver branch and CUDA version — the install command updates live. Copy and run on any GPU node.
# 1. Download installer from mirror wget https://mirrors.siam.ai/get-cuda-mirror.sh chmod +x get-cuda-mirror.sh # 2. Install sudo ./get-cuda-mirror.sh --nvidia-driver=595 --cuda-toolkit=13-2 --nvitop=true
verify-install.sh takes the installer's own flag set, so it checks the node against what you asked for instead of only checking that the node is self-consistent. Details and sample output in section 05.
Both ubuntu2204 and ubuntu2404 carry the same builds — the mirror takes the whole driver stack from NVIDIA's own CUDA repo, and a build is only synced when a fabricmanager of the identical version exists alongside it.
| Branch | Installable versions | Kernel module | Install flag (get-cuda-mirror.sh) |
|---|---|---|---|
| loading live versions from the mirror… | |||
How to install. Pass --nvidia-driver=<branch> (e.g. --nvidia-driver=590) to get that branch's newest build — the one tagged default above, resolved live from the mirror. To pin an exact build, pass the full version from that branch's row above (e.g. --nvidia-driver=<branch>.<build>). When a branch has more than one build on the mirror, every installable version is listed in its row so you can pin any of them. The matching fabricmanager (nvidia-fabricmanager-<branch> on older branches, plain nvidia-fabricmanager from 580 on) is installed automatically in the same apt transaction, at the same exact version.
Everything comes from NVIDIA. The mirror sources the driver stack from NVIDIA's CUDA repo only — never the Ubuntu archive. That is deliberate: Ubuntu publishes just the one current build per branch and rewrites it in place, so a build you installed last month is gone from upstream today and the fleet drifts apart. NVIDIA keeps every point release, which is what makes --nvidia-driver=<exact build> reproducible months later. Branches are auto-selected by an FM-gated rolling window: keep the newest 5 branches that have both a driver and a fabricmanager of the same exact version (floor 570), keep the newest 5 builds within each branch, and serve each dropped branch 30 days more before deletion. A branch whose FM has not shipped yet is skipped until it does. Driver .debs already on disk are folded back into each run, so a build stays installable even after upstream moves on.
When a driver branch is retired, the package name is not deleted — it is turned into a tiny transitional shim: a metapackage that keeps the old name but whose Depends: now point at a different branch, and whose version is the new branch's. NVIDIA's repo does this too, e.g. nvidia-driver-530 = 560.35.03 → depends → nvidia-driver-560. Installing that shim does not install 530 — apt pulls 560 instead, which is exactly the "I picked a version but got upgraded" trap.
Two things make that unreachable here. First, the mirror and the installer key a build's branch off its version, not its package name, so a shim can never be returned for the branch its name advertises. Second, every build's Depends: is read and any shim whose driver/dkms dependency leaves its own branch is dropped, so the menu above lists only branches that install as themselves. The installer adds a third guard on the node: a version-based APT pin plus an install --simulate pre-check that aborts if a foreign branch would be pulled in — pick X, get exactly X, or nothing.
Package names also shift between NVIDIA's packaging generations — nvidia-driver-575 (≤575), nvidia-driver-580 with an unsuffixed nvidia-fabricmanager (580), and fully unsuffixed nvidia-driver / nvidia-dkms from 590 on, where the branch lives only in the version. The installer resolves all three, so --nvidia-driver=<branch> and --nvidia-driver=<exact build> work the same on every branch above.
A driver supports its own CUDA version and every lower one (backward compatible). Pick a CUDA toolkit ≤ the number below for the driver you install.
| Driver branch | Max CUDA toolkit | Also runs |
|---|---|---|
| loading live versions from the mirror… | ||
Source: NVIDIA Data Center Driver release notes. Newer minor CUDA toolkits need a driver whose branch reaches that number — e.g. CUDA 13.2 needs driver ≥ 595, CUDA 13.1 needs ≥ 590. Older toolkits always work on newer drivers.
NVIDIA ships CUDA 13.x for jammy (22.04) as well as noble (24.04), so the mirror carries the same set for both. The table below is live from the mirror — a version shows — only if that build has not synced yet. Running CUDA 13.x on jammy still needs a driver ≥ 580 available for that node.
| Version | ubuntu2404 | ubuntu2204 |
|---|---|---|
| loading live versions from the mirror… | ||
| Library | Scope | Notes |
|---|---|---|
| DCGM 4 | cuda12 + cuda13 | datacenter-gpu-manager-4-cuda12/13 |
| cuDNN 9 | cuda11/12/13 | All variants — covers all our CUDA |
| NCCL 2.29 | cuda12/13 | Filter +cuda12 / +cuda13 |
| TensorRT 10 | all | 10.4–10.15, builds against CUDA 12.6–13.x |
| DOCA-OFED 3.0–3.4 | separate path | /srv/mirror/nvidia/doca/ — manual download |
For HGX/NVSwitch nodes with ConnectX + GPUDirect RDMA. Install DOCA-OFED and the driver in a single command — reboot only once at the end.
# DOCA + driver + CUDA + nvitop in one command wget https://mirrors.siam.ai/get-cuda-mirror.sh chmod +x get-cuda-mirror.sh sudo ./get-cuda-mirror.sh --doca=true --nvidia-driver=580 --cuda-toolkit=13-0 --nvitop=true # Reboot once — loads DOCA ib_core + driver + nvidia_peermem together sudo reboot
DOCA-OFED and the driver build their DKMS modules in sequence (DOCA first). Because nvidia_peermem links against DOCA's ib_register_peer_memory_client symbols at build time — not runtime — a single reboot at the end loads DOCA's ib_core, the driver, and nvidia_peermem together. Running --doca=true on its own still stops and asks for a reboot before the driver.
Use when the GPU node has network access and doesn't need GPUDirect RDMA (e.g., VMs without IB).
# Download installer wget https://mirrors.siam.ai/get-cuda-mirror.sh chmod +x get-cuda-mirror.sh # Latest driver + CUDA sudo ./get-cuda-mirror.sh --nvidia-driver=595 --cuda-toolkit=13-2 --nvitop=true # VM without NVLink sudo ./get-cuda-mirror.sh --nvidia-driver=590 --cuda-toolkit=12-9 --nvitop=true --no-nv=true
--local-install)For a node that can't reach the mirror at install time, pre-stage the .deb files from the mirror, copy them to the node, then point the same installer at the local repo — no official NVIDIA egress.
# On a machine WITH mirror access — pull the installer + the .deb files you need wget https://mirrors.siam.ai/get-cuda-mirror.sh # (copy get-cuda-mirror.sh + the .deb set to the air-gapped node) # On the air-gapped node — install from the pre-staged local repo sudo ./get-cuda-mirror.sh --local-install=true --nvidia-driver=580 --cuda-toolkit=13-0
Run verify-install.sh with the same flags you installed with — it covers everything below plus the checks that are easy to miss by eye. See section 05. For a quick look by hand:
nvidia-smi -L | wc -l # GPU count systemctl status nvidia-fabricmanager # FM service lsmod | grep nvidia_peermem # GPUDirect RDMA dcgmi discovery -l # DCGM sees all GPUs dpkg-query -W -f='${Package} ${Version}\n' nvidia-driver-580 nvidia-fabricmanager
Extra libraries install straight from the mirror with apt — no extra setup, no reaching out to NVIDIA.
sudo apt install -y just works
The base install already bound this node's apt to the mirror — the repo lives in /etc/apt/sources.list.d/cuda-<distro>-x86_64.list. From then on, any install or upgrade of a package inside the mirror's scope is pulled from mirrors.siam.ai instead of NVIDIA's official servers. No re-configuring, no VPN, no egress to NVIDIA.
# NCCL — multi-GPU / multi-node collective comms sudo apt update sudo apt install -y libnccl2 libnccl-dev # cuDNN 9 (match your CUDA major — cuda-13 shown) sudo apt install -y cudnn9-cuda-13 libcudnn9-dev-cuda-13 # TensorRT sudo apt install -y tensorrt libnvinfer-dev python3-libnvinfer # DCGM 4 — health / telemetry sudo apt install -y datacenter-gpu-manager-4-cuda13 # NVIDIA Container Toolkit — GPUs in Docker sudo apt install -y nvidia-container-toolkit
Every patch build is kept on the mirror (all-versions mode). List them with apt-cache madison libnccl2, then pin: sudo apt install libnccl2=2.29.7-1+cuda13.2.
Burn-in / thermal test — hammers every GPU with FP32 (or Tensor-core) matrix multiplies to surface unstable cards, throttling, or cooling problems. Needs the CUDA toolkit (nvcc) already installed.
# Build sudo apt install -y git build-essential git clone https://github.com/wilicc/gpu-burn.git cd gpu-burn make # if nvcc not found: make CUDAPATH=/usr/local/cuda-13.0 # Run — 120 s across all GPUs ./gpu_burn 120 # Tensor-core (mixed precision) stress ./gpu_burn -tc 120
In another shell: watch -n1 nvidia-smi (or nvitop). Healthy cards finish with OK (Ok) for every GPU; a FAULTY result or thermal shutdown means that card needs attention.
apt update fails one-time fixOn a node set up before this mirror moved to curated metadata, apt update ends with:
E: The repository 'https://mirrors.siam.ai/compute/cuda/repos/ubuntu2404/x86_64 Release' is no longer signed.
N: Updating from such a repository can't be done securely, and is therefore disabled by default.
Run this on that node. It repairs the apt entry and installs nothing:
wget https://mirrors.siam.ai/get-cuda-mirror.sh chmod +x get-cuda-mirror.sh sudo ./get-cuda-mirror.sh --fix-repo
Once per node, permanently. It is not needed again on a node that has had it, and a node installed from the current mirror never needs it at all.
The old mirror was a verbatim copy of NVIDIA's repo, so it could pass NVIDIA's signature along with the files, and the installer wrote an apt entry meaning “accept this repo only if NVIDIA signed it”.
This mirror is curated, not a copy: it keeps a fixed number of versions per package and rebuilds Packages and Release with apt-ftparchive after pruning. Those files are ours, so NVIDIA's signature cannot cover them — and signing them as NVIDIA would need NVIDIA's private key. apt finds a repo that used to be signed and no longer is, and refuses it.
Nothing on the mirror can repair this. apt decides what to trust by reading files on the node itself, and a mirror that could change that decision remotely would defeat the point of signing. The fix has to be applied on the node, which is all --fix-repo does.
apt upgrade on an unrepaired node
When apt disables a repo it does not discard the index it already has — it keeps using the stale copy, which still reports Origin: NVIDIA CUDA. The Pin: release o=Siam-AI rule never matches it, so the mirror loses its priority and ties with Ubuntu's archive, where the higher version number wins.
That is how a node ends up with an Ubuntu driver build that has no matching Fabric Manager. Run --fix-repo first, then review apt list --upgradable | grep -i nvidia before upgrading.
Any normal run of the installer (--nvidia-driver, --cuda-toolkit, --dcgm, --doca) rewrites the same apt entry, so a node you are installing on is fixed as a side effect. --fix-repo is for the case where you only want apt update to work and are not installing anything.
# Interactive — lists only what's installed, then pick what to remove sudo ./get-cuda-mirror.sh --uninstall # Specific components only (no prompt) sudo ./get-cuda-mirror.sh --uninstall=doca,driver # Everything sudo ./get-cuda-mirror.sh --uninstall=all
verify-install.sh checks a finished node against the flags it was installed with. Hand it the same flags as the install command and it answers "did this node get exactly what was asked for" — not just "is this node self-consistent". It is read-only: it installs nothing, changes nothing, starts no services. Exit code is 0 on a clean run, 1 if anything failed, so it drops straight into a provisioning pipeline.
wget https://mirrors.siam.ai/verify-install.sh chmod +x verify-install.sh # VM / no NVLink — same flags used to install sudo ./verify-install.sh --nvidia-driver=580 --cuda-toolkit=13-0 --dcgm=true --nvitop=true --no-nv=true # HGX with DOCA — same flags used to install sudo ./verify-install.sh --doca=true --nvidia-driver=580 --cuda-toolkit=13-0 --dcgm=true --nvitop=true # Also run dcgmi diag -r 2 (several minutes) sudo ./verify-install.sh --nvidia-driver=580 --cuda-toolkit=13-0 --dcgm=true --deep
The checker accepts the installer's whole flag set. Flags that cannot affect the result (--open, --mirror, --local-install, --doca-version, --yes) are accepted and ignored, so the install line pastes across verbatim. Run it with no flags at all and it still works — it just falls back to checking internal consistency, because nothing told it what you wanted.
| # | Group | What it catches |
|---|---|---|
| 1 | Kernel modules | nvidia, nvidia_uvm, nvidia_modeset, nvidia_drm actually loaded |
| 2 | Driver version lock | Every driver package on one version; running module matches the installed package (a mismatch = reboot pending); no Ubuntu-archive builds mixed in; branch is the one you asked for |
| 3 | Secure Boot | If Secure Boot is on, modinfo -F signer nvidia is non-empty — catches the unsigned module that only fails at the next reboot |
| 4 | CUDA toolkit | nvcc release, /usr/local/cuda symlink target, cuda-toolkit-<ver>, and the cuda-<ver> meta |
| 5 | Fabric Manager | Present or absent per --no-nv, version exactly equal to the driver, service state |
| 6 | NVLink | NvLinkDisable and /etc/modprobe.d/ state agree with the flags on this run |
| 7 | DCGM | Core package, service, dcgmi discovery -l, and the plugin major matching the driver's max CUDA |
| 8 | nvitop | Installed and able to read the GPU (nvitop -1) |
| 9 | DOCA-OFED | doca-ofed, mft, ofed_info, ib_core, nvidia_peermem, the ib_register_peer_memory_client symbols for the running kernel, active IB ports |
| 10 | Container toolkit | nvidia-container-toolkit version, informational |
| 11 | Hygiene | Leftover apt driver pin, held packages, a clean dependency tree, pending reboot, and free space on / and /var |
nvidia-smi will not show it: it reports one number while a stray package sits on another build. The check compares all of them and prints the split by version if they disagree. Enablers that legitimately track their own release trains (dkms, DCGM, container toolkit, the EGL libraries) are identified by version shape and excluded.-0ubuntu0.24.04.1) where NVIDIA's carries -1ubuntu1. Ubuntu publishes one build per branch and rewrites it in place, so anything from that lineage will silently land on a different build on the next machine. Any of it in the NVIDIA stack is a failure./etc/apt/preferences.d/ while it works and removes it on exit. If a run is killed mid-way the pin survives, and from then on apt refuses packages for a reason nothing on screen explains. The check names the file and the rm that clears it.Fabric Manager missing is a pass under --no-nv=true — the installer skips FM deliberately in that mode. FM also reports a pass when it is installed but not running because the node has no NVSwitch; the check reads the journal before deciding, instead of calling it broken.
Before the first reboot, DOCA warns rather than fails — ib_core, nvidia_peermem and the peer-memory symbols are legitimately not up yet. Warnings never change the exit code.
Running both workflows on the same node? The installer does not remove a disable-nvlink.conf written by an earlier --no-nv run, so a later run without that flag keeps NVLink off and nothing on the console says so. The check catches the leftover and prints the fix.
A VM node installed with --nvidia-driver=580 --cuda-toolkit=13-0 --dcgm=true --nvitop=true --no-nv=true, abridged:
==== 2. Driver version lock [PASS] nvidia-smi reports driver 580.178.04 (max CUDA 13.0) [PASS] all 17 driver packages at one version: 580.178.04-1ubuntu1 [PASS] running module matches the installed package (580.178.04) [PASS] no Ubuntu-archive builds in the NVIDIA stack (NVIDIA lineage only) [PASS] driver is on the requested branch 580 (build 580.178.04) kernel module flavor: open ==== 3. Secure Boot [PASS] Secure Boot ON, nvidia module signed by: oa-test-mirros-0001 Secure Boot Module Signature key ==== 4. CUDA toolkit [PASS] nvcc 13.0 (/usr/local/cuda/bin/nvcc) [PASS] /usr/local/cuda -> /usr/local/cuda-13.0 [PASS] meta cuda-13-0 13.0.3-1 installed ==== 5. Fabric Manager [PASS] no Fabric Manager, as expected with --no-nv=true ==== 6. NVLink [PASS] NvLinkDisable: 1 — NVLink is off, as requested ==== 7. DCGM [PASS] plugin datacenter-gpu-manager-4-cuda13 matches the driver's max CUDA (13.0) [PASS] dcgmi discovery: 1 GPU(s), 0 NvSwitches found, 0 ConnectX found ==== 11. Hygiene [PASS] no leftover apt driver pin [PASS] apt dependency tree is clean [WARN] only 4312 MB free where apt stages .debs — a CUDA toolkit install needs ~4500 MB sudo apt-get clean (safe: pure cache) ======================================== RESULT: PASS — 28 passed, 1 warning(s) ========================================
Stock Ubuntu LVM puts /var on its own logical volume. apt stages every .deb into /var/cache/apt/archives before unpacking anything into /usr/local, so a CUDA install can fail on a full /var while / still has tens of gigabytes free. That is what the warning above is about — sudo apt-get clean is safe, it only drops cached downloads.
| Flag | Values | Effect |
|---|---|---|
| --nvidia-driver | <branch> → newest, or a full version to pin an exact build live list in section 03 | Install NVIDIA driver — branch alone installs the newest build; a full version pins that exact build |
| --open=true|false | boolean — default auto | Kernel module flavor. Auto = keep what is already installed, else open (NVIDIA's default for Turing+); forced open on Blackwell / B300, proprietary on pre-Turing |
| --cuda-toolkit | <version> e.g. 13-2 / 12-9 live list in section 03 | Install CUDA toolkit version |
| --doca=true | boolean | Install DOCA-OFED — combine with driver flags, one reboot at end |
| --doca-version | 3.4.0 (default) | DOCA-OFED version |
| --dcgm=true | boolean | Install DCGM — auto-picks cuda12/cuda13 from --cuda-toolkit |
| --nvitop=true | boolean | Install nvitop (GPU monitor) |
| --no-nv=true | boolean | Blacklist NVLink — reboot required |
| --local-install=true | boolean | Use pre-staged local .deb repo |
| --force-install=true | boolean | Force driver 575 + toolkit 12-9 (legacy default) |
| --mirror=false | boolean | Pull from official NVIDIA instead of mirror |
| --yes | — | Answer yes to the driver-lineage swap prompt (replacing an Ubuntu-archive driver with NVIDIA's) — for unattended runs |
| --uninstall | — | Interactive: list only installed components, then pick what to remove |
| --uninstall=LIST | driver,fabric,cuda,dcgm,doca,nvitop,all | Remove selected components (comma-separated, no prompt) |
| --uninstall-all=true | boolean | Alias for --uninstall=all (purge everything) |
Running ./get-cuda-mirror.sh with no arguments prints the usage guide and exits.
nvidia-fabricmanager.service to fail at start. The mirror only syncs a driver build when a fabricmanager of the identical version exists, and the installer puts both in the same apt transaction, so this cannot drift apart on its own.-open with no fallback. A node already running the proprietary module keeps it unless you pass --open=true. Under Secure Boot the module is DKMS-signed with the machine's MOK key, and the installer verifies it with modinfo -F signer nvidia after the build instead of leaving you to find out at reboot.--doca=true together with the driver flags so nvidia_peermem links at DKMS build time; reboot once at the end.--no-nv=true needs reboot — adds kernel blacklist, takes effect after reboot.dcgmi diag loads the plugin for the driver's max CUDA (driver 580/590/595 → cuda13), regardless of which CUDA toolkit you install. Ticking --dcgm in the builder above locks the CUDA menu to that same major so the toolkit and DCGM plugin stay aligned. Editing the command by hand can break this — if you keep a lower toolkit with DCGM, make sure the matching datacenter-gpu-manager-4-cuda<driver-major> plugin is installed or dcgmi diag will fail to load plugins.