GB10 한 대에 Gemma‑4‑26B 넉 달, 이 조합은 잘 맞았다
GB10 한 대에 Gemma-4-26B-A4B를 vLLM으로 올려 사내 챗봇으로 넉 달째 쓰고 있습니다. 공식 NVFP4 4비트 판으로 바꾸자 디코드가 22.5에서 41.1 tok/s로 뛰었고, 한국어 산문 답변은 51.5 tok/s가 나옵니다. 다만 긴 문서 한 건이 팀 전체를 83초 멈추는 문제는 파라미터로 고치지 못했습니다.

한 줄 결론
이 하드웨어에서 이 모델은 잘 맞는다. 한국어 산문 51.5 tok/s면 읽는 속도보다 빠르고 동시 32건까지 큐 없이 받는다. 26B급 MoE는 통합 메모리 기계에 특히 잘 맞는데, 토큰마다 활성 파라미터만 읽으면 되니 273GB/s가 병목이 덜 된다. 아직 못 푼 것은 긴 문서 프리필이 팀 전체를 멈추는 문제이고, 이건 파라미터가 아니라 구조 문제라 정직하게 말하면 기계를 더 놓아야 끝난다.
정정 (2026년 10월 3일): 원래 순수 디코드 속도 범위를 "38.8 ~ 56.6 tok/s"로 적었으나, 측정 기록과 본문 설명에 맞춰 "38.1 ~ 56.6 tok/s"로 고쳤습니다.
작은 회사에서 사내용 을 도입 전 테스트를 GB10으로 진행했습니다. 서버는 NVIDIA DGX Spark(GB10) 한 대가 전부입니다. GB10 칩에 통합 메모리 128GB, 대역폭 273GB/s — 이 위에 채팅 백엔드와 프런트, DB, 그리고 LLM 서빙까지 전부 올라가 있습니다. 사용자는 사내 직원들이고 대부분 한국어 업무 문서를 붙여 넣고 요약하거나 문서 초안을 작성합니다. 기본 모델로 Gemma-4-26B-A4B를 쓰는데, 26B짜리 인데 당 가 약 4B라 크기에 비해 가볍습니다.
이 글은 그 모델을 넉 달 써보면서 바꾼 설정과, 바꿔봤다가 원상복구한 것들, 그 과정에서 알게 된 것들을 정리한 기록입니다. 수치는 전부 이 작은 서버에서 직접 확인한 것입니다. 사내 네트워크 구성이나 도메인 같은 건 뺐습니다. 이름부터 한 번 정리하면, 이 글에서 DGX Spark와 GB10은 같은 플랫폼을 가리키고 실제로 쓰는 기기는 델이 낸 Dell Pro Max with GB10입니다.
직원 수십 명 규모의 사내 챗봇을 기계 한 대로 끝내고 싶으시다면 이 조합을 권합니다. 반대로 사용자들이 수만 토큰짜리 문서를 상시로 붙이는 팀이라면 한 대로는 안 되고, 아래 "긴 문서" 절을 먼저 읽으신 뒤 두 대를 잡으시는 편이 낫습니다. 이미 GB10에 을 올려 쓰고 계시다면 같은 세대의 MoE로 바꾸는 것만으로 체감이 달라질 수 있습니다.
공식 4비트 판에 슬롯 32, 커스텀 빌드로 실행한다
모델은 nvidia/Gemma-4-26B-A4B-NVFP4(공식 4비트), 엔진은 (GB10용 커스텀 arm64 빌드), 드래프트는 gemma4-26b-assistant( k=2)입니다. 실행 플래그는 이렇습니다.
--kv-cache-dtype fp8--gpu-memory-utilization 0.45--kv-cache-memory-bytes 21474836480(20 GiB 고정)--max-model-len 131072--max-num-seqs 32--max-num-batched-tokens 8192--moe-backend marlin--reasoning-parser gemma4--enable-auto-tool-choice --tool-call-parser gemma4
이 상태에서 가 123만 이고, 131k짜리 요청을 9.39건까지 동시에 담습니다.
속도는 세 가지로 나눠서 측정했다
먼저 이 이야기부터. 속도 이야기는 측정 방법을 안 밝히면 무의미하고, 같은 모델이 길이에 따라 12 tok/s로도 50 tok/s로도 보입니다. 그래서 세 가지를 섞지 않습니다.
- (decode) — 짧은 프롬프트에
ignore_eos로 길이를 고정하고, 첫 글자 이후 구간만 측정합니다. - (prefill) — 매번 다른 접두사를 맨 앞에 붙여 를 피한 긴 프롬프트에
max_tokens=1. 이때 가 곧 프리필 속도입니다. - 동시 — 같은 작업 N건을 배리어로 진짜 동시에 출발시킵니다.
여기에 하나 더. 체감 e2e — 실제 한국어 업무 질문 세 개를 자연 종료까지 받아 총 소요를 측정하는 것인데, 위 세 가지는 엔진을 비교할 때 쓰고 사용자가 실제로 느끼는 건 여기입니다.
한국어 산문 51.5 tok/s, 동시 32건까지 큐가 없다
- 한국어 산문 답변 한 건(약 1,100) — 22.0초 / 51.5 tok/s
- 본문 첫 글자까지 — 0.14초
- 순수 (256 고정) — 38.1 ~ 56.6 tok/s (편차가 큽니다. 아래 참고)
- 3.5k 토큰 — 2,383 ~ 2,609 tok/s ( 1.3~2.2초)
- 프리필 34k 토큰 — 1,130 tok/s (TTFT 30.3초)
- 동시 4건 — 건당 37.9 / 합계 142.1 tok/s
- 동시 20건 — 건당 17.0 / 합계 318 tok/s
읽는 속도보다 빠르고, 사용자 불만이 없는 구간입니다.
디코드 항목의 편차는 정직하게 적어둡니다. 하루에 여러 번 측정했는데 38.1에서 56.6까지 흔들렸고, 같은 에 같은 설정인데도 일정하지 않습니다. 그래서 이 항목 하나로 판정하지 않고 위의 체감 e2e를 같이 봅니다. 그쪽은 자연 종료까지 받는 대신 0이라 출력 토큰 수까지 재현돼서, 세 문항 중 둘은 소수점까지 반복됩니다.
참고로 같은 GB10에서 같은 모델을 테스트한 커뮤니티 실측이 산문 49.8 tok/s로 공개돼 있는데 우리가 51.5입니다. 특별히 잘 튜닝했다기보다는 이 하드웨어에서 이 모델의 한계가 거기쯤이라는 뜻으로 읽고 있습니다.
4비트 전환 하나가 디코드를 1.83배로
가장 큰 개선입니다. 같은 모델의 공식 NVFP4 판으로 바꿨더니 가 22.5에서 41.1 tok/s로, KV 용량은 2.2배가 됐습니다.
바꾼 건 compose 두 줄입니다. 가중치 경로와 --moe-backend marlin. 모델 ID가 그대로라 DB도, 감사 기록도, 이 엔드포인트를 쓰는 사내 다른 앱도 하나도 안 건드렸는데 이게 의외로 중요했습니다. (quantization) 교체를 "모델 교체"로 만들지 않은 덕에 반나절이면 끝났습니다.
여기서 배운 것 하나. 은 4비트로도 안 빨라지고 오히려 2% 손해였습니다. 프리필은 연산 병목이고 디코드는 메모리 대역폭 병목이라, 가중치를 줄이는 건 디코드에만 듣습니다. GB10의 273GB/s를 당 읽는 바이트로 나눈 값이 디코드 한계이고, 4비트는 그 분모를 줄인 것입니다.
동시 슬롯을 32로 올려도 단독 속도는 그대로였다
로 KV가 넉넉해지자 슬롯 숫자만 병목으로 남았습니다. 16일 때 동시 20건을 걸면 17번째부터 큐에서 첫 글자까지 15초를 기다렸습니다.

