
LoRA và QLoRA là hai kỹ thuật giúp bạn tinh chỉnh mô hình ngôn ngữ lớn (LLM) mà không cần toàn bộ bộ nhớ VRAM mà một con GPU thương mại có. Bài viết này giải thích cơ chế low-rank adaptation, cách lượng tử hoá 4-bit mở đường cho fine-tuning trên phần cứng phổ thông, kèm các tham số thực tế và ví dụ cấu hình.
Nếu bạn từng thử fine-tune một model 7B từ chối vì hết VRAM, thì lý do không phải bạn thiếu GPU đắt tiền. Vấn đề là kỹ thuật mặc định đang cập nhật toàn bộ tham số của mô hình, trong khi phần lớn tham số đó không cần thay đổi. LoRA thay đổi đúng điều đó.
LoRA là gì
LoRA (Low-Rank Adaptation) là kỹ thuật được giới thiệu trong bài báo của Hu và cộng sự, với ý tưởng cốt lõi: thay vì sửa trực tiếp ma trận trọng số W của một lớp, ta giữ nguyên W và thêm vào một tích phân thứ hạng thấp:
W' = W + (alpha / r) * B * A
Trong đó A và B là hai ma trận nhỏ có kích thước r x d và r x k, với r là thứ hạng (rank) nhỏ hơn rất nhiều so với cả d và k. Chỉ A và B được huấn luyện, còn W được đóng băng hoàn toàn.
Ý nghĩa thực tế rất lớn. Nếu W có kích thước 4096 x 4096 (khoảng 16,7 triệu tham số), còn bạn chọn r = 8, thì A và B chỉ có 4096 x 8 + 8 x 4096 = 65.536 tham số, tức khoảng 0,4% của ma trận gốc. Tỷ lệ tham số huấn luyện được toàn bộ mô hình thường rơi vào khoảng 0,1% đến 1%.

Lý do tại sao cách tiếp cận này hoạt động là do thay đổi cần thiết giữa một model pretrained và một model đã được tinh chỉnh thường có kích thước nhỏ hơn nhiều lần so với bản thân ma trận trọng số. Vì vậy nó có thể được xấp xỉ tốt bằng một tích phân thứ hạng thấp. Bài báo gốc báo cáo giảm tới 10.000 lần số tham số huấn luyện và giảm 3 lần mức dùng bộ nhớ GPU khi so sánh với fine-tuning toàn bộ trên GPT-3 175B.
So sánh PEFT và fine-tuning toàn bộ
PEFT (Parameter-Efficient Fine-Tuning) là tên gọi chung cho nhóm kỹ thuật như LoRA, với mục tiêu chỉ huấn luyện một tập con nhỏ tham số. Bảng dưới đây tổng hợp sự khác biệt dựa trên tài liệu chính thức của Hugging Face PEFT:
| Tiêu chí | Fine-tuning toàn bộ | LoRA | QLoRA |
|---|---|---|---|
| Tham số huấn luyện | 100% | 0,1% – 1% | 0,1% – 1% |
| Định dạng trọng số gốc | bfloat16 / float16 | bfloat16 / float16 | 4-bit (NF4) |
| VRAM cho LLaMA-7B | trên 20GB | khoảng 10GB | dưới 10GB |
| VRAM cho LLaMA-13B | trên 78GB | trung gian | khoảng 24GB |
| Chất lượng sau tinh chỉnh | Tham chiếu | Sát tham chiếu | Sát tham chiếu |
| Thời gian huấn luyện | Tham chiếu | Nhanh hơn | Nhanh hơn nữa |
Điểm mấu chốt: LoRA hầu như không làm giảm chất lượng so với fine-tuning toàn bộ, nhưng lại giảm mạnh chi phí. Đó là lý do nó trở thành lựa chọn mặc định cho phần lớn dự án tinh chỉnh LLM thực tế.

