이것저것 해보자 : 로컬 LLM

sunn_ni·2026년 10월 2일

GPT랑 공부하니까 너무좋다.. 다들 GPT랑 공부하세요.. (물론 약간의 개념공부는 끝내고..)


0. 용어정리

1) LLM 단계

단계용어쉽게 말하면예시
1Tokenization문장을 token으로 쪼갬"Explain HTTP" → 여러 token
2Prompt사용자가 LLM에게 넣는 입력"Explain HTTP in one sentence."
3Prefill요청 전송부터 첫 출력 token 수신까지 걸린 시간질문을 "읽고 이해할 준비"
4Decode모델이 답변 token을 하나씩 생성HTTP → is → a → ...
5Response생성된 token들이 모여 최종 답변이 됨"HTTP is a protocol..."

2) 측정값

항목의미쉽게 이해하기
prompt_eval_count입력 token 수질문이 몇 token이야?
prompt_eval_duration서버가 입력 prompt를 처리하는 데 걸린 시간질문 처리하는 데 얼마나 걸렸어?
eval_count출력 token 수답변을 몇 token 만들었어?
eval_duration출력 생성 시간답변 만드는 데 얼마나 걸렸어?
load_duration모델 로딩 시간모델을 메모리에 올리는 데 얼마나 걸렸어?
total_duration전체 처리 시간처음부터 끝까지 얼마나 걸렸어?
stream출력 전달 방식답변을 조금씩 받을까, 한꺼번에 받을까?
tok/s초당 token 생성량1초에 답변을 몇 token 만들 수 있어?

1. 로컬 환경

GPU: RTX 3050
VRAM: 3926 MiB / 8192 MiB
GPU Util: 5%
Process: /llama-server

2. benchmark

1) thinking여부

실험ModelTokensDecode TimeThroughput
ThinkingQwen3 4B2594.17s62.1 tok/s
ThinkingQwen3 4B94714.88s63.6 tok/s
InstructQwen3 4B Instruct20.017s짧아서 참고용
InstructQwen3 4B Instruct2003.19s62.7 tok/s

2) Prefill + TTFT (길이별)

Prompt실제 입력 토큰Prefill출력Decode전체
짧음1528.2 ms20314.9 ms392.3 ms
중간76338.8 ms20297.1 ms650.9 ms
장문19492.2 ms20295.8 ms405.4 ms

-> 중간길이의 테스트가 장문보다 오래걸림. 좀더 확인요망 (캐시때문인가?)

3) HTTP 설명 요청을 10회 보내서 LLM의 첫 응답까지 걸리는 시간과 전체 응답 시간, 생성 속도를 측정.

회차TTFT전체 응답 시간출력 Token생성 속도
130.24 ms578.37 ms3767.62 tok/s
232.54 ms587.84 ms3461.33 tok/s
331.46 ms532.05 ms3468.01 tok/s
429.71 ms609.03 ms3764.00 tok/s
527.92 ms622.20 ms3762.35 tok/s
638.02 ms555.61 ms3465.75 tok/s
724.88 ms579.96 ms3461.33 tok/s
825.06 ms592.20 ms3765.36 tok/s
928.55 ms596.12 ms3765.30 tok/s
1025.60 ms528.41 ms3467.76 tok/s

전체요약

지표평균P50P95의미
TTFT29.40 ms29.13 ms35.55 ms첫 번째 출력까지 걸린 시간
전체 응답 시간578.18 ms583.90 ms616.27 ms요청부터 답변 완료까지 걸린 시간

3. kv-cache

이전 토큰의 K/V를 저장해서 Decode 때 재계산하지 않도록 하는 메모리.

요청이 많고 Context가 길어지면 KV Cache가 GPU VRAM을 많이 차지한다.
->fragmentation(메모리 파편화) 이슈 발생

4. vLLM

PagedAttention - KV Cache를 작은 Block 단위로 관리해서 GPU 메모리를 더 효율적으로 사용하는 아이디어.이를 통해 LLM을 많은 요청에 효율적으로 Serving한다.(메모리 fragmentation을 줄이고 block 재사용을 쉽게 하는 것이 핵심)

[개인적인 비유]

  • 캐시 저장방식은 뭐랄까.. 가상메모리같기도하고.. 포인터같기도한것같다..
  • 먼저 끝난 프로세스가 나가고 그 자리에 새로운 프로세스가 들어오는 것
    -> NodeJS에서의 Event loop방식이랑 비슷하다고 생각했는데 이건 아니라고한다. (동시에 여러프로세스가 돌아갈 수 있기 때문/그리고 PagedAttention과 Event Loop는 서로 다른 문제를 해결한다.)

5. GPU 동시 요청 실험

  • 동시에 4개 요청 보내기
요청생성 토큰완료 시간
D2008.21s
C1009.75s
A20012.81s
B3013.28s

관찰

  • 동일한 시점에 4개 요청을 시작했지만 요청별 완료 시간이 크게 달랐음
  • 생성 토큰 수가 적은 B(30 tokens)가 가장 늦게 완료되는 현상도 관찰됨
  • 단일 요청에서 측정한 decode throughput과 비교하면 동시 요청 상황에서 요청별 latency가 크게 증가함
  • 먼저 하나가 끝난 뒤 마지막 요청 실행
요청토큰TTFT완료
B300.35s0.80s
A3000.82s5.46s
C3005.50s10.08s
D30010.12s14.70s
E30013.94s19.34s

관찰

  • B가 0.80초에 완료된 후 E를 새로 요청했지만, E의 TTFT는 13.94초로 측정됨
  • C, D, E의 TTFT가 앞선 요청의 처리 완료 시점과 유사한 간격으로 증가하는 현상이 관찰됨
  • 요청이 동시에 GPU decode batch에 참여하고 있다고 보기 어려우며, 요청이 순차적으로 처리되거나 대기하는 구간이 존재할 가능성이 있음

→ 이번 실험을 통해 단순한 HTTP 동시 요청과 LLM Serving에서의 Continuous Batching은 서로 다른 개념임을 확인함.
→ 실제 Continuous Batching의 동작과 Request Scheduler를 확인하기 위해 vLLM 기반으로 추가 실험할 예정

profile
방황중인 서버개발자

0개의 댓글