Last active
February 7, 2025 13:51
-
-
Save webdev23/88b98b6151d03335a8d24fd9bc3472bd to your computer and use it in GitHub Desktop.
Control multiple GPU Fan speed based on CPU temperature - Linux systemd service - Nvidia
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
This setup allows to provide extra boost of cool air, dedicated for overclocked CPU. | |
Using the powerful GPU fans based on both CPU and GPU temperature. | |
As a permanent systemd service, across reboots. | |
It should be -run once and forget-, make sure to adjust <USER> and always use FULL PATH. | |
We cannot control GPU fan speed without sudo rights, and various issue arise with display settings. | |
THe following works great for me, over reboot, and it should work in any Linux. | |
There is many tricks against issues controlling nvidia-settings, that one works, but: | |
DONT DO THAT https://askubuntu.com/questions/1411667/unable-to-control-nvidia-fan-speed <= NO NO NO | |
Instead here is the proper way to run `nvidia-settings` as a systemd service. | |
Make sure to replace <USER> in all these scripts: | |
### Remove sudo locks on nvidia-settings ONLY | |
sudo visudo | |
Add | |
root ALL=(ALL) NOPASSWD: /usr/bin/nvidia-settings | |
<USER> ALL=(ALL) NOPASSWD: /usr/bin/nvidia-settings | |
### Create file `gpu_auto_fan` in /home/<USER>/.local/bin/gpu_auto_fan - ADJUST AS NEED | |
``` | |
#!/bin/bash | |
export DISPLAY=:1.0 # Set the display number MIGHT REQUIRE ADJUSTMENT | |
export XAUTHORITY=/home/<USER>/.Xauthority # FULL PATH to X authority file | |
# Function to get the CPU temperature | |
get_cpu_temp() { | |
sensors | awk '/Package/ {gsub(/[+°C]/, "", $4); print $4}' | |
} | |
# Function to adjust GPU fan speed based on temperatures | |
adjust_fan_speed() { | |
local gpu_temp=$1 | |
local cpu_temp=$2 | |
local pcfan=26 | |
local CPU_HOT_THRESHOLD=54 | |
local CPU_BOIL_THRESHOLD=64 | |
# Determine the fan speed based on GPU and CPU temperatures | |
if (( $(echo "$cpu_temp >= $CPU_BOIL_THRESHOLD" | bc -l) )); then | |
pcfan=74 # Hardcore hot, higher fan speed | |
elif (( $(echo "$cpu_temp >= $CPU_HOT_THRESHOLD" | bc -l) )); then | |
pcfan=50 # CPU hot, moderate fan speed | |
elif (( $(echo "$gpu_temp < 41" | bc -l) )); then | |
pcfan=26 | |
elif (( $(echo "$gpu_temp < 46" | bc -l) )); then | |
pcfan=36 | |
elif (( $(echo "$gpu_temp < 51" | bc -l) )); then | |
pcfan=40 | |
elif (( $(echo "$gpu_temp < 56" | bc -l) )); then | |
pcfan=50 | |
elif (( $(echo "$gpu_temp < 60" | bc -l) )); then | |
pcfan=66 | |
else | |
pcfan=80 # Max fan speed for high temperatures | |
fi | |
# Update fan speed if it has changed | |
if [[ "$pcfan" -ne "$last_pcfan" ]]; then | |
echo "Changing fan speed to $pcfan%" | |
echo "PCFAN=$pcfan" | nvidia-settings -a "[gpu:0]/GPUFanControlState=1" \ | |
-a "[fan:0]/GPUTargetFanSpeed=$pcfan" \ | |
-a "[fan:1]/GPUTargetFanSpeed=$pcfan" | |
last_pcfan=$pcfan | |
fi | |
} | |
# Initialize last fan speed | |
last_pcfan=-1 | |
# Main loop | |
while true; do | |
gpu_temp=$(nvidia-smi --query-gpu=temperature.gpu --format=csv,noheader,nounits | tail -n1) | |
cpu_temp=$(get_cpu_temp) | |
adjust_fan_speed "$gpu_temp" "$cpu_temp" | |
sleep 2 | |
done | |
``` | |
Make sure `gpu_auto_fan` is executable: | |
chmod +x gpu_auto_fan | |
### Then create a systemd service: | |
Create `gpu_auto_fan.service` (whatever.service): | |
sudo nano /etc/systemd/system/gpu_auto_fan.service | |
``` | |
[Unit] | |
Description=gpu_auto_fan | |
After=graphical.target | |
[Service] | |
Type=simple | |
ExecStart=/home/<USER>/.local/bin/gpu_auto_fan | |
Restart=on-failure | |
User=<USER> | |
Environment=DISPLAY=:0 | |
Environment=XAUTHORITY=/home/<USER>/.Xauthority | |
[Install] | |
WantedBy=graphical.target | |
``` | |
### Then reload systemd: | |
sudo systemctl daemon-reload | |
### Enable `gpu_auto_fan` background service. | |
sudo systemctl enable gpu_auto_fan.service | |
### Start service | |
sudo systemctl start gpu_auto_fan.service | |
# Test carefully!!! | |
### See logs in journalctl | |
sudo journalctl -f |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment