Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python3
- """
- NVIDIA Aggressive Fan Control Daemon
- RTX Pro 6000 Blackwell - Gaming-style fan curve
- Runs headless, no X11 required.
- """
- import pynvml
- import time
- import logging
- import sys
- logging.basicConfig(
- level=logging.INFO,
- format='%(asctime)s %(levelname)s %(message)s',
- handlers=[logging.StreamHandler(sys.stdout)]
- )
- log = logging.getLogger(__name__)
- # --- Fan curve: (temp_C, fan_pct) ---
- # More aggressive than stock workstation defaults.
- # By 70C fans are already at 80%, by 80C they're maxed.
- FAN_CURVE = [
- (0, 30),
- (45, 40),
- (55, 55),
- (63, 70),
- (70, 82),
- (75, 90),
- (80, 100),
- ]
- POLL_INTERVAL = 3 # seconds between checks
- GPU_INDEX = 0 # change if you have multiple GPUs
- def interpolate_fan(temp):
- """Return target fan % for a given GPU temp using the curve above."""
- if temp <= FAN_CURVE[0][0]:
- return FAN_CURVE[0][1]
- if temp >= FAN_CURVE[-1][0]:
- return FAN_CURVE[-1][1]
- for i in range(1, len(FAN_CURVE)):
- t1, f1 = FAN_CURVE[i - 1]
- t2, f2 = FAN_CURVE[i]
- if t1 <= temp <= t2:
- ratio = (temp - t1) / (t2 - t1)
- return int(f1 + ratio * (f2 - f1))
- return 100
- def set_fans(handle, num_fans, pct):
- pct = max(0, min(100, pct))
- for fan_idx in range(num_fans):
- pynvml.nvmlDeviceSetFanSpeed_v2(handle, fan_idx, pct)
- def main():
- pynvml.nvmlInit()
- driver = pynvml.nvmlSystemGetDriverVersion()
- log.info(f"NVIDIA driver: {driver}")
- handle = pynvml.nvmlDeviceGetHandleByIndex(GPU_INDEX)
- name = pynvml.nvmlDeviceGetName(handle)
- num_fans = pynvml.nvmlDeviceGetNumFans(handle)
- log.info(f"Controlling: {name} ({num_fans} fans)")
- log.info("Fan curve (temp->fan%): " +
- " ".join(f"{t}C->{f}%" for t, f in FAN_CURVE))
- # Take manual control of the fan
- for fan_idx in range(num_fans):
- pynvml.nvmlDeviceSetFanControlPolicy(
- handle, fan_idx,
- pynvml.NVML_FAN_POLICY_MANUAL
- )
- log.info("Fan control set to MANUAL")
- last_pct = -1
- try:
- while True:
- temp = pynvml.nvmlDeviceGetTemperature(
- handle, pynvml.NVML_TEMPERATURE_GPU)
- target = interpolate_fan(temp)
- if target != last_pct:
- set_fans(handle, num_fans, target)
- log.info(f"GPU {temp}C -> fans {target}%")
- last_pct = target
- time.sleep(POLL_INTERVAL)
- except KeyboardInterrupt:
- log.info("Interrupted - restoring automatic fan control")
- finally:
- # Hand control back to the driver on exit
- for fan_idx in range(num_fans):
- pynvml.nvmlDeviceSetFanControlPolicy(
- handle, fan_idx,
- pynvml.NVML_FAN_POLICY_TEMPERATURE_CONTINOUS_SW
- )
- pynvml.nvmlShutdown()
- log.info("Fan control restored to automatic")
- if __name__ == "__main__":
- main()
Advertisement