Speculative Decoding 벤치마크

limes22·2026년 8월 28일
post-thumbnail

vLLM 0.28.0에서 speculative decoding 4개 구성을 비교 측정한 결과.

항목
모델Qwen/Qwen3-32B (bf16, 17 shards / 65.5 GB)
비교 구성vanilla · n-gram · improved n-gram · eagle3
측정 지점concurrency 1, 16 → 8건
데이터셋Spec-Bench (480문항 중 16 프롬프트, 출력 512 토큰)
하드웨어NVIDIA RTX PRO 6000 Blackwell 96GB × 2노드
일시2026-08-28

결론 먼저

eagle3를 쓰세요. concurrency 1에서 2.11배, 16에서 1.83배.
n-gram은 주어진 설정(6 / 4–6)으로는 concurrency 16에서 오히려 0.95배로 느려집니다.
eagle3의 TTFT 비용은 122 → 142 ms로 미미해 대화형 서비스에도 안전합니다.


1. 개념

1.1 Speculative Decoding이란

LLM의 토큰 생성(decode)은 메모리 대역폭에 묶인(memory-bandwidth-bound) 작업이다.
토큰 하나를 만들 때마다 모델 가중치 전체를 읽어야 하는데, 실제 연산량은 그에 비해 적어
GPU 연산 유닛이 논다. Qwen3-32B는 bf16 65.5GB를 매 토큰마다 읽는다.

Speculative decoding은 이 낭비를 이용한다:

1. Draft  : 가볍고 빠른 방법으로 다음 k개 토큰을 "추측"
2. Verify : 원본 모델이 k개를 한 번의 forward로 동시에 검증
3. Accept : 맞은 것까지 채택, 틀린 지점부터 폐기

핵심은 2번이다. 토큰 1개를 만들 때나 k+1개를 검증할 때나 가중치를 읽는 비용은 같다.
채택률이 높으면 가중치 읽기 비용을 여러 토큰에 분할상환(amortize)하게 된다.

출력 품질은 변하지 않는다. 검증 단계에서 원본 모델의 분포와 일치하는 토큰만 채택하므로
vanilla와 동일한 출력을 더 빠르게 얻는 것이 목표다. 순수한 속도 최적화다.

1.2 이득이 나는 조건 / 손해가 나는 조건

조건영향
채택률이 높다이득 ↑
speculation이 자주 발동한다이득 ↑ — 이번 실험에서 n-gram의 결정적 약점
채택률이 낮거나 발동이 드물다손해 — draft 생성 + 검증 오버헤드가 순손실
배치가 작다 (저동시성)이득 ↑ — memory-bound 구간, 연산 유닛에 여유
배치가 크다 (고동시성)이득 ↓ — 이미 compute-bound

speculative decoding 을 켜면 얻는 것만 있는게 아니라 반드시 내는 비용(버려지는 토큰)이 있다 실제로 이번에 n-gram이 vanilla보다 느린 사례가 나왔다(§4.2).

1.3 비교한 4가지 구성

(1) vanilla

(2) n-gram (prompt lookup)

드래프트 모델 없이 프롬프트에서 같은 n-gram을 찾아 그 뒤 토큰을 복사한다.
추가 모델도 학습도 필요 없다.

{"method":"ngram", "num_speculative_tokens":6, "prompt_lookup_min":4, "prompt_lookup_max":6}
  • num_speculative_tokens — 한 번에 몇 개를 추측할지
  • prompt_lookup_min/max — 매칭할 n-gram 길이 범위

요약·RAG·코드 편집처럼 입력을 그대로 옮겨 쓰는 과제에 강하고, 자유 생성·추론에는 약하다.

(3) improved n-gram

매칭할 패턴의 길이를 늘리고, 추측 개수를 줄인 설정.

{"method":"ngram", "num_speculative_tokens":4, "prompt_lookup_min":2, "prompt_lookup_max":128}
  • min 4→2 : 짧은 매칭도 허용 → 발동 기회 증가
  • max 6→128 : 긴 매칭도 활용
  • num_spec 6→4 : speculative 발동 1회당 제안할 토큰 갯수