붐빌 때 건당 23에서 17 tok/s로 떨어지고, 혼자 쓸 때도 약 3% 느려집니다(40.8 → 39.6, 각 8회). 일이 사라진 게 아니라 대기가 앞사람에게 몰리지 않고 전체에 고르게 퍼진 것이고, 17 tok/s는 여전히 읽는 속도보다 빠릅니다. 15초 정지와 맞바꿀 값이라고 봤습니다.
KV는 비율 대신 바이트로 고정했다
이게 이 플랫폼에서 제일 실용적인 발견. gpu-memory-utilization과 실제 KV 크기의 관계가 예측 불가능한데, util 0.35에서 KV가 40.5 GiB인데 0.30에서 13.8 GiB가 나오는 식입니다. 기동 시점의 여유 메모리에 좌우되기 때문입니다. 그래서 util은 손대지 않고 --kv-cache-memory-bytes로 크기를 고정했고, 그 뒤로 기동이 재현 가능해졌습니다.
부수 효과로 여유가 생겼습니다. 로 KV가 222만 까지 갔었는데 20 GiB(123만 토큰)로 일부러 낮춰 잡았고, 남긴 몫으로 음성 전사 모델과 두 번째 을 같은 기계에 올렸습니다. 131k를 꽉 채운 요청 기준 9.39건이면 우리 규모에는 충분한 수치.
31B로 올려봤다가 속도에 놀라 바로 내렸다
같은 세대의 31B를 로 붙여 비교했더니 결과는 전 항목 열세.

