nvidia-power-limit.service applied the miner profile (power limit + -lmc 810,810) at every boot as a host setting. A host switched from mining back to LLM inference kept the lock with the miner stopped. Inference is memory-bandwidth bound: a 27B model on 2× RTX 5090 decoded at 3.8 tok/s on a build that had measured 21.9 tok/s. Nothing reported it. A -lmc lock is not a clocks event reason, utilisation reads ~98%, and the only signs are P5, the 810 MHz memory clock and ~125 W of power draw.
Change
The profile now follows the workload instead of the host:
nvidia-power-limit.sh takes a mode. miner applies /etc/default/nvidia-power-limit exactly as before. default resets each card to its own power.default_limit and runs -rmc.
nvidia-power-limit.service runs default at boot, ordered before both quantus-miner and neuron.
New asset/systemd/neuron-gpu-exclusive.conf → neuron.service.d/50-gpu-exclusive.conf. It sets Conflicts=quantus-miner.service, After=quantus-miner.service so the miner's ExecStopPost reset finishes first, and ExecStartPre=+… default. Starting either service stops the other, and the clocks follow.
infra-setup.sh:
installs the drop-in on every GPU host;
always writes the profile config, so removing a host from the lists clears its profile;
applies the profile that matches the running workload, instead of restarting the boot unit under a live miner.
readme: a new GPU profiles and inference section, and a rewritten Known conflict section.
Companion PR
quantus/miner (feat/gpu-profile-with-lifecycle) adds the other half:
ExecStartPre=+nvidia-power-limit.sh miner / ExecStopPost=+… default on the unit;
a deploy guard that ships files but won't enable or start the miner on a host where neuron.service is enabled;
bench changes that re-apply the profile for the measurement window.
Rollout order
Merge this PR, then run script/infra-setup.sh against the GPU hosts. It installs the new script and drop-in, and resets any host not currently mining.
Re-run quantus/miner's deploy/infra-setup.sh, which adds new sudoers lines for the bench.
Merge the miner PR.
The two halves can land in either order. The old script ignores the mode argument, so it keeps working in the meantime, just without the reset on stop.
Tested
nvidia-power-limit.sh was exercised against a stub nvidia-smi: both modes, clamping, a bad mode (exit 2), a failing -rmc (exit 1, loud), and an empty profile.
systemd-analyze verify passes on neuron.service with the drop-in and on the boot unit.
## Problem
`nvidia-power-limit.service` applied the miner profile (power limit + `-lmc 810,810`) at every boot as a *host* setting. A host switched from mining back to LLM inference kept the lock with the miner stopped. Inference is memory-bandwidth bound: a 27B model on 2× RTX 5090 decoded at **3.8 tok/s** on a build that had measured **21.9 tok/s**. Nothing reported it. A `-lmc` lock is not a clocks event reason, utilisation reads ~98%, and the only signs are P5, the 810 MHz memory clock and ~125 W of power draw.
## Change
The profile now follows the workload instead of the host:
- `nvidia-power-limit.sh` takes a mode. `miner` applies `/etc/default/nvidia-power-limit` exactly as before. `default` resets each card to its own `power.default_limit` and runs `-rmc`.
- `nvidia-power-limit.service` runs `default` at boot, ordered before both `quantus-miner` and `neuron`.
- New `asset/systemd/neuron-gpu-exclusive.conf` → `neuron.service.d/50-gpu-exclusive.conf`. It sets `Conflicts=quantus-miner.service`, `After=quantus-miner.service` so the miner's `ExecStopPost` reset finishes first, and `ExecStartPre=+… default`. Starting either service stops the other, and the clocks follow.
- `infra-setup.sh`:
- installs the drop-in on every GPU host;
- always writes the profile config, so removing a host from the lists clears its profile;
- applies the profile that matches the running workload, instead of restarting the boot unit under a live miner.
- readme: a new *GPU profiles and inference* section, and a rewritten *Known conflict* section.
## Companion PR
quantus/miner (`feat/gpu-profile-with-lifecycle`) adds the other half:
- `ExecStartPre=+nvidia-power-limit.sh miner` / `ExecStopPost=+… default` on the unit;
- a deploy guard that ships files but won't enable or start the miner on a host where `neuron.service` is enabled;
- bench changes that re-apply the profile for the measurement window.
## Rollout order
1. Merge this PR, then run `script/infra-setup.sh` against the GPU hosts. It installs the new script and drop-in, and resets any host not currently mining.
2. Re-run quantus/miner's `deploy/infra-setup.sh`, which adds new sudoers lines for the bench.
3. Merge the miner PR.
The two halves can land in either order. The old script ignores the mode argument, so it keeps working in the meantime, just without the reset on stop.
## Tested
- `nvidia-power-limit.sh` was exercised against a stub `nvidia-smi`: both modes, clamping, a bad mode (exit 2), a failing `-rmc` (exit 1, loud), and an empty profile.
- `systemd-analyze verify` passes on `neuron.service` with the drop-in and on the boot unit.
- Not yet run on real cards.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01XViS3RVfGTRaRSopLN68MA
The power limit and 810 MHz memory lock were a host setting, applied at
every boot by nvidia-power-limit.service regardless of what the GPU was
doing. A host switched from mining back to LLM inference kept the lock
with the miner stopped, and inference is memory-bandwidth bound: a 27B
model on 2x RTX 5090 decoded at 3.8 tok/s on a build that had measured
21.9 tok/s. Nothing reported it — a -lmc lock is not a clocks event
reason, and utilisation still reads ~98%.
The profile now follows the workload:
- nvidia-power-limit.sh takes a mode. `miner` applies the configured
profile as before; `default` resets each card to its own default power
limit and memory clock.
- nvidia-power-limit.service runs `default` at boot. The miner applies
`miner` in ExecStartPre and `default` in ExecStopPost (quantus/miner).
- A drop-in for neuron.service makes it conflict with the miner and
reset to default before starting, so either one can take the host with
a single systemctl start and the clocks follow.
- infra-setup.sh installs the drop-in, always writes the profile config
(so removing a host clears it), and applies whichever profile matches
the running workload instead of restarting the boot unit under a live
miner.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XViS3RVfGTRaRSopLN68MA
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Problem
nvidia-power-limit.serviceapplied the miner profile (power limit +-lmc 810,810) at every boot as a host setting. A host switched from mining back to LLM inference kept the lock with the miner stopped. Inference is memory-bandwidth bound: a 27B model on 2× RTX 5090 decoded at 3.8 tok/s on a build that had measured 21.9 tok/s. Nothing reported it. A-lmclock is not a clocks event reason, utilisation reads ~98%, and the only signs are P5, the 810 MHz memory clock and ~125 W of power draw.Change
The profile now follows the workload instead of the host:
nvidia-power-limit.shtakes a mode.minerapplies/etc/default/nvidia-power-limitexactly as before.defaultresets each card to its ownpower.default_limitand runs-rmc.nvidia-power-limit.servicerunsdefaultat boot, ordered before bothquantus-minerandneuron.asset/systemd/neuron-gpu-exclusive.conf→neuron.service.d/50-gpu-exclusive.conf. It setsConflicts=quantus-miner.service,After=quantus-miner.serviceso the miner'sExecStopPostreset finishes first, andExecStartPre=+… default. Starting either service stops the other, and the clocks follow.infra-setup.sh:Companion PR
quantus/miner (
feat/gpu-profile-with-lifecycle) adds the other half:ExecStartPre=+nvidia-power-limit.sh miner/ExecStopPost=+… defaulton the unit;neuron.serviceis enabled;Rollout order
script/infra-setup.shagainst the GPU hosts. It installs the new script and drop-in, and resets any host not currently mining.deploy/infra-setup.sh, which adds new sudoers lines for the bench.The two halves can land in either order. The old script ignores the mode argument, so it keeps working in the meantime, just without the reset on stop.
Tested
nvidia-power-limit.shwas exercised against a stubnvidia-smi: both modes, clamping, a bad mode (exit 2), a failing-rmc(exit 1, loud), and an empty profile.systemd-analyze verifypasses onneuron.servicewith the drop-in and on the boot unit.🤖 Generated with Claude Code
https://claude.ai/code/session_01XViS3RVfGTRaRSopLN68MA