이 프로젝트는 아직 개발 중입니다. 일부 기능은 아직 구현되지 않았을 수 있으며 문서가 불완전할 수 있습니다.
연구 목적에 맞춰 제작된 작지만 강력한 LLM 추론 시스템입니다.
단 2,000개의 코드 라인(vLLM의 2%)으로 vLLM과 동등한 성능을 제공합니다.
HuggingFace Transformers, vLLM, LightLLM, DistServe 및 DeepSpeed-MII를 포함하여 LLM 서비스를 위한 오픈 소스 프레임워크가 너무 많습니다. 왜 SwiftLLM인가요?
그 이유는 이러한 프레임워크가 연구 보다는 생산 에 맞춰져 있기 때문입니다. 100개 이상의 모델 지원, 다양한 하드 지원, LoRA, 양자화, 멀티모달, 접두사 캐싱, 빔 검색 등과 같은 다양한 기능을 갖추고 있습니다. 프로덕션을 위한 올인원 솔루션이지만 코드베이스가 너무 크고 복잡하여 이해하고 수정할 수 없습니다(예: vLLM에는 100,000줄 이상의 코드가 있음). 따라서 연구 목적으로 사용하기가 어렵습니다. 또한 그들의 역사적 부담도 문제이다.
SwiftLLM은 연구 목적 에 맞게 맞춤화된 작지만 강력한 LLM 추론 시스템으로 설계되었습니다. "Tiny"는 연구에 꼭 필요한 기능만 유지한다는 의미이고, "Powerful"은 성능 저하가 없다는 의미이며, "Swift"는 이해하고 수정하기 쉽다는 의미입니다. 기본 기능(아래 목록 참조)을 지원하고 vLLM과 동등한 성능을 달성할 수 있는 동시에 SwiftLLM의 코드베이스는 Python 및 OpenAI Triton(작성용 DSL)으로 작성된 2,000 줄 미만의 코드(vLLM의 ~2%)입니다. CUDA 커널)을 사용하면 쉽게 읽고, 수정하고, 디버그하고, 테스트하고, 확장할 수 있으며 새롭고 뛰어난 연구 아이디어와 쉽게 통합될 수 있습니다.
현재 SwiftLLM은 다음 기능을 지원합니다.
그리고 앞으로는 다음 기능에 대한 지원을 추가할 계획입니다.
코드베이스를 작게 유지하기 위해 다음 기능은 지원하지 않습니다. 연구 프로젝트에서 이를 사용하려면 직접 구현해야 할 수도 있습니다.
SwiftLLM은 프로덕션을 위한 올인원 솔루션이 아니라는 점을 기억하십시오. 이를 연구 프로젝트의 "기반"으로 생각하는 것이 좋으며 일부 기능을 직접 구현해야 할 수도 있습니다. 사랑하는 연구자 여러분, 코드를 읽고, 이해하고, 수정하고, 연구 요구 사항에 맞게 확장하시기 바랍니다.
SwiftLLM의 아키텍처는 제어 평면 과 데이터 평면 이라는 두 가지 주요 부분으로 나눌 수 있습니다.
간단히 말하면 제어 평면은 "계산 대상" 또는 "일정 방법"을 결정하고, 데이터 평면은 "계산 방법" 또는 "구현 방법"을 결정하고 구체적인 계산을 수행합니다. 이들은 마스터-워커 방식으로 작동합니다. 제어 플레인은 마스터처럼 작동하여 높은 수준의 예약 및 조정을 수행하고 데이터 플레인에 작업을 보냅니다. 데이터 플레인은 낮은 수준의 계산을 수행하는 작업자처럼 작동합니다.
제어 평면의 코드는 Engine
, Scheduler
, API 서버 및 TokenizationEngine
과 같은 구성 요소를 포함하여 swiftllm/server
디렉터리에 있습니다. 데이터 플레인에 대한 코드는 계산 그래프( Swiftllm/ swiftllm/worker
swiftllm/worker/model.py
), 모델의 레이어 구현( swiftllm/layers
) 및 OpenAI Triton 커널( GPU에서 실행되는 함수로 "커널"을 상상할 수 있습니다( swiftllm/kernels
에서).
장난감 API 서버( swiftllm/server/api_server.py
에 있음)를 예로 들어보겠습니다.
EngineConfig
사용하여 Engine
생성합니다.Engine.initialize
통해 초기화되어 Scheduler
, TokenizationEngine
및 일련의 작업자(현재는 Tensor 병렬 처리가 지원되지 않으므로 하나만)를 생성합니다. 그런 다음 작업자에게 profile_num_blocks
실행하여 GPU 블록 수를 계산하도록 명령한 후 엔진은 모든 작업자에게 KV 캐시 및 KV 스왑을 할당하도록 명령합니다.Engine.start_all_event_loops
를 통해 활성화됩니다. 루프의 각 단계에서 엔진은 스케줄러에 계산할 다음 요청 배치를 쿼리하고 작업자에게 스왑 인/아웃을 수행하도록 명령한 다음 배치를 작업자에게 보내 계산합니다. 현재 제어 평면( Engine
)과 데이터 평면( LlamaModel
)은 동일한 노드에 있습니다. Tensor Parallelism/Pipeline Parallelism이 구현된 후 데이터 평면은 여러 노드에 분산될 수 있습니다.
SwiftLLM을 사용하는 방법에는 제어 플레인과 데이터 플레인을 모두 사용하거나 데이터 플레인만 사용하는 두 가지 방법이 있습니다.
아이디어가 기존 제어 플레인에 원활하게 통합될 수 있을 만큼 간단하거나 우아하다면 제어 플레인과 데이터 플레인을 모두 사용할 수 있습니다. 훌륭한 아이디어를 구현하려는 또 다른 경우에는 데이터 플레인만 활용하고 새로운 제어 플레인을 직접 구현할 수 있습니다.
먼저 환경을 설정해 보겠습니다.
pip install packaging
통해 packaging
설치그런 다음 설치가 이루어집니다.
git clone https://github.com/interestingLSY/swiftLLM.git
통해 이 저장소를 복제하세요.cd
repo( cd swiftLLM
)에 넣고 pip install -r requirements.txt
를 통해 다른 종속성을 설치합니다.pip install -e .
귀하의 환경에 SwiftLLM을 설치합니다.pip install -e csrc
통해 일부 C 바인딩을 설치합니다.다음은 몇 가지 예입니다.
.bin
형식과 .safetensors
형식이 모두 지원됩니다. 모델 가중치가 /data/to/weight/
에 저장되어 있다고 가정합니다.python3 examples/offline.py --model-path /data/to/weight
시도해 볼 수 있습니다. 이 예에서는 데이터 영역만 활용합니다. 제어 플레인 없이 SwiftLLM을 사용할 계획이라면 이것이 좋은 출발점이 됩니다.Engine
사용하는 온라인 제공 예시의 경우 python3 examples/online.py --model-path /data/to/weight
시도해 볼 수 있습니다. 이는 제어 영역과 데이터 영역을 모두 사용하려는 경우 좋은 예입니다.swiftllm/server/api_server.py
를 참조하세요. API 서버를 시작하고 온라인 서비스를 위해 vLLM과 유사한 인터페이스를 제공합니다. SwiftLLM은 작음에도 불구하고(작은 것도 사랑스러울 수 있습니다!), SwiftLLM은 성능에 타협하지 않습니다. 우리는 여러 시나리오에서 SwiftLLM을 평가했으며 SwiftLLM이 vLLM과 비교하여 동등하거나 더 나은 성능을 달성할 수 있음을 입증했습니다.
첫 번째 시나리오는 "단일 전달 작업"으로, 모델에 입력 배치를 제공하고 하나의 출력 토큰을 생성하도록 합니다(하나의 "전달" 작업과 동일). 이는 LLM 추론(온라인 및 오프라인 모두)의 기본 작업이므로 성능이 중요합니다.
여기서는 FP16 정밀도에서 NVIDIA A100 80G PCIE / RTX 4090 GPU가 탑재된 LLaMA-3 7B 모델을 사용합니다. 결과는 아래와 같습니다(낮을수록 좋음).
SwiftLLM은 동일한 설정에서 vLLM과 동등한 성능(또는 심지어 더 나은 성능)을 달성할 수 있음을 알 수 있습니다.
두 번째 시나리오는 "온라인 제공"으로, API 서버를 시작하고 실제 데이터 세트에서 샘플 프롬프트를 표시하며 모델이 완성을 생성하도록 합니다. 이는 LLM이 챗봇이나 코드 완성과 같은 실제 애플리케이션에 사용되는 시나리오입니다.
여기서는 ShareGPT 데이터 세트를 사용하여 프롬프트를 샘플링하고 다양한 람다를 사용하는 포아송 프로세스를 사용하여 다양한 요청 도착 속도를 시뮬레이션합니다. 결과는 아래와 같습니다(낮을수록 좋음).
A100 80G PCIE에서 SwiftLLM은 vLLM과 동등한 성능을 달성할 수 있는 반면, RTX 4090에서는 SwiftLLM이 vLLM보다 훨씬 뛰어난 성능을 보인다는 것을 알 수 있습니다(주로 제어 평면의 오버헤드가 낮기 때문입니다).