재미있는 건 수용률은 31B가 더 높았다는 점입니다(74.3% 대 69.0%). 드래프터는 오히려 잘 맞는데 본 모델이 느려서 진 것입니다. 26B는 라 마다 만 읽고, 31B는 dense라 30.4 GiB를 전부 읽습니다. NVFP4가 된 건 MLP뿐이고 60개 층의 (attention)은 으로 남아 있었습니다.
품질은 고정 19문항 블라인드로 31B 9 / 26B 7 / 동등 3으로 무승부. 두 배 느린 값으로 살 만한 차이가 아니었습니다.
컨텍스트를 8k로 줄이고 남는 메모리를 전부 KV로 몰아준 구성도 다시 측정했습니다. 개별 속도는 소수점까지 그대로였고 동시 처리 천장만 올라갔습니다( 3.7 → 3.7, 604.8 → 605.7). 이때 확실히 알았습니다 — max-model-len과 util은 자리를 정할 뿐 속도를 정하지 않습니다.
청크를 두 배로 키웠다가 되돌렸다
긴 문서의 첫 글자를 앞당기려고 --max-num-batched-tokens를 16384로 올렸는데 46.0초가 45.5초가 됐을 뿐, 전혀 안 좋아졌습니다. 은 연산 병목이라 청크를 어떻게 쪼개든 총 연산량이 같습니다. 잃은 건 확실했습니다.
- 34k — 46.0초 → 45.5초
- KV — 222만 → 162만 토큰(−27%)
- 동시 20건 합계 — 318 → 271
되돌렸습니다.
긴 문서 한 건이 팀 전체를 83초 멈춘다
이건 아직 안 풀린 숙제. 이 실행되는 동안 다른 사용자의 생성이 멈춥니다.
- 48,508 을 붙이면 — 83초 정지
- 114,059 토큰을 붙이면 — 6분 38초 정지
48k는 지금 당장 도달합니다. 우리 첨부 상한이 48,000 토큰이라, 한 사람이 큰 문서를 붙이면 83초 동안 팀 전체가 멈춘다는 뜻입니다. 파라미터를 전부 시도해 봤지만 안 고쳐졌습니다 — 의 Concurrent Partial Prefill은 우리가 쓰는 경로에 없습니다.
결론은 파라미터가 아니라 구조. 인스턴스를 나누면 정지가 감속으로 바뀝니다.
- 한 인스턴스 — 생성 중에 긴 문서가 들어오면 16 tok/s가 0~1로 떨어지고 50초 정지
- 인스턴스 분리 — 17 tok/s가 6~7로 내려가되 멈추지는 않습니다
문서 전용 인스턴스를 띄울 자리는 잡아뒀는데 상시로 띄우려면 메모리가 모자라고, 사실상 기계를 한 대 더 놓아야 끝나는 문제입니다.
플래그 하나가 빠지면 에러 없이 조용히 느려진다
재현되는 것만 적습니다.
--quantization을 주면 죽습니다. 체크포인트에 --quantization modelopt를 주면 전용 클래스로 잡혀 기동에 실패하고, 플래그를 빼면 알아서 modelopt_fp4를 고릅니다.
--moe-backend marlin이 없으면 조용히 느려집니다. sm121에서 나쁜 커널을 타는데, 에러가 안 나기 때문에 벤치를 실행해 보지 않으면 모릅니다.
체크포인트의 chat template이 낡아 있었습니다. 공식 배포본인데 몇 달 전 버전이라 그 사이 수정이 빠져 있었고, 손으로 덮어썼습니다. 재다운로드하면 날아가므로 별도 파일에 경위를 적어뒀습니다.
재기동 전에 페이지 캐시를 비워야 하는데 순서가 중요합니다. 안 비우면 CUDA가 가용 메모리를 낮게 봐서 기동을 거부하는데, 그렇다고 띄운 채로 비우면 그 컨테이너 몫이 안 잡혀서 여유가 모자란 채로 재생성이 진행됩니다. 컨테이너를 먼저 내리고 비워야 합니다. 같은 실수로 두 번째 모델을 10시간 죽여본 적이 있습니다(내렸을 때 62GiB, 띄운 채로는 20GiB).
--kv-cache-memory-bytes를 주면 gpu-memory-utilization이 무시됩니다. 기동 로그에 "kv_cache_memory_bytes로 지정했으므로 메모리 프로파일링을 건너뛴다. 이는 gpu_memory_utilization을 존중하지 않는다"고 명시돼 있습니다. 즉 넘치면 사전 검사 없이 그대로 OOM으로 갑니다. 우리 설정 주석에 "util을 기동 게이트로 쓴다"고 적어놨었는데 틀린 설명.
설정 파일은 파일이 아니라 디렉토리로 마운트하는데, 그 디렉토리도 inode에 걸립니다. 브랜치를 바꿔서 디렉토리가 지워졌다 다시 생기면 컨테이너는 사라진 옛 디렉토리를 계속 보고, 그 안은 비어 있습니다. 이걸 모르고 nginx를 reload했다가 사이트를 52초 죽였습니다.
기동에 10분이 걸립니다. 모델이나 파라미터를 바꾸는 건 계획된 중단으로 잡아야 하고, "잠깐 재기동"이라는 게 없습니다.
통합 메모리에서는 이웃이 대가를 치른다
두 번째 모델에 KV를 8에서 24 GiB로 늘려봤더니 그쪽은 의도대로 좋아졌는데, 놀고 있던 gemma가 같이 느려졌습니다.

