TPS (Tokens Per Second)

김동준·2025년 10월 20일

TPS (Tokens Per Second)

TPS = 초당 생성되는 토큰의 개수

LLM의 생성 속도를 측정하는 가장 기본적인 지표입니다.

정의

TPS = 생성된 총 토큰 수 / 소요 시간(초)

예시:
100개 토큰 생성에 5초 소요
→ TPS = 100 / 5 = 20 tokens/s

측정 방법

단일 요청 TPS

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

배치 처리 TPS (Throughput)

# 여러 요청을 동시 처리
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

TPS의 종류

1. Per-Request TPS (개별 요청 TPS)

단일 요청의 생성 속도

예시:
요청: "Python 코드 작성해줘"
생성: 150 토큰
시간: 10초
→ TPS = 15 tokens/s

사용자가 체감하는 속도

2. System TPS (시스템 처리량)

시스템 전체의 토큰 생성 능력

예시:
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 (시스템 전체)

서버 용량을 나타내는 지표

실제 예시

예시 1: 스트리밍 생성

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초

예시 2: 모델 크기별 TPS 비교

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

예시 3: 배치 크기에 따른 TPS

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  ← 개별 속도 저하

TPOT와의 관계

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. 모델 크기

작은 모델 (1-7B):
TPS: 40-150 tokens/s ⚡

중간 모델 (13-30B):
TPS: 15-40 tokens/s

큰 모델 (70B+):
TPS: 5-15 tokens/s 🐢

2. 하드웨어

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

3. 배치 크기

배치 1 (순차 처리):
전체 TPS: 40
요청당: 40 TPS

배치 16 (병렬 처리):
전체 TPS: 500 ← 12.5배 증가!
요청당: 31 TPS ← 약간 감소

4. 양자화 (Quantization)

# 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배 빠름)

5. KV 캐시 최적화

# 캐시 없음 (매번 재계산)
# TPS: 20 tokens/s

# Prefix 캐싱
llm = LLM(model="Llama-2-7b", enable_prefix_caching=True)
# 캐시 히트 시 TPS: 80 tokens/s (4배 향상!)

벤치마크 예시

GPT 시리즈 추정치

모델           하드웨어    TPS (추정)
─────────────────────────────────────
GPT-3.5       A100×8     ~60-100
GPT-4         H100×8     ~20-40
GPT-4-Turbo   H100×8     ~40-60

오픈소스 모델 (A100 기준)

모델              배치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

실전 최적화

1. 처리량 우선 (Throughput)

llm = LLM(
    model="Llama-2-7b",
    max_num_seqs=64,          # 큰 배치
    gpu_memory_utilization=0.95,
)
# 목표: 시스템 전체 TPS 최대화

2. 지연시간 우선 (Latency)

llm = LLM(
    model="Llama-2-7b",
    max_num_seqs=4,           # 작은 배치
    enable_chunked_prefill=True,
)
# 목표: 개별 요청 TPS 최대화

3. 모니터링

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)

목표 TPS 설정

실시간 대화:
목표: 30-50+ TPS
이유: 사람 읽기 속도 (200-300 단어/분)

배치 처리:
목표: 200-1000+ TPS
이유: 처리량 최대화

코드 생성:
목표: 50-100+ TPS
이유: 긴 코드를 빠르게 생성

TPS는 LLM 시스템의 성능을 측정하는 핵심 지표이며, 사용 사례에 따라 개별 TPS와 시스템 TPS 중 어느 것을 최적화할지 결정해야 합니다!

profile
Story Engineer

0개의 댓글