실측 효과(§4.3): 발동이 429 → 1,552회로 3.6배 늘었고, 근거가 약해진 만큼
채택 길이는 2.562 → 1.881로 떨어졌다. 순효과는 채택 토큰 2배(670 → 1,367).
개선의 대부분은 max를 넓혀 발동 횟수를 늘린 데서 왔다. num_speculative_tokens를
줄인 것은 버림 비율을 낮추지 못했다(74% → 78%).

(4) EAGLE-3

별도 학습된 소형 draft 모델을 쓴다. 원본 모델의 중간 hidden state를 입력받아
다음 토큰을 예측하도록 증류된 1개 레이어 네트워크다.

{"method":"eagle3", "model":"/path/to/Qwen3-32B-speculator.eagle3", "num_speculative_tokens":3}

사용한 speculator: RedHatAI/Qwen3-32B-speculator.eagle3 (3.0 GB)

중요: speculator config의 verifier 필드가 학습 기준 타깃이다.
이게 실제 서빙 모델과 다르면(예: bf16 기준 학습 → 양자화 모델에 적용)
hidden state 분포가 어긋나 채택률이 떨어진다.

1.4 측정 지표

지표의미방향
output throughput (tok/s)초당 생성 토큰 수높을수록 좋음
total token throughput입력+출력 합산 처리량높을수록 좋음
TPOT (Time Per Output Token)토큰당 생성 시간낮을수록 좋음
TTFT (Time To First Token)첫 토큰까지 지연 - 대화형 UX 핵심낮을수록 좋음
ITL (Inter-Token Latency)토큰 간 간격 (스트리밍 부드러움)낮을수록 좋음
spec_decode_acceptance_ratedraft 토큰 채택률 (%)높을수록 좋음
spec_decode_acceptance_lengthdraft 1회당 평균 채택 토큰 수높을수록 좋음
spec_decode_num_draftsspeculation 발동 횟수n-gram 진단의 핵심

1.5 데이터셋 선택이 중요한 이유

Speculative decoding의 채택률은 입력 데이터에 절대적으로 의존한다.

  • random 합성 토큰 — n-gram이 매칭할 패턴이 없어 구조적으로 채택률 0. 측정 자체가 무의미
  • Spec-Bench — speculative decoding 평가 전용 데이터셋

Spec-Bench 480문항: translation / summarization / qa /
math_reasoning / rag 각 80문항 + writing, roleplay, reasoning, math, coding, extraction,
stem, humanities 각 10문항.


2. 환경 구축

2.1 최종 스택

항목버전
OSUbuntu 24.04.4 LTS / x86_64 / Python 3.12.3
GPURTX PRO 6000 Blackwell 96GB (sm_120)
Driver / CUDA580.173.02 / CUDA 13.0
vLLM0.28.0
torch2.13.0+cu130

2.2 폐쇄망 대응 - venv를 베스천에서 만들어 배포

# --- 베스천 ---
python3 -m venv /vllm-venv
/vllm-venv/bin/pip install vllm==0.28.0 --timeout 30 --retries 3
/vllm-venv/bin/pip install "vllm[bench]==0.28.0"   # pandas 등 벤치 의존성

/vllm-venv/bin/python -c \
  "import torch,vllm; print(vllm.__version__, torch.__version__, torch.cuda.get_arch_list())"
# → 0.28.0 2.13.0+cu130 ['sm_75','sm_80','sm_86','sm_90','sm_100','sm_120']

# --- 워커로 배포 (동일 경로 필수) ---
rsync -a /vllm-venv/ maymust@10.10.30.14:/vllm-venv/
rsync -a /vllm-venv/ maymust@10.10.30.15:/vllm-venv/

네트워크가 불안정해 pip이 자주 정지한다. --timeout 30으로 짧게 잡고 재시도 루프로 감싸면
pip 캐시에 완료분이 남아 반복할수록 수렴한다.

2.3 필수 환경변수

export CUDA_HOME=/vllm-venv/lib/python3.12/site-packages/nvidia/cu13
export CUDA_PATH="$CUDA_HOME"
export PATH="/vllm-venv/bin:$CUDA_HOME/bin:$PATH"   # ninja 등을 위해 필수
export VIRTUAL_ENV=/vllm-venv
export CC=/usr/bin/gcc
export TRITON_PTXAS_PATH="$CUDA_HOME/bin/ptxas"
export VLLM_USE_FLASHINFER_SAMPLER=0

2.4 인프라 결함 2건

(a) 커널 업그레이드마다 GPU 인식 실패

