S-LoRA: base 모델 하나로 LoRA adapter 수천 개를 동시에 서비스하기
papers/slora-mlsys24.pdf (16쪽) · 인용 표기 §5.1 p.5 = 논문 절·쪽 · 논문에 없음 = 이해를 돕기 위해 덧붙인 설명0한눈에 보기
LoRA 를 base 모델에 merge 해서 서비스하면 adapter 마다 모델 사본이 필요하고, 서로 다른 adapter 요청을 한 batch 로 묶을 수 없다.
S-LoRA 는 base 계산(xW)은 모두 묶고 adapter 계산(xAB)만 따로 하며, adapter 와 KV cache 를 한 paged pool 에 넣어 A100 한 장에서 adapter 2,000 개를 서비스한다.
1배경 용어 먼저
이 논문을 읽으려면 6 가지만 알면 된다: LoRA, KV cache, PagedAttention, continuous batching, fragmentation, tensor parallelism.
각 용어는 그림으로 먼저 보고, 논문이 그것을 어디에 쓰는지 한 줄로 잇는다.
LoRA (Low-Rank Adaptation)
원래 weightW(h×d) 는 얼리고, 작은 행렬 A(h×r) · B(r×d) 만 학습한다. W' = W + AB, 그래서 xW' = xW + xAB Eq.1–2 §2 p.2. r 은 8~64 로 h(4096~8192)보다 훨씬 작다. 보통 attention 의 q·k·v·o projection 에만 붙인다.
논문에서의 역할: adapter 가 여러 개면 merge 는 adapter 수만큼 모델 사본이 필요하므로, S-LoRA 는 on-the-fly 로 계산한다.
KV cache 와 PagedAttention
LLM 은 token 을 하나씩 만든다(decode). 매번 앞 token 전부를 다시 보므로 앞 token 의 Key·Value 를 GPU 에 저장해 둔다 = KV cache §2.1 p.2–3. 길이가 요청마다 달라 크기가 계속 변한다. vLLM 의 PagedAttention 은 OS 의 paging 처럼 KV 를 고정 크기 page 로 쪼개 흩어진 자리에 저장한다. 논문에서의 역할: S-LoRA 는 이 page 개념을 adapter weight 에도 적용한다 (Unified Paging).batching · continuous batching
여러 요청을 한 번의 GPU 연산으로 묶는 것. decode 는 memory-bound 라 batch 가 커질수록 공짜로 throughput 이 오른다. Orca 의 iteration-level (continuous) batching 은 token 한 step 마다 끝난 요청을 빼고 새 요청을 넣는다 §2.1 p.3.memory fragmentation (단편화)
크기가 제각각인 덩어리를 할당·해제하다 보면 빈 공간이 잘게 흩어져, 총량은 충분해도 큰 덩어리를 못 넣는 상태 논문에 없음. adapter 는 rank 마다, KV 는 길이마다 크기가 달라 둘을 섞으면 심해진다 §5 p.4.GEMM · GEMV · custom kernel
GEMM = 행렬×행렬 (prefill 처럼 token 여럿), GEMV = 행렬×벡터 (decode 처럼 token 하나). BLAS 의 batch GEMM 은 모든 문제가 같은 크기여야 해서 rank·길이가 다르면 padding(0 채우기)이 필요하다 §4.1 p.4.tensor parallelism · all-reduce · all-gather
행렬 하나를 여러 GPU 에 열(column)·행(row) 방향으로 나눠 계산 §6 p.5. all-gather = 각 GPU 조각을 모아 모두가 전체를 갖기, all-reduce = 각 GPU 부분합을 더해 모두가 합을 갖기 논문에 없음. Megatron-LM 방식이 표준.SLO · first token latency
SLO (Service Level Objective) = 지켜야 할 지연 목표. 이 논문은 "첫 token 이 6 초 안에 나온 요청 비율" 을 SLO attainment 로 쓴다 §7.1 p.7.admission control
부하가 용량을 넘으면 어떤 요청을 받고 어떤 요청을 버릴지 정하는 것. 다 받으면 결국 모든 요청이 SLO 를 놓친다 §4.3 p.4.2문제: 왜 기존 방식으로는 수천 개를 못 싣나
원래 LoRA 논문 방식(merge 후 adapter 를 더했다 뺐다 교체)은 한 번에 adapter 하나만 돌아 서로 다른 adapter 요청을 batch 로 묶을 수 없다.
그렇다고 adapter 마다 merge 된 모델 사본을 두면 GPU 메모리가 곧 바닥난다 (vLLM-packed 는 adapter 100 개에서 OOM).
"merging the weights into the base model leads to multiple weight copies and missed batching opportunities."§4.1 p.3
on-the-fly 로 가면 새로 생기는 세 가지 어려움
| 어려움 | 왜 생기나 | S-LoRA 의 답 |
|---|---|---|
| 2.2.1메모리 관리 | adapter 를 GPU 밖에 두고 필요할 때 올리면, 크기가 다른 adapter 와 KV 가 섞여 fragmentation · I/O 지연 | Unified Paging + prefetch (§5.1–5.2) |
| 2.2.2batch 연산 | rank 가 다른 adapter 들이 비연속 메모리에 있어 BLAS batch GEMM 으로는 padding 이 필요 | MBGMM · MBGMV kernel (§5.3) |
| 2.2.3multi-GPU | LoRA 가 새 행렬·곱셈을 더해 기존 tensor parallelism 분할에 맞지 않음 | S-LoRA TP (§6) |
§1 p.2
3기법: 네 부품
① base 계산은 GEMM 으로 묶고 LoRA 계산은 custom kernel 로 따로 ② 모든 adapter 는 main memory, 현재 batch 의 adapter 만 GPU 로.
③ adapter 와 KV 를 H 크기 page 로 한 pool 에 ④ multi-GPU 에서는 LoRA 통신을 base 통신에 합쳐 추가 비용을 거의 0 으로.
3.1① 계산 분리: xW 는 묶고 xAB 는 따로
W 는 하나라 한 번의 GEMM 으로 묶인다. adapter 별 xAB 만 따로 계산해 더한다. xAB 는 xW 보다 훨씬 싸서, 묶어서 얻는 이득이 추가 비용보다 크다 §4.1 p.4.3.2② 메모리 배치: adapter 는 main memory, 필요한 것만 GPU
prefetch: 현재 decode batch 를 돌리는 동안 대기열(waiting queue)을 보고 다음 batch 에 필요한 adapter 를 미리 GPU 로 올려 I/O 를 계산 뒤에 숨긴다 §5.2 p.5.
3.3③ Unified Paging: adapter 와 KV 를 같은 page 에
왜 이렇게 하나
| KV cache | LoRA weight | |
|---|---|---|
| 3.3.3.1shape | (S, H) | (R, H) |
| 3.3.3.2크기가 변하는 이유 | 요청마다 S 가 다르고 decode 로 자람 | adapter 마다 R 이 다르고 batch 마다 load·offload |
| 3.3.3.3page 수 | S 개 | R 개 |
참고: 같은 prompt 라도 adapter 가 다르면 Wk·Wv 에 LoRA 가 붙어 KV 값 자체는 달라질 수 있다. 이것은 저장 방식이 아니라 값의 차이다 논문에 없음.
3.4custom kernel: MBGMM · MBGMV
| kernel | 단계 | 하는 일 | 구현 |
|---|---|---|---|
3.4.1.1MBGMM | prefill | Multi-size Batched Gather Matrix-Matrix: token 여럿 × pool 에서 모은(gather) 서로 다른 rank 의 adapter | Triton, tiling |
3.4.1.2MBGMV | decode | Multi-size Batched Gather Matrix-Vector: token 하나 × 서로 다른 rank adapter | Punica kernel 을 고쳐 비연속 메모리·여러 rank 지원 (Triton 판보다 빨라 실험에 사용) |
§5.3 p.5 padding 없이 page 주소를 따라가며 읽으므로 BLAS batch GEMM 의 낭비가 없다.
3.5④ S-LoRA TP: LoRA 통신을 base 통신에 얹기
LoRA 추가 통신 = 3(N−1)·B·r / N + 2(N−1)·B·r / N = 5(N−1)·B·r / N§6.2 p.6
비율 = LoRA / base = 5r / (2h)논문에 없음
| 항목 | 뜻 |
|---|---|
3.5.3.13(N−1)Br/N | q·k·v projection 세 개의 all-gather (크기 B×r) |
3.5.3.22(N−1)Br/N | output projection 의 all-reduce (크기 B×r) |
3.5.3.3r ≪ h | 그래서 LoRA 통신은 무시할 만하다. 메모리 면에서도 모든 weight 를 나눠 복제가 없어 최적 §6.2 p.6 |
scheduling: adapter clustering · early abort admission control
- 3.5.5
- 3.5.5.1adapter clustering: 같은 adapter 요청을 우선 묶어 batch 안 adapter 수(d)를 줄이면 KV 에 메모리를 더 줄 수 있다. 대신 평균 latency·adapter 간 공정성이 나빠질 수 있다 §4.2 p.4, App.A.2 p.15.
- 3.5.5.2early abort: 사용자 만족도 reward
r(t)(first token latency t 가 SLO 를 넘으면 0) 의 합을 최대화.r'(t) ≤ 0이면 "가장 최근 l 개를 도착 순서대로" 가 최적 (Theorem B.1) App.B p.15–16. - 3.5.5.3실제 heuristic:
현재시각 − 도착시각 + 최대 prefill 시간 > SLO인 요청은 먼저 버린다. 도착률 R1 > 처리율 R2 (과부하) 면 최신 요청부터, 아니면 오래된 요청부터 넣는다 App.B p.16.
4구현
LightLLM (PyTorch + Triton 기반 단일 모델 serving 시스템) 위에 만들었다 §7 p.6–7.
scheduling 은 Orca 식 iteration-level batching, 기본은 FCFS. decode kernel 은 Punica 를 고친 MBGMV.
실험 구성 (Table 1 · 하드웨어 · baseline)
| baseline | 무엇 |
|---|---|
| 4.2.1HuggingFace PEFT | 한 adapter 요청만 묶고 batch 사이에 adapter 교체. KV cache·continuous batching 없음 |
| 4.2.2vLLM-packed | 당시 vLLM 은 LoRA 미지원 → merge 된 모델마다 vLLM worker 하나, NVIDIA MPS 로 한 GPU 공유 |
| 4.2.3S-LoRA-no-unify-mem | Unified Paging 제거 |
| 4.2.4S-LoRA-bmm | Unified Paging + custom kernel 제거. adapter 를 연속 메모리에 복사하고 padding 한 batch matmul |
GPU: A10G 24GB, A100 40/80GB (1·2·4 장). host memory 64~670 GB §7.1 p.7.
5평가
합성 workload (Gamma 도착, adapter 인기도 power-law α) 와 LMSYS Chatbot Arena trace 로 throughput · latency · SLO attainment 를 잰다.
좋아진 이유는 세 가지: 서로 다른 adapter 도 한 batch (vs PEFT·vLLM-packed), 흩어진 page 로 메모리 효율 (vs no-unify-mem), padding 없는 kernel (vs bmm).
vLLM-packed 는 모델 사본을 n 벌 둬야 해 n=5 에서 이미 느리고 (8.05 vs 2.04 → 약 4×) n=100 이면 OOM 이며, 사본끼리 batch 를 못 묶는다. PEFT 는 KV cache 가 없어 최대 batch 가 6 (S-LoRA 30) 이고 continuous batching 이 없어 짧은 요청이 긴 요청을 기다린다 → 최대 30× §7.2 p.8, App.A.1 p.15.
adapter 가 아무리 많아도 한 batch 에서 동시에 쓰이는 adapter 수는 batch 크기로 묶여 있어 LoRA overhead 가 일정해진다. no-unify-mem 과의 차이 = Unified Paging 효과, bmm 과의 차이 = custom kernel 효과 §7.2 p.8.
Table 2 · Fig.6 · Fig.7 — 요청률을 올리면, 실제 trace 에서는
Fig.8 — multi-GPU tensor parallelism
Fig.9 · Fig.10 — ablation: merge vs on-the-fly, early abort
부록 — PEFT 분석 (Table 4·5) · adapter clustering (Fig.11·12)
6결론과 한계
논문의 결론: unified memory pool, tensor parallelism, adapter batching, CUDA kernel 로 한 머신에서 LoRA adapter 수천 개를 높은 throughput 으로 서비스한다 §9 p.11.
향후 과제로 다른 adapter 방식 지원, 더 fused 된 kernel, base·LoRA 계산을 여러 CUDA stream 으로 병렬화를 든다. limitation 절은 없어 아래는 읽으며 정리했다 논문에 없음.
| 한계 | 근거 |
|---|---|
| 6.1.1KV cache 는 요청이 끝나면 해제된다. 같은 prefix·다회 대화의 history KV 재사용이 없다 | "KV caches are allocated when requests arrive and deallocated once the requests are completed" (§5.1 p.5) |
| 6.1.2adapter 수가 적으면 on-the-fly 계산 overhead 때문에 merge 보다 느리다 | Fig.9 (adapter 1 개), Fig.5 초반 하락 |
| 6.1.3prefetch 는 대기열만 보고 예측한다. 대기열에 없던 cold adapter 가 오면 로딩을 기다린다. 로딩 지연을 따로 측정한 결과는 없다 | §5.2 p.5 |
| 6.1.4vLLM baseline 은 당시 LoRA 미지원이라 merge 사본 + MPS 로 만든 것. 이후 vLLM·Punica 의 native multi-LoRA 와의 비교는 없다 | §7.1 p.7, Punica 는 concurrent work (§8 p.10) |
| 6.1.5실제 LoRA 서비스 trace 가 아니다. 합성 Gamma 과정과 Arena 의 "base 모델 분포" 를 adapter 분포로 간주한 trace | §7.2–7.3 p.7–9 |
| 6.1.6Llama-70B 는 공식과 다른 구조, GQA 미사용. 실제 70B 에서 KV·통신 비율이 달라진다 | Table 1 각주 1 (p.7) |
| 6.1.7early abort 는 SLO 를 놓칠 요청을 버린다. 버린 요청 비율은 따로 보고하지 않는다 | App.B p.16 |
7관련 연구
가장 가까운 것은 Punica (base·adapter 계산 분리, concurrent work) 와 PetS (BERT 급 encoder 전용). S-LoRA 의 차별점은 Unified Paging 과 LoRA tensor parallelism §8 p.10.
quantization·sparsification 같은 알고리즘 기법과는 직교해 함께 쓸 수 있다.
관련 연구 한 줄씩
| 연구 | 한 일 | S-LoRA 와 차이 |
|---|---|---|
| 7.1.1Punica | multi-LoRA 에서 base·adapter 계산 분리, SGMV kernel | S-LoRA decode kernel 의 바탕. 메모리 관리·TP 는 없음 |
| 7.1.2PetS | parameter-efficient transformer 통합 serving | 작은 encoder-only BERT 만. 생성·대량 adapter·multi-GPU 없음 |
| 7.1.3Orca · vLLM | iteration-level batching · PagedAttention | S-LoRA 가 가져다 쓰고 paging 을 adapter 로 확장 |
| 7.1.4Clipper · AlpaServe 등 | 일반 모델 serving (batching, placement, 다중화) | autoregressive 특성과 adapter 를 고려하지 않음 |
| 7.1.5Prefix-tuning · (IA)³ 등 PEFT | LoRA 외 적은 parameter fine-tuning | 대부분 기법을 쉽게 적용 가능하다고 주장 |