LoRA và QLoRA: Tinh chỉnh mô hình ngôn ngữ lớn tiết kiệm bộ nhớ

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%.

Sơ đồ mạng nơ-ron nhiều tầng với các nút kết nối chéo giữa ba lớp

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ế.

Mạng nơ-ron kết nối đầy đủ và biểu diễn nó bằng tích phân Kronecker

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.

Cụm máy tính nhiều node đặt trong tủ rack phục vụ huấn luyện mô hình

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

Tôi là một lập trình viên IOS. Code chính là IOS nhưng thỉnnh thoảng vẫn đá sang Android hoặc web. Mặc dù không quá thông thạo nhưng tôi sẽ chia sẻ những kiến thức mà mình đã tìm hiểu, áp dụng qua.

Bài viết liên quan

Vector database là gì: Cơ sở dữ liệu tìm kiếm ngữ nghĩa cho AI

Vector database là gì? Vector database là hệ quản trị dữ liệu được thiết kế riêng để lưu trữ, tìm kiếm và so sánh các vector đặc trưng (embedding) có…

Xem thêm
Mặt sau hàng server rack tại trung tâm dữ liệu với hệ thống cáp và thiết bị mạng

Speculative Decoding là gì: Tăng tốc suy luận LLM gấp nhiều lần

Speculative Decoding là gì: Tăng tốc suy luận LLM Speculative Decoding là kỹ thuật tối ưu nhằm tăng tốc quá trình suy luận (inference) của mô hình ngôn ngữ lớn…

Xem thêm
Sơ đồ kiến trúc Mixture of Experts với router điều phối token tới các chuyên gia

Mixture of Experts là gì: Kiến trúc MoE cho mô hình ngôn ngữ lớn

Mixture of Experts (MoE) là kiến trúc mô hình ngôn ngữ lớn cho phép tách một mạng nơ-ron thành nhiều “chuyên gia” nhỏ và chỉ kích hoạt một phần trong…

Xem thêm
0 0 đánh giá
Article Rating
Theo dõi
Thông báo của
guest
0 Comments
Cũ nhất
Mới nhất Được bỏ phiếu nhiều nhất