본문으로 건너뛰기
5분 AI.
GITHUB TRENDING PYTHON WEEKLY #15 딥다이브 · 2026-10-23 분석

tokenspeed 딥다이브
— GPU를 기다리게 하지 않는 추론 엔진의 설계

추론·서빙 엔진

빠른 판단

무엇
C++ 스케줄러·Python 실행 계층·교체형 GPU 커널로 요청 배치와 캐시를 관리하는 LLM 서빙 엔진
이럴 때
모델을 직접 운영하며 긴 대화·반복 호출·동시 요청의 지연과 GPU 활용을 조정할 때
LLM이 답을 만드는 동안, 다음 요청을 고르고 메모리를 준비하는 일은 누가 할까요? TokenSpeed는 C++20 스케줄러·Python 모델 실행·교체 가능한 GPU 커널을 연결해 이 문제를 푸는 추론 엔진입니다. 이 글은 요청 하나가 토큰으로 돌아오는 경로를 따라가며 비동기 처리, 상태 머신, 캐시 소유권, 양자화를 배웁니다. 저장소 lightseekorg/tokenspeed · 2026-10-23 GitHub 기준 스타 2,772 · 포크 371 · MIT · 코드 기준 커밋 1ed2de1.
목차
  1. 프로젝트 한줄 요약
  2. 왜 주목받는가
  3. 기술 스택 전체 지도
  4. 아키텍처 심화 분석
  5. 디렉토리 구조 해부
  6. 학습 포인트 (기술별)
  7. 하드웨어 / 시스템 요구사항
  8. 직접 해볼 수 있는 실습 과제
  9. 관련 기술 심화 학습 로드맵
  10. 핵심 키워드 사전
  11. 참고 링크

1프로젝트 한줄 요약

모델을 만드는 도구가 아니라, 이미 있는 모델을 빠르게 운영하는 엔진

TokenSpeed는 공개 LLM의 가중치를 불러와 여러 사용자의 생성 요청을 처리하는 추론·서빙 엔진입니다. 모델의 지식을 새로 학습시키는 것이 주목적은 아닙니다. 같은 모델로도 요청을 묶는 방법, 캐시를 보관하는 방법, GPU 연산을 호출하는 방법에 따라 응답 속도와 처리량이 달라집니다.

이 저장소의 핵심은 모델 계산을 빠르게 만드는 일과, 그 계산이 멈추지 않도록 준비하는 일을 함께 설계한다는 점입니다. Python만 읽어도 입구를 이해할 수 있지만, 중요한 결정은 C++과 GPU용 DSL까지 이어집니다.

한 문장 비유

LLM이 주방이라면, TokenSpeed는 주문표·조리대·재료 창고를 함께 관리하는 운영 시스템입니다

GPU는 요리사입니다. 주문이 도착할 때마다 재료를 처음부터 꺼내고, 한 접시가 완성될 때까지 다음 주문표를 만들지 않으면 요리사가 쉽니다. 스케줄러는 다음 조리 순서를 정하고, 캐시는 이미 손질한 재료를 보관하며, 커널은 실제 조리 동작을 수행합니다.

그런데 조리 중인 재료를 다른 주문에 넘겨 버리면 음식이 뒤섞입니다. 그래서 빨리 배정하는 능력과 안전하게 회수하는 능력이 같은 정도로 중요합니다.

1-1. 답변 생성에는 성격이 다른 두 구간이 있다

구간무엇을 하나주요 관심사
Prefill입력 프롬프트의 토큰들을 처리하고 이후 계산에 필요한 상태를 만든다.긴 입력의 연산량, 첫 토큰 대기, 다른 요청과의 간섭
Decode앞서 만든 상태를 이용해 다음 토큰을 반복 생성한다.토큰 사이 대기, 캐시 읽기, 작은 연산의 호출 비용
용어
토큰과 KV 캐시
토큰은 모델이 읽고 쓰는 문자열 조각입니다. 한 글자나 한 단어와 정확히 같지는 않습니다. KV 캐시는 Attention 계산에 쓰인 Key·Value를 보관한 중간 결과입니다. 다음 토큰을 만들 때 과거 토큰의 K·V를 다시 계산하는 일을 줄입니다. 모델 가중치와는 별도의 메모리를 사용합니다.

1-2. 사용자에게 보이는 명령과 내부 구조

python/pyproject.toml은 tokenspeed와 ts를 같은 CLI 진입점에 등록합니다. python/tokenspeed/cli/serve_smg.py의 설명에 따르면 ts serve는 SMG 게이트웨이와 gRPC 엔진을 함께 기동하고, --headless는 외부 프론트엔드가 연결할 엔진만 기동합니다.

# 공식 시작 가이드의 실행 형태를 읽는 예시
tokenspeed serve openai/gpt-oss-20b \
  --host 127.0.0.1 \
  --port 8000 \
  --tensor-parallel-size 1

# 모델 이름 → 가중치·토크나이저 선택
# host·port → 서비스 접점, tensor-parallel-size → 연산 분할 폭

이 명령은 사용 형태를 보여 주는 예시입니다. 실제 기동에는 지원 가속기와 설치 환경, 모델 파일이 필요합니다. 먼저 AsyncLLM.generate_request()가 요청을 받고, 스케줄러 계획과 GPU 실행을 거쳐 응답을 내보내는 흐름부터 이해해 봅시다.

학습 목표
“어느 함수가 빠른가”에서 “누가 무엇을 소유하는가”로

글을 읽은 뒤에는 요청 상태, 실행 계획, GPU 작업, 완료 통지가 각각 어디에 있는지 설명할 수 있어야 합니다. 이 구분은 추론 엔진뿐 아니라 작업 큐, 파일 업로드, 영상 변환 서버에도 적용됩니다.

2왜 주목받는가

에이전트의 긴 대화와 반복 호출이 드러내는 추론 엔진의 병목

2-1. 에이전트 작업은 한 번의 질문으로 끝나지 않는다

코딩 에이전트는 코드와 도구 결과를 읽고, 답을 생성하고, 다시 도구 결과를 받는 과정을 반복합니다. 대화가 길어질수록 입력이 커지고 공통 접두부가 늘어나므로 캐시 재사용과 응답 지연이 중요해집니다. TokenSpeed의 README는 이런 에이전트 작업 부하를 주된 대상으로 밝힙니다.

저장소에도 이를 구체화한 실험이 있습니다. test/agentic_benchmark/Qwen3.8-Flash-Next/README.md는 첫 프롬프트를 최대 50,000토큰, 이후 사용자 입력 증가를 최대 800토큰으로 조정하고, 동시성 1·2·4·8·16·32에서 각각 측정합니다. 각 턴의 출력은 ignore_eos=true로 500토큰을 생성하도록 설정합니다.

이 실험은 대화를 재생하는 서빙 벤치마크입니다. 문서도 생성된 도구 호출을 실제 실행하지 않는다고 명시합니다. 따라서 이 수치를 에이전트의 문제 해결률이나 실제 개발 업무의 완료 시간으로 해석하면 안 됩니다.

2-2. 화제의 근거와 해석의 범위