2회 재현됐고 되돌리니 복구됐습니다. 는 멀쩡한데 과 동시 처리만 맞았다는 게 힌트입니다. 디코드는 스텝마다 하나치 활성만 잡지만, 프리필은 8,192토큰 폭의 임시 버퍼를 한 번에 잡습니다. GB10은 통합 메모리라 그 임시 할당이 호스트 여유와 같은 풀에서 나오고, 호스트 가용이 30에서 14 GiB로 줄자 그쪽만 눌린 것입니다.
여러 모델을 한 기계에 올릴 때 상주 메모리만 계산하면 안 됩니다. 임시 버퍼가 들어갈 자리를 남겨야 합니다.
속도를 올린 건 전부 읽는 양을 줄인 쪽이었습니다. 4비트 전환이 그렇고 선택이 그렇습니다. 반대로 자리를 늘리는 값들(max-model-len, util, max-num-batched-tokens)은 한 번도 속도를 올린 적이 없고, 두 종류를 구분하는 데 시간이 좀 걸렸습니다.
아직 못 푼 건 하나입니다. 긴 문서 프리필이 팀 전체를 멈추는 것. 이건 파라미터가 아니라 구조 문제고, 정직하게 말하면 기계를 더 놓아야 끝납니다.
그리고 엔진 버전을 아직 못 올렸습니다. 우리가 쓰는 건 gemma 4 지원을 위한 커스텀 빌드라 상류 최신판과 거리가 꽤 벌어져 있는데, 최신판에 sm12x용 디코드 커널과 새 MoE 백엔드가 들어왔습니다. 운영 모델이라 손대는 값어치를 아직 못 정했습니다.
그래도 이 하드웨어에서 이 모델은 잘 맞습니다. 한국어 산문 51.5 tok/s면 읽는 속도보다 빠르고 동시 32건까지 큐 없이 받는데, 26B급 MoE는 통합 메모리 기계에 특히 잘 맞습니다. 토큰마다 만 읽으면 되니 273GB/s가 병목이 덜 되기 때문입니다.
4.2 / 5.0
좋았던 점
- 공식 NVFP4 4비트로 바꾸는 것만으로 디코드 1.83배·KV 용량 2.2배
- 한국어 산문 답변 51.5 tok/s로 읽는 속도보다 빠름
- 26B MoE라 통합 메모리 기계에서 토큰당 활성 파라미터만 읽음
- kv-cache-memory-bytes로 KV 크기를 고정하면 기동이 재현 가능해짐
- 모델 ID를 유지한 채 가중치 경로만 바꿔 반나절 만에 전환
아쉬운 점
- 긴 문서 프리필이 팀 전체 생성을 멈추는 문제를 파라미터로 못 고침 — 48k 토큰에 83초 정지
- gemma 4 지원용 커스텀 빌드라 상류 최신 vLLM과 거리가 벌어져 엔진 업데이트가 밀림
- 기동에 10분이 걸려 잠깐 재기동이라는 선택지가 없음
- 같은 기계의 다른 모델이 메모리를 늘리면 프리필과 동시 처리가 같이 눌림
테스트: GB10(DGX Spark) 1대, 사내 자체 운영 · 4개월, 사내 상시 운영 중 · 2026년 5월 1일 시작 · 속도를 올린 값은 전부 읽는 양을 줄인 쪽이었다. 4비트 전환과 MoE 선택이 그렇고, 자리를 늘리는 값(max-model-len·gpu-memory-utilization·max-num-batched-tokens)은 한 번도 속도를 올리지 않았다. 남은 숙제는 긴 문서 프리필의 팀 전체 정지와 엔진 버전 상향 두 가지다.