QLoRA: đưa fine-tuning xuống phần cứng phổ thông
QLoRA là bước nâng cấp từ bài báo QLoRA, kết hợp ba kỹ thuật:
- Lượng tử hoá 4-bit theo NF4 (4-bit NormalFloat): định dạng số học được tối ưu cho phân phối gần chuẩn, thu hẹp trọng số từ 16-bit xuống 4-bit, giảm 4 lần bộ nhớ cho phần trọng số.
- Double quantization: lượng tử hoá cả hằng số định dạng của bộ lượng tử, tiết kiệm thêm một lượng nhỏ bộ nhớ.
- Paged optimizers: dùng bộ nhớ hợp nhất của NVIDIA để tránh phân mảnh khi trạng thái optimizer vượt quá bộ nhớ vật lý.
Kết quả là fine-tune được mô hình 65B trên một GPU 48GB duy nhất. Khi tính toán, trọng số 4-bit được giải nén tạm thời sang bfloat16, vì vậy bạn cần đặt đúng dtype tính toán.
Cấu hình tham số thực tế
Ba tham số quyết định phần lớn kết quả cuối cùng:
rank (r) và lora_alpha
r là thứ hạng của tích phân thích ứng. Giá trị phổ biến cho phần lớn tác vụ là 8, 16, 32 hoặc 64. Rank thấp tiết kiệm VRAM nhưng giảm biểu diễn; rank cao thì ngược lại. lora_alpha là hệ số scale, thường đặt bằng r x 2 (ví dụ r=16 thì alpha=32). Khi dùng rank-stabilized scaling (use_rslora=True), công thức scale đổi thành alpha / sqrt(r) thay vì alpha / r, giúp ổn định hơn khi rank thay đổi.
target_modules
Đây là quyết định ảnh hưởng lớn nhất tới dung lượng. Với model họ LLaMA, bộ target_modules đầy đủ là:
["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"]
Nếu chỉ chọn ["q_proj", "v_proj"] thì nhẹ hơn nhưng thường cho kết quả kém hơn. Với QLoRA, target_modules="all-linear" là lựa chọn thường dùng.
Code mẫu QLoRA với thư viện peft
Dưới đây là cấu hình tối thiểu theo hướng dẫn chính thức trong hướng dẫn quantization của PEFT:
from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import LoraConfig, prepare_model_for_kbit_training, get_peft_model
import torch
model_id = "meta-llama/Llama-3.1-8B"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(
model_id,
device_map="auto",
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_use_double_quant=True,
bnb_4bit_compute_dtype=torch.bfloat16,
)
# Chuan hoa layer de dung cho k-bit training
model = prepare_model_for_kbit_training(model, use_gradient_checkpointing=True)
lora_config = LoraConfig(
r=16,
lora_alpha=32,
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM",
target_modules=["q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj"],
)
model = get_peft_model(model, lora_config)
model.print_trainable_parameters()
Dòng model.print_trainable_parameters() sẽ in ra tỷ lệ tham số huấn luyện. Nếu con số nằm trong khoảng 0,1% – 1% thì cấu hình đang đúng. Nếu lớn hơn nhiều, hãy kiểm tra lại target_modules có đang vô tình bao gồm cả các lớp không thuộc Transformer không.
Chọn định dạng lượng tử theo phần cứng
bnb_4bit_compute_dtype nên đặt là torch.bfloat16 trên GPU hỗ trợ BF16 như A100, A6000, hoặc thế hệ Ampper trở lới. Với GPU cũ hơn chỉ hỗ trợ FP16, hãy dùng torch.float16 và bật use_cache=False khi dùng gradient checkpointing.

Khi nào LoRA không phải lựa chọn tốt
Có những trường hợp bạn vẫn nên dùng full fine-tuning:
- Thay đổi kiến thức nền tảng, không chỉ là văn phong hoặc định dạng đầu ra.
- Bạn cần thay đổi kiến trúc kiến thức ở mức sâu, không phải chỉ là hành vi bề mặt.
- Bạn có đủ VRAM và không bị giới hạn về chi phí, cần hiệu năng tối đa.
Ngược lại, nếu mục tiêu là dạy model một kỹ năng hẹp, một định dạng đầu ra cụ thể, hay điều chỉnh giọng văn theo hướng dẫn sử dụng, LoRA gần như luôn là lựa chọn đúng.
Các thư viện nên dùng
Ngoài peft là lớp nền tảng, hệ sinh thái còn có:
trl(Transformer Reinforcement Learning): cung cấp các trainer cho SFT, DPO, và các phương pháp căn chỉnh theo sở thích. DPOTrainer dùng loss log-sigmoid trên tỷ lệ log giữa mô hình chính sách và mô hình tham chiếu.unsloth: tối ưu tốc độ và giảm mức dùng VRAM, hỗ trợ cả LoRA lẫn QLoRA.axolotl: cấu hình tinh chỉnh bằng file YAML, tiện cho thử nghiệm nhiều biến thể.LLaMA Factory: giao diện đồ hoạ và CLI cho hàng loạt model open source.
Kinh nghiệm thực hành
Bật gradient checkpointing để đổi một phần tốc độ lấy rất nhiều VRAM, đây là đòn bẩy hiệu quả nhất khi bạn sát giới hạn bộ nhớ. Bắt đầu với một tập dữ liệu nhỏ khoảng 500 – 1000 mẫu chất lượng cao, dùng learning rate 1e-4 đến 2e-4 với 2 đến 3 epoch. Nếu kết quả không tốt, hãy tăng rank hoặc bổ sung target module thay vì tăng số epoch, vì overfit trên tập nhỏ thường xấu hơn là thiếu năng lực mô hình.
Sau khi huấn luyện, adapter thường có dung lượng vài chục đến vài trăm MB, rất dễ chia sẻ và ghi vào Hugging Face Hub. Bạn có thể nạp lại adapter đó lên bất kỳ bản base model tương thích nào mà không cần lưu toàn bộ model.
Kết luận
LoRA đã biến fine-tuning LLM từ một dự án chỉ dành cho phòng lab thành thứ bất kỳ ai có một GPU 24GB đều làm được. Nếu bạn vừa bắt đầu, hãy thử LoRA với r=16, alpha=32, target modules đầy đủ trên một model 7B trước. Khi cần nhiều VRAM hơn, QLoRA với NF4 là bước nâng cấp tiếp theo tự nhiên nhất.
Nguồn tham khảo: Hugging Face PEFT Documentation | PEFT LoRA Conceptual Guide | LoRA: Low-Rank Adaptation of Large Language Models | QLoRA: Efficient Finetuning of Quantized LLMs