관찰근거어떻게 읽을까
관심 증가2026-10-23 GitHub 기준 스타 2,772·포크 371, Python 주간 트렌딩 #15관심의 신호이며 운영 안정성의 점수는 아니다.
최신 모델 최적화README의 10월 소식: EAGLE-4, Beam, MLA 2, Qwen3.8, AMD Kimi K3프로젝트의 공개 발표이며 개별 지원 조합은 별도 확인한다.
세밀한 성능 작업커밋 1ed2de1 제목은 Kimi K3의 KDA Q·K·V 복사 제거와 FP8 양자화 타일 조정을 설명모델 추가뿐 아니라 데이터 이동·실행 단위까지 다룬다.
검증 인프라C++ 수명주기 테스트, GPU별 단위 테스트, 정확도·성능 CI 명세어떤 조건을 검증하는지 소스로 읽을 수 있다. 통과 이력과는 별개다.

이런 개발 방향은 트렌딩을 이해하는 배경입니다. 각 요인이 스타 증가에 얼마나 영향을 주었는지는 공개 코드만으로 알 수 없습니다. README의 “빛의 속도”라는 표현도 물리적 보장이 아니라 프로젝트의 성능 지향을 나타내는 문구입니다.

2-3. 경쟁 제품과 비교할 때 볼 축

도구공식 자료에서 확인할 특징TokenSpeed에서 배울 차별점
vLLMPagedAttention, 연속 배칭, 접두부 캐시, 다양한 모델·하드웨어 지원C++ 상태 머신과 Python 실행의 경계를 좁은 인터페이스로 읽기 좋다.
TensorRT-LLMNVIDIA 중심의 최적화, 진행 중 배칭, 청크 단위 입력 처리, KV 캐시 관리공용 커널 API 아래 NVIDIA·AMD·NPU 구현을 연결하는 방식을 볼 수 있다.
TokenSpeed에이전트 작업 지향, 요청·캐시 수명 관리, 커널 등록·선택 계층스케줄링 정확성과 GPU 최적화를 한 요청 경로에서 함께 공부할 수 있다.

비교 근거는 vLLM 공식 개요와 TensorRT-LLM 공식 Attention 문서입니다. 배칭·양자화·캐시가 TokenSpeed만의 기능인 것은 아닙니다. 위 표는 설계와 학습 관점의 비교입니다.

추론 엔진의 우열은 이름표가 아니라 같은 모델·정밀도·하드웨어·입출력 길이·동시성에서 비교해야 합니다. README의 “TensorRT-LLM 수준 성능, vLLM 수준 사용성”은 프로젝트가 내세우는 목표로 읽어야 합니다.

성능 지표
첫 토큰 지연·토큰 간 지연·전체 처리량
TTFT는 첫 토큰이 나오기까지의 대기, TPOT는 출력 토큰당 시간입니다. 전체 처리량은 여러 요청이 합쳐서 만든 토큰의 양입니다. 동시성을 높이면 전체 처리량이 늘면서 한 사용자에게 보이는 속도는 낮아질 수 있습니다.

예를 들어 test/ci/perf/qwen3.8-flash-next-nvfp4-tp4ep4-evalscope-agentic.yaml은 사용자당 속도와 GPU당 출력 처리량의 단위를 구분합니다. perf_reference는 기존 측정 결과를 바탕으로 정한 CI 비교 기준값입니다.

3기술 스택 전체 지도

요청 처리, 모델 계산, 네이티브 확장, 문서 사이트를 나눠 읽기

3-1. 백엔드: Python으로 연결하고 C++로 일정을 정한다

계층실제 선언역할과 근거 파일
주 패키지tokenspeed 0.1.1, Python >=3.11python/pyproject.toml의 프로젝트 버전·실행 환경
모델 생태계transformers==5.12.0, torch, torchvision주 패키지는 Torch 버전을 고정하지 않는다. 모델 설정·텐서 연산에 사용
비동기·전송uvloop, pyzmq, msgspec, orjson이벤트 루프, 프로세스 간 메시지, 직렬화. 여기 나열한 항목은 주 파일에서 버전 미고정
웹·제어fastapi, uvicorn, aiohttpHTTP·제어 경로용 의존성. 주 서빙 명령의 게이트웨이는 SMG가 담당
게이트웨이tokenspeed-smg==1.13.0.post20261019python/tokenspeed/cli/serve_smg.py가 외부 패키지의 게이트웨이와 엔진을 조합
gRPC 연결proto 0.4.27.post20261019, servicer 0.14.0.post20261019tokenspeed-smg-grpc-proto·tokenspeed-smg-grpc-servicer의 정확한 핀
보조 기능xgrammar==0.2.8, torch_memory_saver==0.0.9.post1구조화 출력, 선택적으로 켜는 메모리 절약 경로

openai>=2.24.1도 의존성에 있습니다. 이것이 OpenAI 원격 API 호출을 필수로 뜻하지는 않습니다. 이 프로젝트의 중심은 모델 가중치를 직접 실행하는 서빙입니다. 패키지 이름만으로 데이터 흐름을 추정하지 말고 호출부를 따라가야 합니다.

3-2. C++ 확장과 GPU 커널: 같은 버전 번호로 묶이지 않는다

부품버전·도구읽을 파일
스케줄러0.1.42, Python >=3.10, C++20tokenspeed-scheduler/pyproject.toml·tokenspeed-scheduler/CMakeLists.txt
바인딩·빌드nanobind>=2.13.0, scikit-build-core>=0.9.5, CMake >=3.22, Ninja >=1.11스케줄러의 빌드 의존성. OpenSSL::Crypto도 링크
커널 공용 패키지기준 버전 0.1.4, Python >=3.11tokenspeed-kernel/python/setup.py의 BASE_VERSION; 실제 버전은 브랜치·날짜에 따라 동적 생성
NVIDIA 연산torch==2.14.0, torchvision==0.29.0, flashinfer-python==0.7.2tokenspeed-kernel/python/requirements/cuda.txt
NVIDIA DSLnvidia-cutlass-dsl[cu13]==4.8.0, apache-tvm-ffi==0.1.13.post3같은 CUDA 의존성 파일에 선언
공용 GPU DSLtokenspeed-triton>=3.9.10.post20261008CUDA·ROCm 요구사항에 공통으로 선언
AMD 커널tokenspeed-kernel-amd 0.1.4tokenspeed-kernel-amd/pyproject.toml; Torch와 TokenSpeed Triton에 의존
NPU 커널tokenspeed-kernel-npu 0.1.0, triton-ascend==3.2.1tokenspeed-kernel-npu/pyproject.toml; 호환 TorchNPU 환경은 따로 필요
MLA 커널tokenspeed-mla 2.0.4, CUTLASS DSL >=4.8.0tokenspeed-mla/pyproject.toml; 저수준 Attention 전용 부품

표의 NVIDIA DSL 의존성도 tokenspeed-kernel/python/requirements/cuda.txt에서 확인할 수 있습니다. tokenspeed-kernel/python/requirements/cuda-thirdparty.txt에는 tokenspeed-deepep==2.1.0.post20260810, tokenspeed-deepgemm==2.8.0.post20260924, tokenspeed-mla==2.0.4 등이 별도로 선언됩니다.