실험 중 두 노드가 커널 6.8.0-137 → 138로 업그레이드되며 재부팅되었고 GPU 인식을 못함

드라이버 문제가 아님 모듈은 정상 빌드되어 있었다:

modinfo /lib/modules/6.8.0-138-generic/kernel/nvidia-580srv-open/nvidia.ko
#   vermagic: 6.8.0-138-generic SMP preempt mod_unload modversions   ← 커널과 일치

진짜 원인: 부팅 시 자동 로드 설정 부재. /etc/modules, /etc/modules-load.d/에 nvidia 없고
nvidia-persistencedstatic(enabled 아님).

sudo modprobe nvidia          # 즉시 복구

# 영구 해결 (적용 완료)
printf "nvidia\nnvidia_uvm\nnvidia_modeset\n" | sudo tee /etc/modules-load.d/nvidia.conf
# 되돌리기: sudo rm /etc/modules-load.d/nvidia.conf

이전 커널로 롤백해도 재발한다. 커널 버전과 무관한 문제

(b) NFS 라우팅 오류 + IP 중복

재부팅 후 워커에서 NFS(192.168.160.7) 도달 불가. stale 라우트가 원인:

192.168.160.0/24 dev ens33 scope link     ← 10.10.30.x NIC로 잘못 보냄
sudo ip route del 192.168.160.0/24 dev ens33 scope link
sudo ip route add 192.168.160.0/24 dev ens35 scope link src <노드 ens35 IP>
sudo mount -t nfs4 -o ro,vers=4.2,hard,proto=tcp \
  192.168.160.7:/media/SSD-Storage/SW /mnt/fabrix

⚠️ 미해결: 192.168.160.179두 워커에 중복 할당되어 있다.
worker-2의 /etc/netplan/99-ens35.yaml이 자기 주소(.169) 위에 .179를 추가로 붙인다.
ARP 충돌로 간헐적 통신 장애가 생길 수 있어 정리 필요.


3. 실험 명령어

3.1 모델 준비

hf download Qwen/Qwen3-32B --local-dir ./Qwen3-32B          # 65.5 GB, 17 shards
hf download RedHatAI/Qwen3-32B-speculator.eagle3 \
  --local-dir ./Qwen3-32B-speculator.eagle3                 # 3.0 GB
MODEL=/mnt/models/Qwen3-32B                   # NFS (~105 MB/s)
DRAFT=/mnt/Qwen3-32B-speculator.eagle3         # 로컬
V=/vllm-venv/bin

NFS에서 65.5GB를 읽으므로 구성당 기동에 약 10분이 걸린다.
단 이는 기동 시간만 늘릴 뿐 측정값에는 영향이 없다(§5.2에서 검증).

3.2 서버 기동 — 4가지 구성

공통: --max-model-len 2048 --gpu-memory-utilization 0.95

# (1) vanilla
$V/vllm serve "$MODEL" --served-model-name bench \
  --no-enable-log-requests --max-model-len 2048 --gpu-memory-utilization 0.95

# (2) n-gram
$V/vllm serve "$MODEL" --served-model-name bench \
  --speculative-config '{"method":"ngram","num_speculative_tokens":6,"prompt_lookup_min":4,"prompt_lookup_max":6}' \
  --no-enable-log-requests --max-model-len 2048 --gpu-memory-utilization 0.95

# (3) improved n-gram
$V/vllm serve "$MODEL" --served-model-name bench \
  --speculative-config '{"method":"ngram","num_speculative_tokens":4,"prompt_lookup_min":2,"prompt_lookup_max":128}' \
  --no-enable-log-requests --max-model-len 2048 --gpu-memory-utilization 0.95

# (4) eagle3
$V/vllm serve "$MODEL" --served-model-name bench \
  --speculative-config "{\"method\":\"eagle3\",\"model\":\"$DRAFT\",\"num_speculative_tokens\":3}" \
  --no-enable-log-requests --max-model-len 2048 --gpu-memory-utilization 0.95

--disable-log-requests는 vLLM 0.28에서 --no-enable-log-requests로 바뀌었다.

3.3 벤치마크 실행

