원 기사: LLM 추론에서 가장 뜨거운 것은 GPU가 아니었다 → · In English →
원 기사를 낸 뒤 두 갈래 반응이 있었다. 온도는 재현되는데 성능은 손해를 봤다는 보고(TP=2, DeepSeek V4 Flash 동일 구성), 그리고 우리 클러스터 자체의 후속 측정에서도 단독 스트림 디코드가 밀리는 결과. 그래서 처음부터 다시 쟀다. 이번에는 조작변수를 스핀 하나로 통제하고, 원 측정에 끼어 있던 변수 두 개 — 클럭 상한 유닛과 약하게 돌던 하단 흡기 팬 — 를 확인해 제거했다.
온도는 재현됐고, 더 빨랐다. 팬 없이 CPU 클럭 상한을 푼 조건에서 stock(1초 스핀)은 부하 시작 90초에 85°C, 3.5분에 92°C, 25분에 피크 95°C를 찍었다. 열원은 이번에도 GPU(69°C)가 아니라 스핀 스레드가 사는 성능코어 클러스터였다. 같은 부하에서 2ms 패치는 평균 89.6 → 80.5°C(−9.1°C), 피크 95 → 85°C.
동시 부하 성능 손실은 재현되지 않았다. 30분 연속 부하에서 처리량은 stock 85.8 대 patched 92.1 tok/s로 오히려 patched가 앞섰고(재기동 분산 안), 부하 중 단독 프로브도 동률이었다. 스로틀 개입 여부를 실클럭으로 확인했으므로 "stock이 열로 눌려서 차이가 안 보인 것"도 아니다. 단독 스트림 저부하에서의 소폭 손실(−2~6%)은 별도 측정에서 여전히 관찰된다.
두 노드의 온도 존을 15초 간격으로 실험 전 구간(2시간 26분) 동안 끊김 없이 기록했다. 유휴 기준선 → stock 부하 30분 → 냉각 → 재기동 → patched 부하 30분 → 냉각 순서다. 조작변수는 busy_loop_s 하나, 부하·측정·조건은 두 상이 동일하다.
그림 1 · 실험 전 구간 온도 (head 노드 존 7개 + worker TSOC). 굵은 선이 head TSOC(=최고열 지점 추종), 회색 계열이 나머지 존. 가로 점선은 위에서부터 강제 종료(104.8°C)·원 기사 피크(96°C)·사용자 셧다운 보고 대역(87°C). stock 상에서만 TSOC가 급등하고 GPU·타 클러스터는 70°C 부근에 머문다 — 마우스를 올리면 시각별 존 값이 보인다.
| 임계 | stock (1초 스핀) | patched (2ms) |
|---|---|---|
| 85°C 도달 | 부하 90초 | 12.7분 (스치듯 1회) |
| 90°C 도달 | 2.3분 | 미도달 |
| 92°C 도달 | 3.5분 | 미도달 |
| 95°C 도달 (피크) | 25.3분 | 미도달 (피크 85) |
강제 종료 온도(104.8°C, trip_point_0으로 기기에서 직접 확인)까지 stock의 피크 기준 여유는 9.8°C였다. 87°C 부근 셧다운 보고 대역은 부하 2분 만에 진입한다. 부하를 멈추면 3분 안에 50°C대로 떨어진다 — 열원이 관성 있는 보드가 아니라 즉시 꺼지는 CPU라는 뜻이다.
| head 노드 · 부하 중 | stock 평균 | 최고 | patched 평균 | 최고 | 평균 격차 |
|---|---|---|---|---|---|
| TSOC · SoC 종합 | 89.6 | 95 | 80.5 | 85 | −9.1 |
| TS1P · 클러스터1 성능코어 | 89.6 | 95 | 80.5 | 85 | −9.1 |
| TUNC · 언코어·메모리 | 73.7 | 77 | 71.2 | 75 | −2.5 |
| TGPU · GPU | 69.3 | 71 | 68.8 | 72 | −0.5 |
| TS0P · 클러스터0 성능코어 | 69.0 | 75 | 67.2 | 71 | −1.8 |
worker 노드는 stock/patched 평균 77.2 / 77.6°C로 차이가 없었다 — worker의 대기는 SpinCondition이 아니라 NCCL·CUDA 집합통신 쪽이라는 원 기사 관찰과 일치한다.
부하는 폐루프 방식이다. 클라이언트 스레드 4개가 각자 요청 한 건씩을 물고 있다가, 응답이 끝나는 즉시 다음 요청을 보낸다 — 생각 시간 없이. 그래서 서버에는 항상 정확히 4개의 요청이 동시에 걸려 있다. 요청 하나는 "약 1.4k 토큰 프롬프트 + max_tokens=400, ignore_eos=true" 채팅 완성으로, 내용과 무관하게 매번 정확히 400토큰을 생성하게 강제했다. 프롬프트마다 고유 태그를 넣어 프리픽스 캐시를 회피했으므로 매 요청이 프리필부터 새로 한다. 이 상태를 30분 유지한 것이 한 상(phase)이다.
| 부하 중 측정 | stock | patched |
|---|---|---|
| head vLLM CPU 합 (순간, 6초 델타) | 396~400% | 211~214% |
| worker vLLM CPU 합 | 208% | 206% |
| 30분간 완료된 요청 수 (동시 4 고정 · 요청당 400토큰 생성) | 386건 · 85.8 tok/s | 409건 · 92.1 tok/s |
| 부하 중 단독 프로브 (중앙값) | 18.1 tok/s | 17.8 tok/s |
스핀의 몫은 정확히 head의 400 − 211 ≈ 1.9코어다. 남는 211%는 스핀이 아니라 NCCL·CUDA 대기 스레드(worker에서 stock↔patched 불변으로 확인)와 스텝당 실작업(스케줄러·샘플링·4스트림 디토크나이즈·드래프터 검증)이며, 유휴로 돌아가면 3%까지 떨어진다. 원 기사의 "패치 후 89%"는 턴 사이 유휴가 섞인 실사용 부하의 평균이고, 이번 수치는 갭 없는 포화 부하라 높다 — 측정 조건이 다를 뿐 같은 그림이다.
합리적 의심이라 실클럭으로 확인했다. patched 부하 중(83°C) 성능코어는 3.9 / 3.978GHz — 정격 최대 그대로였다. stock 상의 클럭은 직접 샘플하지 못했지만, stock 부하 중(92°C 부근) 단독 프로브가 patched와 동률(18.1 vs 17.8)이었으므로 stock이 스로틀로 눌려 있었다면 나올 수 없는 값이다. 이 온도 대역에서는 스로틀 개입 없이 두 구성의 동시 부하 성능이 실제로 같다고 보는 게 맞다.
다른 GB10 클러스터에서 그대로 따라 할 수 있게 조건과 명령을 남긴다.
ghcr.io/anemll/dspark-vllm-gx10:0.1.1 (vLLM 0.25.2.dev0+g752a3a504 기반), DeepSeek-V4-Flash-0731 원본 FP8, TP=2 mp 백엔드, MTP 드래프터 5토큰shm_broadcast.py의 busy_loop_s: float = 1 ↔ 0.002 — 호출부가 인자를 넘기지 않으므로 기본값 교체로 충분하다# 1) 스핀 토글 (컨테이너 안, 서버 기동 전)
sed -i 's/busy_loop_s: float = [0-9.]*/busy_loop_s: float = 0.002/' \
/usr/local/lib/python3.12/dist-packages/vllm/distributed/device_communicators/shm_broadcast.py
# 2) 온도 존 식별과 기록 (호스트, 15초 간격 — 존 이름은 device/path에 있다)
for z in /sys/class/thermal/thermal_zone*; do
echo "$(cat $z/device/path): $(($(cat $z/temp)/1000))°C" # \_TZ_.TSOC, TS0P, TS1P, TGPU, TUNC ...
done
# 3) 부하: 4슬롯 롤링 생성 (슬롯마다 ~1.4k 토큰 프롬프트 + 400토큰 ignore_eos, 30분 반복)
# 프리픽스 캐시 회피를 위해 매 요청 프롬프트에 고유 태그를 넣는다
# 4) vLLM CPU 합 (순간): /proc/<pid>/stat의 utime+stime을 6초 간격 두 번 읽어 델타
# 대상 = cmdline에 vllm이 들어가는 전 프로세스
# 5) 프로토콜: 유휴 10분 → A상 30분 → 냉각(60°C 이하까지) → 재기동 → B상 30분
# 상 순서를 바꾸거나 반복해 재기동 분산(±13~15%)을 확인할 것
강제 종료 임계는 /sys/class/thermal/thermal_zone0/trip_point_0_temp(이 기기에서 104800 = 104.8°C)로 확인할 수 있다. 팬 없는 조건의 stock 상은 2분 만에 87°C 대역에 들어가므로, 온도를 지켜볼 수 없는 상황이라면 부하 시간을 짧게 잡는 편이 안전하다.
부하 형태: 슬롯 4개가 각각 "~1.4k 토큰 프롬프트 + 400토큰 ignore_eos 생성"을 완료 즉시 반복(고유 태그로 프리픽스 캐시 회피), reasoning low. 단독 프로브는 부하 유지 중 18분 시점에 256토큰 생성 3회를 추가 투입해 측정. 온도는 양 노드 15초 간격 상시 기록을 부하 창(마커 기준)으로 잘라 집계. CPU는 cmdline에 vllm이 포함된 전 프로세스의 utime+stime 6초 델타 합. 성능코어 실클럭은 cpufreq/policy5·policy15(클러스터0·1 성능코어)의 scaling_cur_freq.
이 실험의 원자료(존 기록 2노드 전체, 요청별 처리량, 이벤트 로그)는 로컬에 보존되어 있다.