파일명이 thirdparty라고 해서 선택 의존성은 아닙니다. tokenspeed-kernel/python/setup.py의 설명과 요구사항 결합 로직은 두 파일을 설치 메타데이터에 함께 반영합니다. ROCm 쪽은 tokenspeed-kernel/python/requirements/rocm.txt에서 Torch 버전을 고정하지 않으며, tokenspeed-kernel/python/requirements/rocm-thirdparty.txt에는 Petit용 triton==3.8.0이 있습니다.

3-3. 프론트엔드: 추론용 대시보드 대신 문서 사이트

docs/package.json은 bun@1.3.0과 vitepress ^1.6.3을 선언합니다. docs/.vitepress/config.mts는 기본 경로 /tokenspeed/, 로컬 문서 검색, 가이드·레시피 메뉴를 설정합니다. 이 구성은 문서를 빌드하는 프론트엔드이며, 별도의 React 채팅 제품을 뜻하지 않습니다.

커밋 1ed2de1의 TypeScript 계열 코드는 .mts 설정 1개·85줄입니다. 작은 설정 파일에서 Bun·VitePress가 보인다고 추론 런타임이 Node.js 서버라고 결론 내리면 안 됩니다.

3-4. 인프라·빌드: 컨테이너 태그와 실제 설치값을 구별하기

버전은 패키지 선언, 가속기별 요구사항, 컨테이너 설치 단계를 함께 읽어야 실제 의미가 드러납니다. 특히 기반 이미지 이름에 적힌 FlashInfer 0.6.18과 현재 CUDA 요구사항의 0.7.2를 같은 값으로 적으면 부정확합니다.

4아키텍처 심화 분석

요청 한 건이 실행 계획과 GPU 작업으로 바뀌는 과정

4-1. 시스템 전체 그림

아래는 ts serve의 대표 경로를 단순화한 구조입니다. 게이트웨이와 gRPC 서빙 구현 일부는 의존 패키지에 있고, 이 저장소는 기동 조합과 런타임을 제공합니다. 직접 ZMQ 연결이나 분리 서빙 같은 선택 경로까지 전부 그린 그림은 아닙니다.

클라이언트 │ 생성 요청 / 스트리밍 응답 ▼ SMG 게이트웨이 [외부 의존 패키지] │ gRPC ▼ 엔진 서비스 + AsyncLLM [Python, 요청 접수] │ InputProcessor / 요청별 상태 │ EngineCoreClient: ZMQ + MessagePack ▼ EventLoop [Python, 제어 루프] ├── next_execution_plan() ──> Scheduler [C++20] │ ├── 요청 상태 머신 │ └── 캐시 배정·재사용 판단 │ <── ExecutionPlan ───────────┘ │ └── DeviceHandle.execute() │ 비동기 작업 제출 ▼ ForwardThread [rank마다 FIFO 소비 스레드] │ 모델 실행 / 캐시 복사 ▼ 모델·Attention·tokenspeed_kernel │ 등록된 구현 선택 ▼ NVIDIA GPU / AMD GPU / 지원 NPU │ 결과 + 복사 완료 이벤트 ▼ PendingExecution.result() │ 완료 반영 / 상태 전이 / 응답 전달 └──────────────────────────> 클라이언트

AsyncLLM.generate_request()는 입력 검증, 배치 정규화, 토큰화와 응답 대기를 조합합니다. _send_one_request()는 rid_to_state에 요청 상태를 저장하고 스케줄러 쪽으로 메시지를 보냅니다. EngineCoreClient는 요청 송신·응답 수신·부하 스냅샷 수신 소켓을 소유합니다.

python/tokenspeed/runtime/engine/core_client.py에서는 호출 이름이 send_pyobj()여도 실제 소켓을 IpcSender·AsyncIpcReceiver로 감쌉니다. 기본 전송 형식은 MessagePack이며, 환경 변수 TOKENSPEED_USE_PICKLE_IPC=1을 설정하면 요청·응답 전송이 pickle로 바뀝니다. 함수 이름만으로 전송 형식을 판단하면 이 차이를 놓칩니다.

4-2. 패턴 ① 제어와 실행을 나누고, 계획으로 연결한다

python/tokenspeed/runtime/engine/event_loop.py의 EventLoop.event_loop()는 요청을 받고, 캐시 완료 이벤트를 반영하고, C++ 스케줄러에서 다음 계획을 얻습니다. 실제 모델 연산은 DeviceHandle 뒤의 실행 계층으로 넘깁니다.

tokenspeed-scheduler/csrc/scheduler/scheduler.cpp의 Scheduler::NextExecutionPlan()은 실행할 요청만 고르는 함수가 아닙니다. 모델 배치와 함께 페이지 초기화·복사, 저장·복원, 원격 처리 작업도 계획에 담습니다. Python에 노출되는 이름은 tokenspeed-scheduler/bindings/python_module.cpp의 next_execution_plan입니다.

# EventLoop.event_loop()를 이해하기 위한 의사 코드
while 서비스가_동작함:
    새_요청을_받는다()
    캐시_완료를_스케줄러에_반영한다()
    plan = scheduler.next_execution_plan()
    pending = device.execute(plan, 준비한_입력, cache_ops=장치_캐시_작업)
    완료된_결과를_반영한다()
    스케줄러에_상태_변화를_알린다()
비유

관제탑이 비행 계획을 내리고 비행기가 운항하는 관계입니다. 관제탑이 직접 엔진을 조작하거나 한 비행기의 착륙만 기다리면 다른 비행기를 관리할 수 없습니다. 계획과 완료 보고를 주고받는 경계가 시스템을 확장하기 쉽게 만듭니다.

4-3. 패턴 ② 상태에 자원을 넣어 수명주기를 드러낸다

tokenspeed-scheduler/csrc/fsm/states.h는 요청 상태를 std::variant로 표현합니다. Submitted, Prefilling, Decoding, Finishing, Finished 외에 원격 처리·저장소 대기·회수와 복원 상태도 포함합니다.

대표적인 로컬 요청 경로를 단순화 Submitted ──> Prefilling ──> PrefillDone ──> Decoding │ ▼ Finishing │ 실행 중 결과가 모두 도착 ▼ Finished 청크 반복: Prefilling ── 다음 청크 ──> Prefilling 한 청크로 끝나면 Submitted ──> PrefillDone도 가능하다. 메모리 회수: Prefilling / PrefillDone / Decoding 중 진행 중 결과가 0인 요청 └──> Retracted ──> Restoring 실제 전이는 입력 청크·추측 생성·엔진 역할에 따라 달라진다.

tokenspeed-scheduler/csrc/fsm/forward_states.h의 ForwardResources는 요청 슬롯, 블록 테이블, 캐시 진행 정보, results_in_flight를 한 묶음으로 가집니다. tokenspeed-scheduler/csrc/fsm/forward_events.cpp는 std::move(state.resources)로 다음 상태에 이 묶음을 전달합니다.

// forward_events.cpp의 ReleaseEvent 본문 핵심 발췌
Finished ReleaseEvent::operator()(Finishing&& state) {
    _assert(coordinator_ != nullptr, "ReleaseEvent requires a cache coordinator");
    _assert(state.resources.results_in_flight == 0,
            "a request is released only once its forwards have landed");
    FreeRequest(*coordinator_, state.resources.block_tables);
    return Finished{};
}