$V/vllm bench serve \
  --backend openai-chat \
  --base-url http://localhost:8000 \
  --endpoint /v1/chat/completions \
  --model bench \
  --tokenizer "$MODEL" \
  --dataset-name spec_bench \
  --dataset-path /home/maymust/datasets/question.jsonl \
  --num-prompts 16 \
  --spec-bench-output-len 512 \
  --max-concurrency 1 \
  --save-result --result-filename qwen_vanilla_conc1.json

설계 판단 3가지

선택이유
--backend openai-chat + /v1/chat/completionseagle3 speculator가 chat 템플릿 기준으로 학습됨. raw completions로 재면 채택률이 낮아짐. 4개 구성 모두 동일 엔드포인트로 공정성 유지
--tokenizer "$MODEL"--served-model-name bench로 띄웠으므로 클라이언트가 "bench"를 HF repo id로 찾다 실패. 실제 경로 명시 필요
--dataset-name spec_benchrandom 합성 토큰은 n-gram 채택률이 구조적으로 0이라 측정 무의미

3.4 데이터셋 준비

git clone https://github.com/hemingkx/Spec-Bench.git
# 사용 파일: Spec-Bench/data/spec_bench/question.jsonl (480줄, 698KB)

3.5 자동화 스크립트

파일역할
run-bench.sh <model-key> <config>1개 구성: 서버 기동 → health 대기 → conc 1·16 벤치 → 정리
run-all.sh <model-key> <cfg>...여러 구성 순차 실행, 완료 시 DONE_<key> 마커 생성
bash run-all.sh qwen vanilla ngram ngram_improved eagle3

스크립트에 넣은 안전장치 (실제 사고를 겪고 추가):

# 1) 부모 프로세스가 죽으면 자식프로세서의 이름이 VLLM::EngineCore로 바뀜. 두 패턴 모두 잡아야 함
#    (놓치면 93GB를 점유한 채 남아 다음 구성이 OOM으로 실패)
kill_vllm () {
  for pat in "[v]llm serve" "VLLM::EngineCore" "[V]LLM::"; do
    for p in $(pgrep -f "$pat" 2>/dev/null); do kill "$1" "$p" 2>/dev/null; done
  done
}
# GPU 메모리가 실제로 해제될 때까지 대기
for i in $(seq 1 30); do
  U=$(nvidia-smi --query-gpu=memory.used --format=csv,noheader,nounits)
  [ "${U:-0}" -lt 5000 ] && break; sleep 2
done

# 2) 모델 경로 폴백 — 로컬 사본이 사라져도 NFS로 계속 진행
pick () { for d in "$@"; do [ -f "$d/config.json" ] && { echo "$d"; return; }; done; echo ""; }
MODEL=$(pick /mnt/Qwen3-32B /mnt/models/Qwen3-32B)
[ -n "$MODEL" ] || { echo "FATAL: no readable model dir"; exit 3; }

# 3) health 대기 — NFS 로딩은 65.5GB에 10분 이상 걸리므로 40분까지 허용
for i in $(seq 1 480); do
  curl -sf http://127.0.0.1:8000/health >/dev/null 2>&1 && break
  kill -0 $SRVPID 2>/dev/null || { echo "SERVER DIED"; tail -40 "$SRVLOG"; exit 1; }
  sleep 5
done

💡 tmux 사용: 세션이 끊겨도 실험이 유지되도록 tmux 윈도우에서 실행함

tmux new-window -t bench -n runqwen
tmux send-keys -t bench:runqwen "bash run-all.sh qwen vanilla eagle3" C-m

4. 결과

4.1 전체 수치

TPOT/TTFT/ITL은 ms(평균). 배수는 같은 노드의 vanilla 대비.

concurrency = 1

configout tok/s배수total tok/sTPOTTTFTITLduration
vanilla21.291.00×26.8146.9468.7946.84378.65 s
ngram (6/4–6)22.831.07×28.6843.65119.8147.47357.42 s
ngram (4/2–128)25.181.18×31.6239.56119.5347.40324.43 s
eagle3 (3)44.762.11×56.5022.2389.7849.47178.13 s

concurrency = 16

configout tok/s배수total tok/sTPOTTTFTITLduration
vanilla301.191.00×379.7551.65128.8151.5726.61 s
ngram (6/4–6)286.890.95× ⚠️360.3251.77124.0856.6928.48 s
ngram (4/2–128)308.851.03×388.0344.73125.5554.3426.41 s
eagle3 (3)562.601.83×706.2025.33141.7357.2014.56 s

