OCulink eGPU 만들기 (RTX4070Ti Super + OCuP4V2 & EXP GDC)
야근을 피하기 위해 …
이것저것 할인을 받을 수 있는 기회 덕분에 오랜만에 새로운 컴퓨터를 구입할 수 있게 되었다. 제품은 GMK사에서 판매한 K8이며, AP는 AMD 8845HS와 RX780M GPU로 구성된 제품이다. 그런데, 슬프게도 회사 잔업이 쏟아지기 시작했다. 현재 주 개발 업무가 LLM 응용 애플리케이션인데, LLM을 내재화하다 보니 모델을 로컬에 업로드 해야만 한다.
대부분 동종 업계 개발이 그렇듯 nVIDIA 계열 GPU는 반 필수다. CUDA를 사용하지 않는다면 모델 업로드 후 추론까지 많은 시간이 소요되기 때문… 망했다.. GMK K8 은 작고 귀여운 큐브 형태의 PC로 확장성은 귀여운 멍멍이한테 줘버린 상태기 때문이다. 하지만, 집에서 잔업을 하지 않으면 매일 야근각이라..
eGPU의 선택, 그리고 OCulink
모두가 하지 말라는 선택을 하게 됐다. … eGPU … 어차피 게임이 아닌 개발이 주 목적이기 때문에 버스에서 발생하는 손실률은 감내할 수 있다 생각했다. 마침 GPU를 비롯한 각종 컴퓨터 부품을 티몬에서 할인 판매를 하고 있어 중고나라보다 더 저렴한 가격에 신품을 구입할 수 있었기에 나중에 중고로 되판다 하더라도 손해를 줄일 수 있을거라 생각했다.
마침 GMK K8 에는 USB 4.0 이 탑재되어 있어 40 Gbps 대역폭을 사용할 수 있다. USB-C 타입 eGPU도 고려해 봤지만, 늘 그렇듯 USB는 시어머니가 많은 녀석이라 PCIe 직결을 원했다. 8840HS를 탑재한 미니 PC들 대부분이 2개의 NVME 슬롯을 탑재하고 있다. K8의 NVME는 PCIe Gen4 규격이며, 4배속으로 연결되기 때문에 이론적으로 64 Gbps의 대역폭을 확보할 수 있다. 거기에 네이티브 연결이기 때문에 인터럽트가 없다. 기본적인 상식만으로도 USB 4.0 보다 더 높은 효율을 기대할 수 있을 것이다.
먼저 NVME to PCIe 제품을 찾아봤다. 가격도 저렴할 뿐만 아니라, 형태만 바꾼다면 외적 요소로 인한 전송속도 손실률을 억제할 수 있을거라 생각했었다. 하지만, 연결성이 좋지 않고 손이 많이 가는 걸 발견했다. 예를 들어 본체 전원을 켜기 전 eGPU 전원을 따로. 직접 켜야 한다거나, 품질도 썩 좋지 않다고. 그래서 인터페이스 선택은 OCulink였다.
완제품을 찾아보면 대부분 RX7600MXT를 탑재하고 있었다. 문제는 K8 내장 GPU, RX780M 보다 성능이 크게 좋지 않으면서 가격도 매우 비싸다는 것인데, RX7600MXT의 PassMark 자료를 단순 비교해 보면 RX780M 보다 65% 더 나은 성능을 보이지만, RTX4060의 60% 정도밖에 미치지 못하는 수준이면서 CUDA를 사용할 수 없어 선택할 수 없기 때문에 선택 대상이 될 수 없었다.
내 선택은 RTX4070Ti Super다. 가장 큰 이유는 16GB의 메모리가 필요했기 때문인데, 7B 모델을 필요한 부분만 쓴다면 꾸역 꾸역 넣을 수 있기 때문이다. (물론 7B 모델을 최대 정밀도로 사용하려면 28GB의 GPU 메모리가 필요) 그리고 RTX4070Ti Super의 성능은 RX780M 보다 무려 440% 이상 좋다. eGPU의 한계인 버스 대역폭으로 인한 퍼포먼스 손실이 발생해 성능이 2/3 토막 나더라도(물론 2/3 토막 날 일은 없다.) 2배이상 빠르기 때문에 충분한 값어치가 있다 생각했다.
이미 완제품을 선택하지 않기로 했기 때문에, 보드 그리고 GPU를 따로 구입해 조립하면 된다. 미사여구가 길었는데, 누군가 eGPU를 선택한다면 내 의식의 흐름을 참고했으면 하는 바람 때문이다.
완제품 보다는 조립으로
TH3P4G3 이쁘고 귀여운 ITX 케이스가 많았지만 eGPU에 최적화된 케이스를 찾았는데, 많은 선배들이 TH3P4G3 케이스를 사용하고 있는것을 발견했다. eGPU를 만드는데 최적화된 구조로 ATX 또는 ITX 파워를 장착할 수 있고 그래픽카드 길이에 따른 크기를 선택할 수 있다. 특히, 옆 패널이 완전 밀착형이 아니라, 공간을 만들 수 있는 형태로 조립할 수 있어 다양한 PCIe 보드를 장착할 수 있는 이점이 있다.
OCuP4V2 eGPU 확장 보드는 OCuP4V2를 선택했다. 위 케이스에 딱 맞는 제품으로 설치가 용이하고 PCIe Gen4를 지원하는 제품으로, NVME to OCulink 보드가 포함된 풀셋 제품을 선택했다. 만듦새는 깔끔한데, 쉴드 처리 되어 있어 쇼트 발생 확률이 낮다는 것이 장점이면서 넓은 방열판이 붙어 있어 발열 관리에도 유리해 보이기 때문이었다.
문제는, 정상적으로 동작하지 않는 문제가 생겼는데, 불규칙하게 시스템이 리부팅되는 문제가 발생했다. 윈도의 덤프 파일을 분석하니 “DXGI call IDXGISwapChain::Present failed [0X887 A0005]” 등이 발생하는 걸 확인했고, 이는 eGPU 시스템 하드웨어 있다는 것을 짐작할 수 있었다. 문제는 정확히 어디에 문제가 있다 확신하기 어려웠기 때문에 반품을 결정했고, 다행히 Aliexpress 무료 반품을 이용해 100% 환불을 받을 수 있었다.
오류 #1: VIDEO_TDR_FAILURE (116)
VIDEO_TDR_FAILURE (116) Attempt to reset the display driver and recover from timeout failed. Arguments: Arg1: ffffe3898cca5050, Optional pointer to internal TDR recovery context (TDR_RECOVERY_CONTEXT). Arg2: fffff8057ffd3670, The pointer into responsible device driver module (e.g. owner tag). Arg3: ffffffffc000009a, Optional error code (NTSTATUS) of the last failed operation. Arg4: 0000000000000004, Optional internal context dependent data. Debugging Details: ------------------ Unable to load image nvlddmkm.sys, Win32 error 0n2 *** WARNING: Unable to verify timestamp for nvlddmkm.sys SYMBOL_NAME: dxgmms2!VidSchiSendToExecutionQueue+17f8d MODULE_NAME: dxgmms2 IMAGE_NAME: dxgmms2.sys IMAGE_VERSION: 10.0.22621.3566 STACK_COMMAND: .cxr; .ecxr ; kb BUCKET_ID_FUNC_OFFSET: 17f8d FAILURE_BUCKET_ID: 0x119_2_DRIVER_FAILED_SUBMIT_COMMAND_dxgmms2!VidSchiSendToExecutionQueue
오류 #2: VIDEO_SCHEDULER_INTERNAL_ERROR (119)
VIDEO_SCHEDULER_INTERNAL_ERROR (119) The video scheduler has detected that fatal violation has occurred. This resulted in a condition that video scheduler can no longer progress. Any other values after parameter 1 must be individually examined according to the subtype. Arguments: Arg1: 0000000000000002, The driver failed upon the submission of a command. Arg2: ffffffffc000000d Arg3: ffff8a0ca00072a0 Arg4: ffffd406e9ca3240 Debugging Details: ------------------ SYMBOL_NAME: nvlddmkm+1493670 MODULE_NAME: nvlddmkm IMAGE_NAME: nvlddmkm.sys STACK_COMMAND: .cxr; .ecxr ; kb FAILURE_BUCKET_ID: 0x116_IMAGE_nvlddmkm.sys OSPLATFORM_TYPE: x64
두 번째 선택, EXP GDC 제품의 불량이 아니라 호환성 문제일 수 있었기에 동일한 제품을 다시 구입한다는건 리스크가 있었다. 특히 직구 억제 정책에 영향을 받을 수 있는 부품이라 지체할 수 없었기에 동사 EXP GDC 제품을 구입하게 됐다. 동일한 PCIe Gen4 4배속 제품으로 케이스 없이 사용할 수 있도록 만들어진 제품이다. 때문에 TH3P4G3(케이스)에 정확히 맞지 않지만, 앞서 이야기한 것 처럼 케이스가 열려 있는 타입이라 케이블을 밖으로 쉽게 빼낼 수 있었다. 어차피 한번 조립하면 분해할 이유가 없어 형태는 큰 문제가 되지 않는다 생각했다.
에너지 옵티머스 700W 마지막으로 파워서플라이는 티몬 할인으로 저렴하게 에너지 옵티머스 700W 80PLUS 브론즈 모듈러 제품을구입했다. 아무래도 케이블이 너무 많으면 정리하기 어려울 거라 생각했기때문에 풀-모듈러를 선택했는데 케이스 내부를 보면 잘선택했다 생각했다.
테스트
GPU-Z를 통해 확인하면 다음과 같은 결과를 얻을 수 있다. PCIe Gen4 4X로 동작하고 있으며 모든 정보를 정상적으로 불러온다.
3DMark TimeSpy를 이용해 얻은 결과는 다음과 같았다. PCIe 대역폭이 4X에 불과하기 때문에 성능 저하는 감내해야 하지만, 내장 GPU 대비 3배 가까운 스코어를 얻을 수 있으면 충분하다 생각했다. 실제 RX780M에서는 꿈도 꾸지 못했던 포르자 레이싱이 풀 스크린 풀 스팩으로 돌아가는 모습을 보니 잘 바꿨다는 생각을 했다.
여기까지다. LangChain으로 모델이 잘 올라가고 추론도 이상 없다는 것을 확인했다. 이제 잘 사용하면 될 것 같다. 참고로, 전원을 켜면 eGPU 가 같이 켜지고 전원이 꺼지면 같이 꺼지며, 아이들 상태에서의 전력 소모는 정말 미소하기 때문에 전기요금에서도 큰 문제가 없을거라 생각하고 있다. 사실 회사에서 AWS 환경에서 진행 중이었고, 이 때는 큰 문제가 없었다. 컨테이너를 만들어 세이지메이커에 올려 점프스타트로 시작하면 됐는데, 현재의 프로젝트가 PoC 고 비용이 급격한 우상향이 되면서 워크스테이션을 구입, 인하우스에서 잔여 개발을 진행하다 보니 이렇게 되어 버려서 .. (ㅠㅠ)