논리적으로 답이 끝나는 시점과 메모리를 다시 빌려줄 수 있는 시점은 다를 수 있습니다. 위 검사는 그 차이를 직접 보여 줍니다. 타입은 상태와 자원 묶음의 형태를 제한하고, 실행 중 결과 수 같은 시간 조건은 런타임 검사로 확인합니다.

용어
RAII와 공유 소유권
RAII는 객체 수명이 끝날 때 자원 반환도 수행하도록 묶는 C++ 기법입니다. tokenspeed-scheduler/csrc/cache/core/cache_block_ref.cpp에서 마지막 CacheBlockRef가 해제되면 제어 객체가 파괴되고, CacheBlock의 소멸자가 풀에 블록을 반환합니다. 요청·캐시·전송이 함께 참조할 수 있어 단순한 “요청 종료 즉시 반환”보다 정교합니다.

README는 타입 시스템을 통한 안전성을 강조합니다. 소스는 여기에 참조 수, 완료 통지, _assert도 결합합니다. 따라서 “모든 비동기 메모리 오류를 컴파일 때 막는다”는 식으로 확대 해석하지 않아야 합니다.

4-4. 패턴 ③ FIFO 제출과 완료 반영을 분리해 CPU·GPU를 겹친다

python/tokenspeed/runtime/execution/forward_thread.py의 ForwardThread는 queue.SimpleQueue와 소비 스레드를 사용합니다. submit_forward()는 작업과 Future를 큐에 넣고 즉시 반환합니다. 작업 중 예외는 future.set_exception()으로 결과를 기다리는 쪽에 전달합니다.

python/tokenspeed/runtime/execution/types.py의 PendingExecution.result()는 먼저 Future를 기다리고, 이어 ModelExecutionResult.sync()로 GPU→CPU 복사 완료 이벤트를 기다립니다. “스레드가 커널 호출을 끝냈다”와 “CPU가 결과를 읽어도 된다”를 별도로 확인하는 셈입니다.

일반적인 overlap 깊이 1의 개념도 시간 ──────────────────────────────────────────────> GPU [ N번 계산 ][ N+1번 계산 ] CPU [N+1 준비] [N 결과 반영] 제출: 기다리지 않고 다음 작업을 큐에 넣는다. 반영: 필요한 순서에서 Future와 복사 완료 이벤트를 확인한다. 의존성이 있는 입력은 먼저 대기열을 비워 정확성을 지킨다.

EventLoop의 in_flight_depth=0은 같은 반복에서 결과를 반영하고, 1은 다음 작업을 제출한 뒤 이전 결과를 반영합니다. 파이프라인 병렬에서는 pp_size가 깊이가 됩니다. _dispatch_depends_on_pending_commit()는 먼저 결과 반영이 필요한 경우를 모읍니다.

비동기는 기다림을 없애는 기술이 아니라, 정확성이 허용하는 시점까지 기다림을 옮기는 기술입니다. 결과를 너무 일찍 읽는 오류와 너무 일찍 기다려 병렬성을 잃는 문제를 함께 다뤄야 합니다.

4-5. 패턴 ④ 공용 연산 계약과 등록된 구현을 분리한다

tokenspeed-kernel/python/tokenspeed_kernel/registry.py의 register_kernel()은 연산 종류, 실행 모드, 형식 서명, 하드웨어 능력, 특성, 우선순위를 등록합니다. tokenspeed-kernel/python/tokenspeed_kernel/selection.py의 select_kernel()은 조건에 맞는 후보를 고르고 결과를 캐시합니다.

공용 연산 API └─ select_kernel(family, mode, format_signature, traits, ...) ├─ 하드웨어·형식·기능·특성에 맞는 후보 필터링 ├─ 연산별 판단 규칙 + 우선순위로 선택 ├─ 같은 선택 조건은 캐시에서 조회 └─ Triton / CuTe DSL / 공급업체 라이브러리 구현 호출

solution=은 특정 구현 계열로 후보를 좁히면서 호환성 검사를 유지합니다. 반면 override=는 하드웨어·형식·특성 매칭을 건너뛰는 강제 선택이며, 필수 기능 검사는 남습니다. 두 인자를 같은 “백엔드 선택 옵션”으로 뭉뚱그리면 중요한 차이를 놓칩니다.

구현에서 확인한 한계
AUTOTUNE이라는 이름이 실제 측정을 보장하지 않는다

tokenspeed-kernel/python/tokenspeed_kernel/selection.py의 _autotune_select()는 현재 _rank()의 첫 후보를 반환하며, 로그에도 휴리스틱으로 대체한다고 기록합니다. 설정에 warmup_iters=3·bench_iters=10이 있어도 이 함수가 모든 후보를 측정하는 구현은 아닙니다. 별도의 benchmark 도구와 구분해야 합니다.

4-6. 커밋 1ed2de1에서 배우는 최적화: 계산식보다 이동과 실행 단위를 바꾸기

python/tokenspeed/runtime/models/kimi_k3.py의 KimiLinearKDA._project_qkvfab()는 합쳐 계산한 투영 결과에서 mixed_qkv = output[:, : 3 * proj_local]로 뷰를 만듭니다. 이 지점에서 .contiguous()로 별도 복사하지 않습니다. 후속 KDA 연산이 뷰의 행 간격을 처리할 수 있어야 가능한 선택입니다. 아래의 토큰 그룹 양자화 함수는 연속 텐서만 받으므로 입력 조건을 구별해야 합니다.

tokenspeed-kernel/python/tokenspeed_kernel/ops/quantization/triton.py의 _fp8_token_group_quantize()는 그룹별 FP8 양자화를 여러 그룹씩 타일로 묶어 실행합니다.

# 실제 분기 조건 발췌: padded_elements = groups * block
if padded_elements < 1 << 14 or block >= 1024:
    groups_per_program = 1
elif padded_elements < 7 << 18:
    groups_per_program = 1024 // block
else:
    groups_per_program = 8192 // block

block=128, 큰 입력이라면 프로그램 하나가 64그룹을 처리합니다. [4096, 7168] 입력은 그룹 크기 128일 때 229,376그룹이고, 64개씩 묶으면 3,584개 프로그램이 됩니다. 이는 실행 단위 개수의 계산이지 64배 속도 향상의 측정값이 아닙니다.

이 커널의 groups는 런타임 인자이고 GROUPS_PER_PROGRAM은 컴파일 때 정해집니다. 서빙 전에는 block이 1024보다 작은 경우 같은 서명에 필요한 세 타일을 warmup()으로 미리 컴파일합니다. 목표는 작업 분할 개선과 함께 서빙 도중 새로운 크기 때문에 컴파일이 끼어드는 일을 줄이는 것입니다.

5디렉토리 구조 해부