Output Throughput by Concurrency

Total Token Throughput by Concurrency

speculative decoding 내부 지표

configconc채택률채택 길이draft 시도채택 토큰
ngram (6/4–6)126.0%2.562429670
ngram (4/2–128)122.0%1.8811,5521,367
eagle3 (3)141.5%2.2453,5564,428
ngram (6/4–6)1627.7%2.661439729
ngram (4/2–128)1623.0%1.9221,5891,465
eagle3 (3)1642.4%2.2723,6054,586

4.2 결론 1 — eagle3가 압도적

concurrency 1  : 21.29 → 44.76 tok/s   (2.11×)   TPOT 46.94 → 22.23 ms
concurrency 16 : 306.70 → 562.60 tok/s (1.83×)   TPOT 51.74 → 25.33 ms

16개 요청 처리 시간이 378.65초 → 178.13초로 절반 이하가 된다.
Execution Duration by Concurrency

Mean TPOT by Concurrency

저배치에서 이득이 더 크다. (2.11× vs 1.83×) concurrency 1은 완전히
memory-bound라 분할상환 여지가 크고, 16에서는 배치 자체가 이미 연산 유닛을 채우기 시작한다.

4.3 결론 2 — n-gram은 (주어진 설정으로는) 쓰면 안 된다

ngram (6/4–6)  conc=1  : 1.07×    (미미)
ngram (6/4–6)  conc=16 : 0.95×    ← vanilla보다 느림

원인은 채택률이 아니라 "발동 횟수"

n-gram은 프롬프트에 매칭되는 n-gram이 있을 때만 발동한다.
총 8,159 토큰을 생성하는 동안 단 429번만 시도했다 — decode 스텝의 약 5%다.
나머지 95%는 speculation이 아예 작동하지 않고, 상시 오버헤드만 남아 손해가 된다.

역설적으로 n-gram은 발동만 하면 품질이 좋다.
채택 길이 2.562는 eagle3의 2.245보다 높다.
문제는 3,556회 대 429회라는 발동 횟수 차이다.

prompt_lookup_max를 6 → 128로 넓히면:

draft 시도채택 길이채택 토큰conc=1conc=16
ngram (max=6)4292.5626701.07×0.95×
ngram (max=128)1,5521.8811,3671.18×1.03×

시도가 3.6배 늘고, 느슨한 매칭이 섞여 채택 길이는 떨어지지만, 순효과는 채택 토큰 2배다.
Draft 시도 vs 채택 토큰

채택률과 채택 길이를 나눠 보면, n-gram이 지는 이유가 품질이 아니라는 점이 분명해진다 — 채택 길이는 오히려 n-gram이 가장 높다.

채택률과 채택 길이

⚠️ 서버 로그의 Accepted throughput 값만 보면 채택률이 거의 0인 것처럼 오해하기 쉽다.
실제 채택률은 22~26%다. 결과 JSON의 spec_decode_num_drafts를 봐야 정확히 진단된다.

4.4 결론 3 — TTFT 비용이 거의 없다

vanillaeagle3변화
conc=1 TTFT68.79 ms89.78 ms+30%
conc=16 TTFT128.81 ms141.73 ms+10%

대화형 서비스에서도 eagle3를 켤 수 있다는 뜻이다.
speculative decoding은 검증 연산이 prefill을 밀어내 TTFT를 해치는 경우가 있는데,
Qwen3-32B bf16에서는 decode가 충분히 느려(47 ms/token) prefill이 끼어들 여유가 있다.

Mean TTFT vs Mean ITL (concurrency 16)

⚠️ 이 결론은 bf16 타깃 한정이다. decode가 훨씬 빠른 타깃(예: 4bit 양자화 모델)에서는
스케줄러가 decode로 꽉 차 prefill이 밀리고 TTFT가 크게 악화될 수 있다.
다른 타깃에 적용하기 전 반드시 재측정할 것.

4.5 결론 4 — ITL은 오히려 나빠진다

vanillaeagle3
conc=1 ITL46.84 ms49.47 ms
conc=16 ITL51.57 ms57.20 ms

ITL(토큰 간 간격)만 보면 eagle3가 느려 보인다. 하지만 이는 착시다.

