LoRA 설명: GPU 비용 부담 없이 수행하는 미세 조정 (Fine-Tuning)
요약
LoRA(Low-Rank Adaptation)의 핵심 원리와 GPU 비용 절감 효과를 설명합니다. 기존 전체 미세 조정(Full Fine-Tuning)과 달리 가중치를 동결하고 저차원 행렬을 학습함으로써 메모리 사용량을 획기적으로 줄이는 방법을 다룹니다.
핵심 포인트
- 가중치를 동결하고 저차원 수정(low-rank correction)을 학습하여 비용 절감
- 옵티마이저 상태가 차지하는 막대한 메모리 부담을 LoRA로 해결
- 업데이트 행렬이 본질적으로 저차원이라는 가설을 바탕으로 동작
- A는 가우시안 초기화, B는 0으로 초기화하여 베이스 모델의 성능 유지
LoRA의 핵심 아이디어는 가중치(weights)를 동결(freeze)하고, 대신 그에 대한 저차원 수정(low-rank correction)을 학습하는 것입니다. 이 아이디어는 하나의 문단으로 요약될 수 있습니다. 미세 조정(fine-tuning)을 할 수 있는 사람의 범위를 바꾼 이유는 산술적(arithmetic)인 측면이며, 이 산술적 내용은 한 번쯤 종이에 적어볼 가치가 있습니다.
전체 미세 조정 (Full Fine-Tuning)의 비용
Adam 옵티마이저를 사용하여 혼합 정밀도(mixed precision)로 가중치를 학습할 때, 파라미터당 비용은 단순히 숫자 하나가 아닙니다. 약 8배의 비용이 들며, bf16 순전파(forward pass)와 fp32 마스터 복사본(master copy)을 사용하는 표준 계산 방식에 따르면 학습 가능한 파라미터당 대략 16바이트가 소요됩니다:
학습 가능한 파라미터당, 혼합 정밀도 Adam
bf16 가중치 (weight) ................ 2 bytes
bf16 그래디언트 (gradient) .............. 2 bytes
...
이것이 바로 7B 모델의 전체 미세 조정(full fine-tuning)이 24GB 카드나 80GB 카드에 들어가지 못하고, 여러 장에 걸쳐 샤딩(sharding)이 필요한 이유입니다. 가중치 자체는 적은 부분이며, 옵티마이저 상태(optimiser state)가 그 중 4분의 3을 차지합니다. LoRA는 가중치가 아닌 그 수치를 공략합니다.
실제 행렬에서의 산술
7B급 모델의 어텐션 프로젝션(attention projection) 중 하나인 쿼리 프로젝션(query projection), 형태(shape) 4096 × 4096을 예로 들어보겠습니다. 전체 미세 조정은 W와 동일한 형태를 가진 업데이트 ΔW를 학습합니다:
전체 업데이트 (full update)
ΔW : 4096 x 4096 = 16,777,216 학습 가능한 파라미터
...
곱 B·A는 여전히 4096 × 4096 행렬입니다. W에 더해져야 하므로 반드시 그래야만 합니다. 하지만 이 행렬은 오직 랭크(rank) 8만을 가질 수 있습니다. LoRA가 거는 베팅은, 수정하려는 가중치는 저차원이 아닐지라도 미세 조정에 필요한 업데이트는 본질적으로 저차원(low-rank)일 것이라는 점입니다. Hu et al. (2021, LoRA: Low-Rank Adaptation of Large Language Models, arXiv 2106.09685)은 이러한 베팅을 하고 그것이 유효함을 측정한 논문입니다.
일반적인 형태를 보면: d × k 가중치를 전체적으로 업데이트하는 데는 d·k개의 파라미터가 들지만, LoRA를 사용하면 r·(d + k)개가 듭니다. 정사각형 d × d 행렬의 경우 d² 대 2·d·r이 되므로, 손익분기점 랭크(break-even rank)는 d/2입니다. 즉, d = 4096일 때 랭크는 2048입니다. 그보다 낮은 모든 랭크는 비용 절감이 되며, 실제 사용되는 랭크는 8에서 64 사이입니다.
실무에서 중요한 논문의 두 가지 세부 사항이 있습니다. A는 무작위 가우시안 (Gaussian) 분포로 초기화되고 B는 0으로 초기화되므로, 0단계에서 B·A = 0이 됩니다. 따라서 조정된 모델은 베이스 모델과 정확히 동일한 상태에서 시작합니다. 즉, 훈련이 노이즈가 아닌 베이스 모델의 동작으로부터 시작된다는 의미입니다. 또한 업데이트는 α/r에 의해 스케일링(scaling)됩니다. 이것이 바로 알파(alpha)를 높이지 않고 랭크(rank)만 높이면 용량(capacity)뿐만 아니라 유효 학습률(effective learning rate)도 변하는 이유입니다.
모델 전체로 확장하기
행렬 하나는 흥미로운 수치가 아닙니다. 32개 레이어와 4096개의 은닉층(hidden layer)을 가진 모델의 모든 레이어에 있는 쿼리(query) 및 값(value) 프로젝션(projection)에 동일한 랭크를 적용해 보겠습니다:
r = 8, targets = {q_proj, v_proj}, 32 layers, d = 4096
per matrix 2 x 8 x 4096 = 65,536
...
수백 기가바이트 대신 67메가바이트의 학습 가능한 상태(trainable state)만 필요하게 됩니다. 동결된(frozen) 베이스 가중치는 여전히 상주해야 합니다. 예를 들어 7B 모델의 경우 bf16에서 13.5GB가 필요합니다. 하지만 이 가중치들은 그래디언트(gradient), 모멘텀(momentum), fp32 마스터 복사본(master copy)이 필요하지 않으므로, 비용이 배수로 증가하는 것이 아니라 고정 비용으로 남게 됩니다. LoRA 논문에 따르면 GPT-3 175B의 경우 GPU 메모리를 약 3배 절감하고, 학습 가능한 파라미터(parameter)를 10,000배 절감했다고 보고합니다.
형태(shape)에 관한 주의사항: 그룹화된 쿼리 주의 집중(grouped-query attention)을 사용하는 모델의 경우, 키(key)와 값(value) 프로젝션은 정사각형이 아닙니다. 32개의 쿼리 헤드(query head)와 8개의 KV 헤드를 가진 모델은 k_proj와 v_proj가 1024 × 4096이므로, 동일한 랭크를 사용하더라도 그 비중이 달라집니다. 실제로 미세 조정하려는 모델의 설정(config)에 맞춰 산술 계산을 다시 수행하십시오.
랭크 선택하기
랭크는 용량(capacity)입니다. 흔히 보고되는 패턴(이는 정리(theorem)라기보다는 반복적으로 확인된 민간 지식(folklore)에 가깝습니다)은 스타일, 형식, 어조(tone) 관련 작업은 낮은 랭크에서 포화(saturate)되는 반면, 모델에게 구조적으로 새로운 무언가를 수행하도록 요구하는 작업은 더 높은 랭크에서 이점을 얻는다는 것입니다.
- r = 4–8. 형식 준수 (Format compliance), 어조 (tone), 고정된 스키마 (fixed schema), 레이블 어휘 (label vocabulary). 몇 메가바이트 수준의 어댑터 (Adapters).
- r = 16–32. 수천 개의 예시를 사용한 지시어 미세 조정 (Instruction tuning) 시 통상적인 기본값. 관행적으로
α = 2r과 함께 사용됨. - r = 64–128. 더 큰 행동 변화 (behavioural shifts), 또는 어텐션 (attention) 레이어뿐만 아니라 모든 선형 레이어 (linear layers)를 대상으로 할 때. 이 단계에 도달하면 피하려고 했던 메모리 프로필 (memory profile)에 가까워지게 됨.
어떤 모듈을 대상으로 하는지는 랭크 (rank)만큼이나 중요합니다. 원본 논문은 어텐션 투영 (attention projections)만을 대상으로 조정했습니다. 이후의 관행은 MLP 블록을 포함한 모든 선형 레이어를 대상으로 하는 경우가 빈번하며, 이는 학습 가능한 파라미터 수를 대략 3~4배로 늘리지만 종종 그만한 가치가 있습니다. 좁은 대상 세트에서 랭크를 높이는 것보다 적용 범위를 넓히는 것이 파라미터당 더 많은 도움을 주는 경향이 있습니다.
랭크를 탐색(sweeping)하며 일주일을 보내기 전에 알아둘 만한 두 가지 발표된 변형 모델이 있습니다. rsLoRA (Kalajdzievski, 2023, arXiv 2312.03732)는 기존의 α/r 스케일링이 높은 랭크의 성능을 저하시키는 원인이라고 주장합니다. 즉, 랭크가 커질수록 계수가 줄어들어 용량을 추가한 바로 그 시점에 업데이트를 억제한다는 것입니다. 대신 α/√r로 스케일링할 것을 제안하며, 이것이 대부분의 학습 라이브러리에 "랭크 안정화 (rank-stabilised)" 플래그가 존재하는 이유입니다. DoRA (Liu et al., 2024, arXiv 2402.09353)는 가중치를 크기 (magnitude)와 방향 (direction)으로 분해하고 저랭크 업데이트 (low-rank update)를 방향에만 적용하며, 동일한 랭크에서 LoRA보다 개선된 성능을 보고합니다. 두 방식 모두 위의 산술적 계산을 바꾸지는 않지만, 학습 가능한 파라미터당 얻을 수 있는 이득을 변화시킵니다.
병합 (Merging), 그리고 추론이 무료인 이유
LoRA를 단순한 학습 도구가 아닌 서빙 (serving) 도구로 만든 특성은 다음과 같습니다. 적응 (adaptation) 과정이 가산적 (additive)이기 때문에, 이를 다시 모델에 접어 넣을 (fold back in) 수 있습니다.
병합 전 서빙 (serving unmerged) y = W·x + (α/r)·B·(A·x) 두 개의 추가 행렬 곱셈 (matmuls)
병합 후 서빙 (serving merged) W' = W + (α/r)·B·A 오프라인에서 한 번 수행
y = W'·x 기본 모델과 동일
병합된 모델은 비트 단위로 동일한 아키텍처를 가진 일반 모델과 완전히 일치합니다. 추가적인 지연 시간(latency)도, 특별한 런타임(runtime)도, 어댑터 배관(adapter plumbing)도 필요하지 않습니다. 어댑터 방식의 서빙(serving)은 토큰당 약간의 오버헤드를 대가로 하나의 베이스 모델에 대해 여러 어댑터를 호스팅할 수 있는 능력을 얻는데, 이는 서로 다르며 종종 더 유리한 거래가 됩니다.
여기서 주의해야 할 함정은 다음과 같습니다: 양자화된(quantised) 베이스 모델에 병합하는 것은 손실이 발생합니다. 만약 4-bit 베이스 모델을 대상으로 학습했다면, 병합 과정에서 역양자화(dequantising), 덧셈, 그리고 재양자화(requantising)가 필요하며, 그 결과물은 당신이 평가했던 모델과 일치하지 않게 됩니다. 전체 정밀도(full-precision) 베이스 모델에 병합한 후 나중에 양자화를 수행하고, 실제로 서빙할 결과물(artefact)에 대해 평가를 다시 실행하십시오.
도움이 되지 않는 경우
- 베이스 모델을 축소시키지 않습니다. 학습을 위해서는 여전히 전체 모델이 상주하고 있어야 합니다. LoRA는 가중치(weights)가 아닌 옵티마이저 상태(optimiser state)를 제거하는 것이며, 가중치를 줄이는 것은 양자화(quantisation)의 역할입니다. 이 두 가지를 결합한 것이 QLoRA입니다.
- 작은 모델을 큰 모델로 만들어주지 않습니다. Rank-16 보정(correction)은 베이스 모델이 가지고 있지 않은 능력을 추가할 수 없습니다. 이는 기존의 능력을 재지향(redirects)하는 것입니다.
- 큰 분포 변화(distribution shifts)에는 취약한 도구입니다. 새로운 언어나 진정으로 새로운 도메인에 적응하는 것은 사전 학습(pretraining) 규모의 문제이며, 지시어 데이터(instruction data)에 대한 저차원(low-rank) 보정은 적절한 도구가 아닙니다.
- 어댑터는 베이스 모델에 고정되어 있습니다. 특정 체크포인트를 대상으로 학습된 어댑터는 동일한 계열의 포인트 릴리스(point release)를 포함하여 다른 체크포인트에서는 의미가 없습니다. 이것이 학습 비용보다 더 오래 지속되는 유지 관리 비용입니다.
관련 항목
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기