파일이 많은 저장소에서 길을 잃지 않는 읽기 지도
tokenspeed/ ├── python/ │ ├── pyproject.toml 주 패키지·CLI·런타임 의존성 │ └── tokenspeed/ │ ├── cli/ 명령 해석·게이트웨이 기동 │ └── runtime/ │ ├── engine/ 접수·IPC·이벤트 루프·응답 │ ├── execution/ 실행 스레드·입력·결과·그래프 │ ├── models/ 모델별 구조와 가중치 연결 │ ├── layers/ Attention·선형층·양자화 │ ├── model_loader/ 모델 가중치 로딩 │ ├── pd/ Prefill·Decode 분리 전송 │ └── utils/ 서버 설정·플랫폼 보조 코드 ├── tokenspeed-scheduler/ │ ├── csrc/{fsm,scheduler,cache}/ 상태 전이·일정·캐시 │ ├── bindings/python_module.cpp nanobind 경계 │ ├── python/ Python 노출부·테스트 │ └── tests/cpp/ 스케줄러·캐시 검증 ├── tokenspeed-kernel/python/ │ ├── requirements/ 가속기별 의존성 │ └── tokenspeed_kernel/ │ ├── registry.py / selection.py 등록·선택 │ ├── ops/ 연산별 구현 │ ├── numerics/ / benchmark/ 수치 검증·측정 │ └── thirdparty/ 외부 소스·라이브러리 연결 ├── tokenspeed-kernel-amd/ AMD 전용 구현 ├── tokenspeed-kernel-npu/ Ascend 전용 구현 ├── tokenspeed-mla/ MLA 전용 커널 ├── test/{runtime,cli,ci}/ 동작 테스트·CI 작업 명세 ├── test/agentic_benchmark/ 모델별 대화 부하 실험 ├── docs/{design,guides,recipes}/ 설계 원칙·설치·모델 레시피 ├── docker/ 가속기별 이미지 빌드 └── .github/workflows/ 테스트·문서·릴리스 자동화

5-1. 코드 규모는 “전체”와 “부품”을 나눠 본다

언어·영역파일 수물리적 줄 수
Python 전체2,3811,024,856
C/C++·CUDA 전체22394,360
JavaScript2221
TypeScript 계열 .mts185
Shell615,077
python/537214,822
tokenspeed-scheduler/11744,378
tokenspeed-kernel/1,132486,749
test/563222,290

표의 아래 네 행은 영역별 Python·C/C++·CUDA 합계입니다. 위의 언어별 합계와 겹치므로 다시 더하지 않습니다.

집계는 .git/을 제외한 물리적 줄 수이며, 빈 줄·주석·라이선스 문구·테스트·동봉한 외부 코드를 포함합니다. C/C++·CUDA는 .c/.cc/.cpp/.h/.hpp/.cu/.cuh, Python은 .py/.pyi를 대상으로 셌습니다.

Python 중 thirdparty/ 안에 있는 코드만 221파일·105,960줄입니다. Python에는 GPU용 DSL도 포함됩니다. 주 언어가 Python이라고 해서 100만 줄 모두가 HTTP 처리나 CPU 처리인 것은 아닙니다.

5-2. 처음이라면 이 순서로 읽기

  1. docs/design/event-loop.md로 제어와 실행의 경계를 파악한다.
  2. python/tokenspeed/runtime/engine/async_llm.py의 generate_request()에서 송신 경로를 따라간다.
  3. python/tokenspeed/runtime/engine/event_loop.py의 event_loop()에서 계획과 완료 반영을 찾는다.
  4. tokenspeed-scheduler/csrc/fsm/forward_events.cpp에서 상태와 자원의 이동을 읽는다.
  5. tokenspeed-kernel/python/tokenspeed_kernel/selection.py에서 관심 있는 연산으로 들어간다.

거대한 모델 구현을 처음부터 읽기보다 요청·계획·실행·완료의 경계를 하나씩 연결하면 전체 구조를 이해하기 쉽습니다.

6학습 포인트 (기술별)

기술 이름을 외우지 말고, 해결하려는 문제와 연결하기

6-1. Python 비동기: 코루틴과 작업 스레드는 다르다

AsyncLLM.generate_request()의 async for는 응답이 생길 때마다 소비자에게 넘깁니다. 반면 ForwardThread는 GPU 작업 제출을 담당하는 별도 스레드입니다. async라는 문법 자체가 GPU 계산을 병렬화해 주지는 않습니다.

배울 것: 코루틴은 대기 시간을 다른 일에 양보하고, 큐·Future는 생산자와 소비자의 책임을 연결합니다. 실습 아이디어: test/runtime/test_forward_thread.py에서 FIFO 순서, 예외 전달, 느린 작업 중에도 제출이 막히지 않는다는 세 테스트를 읽고 각각의 실패 상황을 글로 써 봅니다.

6-2. C++20: enum 플래그 대신 상태별 자료형

std::variant는 “현재 상태가 여러 후보 중 정확히 하나”임을 나타냅니다. HoldsForwardResources라는 concept는 특정 상태가 필요한 자원 묶음을 갖는지 표현합니다. “finished인데 running도 true” 같은 조합을 플래그 여러 개로 만들지 않는 설계입니다.

배울 것: 값의 범위뿐 아니라 유효한 상태 조합을 타입으로 표현하기. 실습 아이디어: 파일 업로드 상태를 대기·수신·검증·완료로 나누고, 임시 파일 핸들을 어느 상태가 소유해야 하는지 표로 그려 봅니다.

6-3. 메모리 계층: 같은 “캐시 크기”에도 단위가 있다

docs/design/cache-concepts.md는 접두부 식별 단위인 prefix_granularity, 이력 블록의 논리 토큰 범위인 block_granularity, 실제 저장 단위인 CacheBlock, 커널의 페이지 크기를 분리합니다. 서버의 기본 prefix_granularity는 64토큰입니다.

여기에 전체 이력, 슬라이딩 윈도, 순환 상태라는 세 캐시 종류가 있습니다. 순환 상태 그룹은 일반 KV 이력과 달리 “토큰 행을 담은 페이지”로 선언하지 않습니다. 모든 Attention 상태를 단일 KV 배열로 취급하면 하이브리드 모델을 설명하기 어렵습니다.

비유

책의 “몇 쪽까지 읽었나”, 책장 칸의 크기, 창고 상자의 크기는 서로 다른 단위입니다. 상자 하나에 여러 칸의 내용물이 들어가도 독서 진도는 쪽수로 계산해야 합니다. 논리 단위와 저장 단위를 나누면 압축·캐시 이동을 바꿔도 일정 계산을 유지할 수 있습니다.

실습 아이디어: tokenspeed-scheduler/tests/cpp/test_kv_cache_lifecycle.cpp에서 전체 이력과 슬라이딩 윈도의 블록 테이블이 어떻게 달라지는지 읽습니다. 특히 슬라이딩 윈도 뒤쪽에 남는 실제 블록과 앞쪽의 0번 자리 표시자를 구분해 봅니다.

6-4. GPU DSL·양자화: 수치 표현과 실행 배치를 따로 이해하기

FP8은 수를 적은 비트로 담아 저장·이동 비용을 줄이는 표현입니다. _fp8_token_group_quantize_kernel()은 그룹별 최댓값으로 scale을 구하고 입력을 나눠 변환합니다. 여러 그룹을 한 프로그램에 배치해도 각 그룹의 계산은 독립적입니다.

