tiny-vllm: C++와 CUDA로 vLLM을 직접 구현하며 배우는 LLM 추론 엔진

2026-06-01 · 2026-06-01_tiny-vllm-cuda-inference-engine.md

#reflection #ai #llm #cuda #inference

원문 출처

tiny-vllm: C++와 CUDA로 vLLM을 직접 구현하며 배우는 LLM 추론 엔진

개요

  • 출처: PyTorchKR (discuss.pytorch.kr), 2026.06.01
  • 작성자: 9bow (박정환) — GPT 모델로 정리한 글 바탕으로 작성
  • 게시판: 읽을거리&정보공유
  • 태그: llm-inference, vllm, cuda, kv-cache, pagedattention, gqa, tiny-vllm
  • 원저자: Jędrzej Maczan (GitHub: jmaczan)
  • 라이선스: Apache License 2.0
  • 분류: LLM 추론 엔진, CUDA 프로그래밍, 교육 자료

내용 분석

프로젝트 개요

목적: 학습 도구 / 대학 강의 자료 구성: 실제 동작하는 추론 서버 전체 소스 코드 + 단계별 안내 코스(course) 글 범위: 학습(training) 아님, 추론(inference)만 다룸. Llama 3.2 1B Instruct 모델을 NVIDIA GPU 위에서 여러 요청을 병렬로 빠르게 실행하는 프로그램 직접 제작.

핵심 개념: 추론 서버(inference server)는 학습이 끝난 모델 가중치 파일을 실행해 프롬프트에 대한 응답을 만들어 내는 프로그램. LLM의 연산은 대부분 행렬 곱이므로 GPU에서 직접 코드를 돌리는 CUDA가 유리함.

추론 엔진의 구성 요소

  • Safetensors 모델 로딩: Safetensors 포맷으로 저장된 Llama 3.2 1B Instruct 가중치 읽기
  • 전체 forward pass: 프리필(prefill) + 디코드(decode) 모두 구현
  • CUDA 커널화: 임베딩 조회, 정규화, 어텐션 등 핵심 연산을 직접 작성한 CUDA 커널로 수행
  • KV 캐시: 이미 계산한 키와 값을 재사용해 디코드 단계의 중복 계산 줄임
  • 정적 배칭 / 연속 배칭: 여러 요청을 묶어 처리량 높이는 두 가지 방식
  • 온라인 softmax: FlashAttention 계열 방식으로 softmax를 점진적으로 계산
  • PagedAttention: 운영체제의 페이징 아이디어를 KV 캐시 메모리 관리에 적용

주의: 코스 본문은 핵심 forward pass(임베딩부터 argmax까지)까지 상세하게 작성되어 있지만, 배칭과 온라인 softmax, PagedAttention을 다루는 뒤쪽 장은 아직 TODO 상태.

forward pass 동작 방식

Llama 3.2 1B 구조: 16개 트랜스포머 레이어

데이터 흐름:

  1. 텍스트 → 토큰 분할 → 임베딩 벡터 조회 (토큰 5개 입력 시 (5, 2048) 행렬)
  2. 16개 트랜스포머 레이어 통과 (각 레이어: RMSNorm → 잔차 연결 → 마스크드 GQA → 피드포워드 네트워크)
  3. 최종 RMSNorm → 선형 출력(lm_head) → argmax로 가장 확률이 높은 토큰 선택

그룹 쿼리 어텐션(GQA): 어텐션은 O(n²·d) 계산 복잡도를 갖는 비싼 연산. 쿼리 프로젝션(q_proj)은 출력 차원 2048인 반면 키/값 프로젝션(k_proj, v_proj)은 512로 더 작음. 여러 쿼리 헤드가 더 적은 수의 키/값 헤드를 공유해 KV 캐시 크기 줄임.

CUDA 커널 구현 예: RMSNorm

학습 가치: 추상적인 설명이 아니라 실제로 돌아가는 CUDA 커널을 직접 보여줌.

RMSNorm은 GPU에서 병렬 리덕션(parallel reduction)으로 구현. 공유 메모리(__shared__)에 제곱 합을 모은 뒤 트리 리덕션으로 합산하고, 그 결과로 입력을 정규화하는 과정이 한 커널 안에 담김.

코스에서 직접 작성하는 커널 목록: RMSNorm, RoPE, 잔차 연결, SiLU, softmax

BF16 포맷: 16비트 안에서 부호 1비트, 지수 8비트, 가수 7비트. 16비트 크기를 유지하면서도 32비트 float와 같은 8비트 지수를 가져 오버플로/언더플로 위험이 작아 추론에서 널리 쓰임.

