gpu-fan-ctrl: auto-detect multi-GPU, burst per-card, updated README
This commit is contained in:
1 parent
7dff5fc516
commit
a91d4c50d4
2 files changed
+34
-18
No files matched your search
@@ -1,6 +1,7 @@
|
|||||||
# GPU Fan Controller — Delta QFR1212GHE
|
# GPU Fan Controller — Delta QFR1212GHE
|
||||||
|
|
||||||
Автоматическое управление вентилятором на Tesla V100-PCIE-32GB по температуре GPU.
|
Автоматическое управление вентилятором на Tesla V100-PCIE-32GB (1 или 2 карты) по температуре GPU.
|
||||||
|
Вентилятор обдувает обе карты. Скрипт автоматически определяет количество карт и берёт max(temp) для логики. Burst по каждой карте отдельно.
|
||||||
|
|
||||||
## Подключение
|
## Подключение
|
||||||
|
|
||||||
|
|||||||
+32
-17
@@ -1,8 +1,8 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# GPU Fan Controller — Delta QFR1212GHE
|
# GPU Fan Controller — Delta QFR1212GHE (1 или 2 Tesla V100)
|
||||||
# Режимы: 2=STANDBY(<25), 3=LOW(<30), 4=MED(<35), 5=HIGH(<40), 6=FULL(>45 или burst)
|
# Режимы: 2=STANDBY(<25), 3=LOW(<30), 4=MED(<35), 5=HIGH(<40), 6=FULL(>45 или burst)
|
||||||
# Режим 1 (STOP) — не используется, фан всегда крутится минимум на standby.
|
# Режим 1 (STOP) — не используется, фан всегда крутится минимум на standby.
|
||||||
# Порог burst: temp > 45°C ИЛИ рост >= 3°C за 2 секунды.
|
# Если 2 карты: берём max(temp0, temp1) для логики. Burst проверяется по каждой карте отдельно.
|
||||||
|
|
||||||
LOG=/home/romanown/gpu_fan.log
|
LOG=/home/romanown/gpu_fan.log
|
||||||
DEV=/dev/ttyUSB0
|
DEV=/dev/ttyUSB0
|
||||||
@@ -28,14 +28,37 @@ prevTime=0
|
|||||||
burstTimer=0
|
burstTimer=0
|
||||||
lastMode=0
|
lastMode=0
|
||||||
noDataCount=0
|
noDataCount=0
|
||||||
|
gpuCount=0
|
||||||
|
|
||||||
echo "[START] $(date) GPU Fan Ctrl PID=$$"
|
echo "[START] $(date) GPU Fan Ctrl PID=$$"
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
TEMP=$(nvidia-smi --query-gpu=temperature.gpu --format=csv,noheader -i 0 | tr -cd '0-9')
|
# Определяем количество GPU и читаем все температуры
|
||||||
|
ALLTEMP=$(nvidia-smi --query-gpu=temperature.gpu --format=csv,noheader | tr -cd '0-9\n')
|
||||||
now=$(date +%s)
|
now=$(date +%s)
|
||||||
|
|
||||||
|
gpuCount=0
|
||||||
|
maxTemp=0
|
||||||
|
burstTriggered=0
|
||||||
|
|
||||||
|
while IFS= read -r t; do
|
||||||
|
[ -z "$t" ] && continue
|
||||||
|
[ "$t" -lt 0 ] 2>/dev/null && continue
|
||||||
|
gpuCount=$((gpuCount + 1))
|
||||||
|
if [ "$t" -gt "$maxTemp" ]; then maxTemp=$t; fi
|
||||||
|
|
||||||
|
# Burst по каждой карте отдельно
|
||||||
|
if [ $prevTime -gt 0 ] && [ $((prevTime != 0 ? now - prevTime : 99999)) -le $BURST_WINDOW ]; then
|
||||||
|
rise=$((t - prevTemp))
|
||||||
|
if [ $rise -ge $TH_BURST_ROISE ]; then
|
||||||
|
burstTriggered=1
|
||||||
|
echo "[BURST-rise] GPU${gpuCount}: rise=$rise°C in $((now-prevTime))s → mode 6"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
prevTemp=$t # сохраняем для следующей итерации
|
||||||
|
done <<< "$ALLTEMP"
|
||||||
|
|
||||||
if [ -z "$TEMP" ] || ! [ "$TEMP" -gt 0 ] 2>/dev/null; then
|
if [ $gpuCount -eq 0 ]; then
|
||||||
noDataCount=$((noDataCount + 1))
|
noDataCount=$((noDataCount + 1))
|
||||||
if [ $noDataCount -ge 10 ]; then
|
if [ $noDataCount -ge 10 ]; then
|
||||||
echo "[ERROR] nvidia-smi failed 10+ times, aborting"
|
echo "[ERROR] nvidia-smi failed 10+ times, aborting"
|
||||||
@@ -44,15 +67,8 @@ while true; do
|
|||||||
sleep 1; continue
|
sleep 1; continue
|
||||||
fi
|
fi
|
||||||
noDataCount=0
|
noDataCount=0
|
||||||
|
|
||||||
# Burst: temp rose TH_BURST_ROISE in BURST_WINDOW
|
TEMP=$maxTemp # берём max для логики
|
||||||
if [ $prevTemp -gt 0 ] && [ $((prevTime != 0 ? now - prevTime : 99999)) -le $BURST_WINDOW ]; then
|
|
||||||
rise=$((TEMP - prevTemp))
|
|
||||||
if [ $rise -ge $TH_BURST_ROISE ]; then
|
|
||||||
burstTimer=$BURST_DURATION
|
|
||||||
echo "[BURST-rise] rise=$rise°C in $((now-prevTime))s → mode 6"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Если в burst-режиме — держим режим 6
|
# Если в burst-режиме — держим режим 6
|
||||||
if [ $burstTimer -gt 0 ]; then
|
if [ $burstTimer -gt 0 ]; then
|
||||||
@@ -62,12 +78,11 @@ while true; do
|
|||||||
lastMode=6
|
lastMode=6
|
||||||
echo "6" >&3
|
echo "6" >&3
|
||||||
fi
|
fi
|
||||||
prevTemp=$TEMP; prevTime=$now
|
|
||||||
sleep 1; continue
|
sleep 1; continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Если burst истёк И temp >= TH_BURST — новый burst
|
# Если burst истёк И temp >= TH_BURST — новый burst
|
||||||
if [ $TEMP -ge $TH_BURST ]; then
|
if [ $TEMP -ge $TH_BURST ] || [ $burstTriggered -eq 1 ]; then
|
||||||
burstTimer=$BURST_DURATION
|
burstTimer=$BURST_DURATION
|
||||||
echo "[MODE 6] full speed (re-burst: $TEMP°C)"
|
echo "[MODE 6] full speed (re-burst: $TEMP°C)"
|
||||||
lastMode=6; prevTemp=$TEMP; prevTime=$now
|
lastMode=6; prevTemp=$TEMP; prevTime=$now
|
||||||
@@ -88,11 +103,11 @@ while true; do
|
|||||||
|
|
||||||
# Отправляем только если режим изменился
|
# Отправляем только если режим изменился
|
||||||
if [ $newMode -ne $lastMode ]; then
|
if [ $newMode -ne $lastMode ]; then
|
||||||
echo "[MODE $newMode] temp=$TEMP°C (hysteresis: no-change zone)"
|
echo "[MODE $newMode] max_temp=$TEMP°C (gpuCount=$gpuCount) (hysteresis: no-change zone)"
|
||||||
lastMode=$newMode
|
lastMode=$newMode
|
||||||
echo "$newMode" >&3
|
echo "$newMode" >&3
|
||||||
fi
|
fi
|
||||||
|
|
||||||
prevTemp=$TEMP; prevTime=$now
|
prevTime=$now
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
Reference in new issue
Block a user