# 커널 계산의 의사 코드. bit8_max는 자료형의 최대 유한값이다.
scale = max(max(abs(group)), 1e-10) / bit8_max
quantized = clamp(group / scale, bit8_min, bit8_max).to(torch.float8_e4m3fn)
복원한_근삿값 = quantized.float() * scale

배울 것: 양자화 오차와 타일링 성능은 서로 다른 검증 대상입니다. 실습 아이디어: tokenspeed-kernel/test/ops/test_fp8_quantization_block.py에서 블록 경계 크기, 블록별 scale, 복원 오차를 어떻게 검사하는지 찾습니다. 이 파일의 블록 양자화 테스트를 토큰 그룹 커널의 성능 측정으로 혼동하지 않습니다.

6-5. CUDA Graph: 매번 새로 만들지 않고 내용을 갱신하기

docs/design/unified_path.md는 일반 실행과 그래프 재생이 동일한 refresh_decode_metadata() 경로를 사용한다고 설명합니다. 그래프 재생에서는 준비한 버퍼의 내용을 갱신한 뒤 기록된 실행을 재사용합니다.

그래프에 담는 배치 크기의 상한과 실제 처리 가능한 배치 크기의 상한도 분리합니다. 기록 범위를 넘는 decode는 같은 메타데이터 갱신 경로로 일반 실행을 합니다. 실습 아이디어: 문서에서 max_capture_bs와 max_decode_bs가 다른 이유를 찾아 설명합니다.

6-6. 검증 설계: 정확도·지연·컴파일 횟수를 함께 보기

test/ci/README.md는 서버를 기동하는 CI가 기본적으로 TOKENSPEED_JIT_COMPILE_CHECK=error를 사용한다고 명시합니다. 요청마다 바뀌는 값을 컴파일 상수로 넣어 서빙 중 재컴파일을 반복하는 문제도 실패로 취급합니다.

성능 최적화의 완료 조건에는 출력의 정확성뿐 아니라 대기·재컴파일·자원 회수의 동작도 포함됩니다. 정답만 같고 지연이 간헐적으로 튀는 변경을 놓치지 않는 관점입니다.

7하드웨어 / 시스템 요구사항

소스 독해 환경과 실제 모델을 띄우는 환경을 분리해서 판단하기
목적·경로확인할 요구사항근거와 주의점
소스 공부텍스트 편집기, Git, 파일 검색 도구이 글의 읽기 과제는 GPU와 모델 다운로드 없이 가능
주 런타임Python >=3.11공식 nightly 안내는 Python 3.11–3.13을 대상으로 설명
NVIDIAsm90/sm100/sm103/sm107으로 지원 범위 제한AGENTS.md의 범위. 같은 제조사의 모든 GPU를 뜻하지 않음
기본 CUDA 경로CUDA 13용 의존성·호환 드라이버·Linux 환경tokenspeed-kernel/python/requirements/cuda.txt의 cu13 DSL과 릴리스 워크플로의 Linux x86_64·ARM64 빌드 대상
H100/H200 별도 경로Linux, Python 3.11, CUDA Toolkit 12.9docs/guides/hopper-cu129.md는 실험적 소스 설치법으로 명시
AMDROCm 7.2 계열, gfx950/gfx1250 및 gfx1201의 이식성 커널RDNA4 gfx1201은 초기 Dense BF16 경로로 범위가 다름
Ascend NPU호환 Torch·TorchNPU·Triton Ascend 및 별도 네이티브 연산지원 모델 범위가 제한됨. GPU 경로 전체를 그대로 사용할 수 있다는 뜻은 아님
네이티브 빌드C++20 컴파일러, CMake·Ninja, OpenSSL 개발 파일스케줄러 빌드 설정 기준. 커널 빌드는 별도 가속기 툴체인 필요
컨테이너·저장소GPU 접근 가능한 Docker, 충분한 공유 메모리·모델 저장 공간시작 가이드의 --shm-size 32g는 예시값이며 보편적 최솟값이 아님
여러 GPU·노드모델 분할 방식에 맞는 GPU 연결·통신 환경TP·EP·PD 전송 비용까지 포함해 모델별 레시피를 확인

7-1. “몇 GB면 되나요?”에는 모델과 대화 길이가 필요하다

저장소 전체에 공통으로 적용할 VRAM 최솟값은 없습니다. 필요한 메모리는 대략 가중치 + KV·순환 상태 + 연산 작업 공간 + 그래프·통신 버퍼입니다. 여기에 동시 요청 수와 최대 문맥 길이가 영향을 줍니다.

# 가중치만 보는 교육용 근사식. 실제 설치 요구량은 아니다.
가중치_바이트 ≈ 전체_매개변수_수 * 매개변수당_비트 / 8

7B 모델을 BF16으로 저장: 7,000,000,000 * 16 / 8 ≈ 14 GB
7B 모델을 4비트로 저장: 7,000,000,000 *  4 / 8 ≈ 3.5 GB

# scale·메타데이터·일부 고정밀 가중치·런타임 버퍼는 별도다.

MoE 모델의 “토큰당 활성 매개변수”가 작아도 전체 전문가 가중치의 저장 비용이 사라지지는 않습니다. 397B-A17B 같은 이름에서 17B만 메모리에 들어간다고 계산하면 안 됩니다.

7-2. 일반적인 KV 캐시의 증가량을 계산해 보기

# 일반적인 비압축 MHA/GQA의 KV 데이터만 계산하는 근사식
KV_바이트 ≈ 2 * 레이어_수 * KV_헤드_수 * 헤드_차원
             * 저장_토큰_수 * 원소당_바이트

# 가상의 설정: 32층, KV 헤드 8개, 차원 128, 4096토큰, BF16
2 * 32 * 8 * 128 * 4096 * 2 = 536,870,912바이트
                           = 요청당 512 MiB

동일 조건의 요청 8개면 KV 데이터만 약 4 GiB입니다. 접두부 공유, 분할 저장, 여유 공간 등은 따로 고려해야 합니다. 이 식은 MLA 압축 캐시나 KDA의 순환 상태에 그대로 적용할 수 없습니다.

하드웨어 선택 전
가속기 지원과 특정 모델의 실행 가능성은 별개다

GPU 아키텍처, 모델 구현, 정밀도, Attention 백엔드, 통신 라이브러리가 모두 맞아야 합니다. 일반 노트북이나 CPU 전용 환경에서 공식 GPU 서빙 레시피가 동작한다고 볼 근거는 없습니다. 메모리 식은 예산 추정용이며 실제 실행을 보증하는 요구사항 표가 아닙니다.

Hopper 가이드는 CUDA Toolkit 12.9를 쓰면서 Torch는 2.14.0+cu126을 사용하는 특수 조합도 설명합니다. 툴킷 버전, Torch가 묶은 런타임 버전, 드라이버 버전을 하나의 숫자로 취급하지 않는 습관을 들이세요.

8직접 해볼 수 있는 실습 과제

설치·모델 기동 없이도 결과물을 남길 수 있는 다섯 과제
과제 1 · 입문 · 30분

요청 한 건의 여행 지도 만들기

