QLoRA
QLoRA tinh chỉnh LLM bằng cách huấn luyện adapter LoRA trên model nền đã đóng băng, được lưu ở định dạng NF4 4-bit, nhờ đó có thể chạy model 65 tỷ tham số trên một GPU 48 GB.
QLoRA (Điều chỉnh thích ứng hạng thấp lượng tử hóa) là phương pháp fine-tune đóng băng một model ngôn ngữ lớn (LLM) tiền huấn luyện ở độ chính xác 4 bit và huấn luyện các adapter LoRA nhỏ trên model đó, lan truyền ngược qua các trọng số đã lượng tử hóa vào adapter. Được Dettmers và cộng sự giới thiệu trong bài báo QLoRA năm 2023, phương pháp này giảm bộ nhớ GPU cần để fine-tune model 65 tỷ tham số từ hơn 780 GB xuống dưới 48 GB—đủ cho một GPU workstation—đồng thời đạt hiệu năng tác vụ tương đương fine-tune 16 bit. Các model Guanaco trong bài báo, được fine-tune theo cách này, đạt 99.3% điểm số ChatGPT trên benchmark Vicuna sau 24 giờ huấn luyện bằng một GPU duy nhất.
Cách QLoRA hoạt động#
QLoRA kết hợp một model nền được đóng băng và nén với ba kỹ thuật tiết kiệm bộ nhớ:
- NormalFloat 4 bit (NF4): Mỗi trọng số được lưu dưới dạng mã 4 bit trỏ đến một trong 16 mức đặt tại các phân vị của phân phối chuẩn; mỗi khối 64 trọng số sử dụng một hệ số tỷ lệ theo giá trị tuyệt đối lớn nhất. Trọng số model tiền huấn luyện có phân phối gần chuẩn, vì vậy các mức phân vị cung cấp độ phân giải cao hơn quanh 0, nơi tập trung phần lớn trọng số.
- Lượng tử hóa kép: Các hệ số tỷ lệ theo khối cũng được lượng tử hóa xuống 8 bit theo từng khối 256 giá trị, giúp giảm phần chi phí bổ sung từ 0.5 xuống khoảng 0.127 bit trên mỗi tham số, tiết kiệm khoảng 3 GB cho model 65B.
- Optimizer phân trang: Trạng thái optimizer nằm trong bộ nhớ hợp nhất của NVIDIA và được chuyển sang RAM CPU khi bộ nhớ tăng đột biến, chẳng hạn với chuỗi dài trong quá trình checkpoint gradient, nhờ đó quá trình huấn luyện không gặp lỗi hết bộ nhớ.
Trong lượt truyền tiến, ngay trước phép nhân ma trận, mỗi lớp đã đóng băng giải lượng tử trọng số NF4 sang bfloat16 rồi cộng đầu ra của nhánh LoRA. Lan truyền ngược tính gradient qua các trọng số đã giải lượng tử nhưng chỉ cập nhật hai ma trận LoRA hạng thấp. Bài báo phát hiện cần gắn adapter vào mọi lớp tuyến tính trong khối transformer để đạt hiệu năng tương đương fine-tune toàn phần:
Đoạn code dưới đây xây dựng các mức NF4 theo cách thư viện bitsandbytes thực hiện và so sánh chúng với 16 mức cách đều nhau trên các khối trọng số có phân phối chuẩn:
import torch
torch.manual_seed(0)
normal = torch.distributions.Normal(0.0, 1.0)
# NF4: 16 levels at quantiles of a normal distribution, with an exact zero (as built in bitsandbytes)
positive = normal.icdf(torch.linspace(0.9677083, 0.5, 9)[:-1])
negative = -normal.icdf(torch.linspace(0.9677083, 0.5, 8)[:-1])
nf4 = torch.cat([negative, torch.zeros(1), positive]).sort().values
nf4 = nf4 / nf4.max()
int4 = torch.linspace(-1, 1, 16) # evenly spaced 4-bit levels for comparison
weights = torch.randn(4096, 64) * 0.02 # pretrained weights are roughly normal, in blocks of 64
absmax = weights.abs().amax(dim=1, keepdim=True) # one scale per block
for name, levels in (("NF4", nf4), ("INT4", int4)):
codes = ((weights / absmax)[..., None] - levels).abs().argmin(dim=-1) # 4-bit index per weight
restored = levels[codes] * absmax
print(f"{name} mean squared error: {(restored - weights).pow(2).mean():.3e}")Đoạn code in ra sai số bình phương trung bình 3.395e-06 với NF4 và 4.053e-06 với các mức cách đều: với cùng 16 mức và cùng hệ số tỷ lệ theo khối, khoảng cách theo phân vị của NF4 giảm khoảng 16% sai số tái tạo trên trọng số có phân phối chuẩn. Trong thực tế, Hugging Face Transformers tải model ở định dạng NF4 thông qua bitsandbytes, với BitsAndBytesConfig thiết lập load_in_4bit=True, bnb_4bit_quant_type="nf4", bnb_4bit_use_double_quant=True và bnb_4bit_compute_dtype=torch.bfloat16; thư viện PEFT gắn các adapter LoRA vào model.
QLoRA và các phương pháp liên quan#
- LoRA: Huấn luyện cùng loại adapter trên model nền được giữ ở độ chính xác 16 bit. Chỉ riêng trọng số 16 bit của model 65B đã chiếm khoảng 130 GB, còn NF4 lưu chúng trong khoảng một phần tư dung lượng đó.
- Fine-tune hiệu quả tham số (PEFT): Nhóm phương pháp huấn luyện một tập tham số nhỏ, bao gồm LoRA, QLoRA, adapter và tinh chỉnh prompt.
- Lượng tử hóa model sau huấn luyện: Nén model đã hoàn thiện để suy luận. Model được tinh chỉnh bằng QLoRA thường được hợp nhất vào trọng số 16 bit rồi lượng tử hóa lại để phục vụ suy luận.
- Huấn luyện có nhận biết lượng tử hóa (QAT): Mô phỏng phép làm tròn độ chính xác thấp trong lượt truyền tiến trong khi tất cả trọng số vẫn được huấn luyện, nhờ đó model triển khai duy trì độ chính xác ở độ chính xác thấp. Ultralytics YOLO26 chạy QAT INT8 khi được huấn luyện với
quantize=8, chèn lượng tử hóa giả vào các lớp tích chập và tuyến tính thông qua NVIDIA ModelOpt để các trọng số đã học vẫn hoạt động sau khi xuất INT8.
Đánh đổi#
QLoRA đánh đổi tốc độ lấy bộ nhớ: giải lượng tử từng trọng số đã đóng băng trong mỗi lượt truyền tiến và truyền ngược khiến một bước huấn luyện chậm hơn LoRA 16 bit. Các adapter đủ nhỏ để lưu trữ và thay đổi theo từng tác vụ, nhưng muốn hợp nhất chúng vào model nền thì trước tiên phải giải lượng tử model xuống 16 bit. Với model 65B, trọng số 4 bit và hệ số tỷ lệ lượng tử hóa kép chiếm khoảng 34 GB, để lại phần dung lượng còn lại của GPU 48 GB cho adapter, activation và trạng thái optimizer phân trang.