실전 문제: cuBLAS의 cublasGemmEx는 열 우선(column-major) 메모리 레이아웃을 가정하는데, C/C++ 배열은 행 우선(row-major). tiny-vllm은 전치(transposition) 트릭으로 해결.

설치 및 실행 환경

  • Linux (커널 6.19.8 x86_64)
  • CUDA Toolkit 13.1
  • C++ 17, GCC 15.2.1
  • NVIDIA GPU (테스트 기준 RTX 5090), AMD CPU (Ryzen 7 9800X3D)
  • Llama 3.2 1B Instruct의 model.safetensors 파일
  • 외부 의존성: nlohmann/json 3.12.0 하나뿐 (단일 헤더 파일 포함)

더 읽어보기 (관련 글)

  • Nano-vLLM (1200줄 경량 구현체)
  • Nano-vLLM 내부 살펴보기 1, 2부
  • Mini-SGLang
  • TokenSpeed
  • FlashKDA

---

새로운 시각

"밑바닥부터 구현"의 교육적 가치

vLLM, SGLang 같은 고성능 추론 엔진을 "사용"하는 것과 "이해"하는 것의 간극이 큽니다. tiny-vllm은 그 간극을 메우는 교육 도구입니다. CUDA 커널을 직접 작성하게 함으로써:

  • KV 캐시가 왜 필요한지: 디코드 단계에서 이전 토큰의 키/값을 다시 계산하지 않는 이유를亲手體驗
  • PagedAttention이 왜 빠른지: 운영체제의 가상 메모리 페이징이 GPU 메모리 관리에 어떻게 적용되는지 이해
  • GQA의 트레이드오프: KV 캐시 크기를 줄이면서 정확도를 얼마나 희생하는지 확인

"학습 아님, 추론만"의 전략적 선택

학습과 추론을 분리한 것은 현명한 선택입니다. 학습은 역전파, 옵티마이저, 분산 학습 등 완전히 다른 복잡도 영역입니다. 추론만 집중하면:

  • GPU 메모리 관리 (KV 캐시, PagedAttention)
  • 배치 처리 (정적 배칭, 연속 배칭)
  • 커널 최적화 (RMSNorm, RoPE, 어텐션)

이라는 추론 특화 기술을 집중 학습할 수 있습니다.

"GPT로 정리한 글"의 메타적 의미

이 글 자체가 AI로 정리된 것입니다. 원문(GitHub README + 코스 글)을 GPT 모델로 요약하고, PyTorchKR에 게시한 과정이 "AI로 학습 자료 만들기"의 실제 사례입니다. 다만 작성자가 "원문도 함께 참고해주세요"라고 경고한 것은 AI 요약의 한계를 인지하고 있는 태도입니다.

---

미래 영향

개발자 교육에 주는 시사점

  • LLM 추론 엔진 이해 = AI 시대의 리터러시: 단순히 API를 호출하는 수준을 넘어, 내부 구조를 이해하는 개발자와 그렇지 않은 개발자의 격차가 커질 것
  • CUDA 프로그래밍의 부활: LLM 추론 최적화를 위해 CUDA 커널 작성 능력이 다시 중요해짐
  • 오픈소스 교육 자료의 가치: tiny-vllm, Nano-vLLM, Mini-SGLang 같은 프로젝트가 대학 강의 자료로 활용될 가능성

자녀 교육 시사점

  • 시스템 프로그래밍의 중요성: 고수준 API 사용 능력도 중요하지만, 밑바닥에서 무슨 일이 일어나는지 이해하는 능력이 더 큰 경쟁력
  • 수학적 기초: 행렬 곱, 벡터 내적, softmax, 정규화 등 수학 개념이 실제 GPU 코드에서 어떻게 구현되는지 연결

내 환경 연결

현재 RTX 3090에 llama-server(Qwen3.6-27B-MTP)를 실행 중입니다. tiny-vllm이 다루는 기술(KV 캐시, PagedAttention, 연속 배칭)이 바로 llama-server 내부에서도 사용되는 기술들입니다. tiny-vllm의 코스를 따라가면 현재 실행 중인 LLM 서버의 내부 동작을 더 깊이 이해할 수 있습니다.

관련 링크

키워드

#LLM추론 #CUDA #vLLM #PagedAttention #KV캐시 #GQA #시스템프로그래밍 #교육자료

관련 노트