목표: generate_request()에서 요청이 어디로 나가고 응답은 어디서 돌아오는지 찾습니다.

방법: python/tokenspeed/runtime/engine/async_llm.py의 검증·토큰화·송신·대기 함수를 표시하고 python/tokenspeed/runtime/engine/core_client.py에서 각 소켓을 연결합니다. 이어 python/tokenspeed/runtime/engine/event_loop.py의 계획 호출을 찾습니다.

완료 기준: 요청 ID 보관 위치, 송신 객체, 계획 생성 함수, 결과 대기 함수를 적은 화살표 그림 한 장. 게이트웨이·엔진 프로세스·실행 스레드를 같은 상자로 그리지 않으면 성공입니다.

# 저장소 루트에서 소스 텍스트만 검색하는 명령
rg -n 'generate_request|_send_one_request|_wait_one_response' \
  python/tokenspeed/runtime/engine/async_llm.py
rg -n 'next_execution_plan|_device.execute|advance_scheduler' \
  python/tokenspeed/runtime/engine/event_loop.py
과제 2 · 입문 · 40분

“답변 완료”와 “자원 반환”의 차이 설명하기

목표: Finishing이 따로 존재하는 이유를 설명합니다.

방법: tokenspeed-scheduler/csrc/fsm/forward_events.cpp의 FinishEvent·ReleaseEvent를 읽습니다. 자원을 가진 상태에서 std::move가 어디로 향하는지 표시하고, tokenspeed-scheduler/csrc/cache/core/cache_block_ref.cpp의 마지막 참조 해제까지 연결합니다.

완료 기준: 결과가 하나 남았을 때와 모두 도착했을 때의 표를 작성합니다. 전자는 정상적인 Release 조건을 만족하지 않으며, 후자는 요청 참조를 놓을 수 있습니다. 다른 캐시·전송 참조가 남으면 물리 블록이 즉시 반환되지 않을 수도 있다는 설명까지 붙입니다.

과제 3 · 중급 · 40분

KV 캐시 예산과 청크 처리표 계산하기

목표: 토큰 수와 메모리 바이트 수를 구분합니다.

방법: 7절의 가상 모델로 4,096·8,192토큰, 동시성 1·8일 때 KV 크기를 계산합니다. 별도로 20,000토큰 입력을 chunked_prefill_size=8192로 나눈 이상적인 청크 길이를 적습니다.

완료 기준: KV는 각각 요청당 512 MiB·1 GiB, 동시성 8에서는 4 GiB·8 GiB라는 표를 만듭니다. 단순 분할은 8,192·8,192·3,616입니다. 실제 스케줄러는 캐시 적중·정렬·가용량에 따라 다르게 자를 수 있다는 주석을 붙입니다.

과제 4 · 중급 · 1시간

커널 선택을 종이 위에서 실행하기

목표: 후보 필터링, 순위 결정, 강제 선택을 구별합니다.

방법: tokenspeed-kernel/python/tokenspeed_kernel/registry.py의 KernelSpec 필드로 가상의 후보 세 개를 적습니다. 하나는 장치가 맞지 않고, 하나는 필수 기능이 없고, 하나만 모두 만족하게 만듭니다. tokenspeed-kernel/python/tokenspeed_kernel/selection.py에서 각 후보가 탈락하는 위치를 연결합니다.

완료 기준: 기본 선택과 solution=·override=의 차이를 설명한 흐름도. override도 필수 기능 검사를 생략하지 않는다는 점과, 현재 _autotune_select()가 실제 측정을 하지 않는다는 근거를 적습니다.

과제 5 · 고급 · 1~2시간

FP8 타일 조정의 검증 계획 쓰기

목표: 코드 변경의 성능 가설과 정확성 조건을 분리합니다.

방법: _fp8_token_group_quantize()의 세 분기로 아래 실행 단위를 계산합니다. 이어 입력 정렬·마지막 타일 마스크·그룹별 scale·시작 후 재컴파일 여부를 검증 항목으로 정합니다.

완료 기준: 예상 프로그램 수 표와 측정 계획서 한 장. 향후 GPU 측정 시에는 준비 실행, 동일 입력·자료형, 반복 시간 분포, 수치 비교를 기록하도록 설계합니다. 프로그램 수 감소만으로 속도 향상 배수를 단정하지 않습니다.

입력·그룹 크기 128그룹 수프로그램당 그룹프로그램 수
[32, 128]32132
[256, 128]256832
[4096, 7168]229,376643,584

실행하지 않고도 데이터 흐름·자원 수명·메모리 예산·최적화 가설을 검증하는 훈련을 할 수 있습니다. 먼저 이 다섯 결과물을 만들면, 나중에 GPU를 사용할 때 무엇을 측정할지 훨씬 명확해집니다.

9관련 기술 심화 학습 로드맵

6주 동안 작은 개념에서 실제 엔진의 경계까지

Python 함수와 리스트를 읽을 수 있다면 1주차부터 시작할 수 있습니다. C++ 템플릿이나 GPU 프로그래밍을 전부 익힌 뒤 읽으려 하지 말고, 각 주차의 질문에 답하는 데 필요한 문법부터 보충합니다.

주차학습 주제연결할 소스·문서남길 결과물
1주토큰화, Attention, Prefill·Decode, 가중치와 KV의 차이docs/index.md, python/tokenspeed/runtime/configs/model_config.py한 요청의 토큰 증가와 메모리 증가 그림
2주asyncio, 비동기 생성기, 큐, Future, IPCpython/tokenspeed/runtime/engine/async_llm.py, python/tokenspeed/runtime/engine/core_client.py, python/tokenspeed/runtime/execution/forward_thread.py요청·응답 시퀀스 그림과 대기 위치 표
3주C++ 이동, RAII, variant, 상태 전이tokenspeed-scheduler/csrc/fsm/forward_states.h, tokenspeed-scheduler/csrc/fsm/forward_events.cpp, tokenspeed-scheduler/csrc/cache/core/cache_block_ref.cpp자원 소유자가 표시된 상태 전이표
4주접두부 캐시, 논리·물리 단위, 청크 배정, 회수·복원docs/design/cache-concepts.md, docs/design/scheduler.md토큰 경계·블록 위치·참조 수를 나눈 캐시 그림
5주텐서 stride, FP8 scale, GPU 타일, JIT 캐시tokenspeed-kernel/python/tokenspeed_kernel/ops/quantization/triton.py, tokenspeed-kernel/python/tokenspeed_kernel/compile_monitor.py, Kimi K3 투영 함수수치 오차 조건과 실행 프로그램 수 계산
6주CUDA Graph, 병렬화, 벤치마크 통제, 정확도 회귀docs/design/unified_path.md, docs/serving/parallelism.md, test/ci/동일 조건 비교를 위한 실험 계획서

3주차의 C++ 문법이 어렵다면 상태 전이 테스트에서 입력과 기대 결과를 먼저 읽어도 좋습니다. 5주차에는 FP8 수치 오차와 GPU 실행 단위의 변화를 각각 설명할 수 있는지 확인합니다.

9-1. 관심 분야에 따라 다음 단계를 고른다

주차별 통과 기준
그림의 화살표 하나마다 코드 근거를 붙일 수 있는가

