Field Log · Entry
LLM Serving은 vLLM만 뜻할까: Qwen3-TTS-Triton으로 보는 서빙의 층위
처음에는 저도 이렇게 이해했습니다.
LLM serving은 vLLM으로 모델을 API 서버처럼 띄우는 것 아닌가?
이해가 완전히 틀린 것은 아닙니다. vLLM은 실제로 LLM을 서빙하기 위한 대표적인 도구입니다. vllm serve로 OpenAI-compatible API 서버를 띄울 수 있고, 여러 요청을 처리하면서 GPU 메모리와 batch를 효율적으로 관리합니다.
그런데 이 문장은 너무 짧습니다. 서빙은 vLLM보다 큰 개념이고, vLLM은 그중 LLM에 특화된 런타임/서빙 엔진입니다. 특히 TTS, 이미지, diffusion, NAR 음성 모델처럼 구조가 달라지면 vLLM 하나로 모든 설명이 끝나지 않습니다.
사실 이 오해에는 이유가 있었습니다. 사내에서 RAG 에이전트를 운영하던 시기, 모델을 “띄운다”는 일은 대부분 vLLM으로 OpenAI 호환 API 서버를 올리는 것으로 끝났습니다. LLM만 다루는 동안에는 vLLM이 서빙의 거의 전부를 덮어 줬기 때문에, 저에게 serving은 한동안 vLLM과 거의 동의어였습니다. 이 글은 그 등호가 언제 깨지는지에 대한 기록이기도 합니다.
이 글은 Qwen3-TTS-Triton v0.3.0 발표를 읽다가 생긴 질문에서 출발합니다. 프로젝트 이름에는 Triton이 붙어 있고, 본문에는 batched serving, CUDA Graph, KV cache, throughput 같은 말이 계속 나옵니다. 처음 보는 입장에서는 전부 “서빙”처럼 보입니다.
결론부터 말하면 이 프로젝트는 vLLM 위에 API 서버를 얹은 프로젝트라기보다, Qwen3-TTS라는 TTS 모델을 더 빠르게 돌리기 위해 모델 내부 실행 경로와 GPU 연산을 직접 최적화한 inference runner에 가깝습니다.
이 글이 답하는 질문
- serving은 단순히 API 서버를 띄우는 것인가?
- vLLM은 정확히 어느 층에서 무엇을 해주는가?
- Qwen3-TTS-Triton의 Triton은 NVIDIA Triton Inference Server인가, triton-lang인가?
- v0.3.0의 batched serving 14배는 latency가 14배 빨라졌다는 뜻인가?
- AR TTS와 NAR TTS는 왜 서빙 최적화 방식이 달라지는가?
모델 실행과 서빙은 다르다
가장 먼저 나눠야 할 것은 inference와 serving입니다.
노트북이나 Python 스크립트에서 모델을 한 번 실행하는 것은 inference입니다.
model = load_model()
result = model.generate("안녕")
print(result)
구조는 단순합니다.
입력 -> 모델 -> 출력
하지만 실제 서비스에서는 한 명만 요청하지 않습니다. 여러 사용자가 동시에 들어오고, 입력 길이도 다르고, 생성 길이도 다릅니다.
사용자 A: "이 문서 요약해줘"
사용자 B: "이 문장을 음성으로 만들어줘"
사용자 C: "이전 대화 이어서 답해줘"
사용자 D: "긴 프롬프트로 코드 생성해줘"
이때부터는 모델을 한 번 실행하는 문제를 넘어서게 됩니다.
- 요청을 받습니다.
- 요청을 줄 세웁니다.
- GPU에 언제 올릴지 결정합니다.
- 여러 요청을 묶어서 처리합니다.
- 중간 상태를 메모리에 보관합니다.
- 결과를 스트리밍하거나 파일로 반환합니다.
- 실패, timeout, OOM, rate limit을 다룹니다.
- throughput과 latency 사이의 균형을 잡습니다.
이 전체가 serving입니다.
식당으로 비유하면 모델은 요리사, GPU는 주방, API 서버는 주문 창구입니다. vLLM 같은 serving engine은 주방장이자 운영 시스템에 가깝습니다. 주문이 몰릴 때 어떤 순서로 요리할지, 같은 재료를 어떻게 묶어 처리할지, 주방 공간을 어떻게 비울지 결정합니다.
반면 Triton kernel이나 CUDA Graph는 더 안쪽입니다. 요리사가 같은 요리를 더 빠르게 만들도록 칼질과 조리 순서를 최적화하는 쪽에 가깝습니다.
서빙 스택을 층으로 보면 덜 헷갈린다
서빙이라는 단어가 헷갈리는 이유는 여러 층의 기술이 한꺼번에 묶여 불리기 때문입니다. 대략 이렇게 나눠볼 수 있습니다.
[사용자]
↓
[API / UI 계층]
FastAPI, vLLM OpenAI-compatible server, Gradio, ComfyUI
↓
[서빙 엔진 / 스케줄러 계층]
vLLM, SGLang, custom batch queue
↓
[모델 실행 계층]
PyTorch generate(), Qwen3-TTS runner, OmniVoice runner
↓
[메모리 / 생성 최적화 계층]
KV cache, PagedAttention, static KV cache, quantized KV cache
↓
[GPU 실행 최적화 계층]
Triton kernels, CUDA Graph, FlashAttention, CUTLASS
↓
[GPU]
vLLM은 이 중 꽤 넓은 영역을 맡습니다. 공식 문서도 vLLM의 기능으로 PagedAttention 기반 KV 메모리 관리, continuous batching, chunked prefill, prefix caching, CUDA/HIP graph, quantization, 최적화 attention kernel, OpenAI-compatible API server 등을 함께 설명합니다.
즉 vLLM은 단순한 HTTP wrapper가 아닙니다. LLM의 생성 방식에 맞춰 요청을 스케줄링하고, KV cache를 관리하고, GPU가 놀지 않게 만드는 inference runtime에 가깝습니다.
사실 “겉보기엔 같은 층 같지만 실제로는 다른 층”인 상황은 서빙에만 있는 게 아닙니다. 저는 에이전트 백엔드에서도 OpenAI SDK·Temporal·LangGraph가 사실 같은 층이 아니라는 이야기를 따로 정리한 적이 있는데, 이번 글의 서빙 스택도 결국 같은 질문 — “이 도구는 어느 층을 맡는가” — 을 다시 던지는 셈입니다.
하지만 중요한 점은 이것입니다.
vLLM이 서빙의 전부는 아닙니다. vLLM은 특히 AR LLM에 잘 맞게 만들어진 강력한 서빙 엔진입니다.
모델 구조가 바뀌면 다른 층의 최적화가 더 중요해질 수 있습니다. Qwen3-TTS-Triton과 OmniVoice-Triton이 바로 그 사례입니다.
Triton이라는 이름이 두 개다
여기서 첫 번째 함정이 나옵니다. Triton이라는 이름은 두 가지 의미로 자주 쓰입니다.
| 이름 | 무엇인가 | 어느 층인가 |
|---|---|---|
| NVIDIA Triton Inference Server | 여러 프레임워크 모델을 HTTP/gRPC로 배포하는 inference serving server | 서버/플랫폼 계층 |
| triton-lang | Python 기반으로 GPU custom kernel을 작성하고 컴파일하는 언어/컴파일러 | GPU 커널 계층 |
NVIDIA Triton Inference Server는 PyTorch, TensorRT, ONNX, OpenVINO 같은 여러 모델을 배포하는 서버입니다. HTTP/REST, gRPC, dynamic batching, sequence batching, metrics 같은 운영 기능을 제공합니다.
반면 triton-lang은 GPU에서 custom DNN compute kernel을 작성하기 위한 Python 기반 언어/컴파일러입니다. RMSNorm, SwiGLU, RoPE 같은 모델 내부 연산을 직접 빠르게 만들 때 쓰입니다.
Qwen3-TTS-Triton, OmniVoice-Triton에서 말하는 Triton은 대부분 후자입니다. 즉 “Triton 서버에 모델을 올렸다”가 아니라 “모델 내부 연산을 Triton kernel로 다시 짰다”에 가깝습니다.
이 차이를 잡으면 글이 훨씬 선명해집니다.
NVIDIA Triton Inference Server
= 모델을 배포하고 요청을 받는 서버
triton-lang
= GPU 연산 하나하나를 빠르게 만드는 커널 도구
vLLM은 무엇을 잘해주는가
LLM은 보통 autoregressive, 즉 AR 방식으로 토큰을 만듭니다.
"나는"
"나는 오늘"
"나는 오늘 밥을"
"나는 오늘 밥을 먹었다"
다음 토큰을 만들 때 앞에서 만든 토큰들을 참고합니다. 매번 처음부터 다시 계산하면 너무 느리기 때문에, 이전 토큰들의 attention key/value를 저장해 둡니다. 이것이 KV cache입니다.
LLM 서빙에서는 KV cache가 매우 중요합니다. 사용자가 많아질수록 각 요청의 KV cache가 GPU 메모리를 차지합니다. 요청마다 prompt 길이와 생성 길이가 다르기 때문에 메모리가 조각나기도 쉽습니다.
vLLM의 핵심 아이디어인 PagedAttention은 이 KV cache 관리를 더 효율적으로 하기 위한 기술입니다. 여기에 continuous batching이 붙습니다. 요청이 한 번에 딱 같은 길이로 들어오지 않아도, 생성 단계에서 여러 요청을 계속 섞어 GPU를 바쁘게 만드는 방식입니다.
그래서 vLLM이 잘하는 일은 이런 쪽입니다.
- 여러 LLM 요청을 동시에 처리합니다.
- 각 요청의 KV cache를 효율적으로 관리합니다.
- prefill과 decode 단계를 스케줄링합니다.
- 요청을 continuous batching으로 묶습니다.
- OpenAI-compatible API로 외부에서 호출하게 합니다.
- quantization, prefix caching, CUDA Graph, optimized attention kernel 같은 최적화를 함께 제공합니다.
처음 배우는 입장에서는 이렇게 기억하면 됩니다.
vLLM은 LLM을 실제 서비스처럼 쓰기 위한 LLM 전용 runtime + serving engine입니다.
Qwen3-TTS-Triton은 vLLM 서버가 아니다
그럼 Qwen3-TTS-Triton은 무엇일까요?
README 기준으로 Qwen3-TTS-Triton은 Qwen3-TTS 1.7B의 성능 병목 연산자를 hand-written Triton kernel로 교체합니다. RMSNorm, SwiGLU, M-RoPE, Norm+Residual 같은 연산을 fusion하고, CUDA Graph와 static KV cache를 쓰는 faster-qwen3-tts와 결합해 hybrid mode를 제공합니다.
중요한 문장은 “No serving infrastructure needed”에 가깝습니다. 이 프로젝트는 별도 서버를 반드시 띄우는 구조가 아니라, pip install qwen3-tts-triton 후 apply_triton_kernels() 또는 runner를 통해 기존 모델 실행 경로를 빠르게 만드는 쪽입니다.
구조를 단순화하면 이렇습니다.
Qwen3-TTS 모델
↓
PyTorch eager inference
↓
Triton fused kernels 적용
↓
CUDA Graph / static KV cache 결합
↓
generate_batch()로 batch throughput 향상
즉, 이 프로젝트의 핵심은 API 서버가 아니라 모델 전용 inference runner 최적화입니다.
물론 Qwen3-TTS가 vLLM과 전혀 관련이 없다는 뜻은 아닙니다. Qwen 공식 PyPI 문서에는 vLLM-Omni가 Qwen3-TTS를 지원하며, 작성 시점 기준으로는 offline inference만 지원하고 online serving은 추후 지원 예정이라고 되어 있습니다.
그러니 선택지는 둘 다 있습니다.
| 하고 싶은 일 | 자연스러운 선택 |
|---|---|
| 표준 LLM을 OpenAI API처럼 서빙 | vLLM, SGLang 같은 서빙 엔진 |
| Qwen3-TTS를 로컬/앱 안에서 빠르게 합성 | qwen3-tts-triton 같은 모델 전용 runner |
| Qwen3-TTS를 multimodal serving stack에서 다루기 | vLLM-Omni 계열 검토 |
| ComfyUI에서 노드로 사용 | ComfyUI-Qwen3-TTS-Triton wrapper |
여기서 핵심은 “vLLM이냐 아니냐”가 아니라 “어느 층을 최적화하고 있느냐”입니다.
14배는 latency가 아니라 throughput 이야기다
Qwen3-TTS-Triton v0.3.0에서 가장 눈에 띄는 문장은 ~14x per-sample throughput입니다. 이 숫자는 조심해서 읽어야 합니다.
README는 v0.3.0에서 모든 runner에 generate_batch()가 추가됐고, 여러 clip을 한 step에서 합성해 1.7B weight를 읽는 비용을 batch 전체에 나눠 가진다고 설명합니다. 동시에 “single-clip latency path is unchanged”라고 못 박습니다.
즉, 이 말은 다음과 다릅니다.
내 요청 하나가 항상 14배 빨리 끝난다 X
여러 요청을 묶었을 때 sample당 처리 비용이 크게 줄었다 O
여기서 latency와 throughput을 나눠야 합니다.
| 용어 | 의미 | 예시 |
|---|---|---|
| latency | 요청 하나가 끝날 때까지 걸리는 시간 | 내 TTS 문장 하나가 2초 만에 생성됨 |
| throughput | 일정 시간 동안 처리한 전체 작업량 | 1초에 TTS clip 10개를 생성함 |
| per-sample throughput | batch 처리 시 sample 하나당 평균 처리 비용 | batch=16에서 clip 하나당 평균 0.36초 |
Qwen3-TTS-Triton README는 이 14배를 hybrid mode의 단일 clip 속도 향상(약 5배) × batch amortization(약 3배) ≈ 약 14배로 분해해서 설명합니다. 즉 batch=16에서 per-sample throughput이 약 14배 좋아졌다는 의미이지, 단일 요청의 체감 latency와는 다른 지표입니다.
VRAM도 마찬가지입니다. “per-sample VRAM이 줄었다”는 말은 전체 VRAM이 무조건 줄었다는 뜻이 아닙니다. batch를 키우면 total peak VRAM은 올라갈 수 있습니다. 다만 여러 요청을 한 번에 처리하기 때문에 sample 하나당 나눠 계산한 VRAM은 내려갑니다.
이 차이는 실제 운영에서 중요합니다.
- 혼자 쓰는 로컬 앱이면 latency가 더 중요할 수 있습니다.
- 동시에 많은 요청을 처리하는 서비스면 throughput이 더 중요할 수 있습니다.
- batch를 키우면 throughput은 좋아지지만, 개별 요청은 batch가 차기를 기다릴 수 있습니다.
- 그래서 serving scheduler는 latency와 throughput 사이에서 타협합니다.
커널 fusion은 왜 빨라지는가
Triton kernel fusion은 GPU 연산을 합쳐 메모리 왕복을 줄이는 최적화입니다.
모델 내부에는 작은 연산들이 많습니다.
정규화
곱셈
활성화 함수
덧셈
다시 정규화
순정 PyTorch eager에서는 이런 연산이 여러 kernel launch로 나뉘고, 중간 결과가 GPU HBM에 저장됐다가 다시 읽힐 수 있습니다.
연산 A -> HBM 저장
연산 B -> HBM 읽기 -> HBM 저장
연산 C -> HBM 읽기 -> HBM 저장
fusion은 가능한 연산을 하나로 묶습니다.
연산 A+B+C를 한 kernel 안에서 처리
계산량 자체가 크게 줄어드는 것보다, 메모리를 오가는 비용과 kernel launch overhead가 줄어드는 효과가 큽니다. Qwen3-TTS-Triton도 RMSNorm, SwiGLU, M-RoPE, Norm+Residual 같은 병목 연산을 fused Triton kernel로 바꿉니다.
이것은 vLLM의 API server와 다른 층입니다. vLLM이 “여러 주문을 어떻게 주방에 배치할까”라면, Triton kernel fusion은 “요리사가 한 동작으로 여러 과정을 처리하게 만들자”에 가깝습니다.
CUDA Graph는 반복 작업을 녹화해 재생한다
CUDA Graph도 자주 나오는 말입니다. 쉽게 말하면 GPU 작업 순서를 한 번 녹화해 두고 다음부터 통째로 재생하는 방식입니다.
일반 실행은 이런 느낌입니다.
Python -> GPU야 A 해
Python -> GPU야 B 해
Python -> GPU야 C 해
Python -> GPU야 D 해
CUDA Graph는 처음에 A-B-C-D를 capture하고, 이후에는 graph를 replay합니다.
처음 한 번: A-B-C-D 녹화
다음부터: 녹화된 작업 묶음을 재생
shape가 반복되고 실행 경로가 안정적일수록 효과가 좋습니다. Qwen3-TTS-Triton의 hybrid mode는 Triton kernel patch를 적용한 뒤 CUDA Graph capture를 결합합니다.
OmniVoice-Triton은 이 점이 더 선명합니다. OmniVoice-Triton README는 OmniVoice가 NAR 구조라 sequence length가 32번의 unmasking step 동안 고정되고, 같은 tensor shape의 forward pass를 반복하기 때문에 CUDA Graph에 잘 맞는다고 설명합니다.
AR과 NAR은 서빙 최적화 방식도 다르게 만든다
Qwen3-TTS와 OmniVoice를 같이 보면 AR/NAR 차이가 서빙 최적화에 어떤 영향을 주는지 보입니다.
AR은 autoregressive입니다. 앞에서 만든 결과를 보고 다음 token을 만듭니다.
token 1 생성
token 2 생성
token 3 생성
token 4 생성
...
LLM 대부분이 이 방식이고, Qwen3-TTS도 AR 성격을 가집니다. 이 구조에서는 KV cache, decode step scheduling, continuous batching, prefix caching 같은 기술이 중요해집니다. 그래서 vLLM류의 서빙 엔진이 강점을 갖습니다.
NAR은 non-autoregressive입니다. token을 하나씩 늘려가는 대신 전체 위치를 한꺼번에 예측하거나 여러 번 refine합니다.
전체 token 위치 준비
step 1에서 전체를 대략 채움
step 2에서 전체를 다시 다듬음
...
OmniVoice는 NAR iterative unmasking 구조입니다. 이런 구조에서는 AR LLM의 token-by-token scheduler보다, 고정 shape 반복 forward, CUDA Graph, batch inference, kernel fusion이 더 중요해질 수 있습니다.
그래서 같은 “음성 생성”이라도 최적화 포인트가 달라집니다.
| 모델 구조 | 생성 방식 | 중요한 최적화 |
|---|---|---|
| AR LLM / AR TTS | 앞 token을 보고 다음 token 생성 | KV cache, continuous batching, decode scheduler |
| NAR TTS / diffusion-like model | 전체 sequence를 병렬 생성 또는 반복 refine | CUDA Graph, fixed-shape batch, kernel fusion |
이 관점에서 보면 qwen3-tts-triton과 omnivoice-triton은 “vLLM을 안 썼으니 서빙이 아니다”가 아닙니다. 모델 구조에 맞춰 다른 층을 직접 최적화한 것입니다.
ComfyUI-Qwen3-TTS-Triton은 wrapper에 가깝다
ComfyUI-Qwen3-TTS-Triton은 qwen3-tts-triton을 ComfyUI에서 쓰기 위한 custom node입니다. README 기준으로 Custom Voice와 Voice Clone 노드를 제공하고, runner mode로 base, triton, faster, hybrid, +tq 계열을 고를 수 있습니다.
즉 이 저장소의 역할은 조금 더 위쪽입니다.
ComfyUI node
↓
qwen3-tts-triton runner
↓
Triton kernel / CUDA Graph / KV cache 최적화
↓
Qwen3-TTS 모델
여기서도 “서빙”이라는 말을 넓게 쓰면 ComfyUI workflow 안에서 모델을 사용할 수 있게 만든 serving interface라고 볼 수 있습니다. 하지만 vLLM 같은 LLM serving engine과는 역할이 다릅니다.
작성 시점 기준 GitHub README에는 ComfyUI wrapper의 release가 v0.2.0으로 표시되고, vendor-isolated install 예시도 qwen3-tts-triton==0.2.0을 pin하고 있습니다. 따라서 qwen3-tts-triton v0.3.0의 generate_batch()가 ComfyUI node UI까지 그대로 노출됐는지는 별도 확인이 필요합니다.
제가 이해를 고친 방식
처음에는 “LLM serving은 vLLM으로 서버를 띄우는 것”이라고 생각했습니다. 앞서 말했듯 사내 RAG를 vLLM으로 서빙하던 동안에는 그 정의가 대부분 들어맞았기 때문입니다. 이제는 이렇게 보는 게 맞다고 느낍니다.
Serving은 모델을 여러 사용자가 실제로 쓸 수 있게 만드는 전체 운영 문제입니다. vLLM은 그중 AR LLM에 특화된 강력한 해법이고, Triton kernel, CUDA Graph, batching, KV cache는 각각 다른 층의 최적화입니다.
그래서 어떤 프로젝트를 볼 때는 먼저 “이게 vLLM인가 아닌가”보다 아래 질문을 던지는 편이 낫습니다.
- 이 프로젝트는 API 서버를 제공하는가?
- 요청을 queueing하고 scheduling하는가?
- 여러 요청을 batch로 묶는가?
- KV cache나 activation memory를 직접 관리하는가?
- 모델의
generate()loop를 바꾸는가? - GPU kernel을 직접 교체하는가?
- 특정 모델 구조에 강하게 의존하는가?
Qwen3-TTS-Triton은 이 질문에 이렇게 답합니다.
| 질문 | Qwen3-TTS-Triton에서의 위치 |
|---|---|
| API 서버인가? | 핵심은 아니다 |
| batch 처리를 하는가? | v0.3.0에서 generate_batch() 제공 |
| KV cache를 건드리는가? | TurboQuant KV cache, static KV cache 경로가 있다 |
| generate runner를 바꾸는가? | runner mode를 제공한다 |
| GPU kernel을 바꾸는가? | RMSNorm, SwiGLU, M-RoPE, Norm+Residual을 Triton kernel로 교체한다 |
| 특정 모델에 맞춘 것인가? | Qwen3-TTS 1.7B talker 구조에 맞춘 최적화다 |
그러니 이 프로젝트를 “vLLM serving이냐 아니냐”로만 보면 핵심을 놓칩니다. 더 정확한 표현은 다음에 가깝습니다.
Qwen3-TTS-Triton은 Qwen3-TTS를 위한 모델 전용 inference runner 최적화 라이브러리이고, v0.3.0에서는 batch generation을 통해 concurrent request의 per-sample throughput을 크게 높인 사례입니다.
초심자용 최종 정리
마지막으로 용어를 짧게 정리해 두면 이렇습니다.
| 용어 | 한 줄 정의 |
|---|---|
| Inference | 모델을 한 번 실행해 결과를 얻는 것 |
| Serving | 여러 사용자가 모델을 실제 서비스에서 쓰게 만드는 전체 운영 과정 |
| vLLM | LLM inference와 serving을 위한 runtime/engine |
| NVIDIA Triton Inference Server | 여러 모델을 배포하는 범용 inference server |
| triton-lang | GPU custom kernel을 작성하는 언어/컴파일러 |
| CUDA Graph | 반복되는 GPU 작업 순서를 녹화해 재생하는 최적화 |
| Batching | 여러 요청을 묶어 throughput을 높이는 방법 |
| KV cache | AR 모델에서 이전 token 계산 결과를 저장해 재사용하는 메모리 |
| Latency | 요청 하나가 끝날 때까지 걸리는 시간 |
| Throughput | 일정 시간 동안 처리할 수 있는 전체 작업량 |
제가 이 사례에서 가져간 핵심은 하나입니다.
LLM serving을 배운다는 것은 vLLM 사용법만 배우는 것이 아닙니다. 요청을 어떻게 묶을지, GPU 메모리를 어떻게 쓸지, 모델 내부 연산을 어떻게 줄일지, latency와 throughput을 어디서 trade-off할지 배우는 것입니다.
LLM에서는 vLLM이 그중 많은 부분을 이미 해줍니다. 하지만 TTS, 음성, 이미지, diffusion, NAR 모델처럼 구조가 달라지면 모델 전용 runner와 kernel 최적화가 여전히 의미를 가집니다.
Qwen3-TTS-Triton v0.3.0은 그 점을 잘 보여주는 예입니다. 다음에 어떤 inference 프로젝트 README를 만나든, “이거 vLLM이야?”라고 묻기 전에 위의 계층 질문 7개를 먼저 던져 보세요. 그 프로젝트가 어느 층을 건드리는지 보이면, 이름에 붙은 Triton이나 serving 같은 단어에 덜 휘둘리게 됩니다.
자주 묻는 질문
Qwen3-TTS-Triton의 Triton은 NVIDIA Triton 서버인가요?
아닙니다. 대부분 triton-lang(GPU custom kernel을 작성하는 언어/컴파일러)을 뜻합니다. “Triton 서버에 모델을 올렸다”가 아니라 “모델 내부 연산을 Triton kernel로 다시 짰다”에 가깝습니다. NVIDIA Triton Inference Server는 이름만 같은 별개의 배포 서버입니다.
v0.3.0의 14배는 제 요청 하나가 14배 빨라진다는 뜻인가요?
아닙니다. ~14x per-sample throughput at batch=16 수치이고, README도 “single-clip latency path is unchanged”라고 못 박습니다. 여러 clip을 batch로 묶었을 때 sample 하나당 처리 비용이 약 14배 줄었다는 의미이지, 단일 요청 latency가 14배 빨라졌다는 뜻이 아닙니다.
Qwen3-TTS를 vLLM으로 서빙할 수는 없나요?
가능성은 열려 있습니다. Qwen 공식 PyPI 문서 기준으로 vLLM-Omni가 Qwen3-TTS를 지원하지만, 작성 시점에는 offline inference만 되고 online serving은 추후 지원 예정입니다. 즉 지금은 “실시간 API 서버”보다는 로컬/오프라인 합성에 가깝습니다.
그냥 vLLM만 배우면 되지 않나요?
LLM만 다룬다면 vLLM이 서빙의 많은 부분을 덮어 줍니다. 하지만 TTS·이미지·diffusion·NAR처럼 모델 구조가 달라지면 KV cache 스케줄링보다 kernel fusion, CUDA Graph, 고정 shape batch 같은 다른 층 최적화가 더 중요해집니다. 그래서 “vLLM 사용법”보다 “어느 층을 최적화할지”를 배우는 편이 오래갑니다.
관련 글
- OpenAI SDK vs Temporal vs LangGraph — LLM 에이전트 백엔드 비교 — “겉보기엔 같은 층 같지만 실제로는 다른 층”을 에이전트 백엔드에서 정리한 글
- Retrieval 성능의 한계에 부딪쳤을 때 1: SPLADE보다 먼저 봐야 할 것 — latency를 stage별로 분리해 병목을 찾는 이야기
- RAPTOR — 재귀 요약 트리로 긴 문맥을 검색하는 RAG 기법 — RAG 인덱싱을 층위로 나눠 보는 이야기