그래픽카드 세대별 로컬 LLM 속도와, 우리 프로덕션이 매일 처리하는 토큰량
모델명·서빙 설정·prefill/decode 실측치까지 전부 공개합니다
지난 글(새 창)에서 그래픽카드를 5090으로 바꾼 얘기를 했습니다. 이번엔 훨씬 더 파고들어서, 실제로 어떤 모델을 어떤 설정으로 돌리고 있는지, 하드웨어별 prefill/decode 속도가 정확히 얼마인지, 그리고 지금 진행 중인 모델 교체 판정의 중간 결과까지 전부 공개합니다.
거쳐온 하드웨어
이 봇의 로컬 LLM 카드는 4070 Ti Super 한 장 → 두 장 → 7900 XTX 한 장 → RTX 5090 한 장 순으로 바뀌어 왔습니다.
| 구성 | VRAM | 결과 |
|---|---|---|
| 4070 Ti Super ×1 | 16GB | 당시 모델이 메모리에 아예 안 올라감 |
| 4070 Ti Super ×2 (tensor-split) | 32GB | 100종목 야간 배치 5.81시간 |
| RX 7900 XTX ×1 | 24GB | 같은 배치 6.15시간(카드 1장이 2장 대체) |
| RTX 5090 ×1 | 32GB | 아래 참고 |
실제 쓰는 모델과 서빙 설정
지금 production에서 밤마다 도는 모델은 Qwen3.6-35B-A3B(MoE, active 3B), GGUF Q4_K_M 양자화입니다. 가중치 20.75GiB + KV/연산 버퍼 1.16GiB = 실사용 21.91GiB(XTX 24GB의 91%). vLLM 서버는 포트 8200, max-num-seqs 14, KV 캐시 fp8, prefix caching 끔, temperature 0.8, thinking 모드 끔으로 동결해서 씁니다.
동시에 Qwen3.8-27B(dense) 채택 여부를 판정 중입니다. 같은 조건(KV fp8, prefix caching 끔, temp 0.8, thinking 끔)이지만 max-num-seqs는 3으로 훨씬 낮춰서 돌립니다 — dense는 MoE와 메모리/연산 특성이 달라서 동시 처리 개수를 줄여야 안정적입니다.
MTP(speculative decoding)는 상시 켜져 있습니다. 수용률은 우리 MoE 모델 기준 50.1%, 외부에서 잰 27B dense는 66.95%, 다른 외부 실측은 81~97%까지도 나옵니다 — 모델·설정에 따라 편차가 큽니다.
Prefill/decode 실측 — 27B dense 기준
같은 27B dense 모델, 콜당 prefill 약 12.7k 토큰 기준으로 우리가 직접 돌려본 카드만 정리하면(AMD R9700은 우리가 직접 재본 적이 없어서 뺐습니다 — 아래 공개 벤치마크 절에서 참고자료로만 다룹니다):
| 구성 | decode | 100종목 환산 | 비고 |
|---|---|---|---|
| RX 7900 XTX, Q4_K_M, MTP on | 62.5 t/s(단일 스트림) | 21.7시간 | prefill 768 t/s, 우리 실측 |
| RTX 5090, 27B dense | 118 t/s(집계 처리량) | 약 6.3시간 | 오늘 랭킹에 쓴 100종목 완주 1회분 — 아래 "오늘 실제 랭킹 실행" 절 참고 |
두 수치는 재는 방식이 달라서(단일스트림 vs 동시요청 평균) 직접 나눠서 "몇 배"라고 말하긴 어렵지만, 100종목 환산 시간만 보면 XTX 21.7시간 → 5090 dense 약 6.3시간으로 줄었습니다. 다만 같은 5090에서 MoE와 직접 맞대결시키면 얘기가 또 달라지는데, 아래에서 다룹니다.
카드별 순수 decode 속도 — 공개 크로스-GPU 벤치마크
같은 27B dense급 모델, MTP 켠 상태에서 카드별 decode 속도(출처: arca.live 크로스-GPU 스레드(새 창), 컨텍스트 깊이 미통제라 참고용):
| 카드 | decode(t/s) |
|---|---|
| RTX 3090 | 40~45 |
| AMD R9700 | 56 |
| RTX PRO 6000 Max-Q | 70 |
| RX 7900 XTX | 71 |
| RTX 5090 | 80 |
XTX 대비 5090이 약 1.13배 빠릅니다. 처음엔 대역폭 비율(1.81배)로 환산해서 5090이 훨씬 빠를 거라 기대했는데, MTP가 켜져 있으면 디코드가 대역폭 한계에서 풀려나기 때문에 그 환산이 틀렸다는 게 나중에 드러났습니다.
우리 실측 로그 기준 decode 속도 (하드웨어 세대별)
ta_usage_tracker가 모든 LLM 호출의 input/output 토큰과 소요시간을 종목별로 기록합니다. 처음엔 콜 단위로 output_tokens ÷ elapsed_s를 평균 냈는데, vLLM이 여러 종목 요청을 동시에 배칭 처리(continuous batching)하기 때문에 그 순간 GPU에 몇 건이 몰려 있었는지에 따라 콜 1건의 체감 속도가 출렁여서 하드웨어 비교로 못 쓸 숫자가 나왔습니다. 그래서 콜 단위 평균 대신, 그 배치가 실제로 도는 동안 만든 output 토큰 총량 ÷ 그 배치의 실제 소요시간(첫 콜~마지막 콜) 으로 다시 계산했습니다.
| 시대 | 집계 처리량(t/s) | 비고 |
|---|---|---|
| 4070 Ti Super ×2, MoE (33일 평균) | 62.4 | 정상 야간 전체배치 |
| RX 7900 XTX, MoE (10일 평균) | 71.6 | 정상 야간 전체배치 |
5090에 대해서는 "정상 야간 전체배치" 대신, 오늘 실제 랭킹을 만드는 데 쓴 실행 그대로를 아래에 정리합니다 — 이쪽이 제일 정확합니다.
오늘 실제 랭킹 실행 — 5090에서 MoE vs dense
MoE와 dense를 나란히 돌려서 비교했고, 최종적으로 오늘 랭킹에는 dense 결과를 썼습니다. 각 모델이 100종목을 한 바퀴 완주하는 데 실제로 걸린 시간입니다(MoE는 어제 저녁, dense는 오늘 새벽 — 둘 다 그 모델의 첫 완주 1회분):
| 모델 | 종목 수 | 실행 시각 | 입력 토큰 | 출력 토큰 | 걸린 시간 | 집계 처리량 |
|---|---|---|---|---|---|---|
| MoE(기존) | 100개 | 어제 20:41~21:27 | 18,315,222 | 2,497,437 | 46분 | 911 t/s |
| 27B dense(오늘 랭킹에 쓴 후보) | 100개 | 오늘 00:13~06:31 | 18,982,363 | 2,680,713 | 6시간 18분 | 118 t/s |
같은 5090, 같은 100종목인데 MoE가 dense보다 약 7.7배 빠릅니다. dense가 느린 건 하드웨어 문제가 아니라 모델 구조(MoE는 활성 파라미터만 계산, dense는 전체 파라미터를 매번 계산) 자체의 특성입니다.
지금 진행 중인 모델 채택 판정
dense와 MoE 중 어느 쪽을 정식으로 쓸지는 아직 최종 결론이 안 났습니다. 오늘은 비교를 위해 실제 랭킹을 dense로도 만들어봤지만, 이게 "정식 채택"을 뜻하진 않습니다 — 진행 중인 검증 방법 하나는 self-QWK: 같은 종목셋을 여러 번 반복 실행해서 등급이 얼마나 일관되게 나오는지 재는 지표(quadratic weighted kappa)입니다. MoE는 같은 99종목으로 3번 반복한 결과가 이미 나와 있습니다(위 "오늘 실제 랭킹 실행"의 MoE 실행도 이 반복 중 하나입니다):
| 비교쌍 | QWK | raw 일치 |
|---|---|---|
| rep1 vs rep2 | 0.0853 | 59/99 |
| rep1 vs rep3 | 0.1260 | 56/99 |
| rep2 vs rep3 | 0.1481 | 61/99 |
| 평균 | 0.1198 |
과거 XTX 시절 관측된 self-QWK 밴드는 0.08~0.21이라, 이번 값(0.1198)은 그 안에 들어옵니다. 등급 분포를 까보면 Hold가 71~80%로 쏠려 있는데, QWK는 한 등급에 쏠릴수록 수치가 기계적으로 낮게 나오는 특성이 있어서 raw 일치율(56~61%)도 같이 봐야 합니다.
dense 쪽 self-QWK는 아직 측정 전입니다(이번 주말 예정). 실제 채택을 가르는 진짜 게이트는 self-QWK가 아니라 forward RankIC(예측 순위와 실제 수익률 순위의 상관)인데, 이 지표는 아직 측정치가 0건입니다 — 즉 지금은 "dense가 더 잘 나올 것 같다"는 정성적 기대만 있고, 실제로 그런지는 검증 전입니다.
매일 처리하는 토큰량
이 프로젝트에는 로컬 LLM으로 종목을 분석하는 AI 파이프라인(새 창)이 있습니다.
평소(모델 비교 없이 MoE 단독 운영) 평일 평균: 호출 약 5,200회, 입력 토큰 약 5,500만 개, 출력 토큰 약 750만 개.
위 "오늘 실제 랭킹 실행"과 같은 100종목 완주 1회분 기준:
| 모델 | 커버 종목 | 종목당 호출 | 입력 토큰 | 출력 토큰 |
|---|---|---|---|---|
| MoE(기존) | 100개 | 17회 | 18,315,222 | 2,497,437 |
| 27B dense(오늘 랭킹에 쓴 후보) | 100개 | 17회 | 18,982,363 | 2,680,713 |
이 구간은 두 모델 다 종목당 호출 수가 같아서(17회) 토큰량 자체는 거의 비슷합니다 — 차이는 토큰량이 아니라 위에서 본 "걸린 시간"(46분 vs 6시간18분)에서 납니다. 참고로 정상적으로 하루 종일 도는 MoE 단독 운영일(평일 평균)에는 종목당 호출 수가 이보다 훨씬 많은 약 55~71회까지 올라가는 날도 있어서, 호출 깊이 자체는 그날그날의 실행 목적(정식 배치인지, 이런 비교 실행인지)에 따라 달라집니다.
다음
forward RankIC 측정이 끝나면 실제로 어느 모델을 채택했는지, 그 판정 결과를 별도 글로 정리하겠습니다.