TPS = 초당 생성되는 토큰의 개수
LLM의 생성 속도를 측정하는 가장 기본적인 지표입니다.
TPS = 생성된 총 토큰 수 / 소요 시간(초)
예시:
100개 토큰 생성에 5초 소요
→ TPS = 100 / 5 = 20 tokens/s
import time
prompt = "AI에 대해 설명해줘"
start_time = time.time()
# 생성
response = model.generate(prompt, max_tokens=100)
end_time = time.time()
elapsed = end_time - start_time
# TPS 계산
tokens_generated = len(response.tokens)
tps = tokens_generated / elapsed
print(f"생성 토큰: {tokens_generated}")
print(f"소요 시간: {elapsed:.2f}초")
print(f"TPS: {tps:.2f} tokens/s")
출력 예시:
생성 토큰: 100
소요 시간: 5.2초
TPS: 19.23 tokens/s
# 여러 요청을 동시 처리
prompts = ["질문1", "질문2", "질문3", ... "질문100"]
start_time = time.time()
responses = model.generate_batch(prompts, max_tokens=50)
end_time = time.time()
# 총 생성된 토큰
total_tokens = sum(len(r.tokens) for r in responses)
elapsed = end_time - start_time
# 전체 TPS
tps = total_tokens / elapsed
print(f"총 요청: {len(prompts)}")
print(f"총 토큰: {total_tokens}")
print(f"TPS: {tps:.2f} tokens/s")
출력 예시:
총 요청: 100
총 토큰: 5,000
소요 시간: 25초
TPS: 200 tokens/s
단일 요청의 생성 속도
예시:
요청: "Python 코드 작성해줘"
생성: 150 토큰
시간: 10초
→ TPS = 15 tokens/s
사용자가 체감하는 속도
시스템 전체의 토큰 생성 능력
예시:
1분간 처리:
- 요청 A: 100 토큰
- 요청 B: 150 토큰
- 요청 C: 80 토큰
- 요청 D: 120 토큰
총: 450 토큰 / 60초 = 7.5 tokens/s per request
또는
1분간 총 10개 요청, 평균 100토큰
→ 1000 토큰 / 60초 = 16.67 tokens/s (시스템 전체)
서버 용량을 나타내는 지표
from vllm import LLM, SamplingParams
import time
llm = LLM(model="meta-llama/Llama-2-7b-hf")
prompt = "인공지능의 미래에 대해 500자로 설명해줘"
start_time = time.time()
token_count = 0
token_times = []
# 스트리밍으로 생성
for output in llm.generate(prompt, SamplingParams(max_tokens=200),
stream=True):
token_count += 1
current_time = time.time()
token_times.append(current_time - start_time)
# 실시간 TPS 계산
if token_count > 1:
instant_tps = 1 / (token_times[-1] - token_times[-2])
print(f"토큰 #{token_count}: {output.text} (TPS: {instant_tps:.1f})")
# 전체 평균 TPS
total_time = time.time() - start_time
avg_tps = token_count / total_time
print(f"\n평균 TPS: {avg_tps:.2f} tokens/s")
print(f"총 토큰: {token_count}")
print(f"총 시간: {total_time:.2f}초")
출력 예시:
토큰 #1: 인 (TPS: 25.3)
토큰 #2: 공 (TPS: 28.1)
토큰 #3: 지 (TPS: 27.5)
토큰 #4: 능 (TPS: 29.2)
...
토큰 #200: 다 (TPS: 26.8)
평균 TPS: 27.3 tokens/s
총 토큰: 200
총 시간: 7.33초
import time
models = [
("TinyLlama-1.1B", "TinyLlama/TinyLlama-1.1B"),
("Llama-2-7B", "meta-llama/Llama-2-7b-hf"),
("Llama-2-13B", "meta-llama/Llama-2-13b-hf"),
]
prompt = "Hello, how are you?"
num_tokens = 50
for name, model_path in models:
llm = LLM(model=model_path)
start = time.time()
output = llm.generate(prompt, SamplingParams(max_tokens=num_tokens))
elapsed = time.time() - start
tps = num_tokens / elapsed
print(f"{name:20s} TPS: {tps:6.2f} tokens/s")
출력 예시:
TinyLlama-1.1B TPS: 145.32 tokens/s ⚡
Llama-2-7B TPS: 42.18 tokens/s
Llama-2-13B TPS: 23.45 tokens/s
from vllm import LLM, SamplingParams
import time
llm = LLM(model="meta-llama/Llama-2-7b-hf")
prompt = "AI란 무엇인가?"
batch_sizes = [1, 4, 8, 16, 32]
for batch_size in batch_sizes:
prompts = [prompt] * batch_size
start = time.time()
outputs = llm.generate(prompts, SamplingParams(max_tokens=50))
elapsed = time.time() - start
total_tokens = sum(len(o.outputs[0].token_ids) for o in outputs)
tps = total_tokens / elapsed
per_request_tps = tps / batch_size
print(f"배치 {batch_size:2d}: "
f"전체 TPS={tps:6.1f}, "
f"요청당 TPS={per_request_tps:5.1f}")
출력 예시:
배치 1: 전체 TPS= 42.3, 요청당 TPS= 42.3
배치 4: 전체 TPS= 156.8, 요청당 TPS= 39.2
배치 8: 전체 TPS= 285.4, 요청당 TPS= 35.7
배치 16: 전체 TPS= 512.0, 요청당 TPS= 32.0 ← 처리량 증가
배치 32: 전체 TPS= 640.0, 요청당 TPS= 20.0 ← 개별 속도 저하
TPS = 1 / TPOT
TPOT (Time Per Output Token): 토큰 하나당 소요 시간
예시:
TPOT = 0.05초
→ TPS = 1 / 0.05 = 20 tokens/s
TPOT = 0.025초
→ TPS = 1 / 0.025 = 40 tokens/s
작은 모델 (1-7B):
TPS: 40-150 tokens/s ⚡
중간 모델 (13-30B):
TPS: 15-40 tokens/s
큰 모델 (70B+):
TPS: 5-15 tokens/s 🐢
GPU 메모리 대역폭이 중요:
H100 (3.35 TB/s):
Llama-2-7B → ~80 TPS
A100 (2.0 TB/s):
Llama-2-7B → ~45 TPS
RTX 4090 (1.0 TB/s):
Llama-2-7B → ~25 TPS
CPU:
Llama-2-7B → ~2-5 TPS
배치 1 (순차 처리):
전체 TPS: 40
요청당: 40 TPS
배치 16 (병렬 처리):
전체 TPS: 500 ← 12.5배 증가!
요청당: 31 TPS ← 약간 감소
# FP16 (기본)
llm_fp16 = LLM(model="Llama-2-7b")
# TPS: ~40 tokens/s
# INT8
llm_int8 = LLM(model="Llama-2-7b", quantization="int8")
# TPS: ~60 tokens/s (1.5배 빠름)
# INT4
llm_int4 = LLM(model="Llama-2-7b-AWQ", quantization="awq")
# TPS: ~90 tokens/s (2.25배 빠름)
# 캐시 없음 (매번 재계산)
# TPS: 20 tokens/s
# Prefix 캐싱
llm = LLM(model="Llama-2-7b", enable_prefix_caching=True)
# 캐시 히트 시 TPS: 80 tokens/s (4배 향상!)
모델 하드웨어 TPS (추정)
─────────────────────────────────────
GPT-3.5 A100×8 ~60-100
GPT-4 H100×8 ~20-40
GPT-4-Turbo H100×8 ~40-60
모델 배치1 배치16
──────────────────────────────────
Llama-2-7B 42 500
Llama-2-13B 23 280
Llama-2-70B 8 96
Mistral-7B 48 580
Mixtral-8x7B 15 180
llm = LLM(
model="Llama-2-7b",
max_num_seqs=64, # 큰 배치
gpu_memory_utilization=0.95,
)
# 목표: 시스템 전체 TPS 최대화
llm = LLM(
model="Llama-2-7b",
max_num_seqs=4, # 작은 배치
enable_chunked_prefill=True,
)
# 목표: 개별 요청 TPS 최대화
import time
class TPSMonitor:
def __init__(self):
self.tokens = 0
self.start = time.time()
def add_tokens(self, count):
self.tokens += count
elapsed = time.time() - self.start
current_tps = self.tokens / elapsed
print(f"누적 TPS: {current_tps:.2f} tokens/s")
monitor = TPSMonitor()
for output in llm.generate(..., stream=True):
monitor.add_tokens(1)
실시간 대화:
목표: 30-50+ TPS
이유: 사람 읽기 속도 (200-300 단어/분)
배치 처리:
목표: 200-1000+ TPS
이유: 처리량 최대화
코드 생성:
목표: 50-100+ TPS
이유: 긴 코드를 빠르게 생성
TPS는 LLM 시스템의 성능을 측정하는 핵심 지표이며, 사용 사례에 따라 개별 TPS와 시스템 TPS 중 어느 것을 최적화할지 결정해야 합니다!