“비동기라 빠르다” 대신 어떤 함수가 제출하고 어디서 기다리는지, “캐시가 안전하다” 대신 누가 참조를 쥐고 언제 놓는지 설명해 보세요. 근거가 연결되지 않는 화살표가 다음에 읽을 파일을 알려 줍니다.

10핵심 키워드 사전

정의를 읽고, 앞의 코드에서 어떤 역할이었는지 떠올리기
용어쉬운 설명
추론·서빙추론은 학습된 모델로 출력을 계산하는 일, 서빙은 여러 사용자의 요청을 서비스로 받는 일입니다.
Token모델이 읽는 문자열 조각. 글자 수나 단어 수와 정확히 같지 않습니다.
Prefill입력 프롬프트를 처리해 다음 생성에 필요한 상태를 만드는 구간입니다.
Decode현재 문맥을 바탕으로 다음 토큰을 반복 생성하는 구간입니다.
KV cache과거 토큰의 Attention용 K·V 중간 결과. 모델 가중치와 별도인 메모리입니다.
Prefix cache여러 요청의 동일한 앞부분에 대한 계산 상태를 재사용하는 장치입니다.
Chunked prefill긴 입력을 여러 조각으로 나누어 처리합니다. 메모리 배정과 다른 요청의 진행을 함께 조절합니다.
연속 배칭모든 요청의 종료를 기다리지 않고, 진행 중인 작업 사이에 새 요청을 편입하는 방식입니다.
제어·실행 평면무엇을 언제 할지 정하는 부분과 실제 계산·전송을 수행하는 부분을 나눈 것입니다.
FSM유한 상태 머신. 요청이 가질 수 있는 상태와 허용되는 전이를 명시합니다.
RAII객체가 살아 있는 동안 자원을 보유하고, 수명이 끝날 때 반환 동작을 수행하는 C++ 방식입니다.
In-flight제출했지만 아직 결과를 반영하지 않은 작업. 자원이 여전히 사용 중일 수 있습니다.
Future나중에 완료될 작업의 결과나 예외를 전달하는 손잡이입니다.
FIFO먼저 넣은 작업을 먼저 꺼내는 순서. 스레드 제출 순서와 GPU 완료 여부는 별도로 봐야 합니다.
D2H장치에서 호스트로 결과를 복사하는 것. 여기서는 주로 GPU→CPU 이동을 말합니다.
KernelGPU 등 가속기에서 실행하는 연산 프로그램입니다. 운영체제 커널과는 문맥이 다릅니다.
Registry사용 가능한 구현과 그 조건을 모은 명부. 선택 로직이 이 명부에서 후보를 고릅니다.
Stride텐서의 다음 원소나 다음 행으로 이동할 때 메모리에서 건너뛰는 간격입니다.
FP8·FP48비트·4비트 부동소수점 계열 표현. scale과 형식에 따라 정확도·저장 방식이 달라집니다.
Tile큰 행렬이나 배열을 나누어 처리하는 작은 작업 덩어리입니다.
JIT실행 시점에 필요한 코드를 컴파일하는 방식. 서빙 중 새 컴파일은 지연을 만들 수 있습니다.
CUDA Graph반복할 GPU 작업 흐름을 기록해 재생하는 기능. 버퍼 수명과 메타데이터 갱신이 중요합니다.
MoE토큰별로 일부 전문가 신경망을 선택하는 모델 구조. 전체 가중치 저장과 전문가 통신도 고려합니다.
MLA·KDA서로 다른 Attention 계열입니다. MLA는 잠재 표현을 활용하고, KDA는 게이트와 순환 상태를 활용합니다.
TP·EP·PP텐서 연산, 전문가, 모델 단계라는 서로 다른 축으로 계산을 여러 장치에 나누는 방식입니다.
PD 분리Prefill과 Decode를 서로 다른 자원에서 처리하고 필요한 캐시 상태를 넘기는 구성입니다.
추측 생성초안 토큰을 먼저 제안하고 대상 모델이 검증해 여러 토큰의 진행을 시도하는 방식입니다.
TTFT·TPOT첫 토큰까지의 대기와 출력 토큰당 시간. 전체 토큰 처리량과 구별해서 봅니다.
NanobindC++ 기능을 Python에서 호출할 수 있게 연결하는 바인딩 도구입니다.
MessagePack·ZMQ메시지의 직렬화 형식과 전송 도구입니다. 각각 “어떻게 담는가”와 “어떻게 보내는가”를 맡습니다.

11참고 링크

변하는 소개 페이지와 커밋에 고정한 코드 근거를 구별하기

11-1. 공식 저장소·문서

11-2. 핵심 코드로 바로 가기

11-3. 관련 기술을 더 읽으려면

현재 상태 (2026-10-23 확인)

항목상태기준
저장소lightseekorg/tokenspeed공식 GitHub
선정GitHub Trending Python Weekly #152026-10-23 분석 기준
스타 / 포크2,772 / 3712026-10-23 GitHub 기준
생성일2026-05-062026-10-23 GitHub 기준
최신 릴리스v0.1.1 · 2026-10-062026-10-23 GitHub 기준
최근 push2026-10-232026-10-23 GitHub 기준
최근 커밋1ed2de1 · 2026-10-23Kimi K3의 KDA Q·K·V 복사 제거와 두 FP8 양자화기의 Prefill 타일 조정 · #2626
주 언어 / 규모Python · 1,024,856줄 / 2,381파일커밋 기준 물리적 줄 수, 테스트·외부 코드 포함
네이티브 코드C/C++·CUDA 94,360줄 / 223파일헤더·테스트·외부 코드 포함, 집계 확장자는 5절 참조
주 패키지 / 부품런타임 0.1.1 · 스케줄러 0.1.42 · MLA 2.0.4각 패키지의 프로젝트 버전 기준, 개별 배포 주기는 다름
라이선스MITLICENSE · LightSeek Foundation, 2026
사용 전에 알아둘 한계
커밋의 코드·릴리스·운영 환경을 구별해야 한다

설명과 코드 규모는 커밋 1ed2de1에 고정되어 있습니다. 이 커밋의 소스는 10월 6일 릴리스 이후 상태이므로, 릴리스 v0.1.1을 설치했다고 모든 설명과 코드가 동일하지는 않습니다.

README의 속도 기록·업계 비교·지원 발표는 프로젝트의 공개 주장입니다. 성능 수치는 모델·정밀도·하드웨어·입출력 길이·동시성 등 측정 조건과 함께 읽어야 합니다. CI 파일의 존재는 해당 커밋이 모든 장치에서 통과했다는 증거가 아니며, 실제 가용 메모리와 설치 호환성도 대상 환경에서 확인해야 합니다.

MIT 라이선스는 엔진 코드에 관한 것입니다. 모델 가중치·데이터셋·동봉한 외부 구성요소에는 별도 이용 조건이 있을 수 있습니다. 게이트웨이 같은 의존 패키지의 동작은 해당 패키지의 문서와 버전도 함께 확인해야 합니다. 설치·실험 전에는 사용할 모델과 정확한 가속기 조합의 공식 레시피를 함께 확인하세요.