Strix Halo에서 ROCm이 빠른데도 진 이유 — APU 런타임 polling이 만든 35% 전력 효율 역전

🎯
한 줄 요약 — AMD Strix Halo (Ryzen AI MAX+ 395, Radeon 8060S iGPU) 위에서 동일 모델 Qwen3-30B-A3B Q4_K_M를 돌렸을 때, HIP/ROCm은 원시 throughput에서 압도적 우위(pp512 354 vs 78 t/s, tg 48 vs 36 t/s) 였지만 모델 로드만으로 CPU 2.5코어가 상시 burn되는 HSA polling 때문에, 24/7 idle 비중이 큰 워크로드에서는 Windows Vulkan(Ollama)이 약 35% 적은 에너지/토큰으로 역전한다. dGPU의 직관을 APU에 그대로 옮기면 안 된다는 사례.
📊
[이미지 #1 — Hero] Strix Halo APU 위에서 마주 선 ROCm과 Vulkan
파일: 2026-05-31-strixhalo-hero.png
notion image

📌 도입 — Strix Halo, 새로 등장한 "중간 지대"

이 글의 독자 — Strix Halo / Ryzen AI MAX+ 시리즈로 로컬 LLM 서빙을 운영하는 인프라/ML 엔지니어, 그리고 "AMD GPU에는 ROCm" 직관을 검증해야 하는 백엔드 의사결정자. throughput 표 한 장만 보고 백엔드를 고르는 모든 운영자에게 해당하는 케이스 스터디.
AMD Strix Halo (Ryzen AI MAX+ 395 + Radeon 8060S iGPU, gfx1151)는 데스크탑 dGPU도, 노트북 iGPU도 아닌 중간 지대다. 65 GB까지 끌어올릴 수 있는 통합 메모리(UMA/GTT) 위에서 30B급 LLM이 GPU에 풀로 올라가고, "데스크탑 한 대로 MoE 30B를 돌린다"가 마케팅이 아니라 실측 가능한 영역으로 들어왔다.
문제는 이 새 변종 위에 dGPU 시절의 직관 — "AMD GPU = ROCm 정답" — 을 그대로 옮기는 순간 운영 메트릭이 거꾸로 뒤집힌다는 것이다. 이 글은 ROCm 7.2.4 + 자체 빌드 HIP llama.cpp와 Windows-native Ollama (Vulkan)를 같은 모델·같은 PC에서 4라운드에 걸쳐 측정한 기록이다.
용어 짧게 정리:
  • APU (Accelerated Processing Unit): CPU와 GPU가 같은 실리콘 다이 위에 있는 통합 칩. dGPU(Discrete GPU)는 PCIe로 연결된 별도 카드.
  • UMA/GTT: APU에서 시스템 RAM 일부를 GPU 전용 메모리로 잘라주는 BIOS 설정. dGPU의 dedicated VRAM과 달리 동적이지 않고 BIOS 단계에서 정해진다.
  • HSA polling: GPU 작업 완료를 기다릴 때, OS 인터럽트로 깨우는 대신 CPU 스레드가 빈 큐를 계속 두드리며 확인하는 방식. dGPU에서는 비용이 묻히지만 APU에서는 그대로 보인다.
측정 환경 요약 — ASUS Strix Halo / Ryzen AI MAX+ 395 (32c) / Radeon 8060S gfx1151 / 64 GB RAM / BIOS UMA 65 GB / 모델 Qwen3-30B-A3B-Instruct-2507 Q4_K_M (17.28 GiB, MoE active 3B) / 측정일 2026-05-31.

🔬 1라운드 — VRAM 인식 문제 ("ROCm은 4 GB만 본다"의 진실)

처음 부딪힌 벽은 정해진 결말이었다. 기본 BIOS 할당으로는 ROCm이 dedicated VRAM만 보고 4 GB로 잘라 30B 모델을 GPU에 올리지 못했다. BIOS UMA/GTT를 65 GB로 늘리니 rocminfo Pool 1 GLOBAL ≈ 95.83 GiB, llama-bench도 정상적으로 device를 인식했다.
🧩
[이미지 #2] BIOS UMA 다이얼 — 4 GB에서 65 GB로
파일: 2026-05-31-strixhalo-vram-dial.png
notion image
rocminfo (gfx1151 agent, Pool 1): Segment: GLOBAL; FLAGS: COARSE GRAINED Size: 100,478,882 KB ≈ 95.83 GiB llama-bench device discovery: Device 0: AMD Radeon(TM) 8060S Graphics, gfx1151 (0x1151) VRAM: 98123 MiB, free: 97044 MiB
여기까지는 평범하다. "이제 쓸 수 있다"가 결론이고, 보통은 여기서 끝낸다.

⚡ 2라운드 — 원시 throughput에서는 HIP의 완승

Qwen3-30B-A3B Q4_K_M, -ngl 99로 풀 오프로드한 결과는 HIP에 굉장히 우호적이었다.
측정
WSL HIP (ROCm 7.2.4)
Windows Ollama (Vulkan)
비고
pp t/s (16 tok)
56.25
<strong>77.7</strong>
짧은 prompt는 Vulkan 우위
pp t/s (128 tok)
155.55
(미측정)
amortization 시작
pp t/s (512 tok)
<strong>354.09 ± 15.72</strong>
(미측정)
HIP의 진짜 강점
tg t/s (warm)
<strong>48.21 ± 16.39</strong>
36.2
warm 후 HIP 33% 빠름
tg t/s (cold first run)
36.06
36.2
cold는 사실상 동률
모델 로드
~27s
~24s
유사
표만 보면 결론은 명확하다. "장-prompt 처리와 warm generation에서 HIP가 압도, 그러니 ROCm으로 가야 한다." 이 시점에서 글을 마쳤다면 통념을 한 번 더 강화했을 것이다.
📈
[이미지 #3] HIP vs Vulkan throughput 막대그래프 — 표면적 압승
파일: 2026-05-31-strixhalo-throughput.png
notion image

🚨 3라운드 — 그런데 CPU가 이상하다 (idle 254% spin)

문제는 throughput 직후 시작됐다. llama-server로 모델을 띄워두고 아무 요청도 안 보낸 상태에서 top을 본 순간 모든 게 어그러졌다.

모델 로드 후 idle (요청 0건, 15초 샘플)

t=3s llama-server CPU: 265% RSS: 454 MB t=6s llama-server CPU: 259% RSS: 454 MB t=9s llama-server CPU: 253% RSS: 454 MB t=12s llama-server CPU: 249% RSS: 454 MB t=15s llama-server CPU: 245% RSS: 454 MB → 평균 ~254% (2.5 코어 상시 burn)

128 토큰 생성 직후 idle (30초 샘플)

t=5s CPU: 248% t=10s CPU: 244% t=15s CPU: 240% t=20s CPU: 237% t=25s CPU: 234% t=30s CPU: 231% system jiffies: busy +5089 / total +81108 = 6.27% of 32-core system → ~2.0 코어 환산. spin 미해소.
perf record/report로 떼어 본 hot path는 모두 libhsa-runtime64.so.1.18.70204의 offset 0x9ab00–0x9ad60 (~200 bytes) — HSA 런타임의 GPU 큐 polling 루프였다.
대조군인 Windows Ollama (Vulkan)는 동일 모델 로드 + 동일 idle 조건에서 측정 결과가 다음과 같았다.
ollama 메인(pid 16372) CPU: 0.0% RSS: 104 MB ollama UI(pid 10212) CPU: 0.0% RSS: 403 MB => AVG idle CPU: 0.0% 추론 중 runner CPU: ~65% of 1 core (32코어 시스템 2% 미만) 생성 직후 idle CPU: 0.0%
🔥
[이미지 #4] HSA runtime polling — 빈 큐를 무한히 두드리는 CPU 코어
파일: 2026-05-31-strixhalo-hsa-polling.png
notion image
HSA_ENABLE_INTERRUPT=1, HSA_ENABLE_DXG_DETECTION=1, GGML_CUDA_NO_PINNED=1, 부분 오프로드(-ngl 16)까지 모두 시도했지만 spin은 해소되지 않았다. polling 루틴이 ROCm 자체에 hardcoded돼 있어 환경변수로는 손대지 못한다.

🧩 왜 dGPU에서는 안 보였는가 — 같은 polling, 다른 다이

HSA polling은 ROCm 전체에 있는 동작이지만, dGPU에서는 잘 안 보였다. 워크로드 자체가 GPU 점유율을 높게 가져가서 polling 스레드가 그 안에 묻혔기 때문이다. 또 dGPU는 별도 다이, 별도 메모리, 별도 코어에서 polling을 돌려도 host CPU 입장에서는 "다른 곳에서 일어나는 일"이었다.
APU는 다르다. CPU와 GPU가 같은 다이를 공유하고 같은 메모리 컨트롤러를 쓴다. polling 스레드는 GPU가 idle한 동안에도 CPU 코어를 잡아먹으며, 그 코어는 host와 자원을 경쟁한다. 같은 polling이 dGPU에서는 "비용 0", APU에서는 "코어 2.5개 상시 burn"이 되는 이유다.
🧠
[이미지 #5] dGPU vs APU의 다이 구조 비교 — polling이 묻히는 곳 vs 드러나는 곳
파일: 2026-05-31-strixhalo-die-comparison.png
notion image
Vulkan은 같은 GPU 위에서 OS의 일반 GPU 완료 대기 메커니즘(인터럽트/이벤트 기반)을 그대로 쓴다. 그래서 idle CPU 0%가 가능하다. 이 차이가 throughput 비교에서는 안 보이고, 운영 시간 전체에서만 보인다.

🔋 4라운드 — 에너지/토큰으로 환산하면 순위가 뒤집힌다

throughput이 같은 영역에서 비교해도 polling 비용이 더해지는 순간 단순 비교가 깨진다. Zen 5 코어당 액티브 ~4 W를 가정하고 환산한 에너지/토큰 추정치는 다음과 같다.
시나리오
HIP 추가 전력
Vulkan 추가 전력
차이
모델 로드 후 idle
+~10 W 상시 (2.5코어 spin)
~0 W
HIP 상수 비용
활성 추론 1초 (GPU 동일 부담 가정)
+~10 W (CPU spin 중복)
+~2–3 W
HIP +7~8 W
추정 에너지/토큰 (GPU 공통 40 W)
~1.94 J/tok
<strong>~1.25 J/tok</strong>
<strong>Vulkan ~35% 적음</strong>
24h 저빈도 서버 (idle 95%+)
+~250 Wh/day
기준
~90 kWh/yr 추가
이 격차는 워크로드 패턴이 결정한다. burst batch처럼 GPU가 짧은 시간 동안 풀로 일하는 워크로드라면 polling 비용이 묻혀서 HIP의 throughput 우위가 살아남는다. 하지만 Discord 봇, API 서빙, 사내 RAG 게이트웨이처럼 idle 비율 95% 이상의 워크로드에서는 polling 비용이 사용 비용 자체를 압도한다. 1년 누적 ~90 kWh, 한국 전기료 기준 1~2만 원과는 별개로 발열·팬 소음·수명 영향이 더해진다.
⚖️
[이미지 #6] 에너지/토큰 시소 — 같은 throughput 영역에서 polling이 균형을 흔든다
파일: 2026-05-31-strixhalo-energy-seesaw.png
notion image

🛠️ 운영 권장 — 백엔드 선택은 throughput 표가 아니라 워크로드 패턴이다

이 측정 한 번으로 단정할 결론은 분명하다. dGPU의 직관 "AMD GPU = ROCm"를 Strix Halo 같은 통합 메모리 APU에 옮기면 틀린다는 것. APU에서는 "어느 백엔드가 빠른가"가 아니라 "어느 런타임이 CPU를 안 태우는가"가 운영 1순위 메트릭이다.
워크로드
권장 백엔드
이유
24/7 서버 (Discord 봇, API 서빙, 사내 RAG)
<strong>Windows Ollama (Vulkan)</strong>
idle CPU 0%, 인터럽트 기반 GPU 대기
burst batch (긴 prompt 일괄, reranking)
HIP llama-server 일시 기동 → 작업 후 즉시 kill
throughput 우위 살리되 polling 시간 최소화
실시간 단일 사용자 채팅
둘 다 가능 — warm tg 차이 12 t/s는 체감 미미
idle 시간 비중으로 결정

무효 튜닝 정리 (HSA spin 해결 안 됨)

  • HSA_ENABLE_INTERRUPT=1 — 스핀 그대로
  • HSA_ENABLE_DXG_DETECTION=1 — 디바이스 인식 필수, 스핀과 무관
  • GGML_CUDA_NO_PINNED=1 — 효과 없음
  • -ngl 16 (부분 오프로드) — CPU↔GPU layer hop 비용으로 CPU-only보다 더 느려짐
  • 클라이언트 정리 — 스핀은 트래픽과 무관

HIP 부활 트리거 (ROCm 릴리스 노트 키워드)

  • "HSA polling fix"
  • "gfx11 generic interrupt support"
  • "APU power efficiency"
이 키워드가 보이면 즉시 재측정. 그 전까지는 폼팩터에 맞는 백엔드를 골라야 한다.
🛡️
[이미지 #7] 워크로드 패턴별 백엔드 선택 — 24/7 idle vs burst batch
파일: 2026-05-31-strixhalo-workload-decision.png
notion image

📚 마치며 — 측정 한계와 갱신 단서

이 글의 모든 수치는 2026-05-31, 단일 PC(ASUS Strix Halo, BIOS UMA 65 GB)에서 ROCm 7.2.4 기준으로 측정한 스냅샷이다. 다음 단서가 바뀌면 결론도 갱신 대상이다.
  • ROCm 릴리스: HSA polling 또는 gfx11 인터럽트 지원 패치가 들어오면 격차가 사라질 수 있음
  • 모델 다양성: Qwen3-30B-A3B (MoE active 3B) 한 종으로만 측정 — dense 모델에서는 비율 다름
  • 전력 측정: 직접 와트미터 측정이 아닌 CPU 코어 점유율 기반 추정 — HWInfo/Ryzen Master 후속 측정 필요
  • 다른 Strix Halo 보드: BIOS UMA 설정과 BIOS 버전에 따라 재현 양상이 다를 수 있음
dGPU 시절 굳어진 "AMD GPU는 ROCm이 정답" 같은 통념이 APU/iGPU에서는 운영 메트릭 전체를 거꾸로 뒤집을 수 있다는 사례 하나. Strix Halo 같은 통합 메모리 APU가 늘어날수록 이런 "런타임 cost" 평가가 표준이 될 것이다.

참고 자료 카테고리

구체 URL은 ROCm/llama.cpp/Ollama 릴리스 노트가 활발히 갱신되는 만큼 검색 키워드로 남긴다.
  • AMD Strix Halo / gfx1151 ROCm 지원 현황 — ROCm release notes의 "Supported GPUs / gfx1151" 섹션, Phoronix "Strix Halo ROCm" 벤치마크 시리즈
  • llama.cpp HIP / Vulkan 백엔드 비교ggml-org/llama.cpp 리포지토리의 Vulkan 라벨 이슈, HIP_UMA 도입 PR
  • HSA runtime polling 이슈 (APU/iGPU) — ROCm 이슈 트래커에서 "HSA polling APU CPU usage" 검색, libhsa-runtime64의 wait_until_busy 관련 토론
  • Ollama Vulkan 백엔드 도입 배경 — Ollama 공식 릴리스 노트의 "Vulkan" 키워드, OLLAMA_VULKAN 환경변수 문서

실측 원본 데이터 출처

  • 측정 PC: ASUS Strix Halo (Ryzen AI MAX+ 395, Radeon 8060S, gfx1151, 64 GB RAM, BIOS UMA 65 GB)
  • 측정일: 2026-05-31
  • HIP 빌드: llama.cpp commit 2d9b7c8 (-DGGML_HIP=ON -DGGML_HIP_UMA=ON -DAMDGPU_TARGETS=gfx1151)
  • Vulkan 측정: Windows-native Ollama, OLLAMA_VULKAN=1, HIP_VISIBLE_DEVICES=-1, ROCR_VISIBLE_DEVICES=-1
  • 모델: Qwen3-30B-A3B-Instruct-2507 Q4_K_M (17.28 GiB, MoE active 3B)

측정일: 2026-05-31 · ROCm 7.2.4 · llama.cpp commit 2d9b7c8 · Qwen3-30B-A3B-Instruct-2507 Q4_K_M