speculative decoding은 한 번의 forward로 여러 토큰을 한꺼번에 내놓는다.
따라서 "이벤트 간 간격"은 늘지만 이벤트당 토큰 수가 늘어 TPOT는 절반이 된다
(46.94 → 22.23 ms). 실제 체감 속도는 TPOT가 정확하다.

speculative decoding 평가 시 ITL을 단독 지표로 쓰지 말 것. TPOT를 봐야 한다.

Mean TPOT vs Mean ITL — 두 지표가 반대로 움직인다


5. 실험 타당성 검증

5.1 노드 동등성

구성을 두 노드에 나눠 측정했으므로(n-gram 계열 → worker-1, eagle3 → worker-2),
vanilla를 양쪽에서 재서 결과 통합 가능 여부를 확인했다.

vanillaworker-1worker-2차이
conc=1 tok/s21.2921.250.19%
conc=1 TPOT46.9447.010.15%
conc=1 ITL46.8446.910.15%
conc=16 tok/s301.19306.701.8%
conc=16 TPOT51.6551.740.17%

conc=1은 사실상 동일. conc=16 처리량의 1.8% 차이는 16요청 배치의 통상 편차다.
conc=16에서 3% 미만 차이는 노이즈로 간주할 것.

5.2 통신 / 스토리지 영향 없음

tensor_parallel_size=1, pipeline_parallel_size=1, world_size=1
  • GPU 1장 단독 실행. NCCL collective 없음, InfiniBand 미사용, 노드 간 통신 없음
  • 두 워커는 서로 다른 구성을 독립 실행할 뿐 데이터를 주고받지 않음
  • NFS는 기동 시간만 늘린다 (65.5GB ÷ 105MB/s ≈ 10분).
    가중치가 GPU에 올라간 뒤에는 저장소가 개입하지 않는다

5.3 gpu-memory-utilization 0.95의 영향

이번 측정에는 영향이 없다.

가중치KV 예산KV 토큰max concurrency실제 KV 사용률
Qwen3-32B bf1661.03 GiB25.35 GiB103,84050.70×0.2 – 0.7%

conc=16에 max-model-len 2048이면 32,768 토큰만 필요한데 103,840이 잡혀 있다.
0.95든 0.70이든 동일한 수치가 나온다.

다만 여유가 5%(≈4.7GB)뿐이라 다른 프로세스가 GPU를 점유하면 기동이 실패한다.

5.4 이 실험의 범위

검증된 것검증되지 않은 것
Qwen3-32B bf16 단일 GPU양자화 타깃 (별도 측정 필요)
concurrency 1과 16그 사이 구간, 16 초과 구간
Spec-Bench (대화·추론·요약·RAG)요약/코드 전용 워크로드 (n-gram에 유리할 수 있음)
num_speculative_tokens=3 (eagle3)다른 k 값
TP=1TP>1, 멀티노드

6. 권고

항목판단
eagle3 도입권장. 2.11× / 1.83×, TTFT 비용 +10%로 대화형에도 안전
n-gram (6/4–6)제외. conc=16에서 vanilla보다 느림 (0.95×)
n-gram (4/2–128)⚠️ 1.18× / 1.03×. eagle3 대비 열위. 요약·RAG 워크로드라면 재평가 여지
평가 지표TPOT를 볼 것. ITL 단독은 오해를 부름(§4.5)
프로덕션 모니터링spec_decode_num_drafts, spec_decode_acceptance_length 수집

후속 실험

  1. 중간 concurrency 지점 — 2/4/8을 채우면 이득이 꺾이는 지점을 특정할 수 있다.
    현재 1(2.11×)과 16(1.83×) 사이 곡선을 모른다.
  2. concurrency 32 이상 — max concurrency가 50.7×이므로 아직 여유가 있다.
    어디서 speculative decoding이 순손실로 뒤집히는지 확인 필요.
  3. 요약/RAG 전용 데이터셋으로 n-gram 재평가 — Spec-Bench는 n-gram에 불리한 구성이다.
    입력 복사가 많은 실제 워크로드에서는 발동 횟수가 크게 늘 수 있다.
  4. 더 긴 출력 길이 — 현재 512 토큰. 출력이 길수록 speculative decoding 이득이 커진다.

profile
GPU 인프라 / MLOps 엔지니어 오수진입니다. 쿠버네티스 기반 GPU 스케줄링(HAMi·KAI·Volcano)과 LLM 서빙 인프라를 다룹니다.

0개의 댓글