DGX Spark에서 보낸 6개월간의 로컬 LLM 경험: 벤치마크는 당신에게 거짓말을 하고 있다
요약
NVIDIA DGX Spark를 6개월간 사용하며 겪은 로컬 LLM 실행 경험을 공유합니다. 단순 사양표의 메모리 용량보다 메모리 대역폭이 토큰 생성 속도에 미치는 결정적인 영향을 분석하고, MoE 모델을 활용한 최적의 워크로드 설정 방법을 제안합니다.
핵심 포인트
- LLM 추론 속도는 메모리 용량이 아닌 메모리 대역폭에 의해 제한됨
- Dense 모델보다 MoE 모델이 DGX Spark의 하드웨어 구조에 훨씬 적합함
- 벤치마크 확인 시 모델 아키텍처, 양자화, 추론 엔진을 반드시 고려해야 함
- 로컬 LLM 운영 시 대역폭 한계를 극복하기 위한 전략적 모델 선택이 필수적임
지난 겨울, 저는 NVIDIA의 DGX Spark를 책상 위에 올려두었습니다. GB10 Grace Blackwell 칩, 128 GB의 통합 메모리(unified memory), 가격은 약 4,700유로이며, 크기는 대략 페이퍼백 두 권을 쌓아놓은 정도입니다. 저는 자동화 컨설팅 회사를 운영하고 있는데, 제 고객들은 독일인이며 문서를 미국 클라우드에 전송하는 것에 거부감을 느낍니다. 따라서 "모델이 제 사무실에서 실행됩니다"라는 말은 제가 말 그대로 판매할 수 있는 하나의 기능(feature)이 됩니다.
이 글은 제가 구매하기 전에 찾을 수 없었던 내용에 관한 것입니다. 이 기기가 실제로 무엇을 잘하는지, 왜 사양표(spec sheet)가 저를 저녁 내내 오도했는지, 그리고 이 기기를 실망스러운 제품에서 현재 제 생산 워크로드(production workloads)의 대부분을 처리하는 기계로 바꿔놓은 설정(config)은 무엇인지에 대해 다룹니다.
중요한 숫자는 마케팅 페이지에 있지 않다
여기에 함정이 있습니다. 헤드라인 사양은 용량을 강조합니다: 128 GB 통합 메모리, 1 페타플롭(petaflop)의 FP4 연산 능력. 용량은 무엇이 들어갈 수 있는지를 결정합니다. 하지만 그것이 무엇을 사용할 수 있는지에 대해서는 아무것도 말해주지 않습니다.
토큰 생성(Token generation)은 메모리 대역폭 제한(memory-bandwidth-bound)을 받습니다. 단 하나의 토큰을 생성할 때마다, 엔진은 본질적으로 활성화된 모든 모델 가중치(model weights)를 칩을 통해 스트리밍합니다. 따라서 당신의 한계치는 간단한 나눗셈으로 결정됩니다:
text
최대 토큰/초 ≈ 메모리 대역폭 / 활성 가중치의 바이트 수
...
실제 수치는 이 한계치보다 낮게 나타납니다. NVIDIA 자체의 Ollama 벤치마크에 따르면, 이 기기에서 FP8 정밀도의 70B 밀집 모델(dense model)은 약 2.7 tok/s를 보여줍니다. 첫날 저녁, 저는 정확히 그런 모델을 로드하고 프롬프트를 입력한 뒤, 토큰이 새는 수도꼭지처럼 뚝뚝 떨어지는 것을 지켜보았습니다. 비교를 위해 말씀드리자면, 819 GB/s의 대역폭을 가진 M3 Ultra는 동일한 모델을 25-30 tok/s로 실행합니다. Spark는 Mac보다 실질적인 모델 용량은 3배 더 크지만, 대역폭은 3분의 1 수준입니다. 아무도 제품 영상에서 이런 문장을 말하지 않습니다.
그렇다면 이 기기가 나쁜 걸까요? 아닙니다. 저는 두 가지 측면에서 기기를 잘못 다루고 있었습니다.
해결책 1: 밀집 모델(dense models) 실행을 중단하라
전문가 혼합(Mixture-of-experts, MoE) 모델은 토큰당 파라미터(parameters)의 일부만 활성화합니다. 대역폭 방정식은 활성화된 바이트만 계산합니다:
text
MoE, 총 ~110B / 활성 ~12B @ Q4 (~7 GB 활성):
273 / 7 ≈ 39 tok/s 한계치
갑자기 이 장비의 의미가 명확해집니다. 128GB의 메모리는 더 작은 기기에는 도저히 담을 수 없는 전체 전문가 세트(expert set)를 수용하면서도, 토큰당 트래픽은 작게 유지합니다. 거대 MoE 모델은 정확히 이 하드웨어가 설계된 목적에 부합하는 워크로드이며, 현재의 오픈 웨이트 (open-weight) 세대(더 큰 Qwen MoE 변체, gpt-oss-120b 및 그 친구들)는 모델과 엔진에 따라 여기서 30-80 tok/s를 제공합니다. 이는 사람이 읽는 속도보다 빠릅니다.
이 급의 하드웨어를 평가하는 모든 이들에게 제가 이제 제안하는 실질적인 규칙은 다음과 같습니다: 세 가지 수식어 없이는 초당 토큰 수 (tokens-per-second) 수치를 절대 믿지 마십시오. 즉, 어떤 모델 아키텍처(dense 또는 MoE)인지, 어떤 양자화 (quantization)를 사용했는지, 어떤 추론 엔진 (inference engine)을 사용하는지입니다. 동일한 장비라도 이러한 선택에 따라 2.7과 60이라는 결과가 나올 수 있으며, 두 숫자 모두 정직한 수치입니다.
두 번째 해결책: 대규모 작업에는 기본 스택을 사용하지 마십시오.
편의 도구들(Ollama 등)은 시작하기에는 훌륭하지만, 이 특정 ARM+Blackwell 플랫폼에서는 눈에 띄게 뒤처져 있습니다. 최적화된 경로인 TensorRT-LLM이나 CUDA 지원으로 빌드된 최신 llama.cpp를 사용하고, 가능한 경우 NVFP4 양자화된 가중치 (quantized weights)를 사용하는 것은 실질적인 성능 향상을 가져다줍니다. NVIDIA는 출시 이후 이 플랫폼을 위해 꾸준한 소프트웨어 업데이트를 제공해 왔으며 그 이득은 유의미했습니다. 이는 출시 당일의 소프트웨어가 성능을 제대로 끌어내지 못했다는 말을 정중하게 표현한 것입니다.
제 설정은 세 개의 레이어로 정착되었습니다.
레이어 1: 모델당 하나씩 운영되는 llama.cpp 서버. 장비에서 소스 코드로 직접 컴파일했습니다 (Ubuntu 파생형인 DGX OS를 실행하므로 특별할 것은 없습니다). 각 모델은 OpenAI 호환 엔드포인트를 노출하는 llama-server 프로세스를 가집니다.
레이어 2: 교통 정리 역할을 하는 llama-swap. 저는 다섯 개의 모델이 한꺼번에 상주하는 것을 원하지 않으며, 모델을 교체하기 위해 SSH로 접속하는 것도 원하지 않습니다. llama-swap은 들어오는 요청의 모델 필드에 따라 모델 서버를 지연 시작(lazily start) 및 중지시키는 작은 프록시 (proxy)입니다:
# config.yaml (축약본)
models:
"qwen-big":
cmd: >
/opt/llama.cpp/llama-server
-m /models/qwen3-moe-q4.gguf
--port ${PORT} -c 32768 -ngl 999
ttl: 900 # 15분 유휴 상태 후 언로드
"gemma-fast":
cmd: >
/opt/llama.cpp/llama-server
-m /models/gemma3-27b-q4.gguf
--port ${PORT} -c 16384 -ngl 999
ttl: 900
요청 모델: "qwen-big"를 지정하면 프록시가 이를 실행하고, 기존 모델을 비운 뒤 라우팅(routing)합니다. 외부에서 보기에는 마치 클라우드 제공업체처럼 하나의 엔드포인트가 여러 모델을 호스팅하는 것처럼 동작합니다.
Layer 3: 모든 것의 앞단에 위치한 LiteLLM 프록시입니다. 이 부분은 제가 칼싸움을 해서라도 지켜낼 만큼 핵심적인 요소입니다. 저의 모든 n8n 워크플로우(workflows)와 스크립트는 단 하나의 API와 통신합니다. 그 뒤에서 LiteLLM은 모델 이름에 따라 라우팅을 수행합니다: 로컬 이름은 Spark로, 프런티어(frontier) 모델 이름은 클라우드 API로 전달됩니다. 즉, 코드 변경 없이 문자열 하나만 바꾸는 것으로 어떤 워크플로우든 로컬과 클라우드 사이를 이동시킬 수 있음을 의미합니다:
model_list:
- model_name: local-workhorse
litellm_params:
model: openai/qwen-big
api_base: [http://spark.local:8080/v1](http://spark.local:8080/v1)
- model_name: heavy-thinking
litellm_params:
model: anthropic/claude-sonnet-4-6
이 방식이 가능하게 하는 마이그레이션(migration) 경로는 진정한 킬러 기능(killer feature)입니다. 저는 클라우드 모델을 대상으로 워크플로우를 프로토타이핑하고, 프롬프트(prompt)가 안정되면 이를 local-workhorse로 지정하여 품질이 유지되는지 확인합니다. 추출(extraction), 분류(classification), 요약(summarization) 또는 변환(transformation)과 관련된 거의 모든 작업에서 예상보다 더 자주 품질이 유지되었습니다. 하지만 진정으로 어려운 추론(reasoning) 작업에서는 그렇지 않으며, 그렇지 않은 척하는 것은 고객을 잃는 결과를 초래할 것입니다.
실제 운영 환경에서 실행되는 것들
구체적으로, 6개월간 정착 과정을 거친 후의 모습은 다음과 같습니다:
중형 밀집 모델(dense model, 27B 급)은 지연 시간(latency)에 민감한 작업을 위해 상시 가동됩니다: 이메일 파이프라인의 분류, 문서에서의 정보 추출, 데이터가 외부로 나가기 전의 익명화(anonymization) 작업 등입니다. 단일 사용자에게는 사실상 즉각적인 속도를 보여줍니다.
대형 MoE(Mixture of Experts) 모델은 품질이 중요한 배치(batch) 작업에 교체 투입됩니다: 보고서 생성, 초안 브리핑, 전사(transcript) 요약 작업 등입니다. 읽기에 편안한 속도이며, 한계 비용(marginal cost)이 제로에 가깝습니다. 비용이 계속 올라가는 상황이 아니기에, 수천 개의 문서를 대상으로 실험을 수행할 때 더 이상 망설이지 않게 되었습니다.
임베딩 모델 (Embedding model) 하나가 제 문서 아카이브 전체를 검색하기 위해 영구적으로 실행됩니다. 이 워크로드 (Workload)는 매우 가벼워서 거의 비용이 들지 않으며, "데이터가 방을 떠나지 않는다"는 점이 저에게 가장 중요하게 작용하는 부분입니다.
이 모든 것을 돌리는 데 드는 월간 전기료는 연료 탱크 하나 정도의 비용이며, 클라우드 API 청구액은 눈에 띄게 줄었습니다. 하지만 솔직히 말씀드리면, 1인 컨설턴트 규모에서는 이 장비의 비용이 몇 달이 아닌 몇 년에 걸쳐 상각됩니다. 저는 데이터 주권 (Data sovereignty)과 자유로운 실험 환경을 구매한 것이며, 비용 절감은 부수적인 이득일 뿐입니다.
구매해야 할까요?
다음의 경우라면 구매하세요: 작고 조용한 박스 안에서 거대 모델 (Big-model) 급의 성능이 필요하거나, 워크로드 (Workload)가 MoE (Mixture of Experts) 형태 또는 배치 (Batch) 형태인 경우, CUDA 호환성이 중요하거나, "로컬 (Local)" 환경이 비용 청구가 가능한 컴플라이언스 (Compliance) 요구 사항인 경우입니다.
다음의 경우라면 건너뛰세요: 주로 빠른 밀집 (Dense) 70B 채팅을 원하는 경우 (대역폭이 넓은 Mac Studio가 부끄러울 정도로 압도적입니다), 리눅스 (Linux)를 다뤄본 적이 없는 경우 (이 장비는 완전히, 영원히 리눅스입니다), 또는 실제 목표가 학습인 경우 (이 경우 현재 사용 중인 노트북에서 8B 모델을 돌리는 것으로도 동일한 교훈을 무료로 얻을 수 있습니다).
그리고 무엇을 구매하든: 구매한 첫날 저녁에 낙담하는 기분으로 대역폭 계산을 하는 것이 아니라, 구매하기 전에 미리 대역폭 계산을 해두십시오. 제가 이름을 언급할 수 있는 어떤 컨설턴트처럼 말이죠.
댓글은 열려 있습니다. 특히 최근의 llama.cpp 빌드와 TensorRT-LLM을 비교했을 때, 다른 분들은 이 플랫폼에서 초당 몇 개의 토큰 (Tokens/sec)을 얻고 계시는지 매우 궁금합니다. 제 수치는 소프트웨어 업데이트가 있을 때마다 계속 개선되고 있으며, 이제는 제 자신의 벤치마크 (Benchmark)조차 반쯤 믿지 못할 지경입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기