TRL documentation

Tích hợp PEFT

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v1.18.0).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Tích hợp PEFT

TRL hỗ trợ các phương pháp PEFT (Parameter-Efficient Fine-Tuning) để huấn luyện mô hình tiết kiệm bộ nhớ. PEFT cho phép tinh chỉnh các mô hình ngôn ngữ lớn bằng cách chỉ huấn luyện một số lượng nhỏ các tham số bổ sung trong khi giữ nguyên mô hình cơ sở, từ đó giảm đáng kể chi phí tính toán và yêu cầu về bộ nhớ.

Hướng dẫn này bao gồm cách sử dụng PEFT với các trình huấn luyện TRL khác nhau, bao gồm các kỹ thuật LoRA, QLoRA và prompt tuning.

Để xem một ví dụ hoạt động hoàn chỉnh, hãy xem notebook SFT với LoRA/QLoRA.

Cài đặt

Để sử dụng PEFT với TRL, hãy cài đặt các phụ thuộc cần thiết:

pip install trl[peft]

Để hỗ trợ QLoRA (lượng tử hóa 4-bit và 8-bit), hãy cài đặt thêm:

pip install bitsandbytes

Bắt đầu nhanh

Tất cả các trainer của TRL đều hỗ trợ PEFT thông qua đối số peft_config. Cách đơn giản nhất để bật PEFT là sử dụng giao diện dòng lệnh với cờ --use_peft:

python trl/scripts/sft.py \
    --model_name_or_path Qwen/Qwen2-0.5B \
    --dataset_name trl-lib/Capybara \
    --use_peft \
    --lora_r 32 \
    --lora_alpha 16 \
    --output_dir Qwen2-0.5B-SFT-LoRA

Ngoài ra, bạn có thể truyền trực tiếp một cấu hình PEFT trong mã Python của mình:

from peft import LoraConfig
from trl import SFTTrainer

# Configure LoRA
peft_config = LoraConfig(
    r=32,
    lora_alpha=16,
    lora_dropout=0.05,
    bias="none",
    task_type="CAUSAL_LM",
)

# Configure training - note the higher learning rate for LoRA (10x base rate)
training_args = SFTConfig(
    learning_rate=2.0e-4,  # 10x the base rate (2.0e-5) for LoRA
    ...
)

# Create trainer with PEFT
trainer = SFTTrainer(
    model=model,
    train_dataset=dataset,
    peft_config=peft_config,
)

Ba cách cấu hình PEFT

TRL cung cấp ba phương pháp khác nhau để cấu hình PEFT, mỗi phương pháp phù hợp với các trường hợp sử dụng khác nhau:

1. Sử dụng cờ CLI (Đơn giản nhất)

Cách dễ nhất để bật PEFT là sử dụng cờ --use_peft với giao diện dòng lệnh. Phương pháp này lý tưởng cho các thí nghiệm nhanh và cấu hình tiêu chuẩn:

python trl/scripts/sft.py \
    --model_name_or_path Qwen/Qwen2-0.5B \
    --dataset_name trl-lib/Capybara \
    --use_peft \
    --lora_r 32 \
    --lora_alpha 16 \
    --lora_dropout 0.05 \
    --output_dir Qwen2-0.5B-SFT-LoRA

Ưu điểm: Thiết lập nhanh, không cần viết mã

Nhược điểm: Chỉ giới hạn ở LoRA, ít tùy chọn tùy chỉnh hơn

2. Truyền peft_config cho Trainer (Được khuyến nghị)

Để có nhiều quyền kiểm soát hơn, hãy truyền trực tiếp một cấu hình PEFT cho trainer. Đây là cách tiếp cận được khuyến nghị cho hầu hết các trường hợp sử dụng:

from peft import LoraConfig
from trl import SFTConfig, SFTTrainer

peft_config = LoraConfig(
    r=32,
    lora_alpha=16,
    lora_dropout=0.05,
    bias="none",
    task_type="CAUSAL_LM",
    target_modules=["q_proj", "v_proj", "k_proj", "o_proj"],
)

trainer = SFTTrainer(
    model=model,
    args=training_args,
    train_dataset=dataset,
    peft_config=peft_config,  # Pass config here
)

Ưu điểm: Kiểm soát hoàn toàn, hỗ trợ tất cả các phương pháp PEFT (LoRA, Prompt Tuning, v.v.)

Nhược điểm: Yêu cầu mã Python

3. Áp dụng PEFT trực tiếp cho Mô hình (Nâng cao)

Để có tính linh hoạt tối đa, bạn có thể áp dụng PEFT cho mô hình của mình trước khi truyền nó vào trainer:

from peft import LoraConfig, get_peft_model
from transformers import AutoModelForCausalLM
from trl import SFTConfig, SFTTrainer

# Load base model
model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2-0.5B")

# Apply PEFT configuration
peft_config = LoraConfig(
    r=32,
    lora_alpha=16,
    lora_dropout=0.05,
    bias="none",
    task_type="CAUSAL_LM",
)
model = get_peft_model(model, peft_config)

# Pass PEFT-wrapped model to trainer
trainer = SFTTrainer(
    model=model,  # Already has PEFT applied
    args=training_args,
    train_dataset=dataset,
    # Note: no peft_config needed here
)

Ưu điểm: Kiểm soát tối đa, hữu ích cho các kiến trúc mô hình tùy chỉnh hoặc các cấu hình phức tạp

Nhược điểm: Cồng kềnh hơn, đòi hỏi phải hiểu các chi tiết bên trong của PEFT

Xem xét về tốc độ học

Khi sử dụng LoRA hoặc các phương pháp PEFT khác, bạn thường cần sử dụng tốc độ học cao hơn (khoảng 10 lần) so với fine-tuning toàn bộ. Điều này là do các phương pháp PEFT chỉ huấn luyện một phần nhỏ các tham số, đòi hỏi tốc độ học lớn hơn để đạt được các cập nhật tham số tương đương.

Tốc độ học được khuyến nghị:

TrainerFine-tuning đầy đủVới LoRA (10x)
SFT2.0e-52.0e-4
DPO5.0e-75.0e-6
GRPO1.0e-61.0e-5
Prompt TuningN/Atừ 1.0e-2 đến 3.0e-2

Tại sao là 10x? Bộ thích ứng LoRA có số tham số có thể huấn luyện ít hơn đáng kể so với toàn bộ mô hình. Tốc độ học cao hơn bù đắp cho số lượng tham số giảm này, đảm bảo quá trình huấn luyện hiệu quả. Để có giải thích chi tiết, hãy xem bài đăng trên blog này.

Để biết thêm các thực hành tốt nhất khi sử dụng LoRA một cách hiệu quả, hãy tham khảo tài liệu LoRA Without Regret.

PEFT với các Trainer khác nhau

Trainers của TRL hỗ trợ các cấu hình PEFT cho nhiều phương pháp huấn luyện khác nhau. Dưới đây là các ví dụ chi tiết cho từng trainer chính.

sft
dpo
grpo

Tinh chỉnh có giám sát (SFT)

SFTTrainer được sử dụng để tinh chỉnh có giám sát trên các bộ dữ liệu hướng dẫn.

Với LoRA

python trl/scripts/sft.py \
    --model_name_or_path Qwen/Qwen2-0.5B \
    --dataset_name trl-lib/Capybara \
    --learning_rate 2.0e-4 \
    --num_train_epochs 1 \
    --per_device_train_batch_size 2 \
    --gradient_accumulation_steps 8 \
    --use_peft \
    --lora_r 32 \
    --lora_alpha 16 \
    --output_dir Qwen2-0.5B-SFT-LoRA

Ví dụ Python

from peft import LoraConfig
from trl import SFTConfig, SFTTrainer

# Configure LoRA
peft_config = LoraConfig(
    r=32,
    lora_alpha=16,
    lora_dropout=0.05,
    bias="none",
    task_type="CAUSAL_LM",
    target_modules=["q_proj", "v_proj"],  # optional: specify target modules
)

# Configure training with higher learning rate for LoRA
training_args = SFTConfig(
    learning_rate=2.0e-4,  # 10x the base rate for LoRA
    ...
)

# Create trainer with PEFT config
trainer = SFTTrainer(
    model="Qwen/Qwen2-0.5B",  # can pass model name or loaded model
    args=training_args,
    train_dataset=dataset,
    peft_config=peft_config,  # pass PEFT config here
)
trainer.train()

QLoRA: Thích ứng hạng thấp đã lượng tử hóa

QLoRA kết hợp lượng tử hóa 4-bit với LoRA để cho phép tinh chỉnh các mô hình rất lớn trên phần cứng tiêu dùng. Kỹ thuật này có thể giảm yêu cầu bộ nhớ lên đến 4 lần so với LoRA tiêu chuẩn.

QLoRA hoạt động như thế nào

  1. Định lượng 4-bit: Mô hình cơ sở được nạp ở độ chính xác 4-bit bằng bitsandbytes
  2. Trọng số đóng băng: Trọng số của mô hình lượng tử hóa vẫn được giữ nguyên trong suốt quá trình huấn luyện
  3. LoRA Adapters: Chỉ các tham số của bộ thích ứng LoRA được huấn luyện ở độ chính xác cao hơn
  4. Hiệu quả bộ nhớ: Cho phép tinh chỉnh các mô hình như Llama-70B trên một GPU tiêu dùng duy nhất

Sử dụng QLoRA với TRL

Chỉ cần kết hợp load_in_4bit=True với cấu hình PEFT:

Dòng lệnh

python trl/scripts/sft.py \
    --model_name_or_path meta-llama/Llama-2-7b-hf \
    --dataset_name trl-lib/Capybara \
    --load_in_4bit \
    --use_peft \
    --lora_r 32 \
    --lora_alpha 16 \
    --per_device_train_batch_size 1 \
    --gradient_accumulation_steps 16 \
    --output_dir Llama-2-7b-QLoRA

Ví dụ Python

Truyền quantization_config trực tiếp cho trainer cùng với peft_config — trainer sẽ tải và lượng tử hóa model cho bạn. Tham số quantization_config tương tự cũng có sẵn trên SFTTrainer, DPOTrainer, GRPOTrainer và RLOOTrainer.

import torch

from peft import LoraConfig
from transformers import BitsAndBytesConfig
from trl import SFTConfig, SFTTrainer

# Configure 4-bit quantization
bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_compute_dtype=torch.bfloat16,
    bnb_4bit_use_double_quant=True,
)

# Configure LoRA
peft_config = LoraConfig(
    r=32,
    lora_alpha=16,
    lora_dropout=0.05,
    bias="none",
    task_type="CAUSAL_LM",
)

# Configure training with higher learning rate for LoRA
training_args = SFTConfig(
    learning_rate=2.0e-4,  # 10x the base rate for QLoRA
    ...
)

# Create trainer with quantization and PEFT config
trainer = SFTTrainer(
    model="meta-llama/Llama-2-7b-hf",
    args=training_args,
    train_dataset=dataset,
    quantization_config=bnb_config,
    peft_config=peft_config,
)

trainer.train()

Các tùy chọn cấu hình QLoRA

BitsAndBytesConfig cung cấp một số tùy chọn để tối ưu hóa bộ nhớ và hiệu suất:

import torch

from transformers import BitsAndBytesConfig

bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",  # or "fp4"
    bnb_4bit_compute_dtype=torch.bfloat16,  # Compute dtype for 4-bit base models
    bnb_4bit_use_double_quant=True,  # Nested quantization for additional memory savings
)

Tham số cấu hình:

  • bnb_4bit_quant_type: Kiểu dữ liệu lượng tử hóa ("nf4" hoặc "fp4"). Khuyến nghị sử dụng NF4.
  • bnb_4bit_compute_dtype: Kiểu dữ liệu (dtype) được sử dụng cho phép tính toán. Hãy dùng bfloat16 để đạt được độ ổn định huấn luyện tốt hơn.
  • bnb_4bit_use_double_quant: Bật lượng tử hóa lồng nhau để tiết kiệm thêm ~0,4 bit cho mỗi tham số.

Lượng tử hóa 8-bit

Để có độ chính xác cao hơn một chút với mức tiết kiệm bộ nhớ giảm đi, bạn có thể sử dụng lượng tử hóa 8-bit:

from transformers import BitsAndBytesConfig, AutoModelForCausalLM

bnb_config = BitsAndBytesConfig(load_in_8bit=True)

model = AutoModelForCausalLM.from_pretrained(
    "meta-llama/Llama-2-7b-hf",
    quantization_config=bnb_config,
    device_map="auto",
)

Hoặc qua dòng lệnh:

python trl/scripts/sft.py \
    --model_name_or_path meta-llama/Llama-2-7b-hf \
    --load_in_8bit \
    --use_peft \
    --lora_r 32 \
    --lora_alpha 16

Điểm kiểm tra đã lượng tử hóa trước

Một số checkpoint được phát hành ở dạng đã lượng tử hóa, chẳng hạn như gpt-oss ở MXFP4 hoặc Mistral Medium 3.5 ở FP8. Các trọng số này không thể được huấn luyện tại chỗ, do đó khi bạn truyền một checkpoint như vậy theo tên, trainer sẽ nạp nó ở dạng đã khử lượng tử hóa, có hoặc không kèm theo peft_config. Mô hình sau đó sẽ chiếm bộ nhớ tương ứng với trọng số đã khử lượng tử hóa của nó, ví dụ khoảng 42 GB ở bfloat16 cho gpt-oss-20b, so với 13 GB cho checkpoint MXFP4 của nó. Để nạp ở bfloat16, giống như bất kỳ mô hình nào khác:

from trl import SFTConfig

training_args = SFTConfig(model_init_kwargs={"dtype": "bfloat16"})

FP8 checkpoints yêu cầu transformers 5.0.0 hoặc mới hơn.

Điều chỉnh Prompt

Prompt tuning là một kỹ thuật PEFT khác, học các prompt mềm (các embedding liên tục) được thêm vào trước đầu vào, trong khi giữ nguyên toàn bộ mô hình ở trạng thái đóng băng. Kỹ thuật này đặc biệt hiệu quả với các mô hình lớn.

Cách Prompt Tuning hoạt động

  1. Virtual Tokens: Thêm các embedding liên tục có thể học được (virtual tokens) vào đầu vào
  2. Mô hình đóng băng: Toàn bộ mô hình cơ sở vẫn được giữ nguyên
  3. Lệnh dành riêng cho từng tác vụ: Mỗi tác vụ học các nhúng lệnh riêng của nó
  4. Hiệu suất cực cao: Chỉ các embedding của prompt được huấn luyện (thường là 8-20 token)

Sử dụng Prompt Tuning với TRL

from peft import PromptTuningConfig, PromptTuningInit, TaskType
from trl import SFTConfig, SFTTrainer

# Configure Prompt Tuning
peft_config = PromptTuningConfig(
    task_type=TaskType.CAUSAL_LM,
    prompt_tuning_init=PromptTuningInit.TEXT,
    num_virtual_tokens=8,
    prompt_tuning_init_text="Classify if the tweet is a complaint or not:",
    tokenizer_name_or_path="Qwen/Qwen2-0.5B",
)

# Configure training with higher learning rate for Prompt Tuning
training_args = SFTConfig(
    learning_rate=2.0e-2,  # Prompt Tuning typically uses 1e-2 to 3e-2
    ...
)

# Create trainer with PEFT config
trainer = SFTTrainer(
    model=model,
    args=training_args,
    train_dataset=dataset,
    peft_config=peft_config,  # pass PEFT config here
)

trainer.train()

Cấu hình điều chỉnh prompt

from peft import PromptTuningConfig, PromptTuningInit, TaskType

peft_config = PromptTuningConfig(
    task_type=TaskType.CAUSAL_LM,  # Task type
    prompt_tuning_init=PromptTuningInit.TEXT,  # Initialize from text
    num_virtual_tokens=8,  # Number of virtual tokens
    prompt_tuning_init_text="Your initialization text here",
    tokenizer_name_or_path="model_name",
)

Tham số cấu hình:

  • task_type: Loại tác vụ (TaskType.CAUSAL_LM cho mô hình hóa ngôn ngữ)
  • prompt_tuning_init: Phương pháp khởi tạo (TEXT, RANDOM)
  • num_virtual_tokens: Số lượng token ảo được thêm vào phía trước (thường là 8-20)
  • prompt_tuning_init_text: Văn bản để khởi tạo các token ảo (khi sử dụng init TEXT)
  • tokenizer_name_or_path: Tokenizer để khởi tạo từ văn bản

Prompt Tuning so với LoRA

Tính năngĐiều chỉnh PromptLoRA
Tham số được huấn luyện~0.001%~0.1-1%
Độ sử dụng bộ nhớTối giảnThấp
Tốc độ huấn luyệnNhanh nhấtNhanh
Chỉnh sửa Mô hìnhKhôngTầng Adapter
Phù hợp nhất choMô hình lớn, nhiều tác vụTinh chỉnh chung
Tốc độ họcCao hơn (1e-2 đến 3e-2)Tiêu chuẩn (1e-4 đến 3e-4)

Cấu hình PEFT nâng cao

Các tham số cấu hình LoRA

from peft import LoraConfig

peft_config = LoraConfig(
    r=16,  # LoRA rank
    lora_alpha=32,  # LoRA scaling factor
    lora_dropout=0.05,  # Dropout probability
    bias="none",  # Bias training strategy
    task_type="CAUSAL_LM",  # Task type
    target_modules=["q_proj", "v_proj"],  # Modules to apply LoRA
    modules_to_save=None,  # Additional modules to train
)

Các tham số chính:

  • r: rank của LoRA (các giá trị điển hình: 8, 16, 32, 64). Rank cao hơn = nhiều tham số hơn nhưng có thể cho hiệu suất tốt hơn.
  • lora_alpha: Hệ số tỷ lệ (thường gấp đôi rank). Kiểm soát độ lớn của các bản cập nhật LoRA.
  • lora_dropout: Xác suất dropout cho các lớp LoRA (thường gặp: 0.05-0.1).
  • target_modules: Các module cần áp dụng LoRA. Các lựa chọn phổ biến:
    • ["q_proj", "v_proj"]: Truy vấn và giá trị chú ý (hiệu quả bộ nhớ)
    • ["q_proj", "k_proj", "v_proj", "o_proj"]: Tất cả các phép chiếu attention
    • ["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"]: Tất cả các lớp tuyến tính
  • modules_to_save: Các module bổ sung cần huấn luyện hoàn toàn (ví dụ: ["embed_tokens", "lm_head"])

Chọn module đích

Bạn có thể chỉ định các module cần áp dụng LoRA. Các mẫu phổ biến:

# Minimal (most memory efficient)
target_modules=["q_proj", "v_proj"]

# Attention only
target_modules=["q_proj", "k_proj", "v_proj", "o_proj"]

# All linear layers (best performance, more memory)
target_modules=["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"]

Sử dụng các đối số dòng lệnh

Các script TRL chấp nhận các tham số PEFT qua dòng lệnh:

python trl/scripts/sft.py \
    --model_name_or_path Qwen/Qwen2-0.5B \
    --dataset_name trl-lib/Capybara \
    --use_peft \
    --lora_r 32 \
    --lora_alpha 16 \
    --lora_dropout 0.05 \
    --lora_target_modules q_proj v_proj \
    --output_dir output

Các cờ khả dụng:

  • --use_peft: Bật PEFT
  • --lora_r: bậc LoRA (mặc định: 16)
  • --lora_alpha: LoRA alpha (mặc định: 32)
  • --lora_dropout: dropout của LoRA (mặc định: 0.05)
  • --lora_target_modules: Các module đích (cách nhau bằng khoảng trắng)
  • --lora_modules_to_save: Các module bổ sung cần huấn luyện
  • --use_rslora: Bật Rank-Stabilized LoRA
  • --use_dora: Bật Weight-Decomposed LoRA (DoRA)
  • --load_in_4bit: Bật lượng tử hóa 4-bit (QLoRA)
  • --load_in_8bit: Bật lượng tử hóa 8-bit

Lưu và tải các mô hình PEFT

Lưu

Sau khi huấn luyện, hãy lưu các bộ thích ứng PEFT của bạn:

# Save the adapters
trainer.save_model("path/to/adapters")

# Or manually
model.save_pretrained("path/to/adapters")

Điều này chỉ lưu trữ trọng số của adapter (~vài MB) thay vì toàn bộ mô hình (~vài GB).

Đang tải

Tải một mô hình PEFT để suy luận:

from transformers import AutoModelForCausalLM
from peft import PeftModel

# Load base model
base_model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2-0.5B")

# Load PEFT adapters
model = PeftModel.from_pretrained(base_model, "path/to/adapters")

# Optionally merge adapters into base model for faster inference
model = model.merge_and_unload()

Đẩy lên Hub

Bạn có thể dễ dàng chia sẻ các bộ thích ứng PEFT của mình trên Hugging Face Hub:

# Push adapters to Hub
model.push_to_hub("username/model-name-lora")

# Load from Hub
from peft import PeftModel
model = PeftModel.from_pretrained(base_model, "username/model-name-lora")

Đào tạo đa GPU

PEFT hoạt động liền mạch với hỗ trợ đa GPU của TRL:

torchrun --nproc_per_node 8 trl/scripts/sft.py \
    --model_name_or_path Qwen/Qwen2-0.5B \
    --dataset_name trl-lib/Capybara \
    --use_peft \
    --lora_r 32 \
    --lora_alpha 16

Đối với QLoRA trên nhiều GPU, mô hình cơ sở sẽ được tự động chia nhỏ:

torchrun --nproc_per_node 8 trl/scripts/sft.py \
    --model_name_or_path meta-llama/Llama-2-70b-hf \
    --load_in_4bit \
    --use_peft \
    --lora_r 32

Song song đường ống ngây thơ (NPP) cho các mô hình lớn

Đối với các mô hình rất lớn (>60B tham số), TRL hỗ trợ Naive Pipeline Parallelism (NPP), giúp phân phối mô hình và các adapter trên nhiều GPU. Các activation và gradient được truyền thông giữa các GPU, hỗ trợ cả int8 và các kiểu dữ liệu khác.

NPP

Cách sử dụng NPP

Tải mô hình của bạn với device_map tùy chỉnh để chia nó trên nhiều thiết bị:

from transformers import AutoModelForCausalLM
from peft import LoraConfig

# Create custom device map (see accelerate documentation)
device_map = {
    "model.embed_tokens": 0,
    "model.layers.0": 0,
    # ... distribute layers across GPUs
    "lm_head": 0,  # Must be on GPU 0
}

model = AutoModelForCausalLM.from_pretrained(
    "meta-llama/Llama-2-70b-hf",
    device_map=device_map,
    peft_config=lora_config,
)
  • Giữ module lm_head trên GPU đầu tiên (thiết bị 0) để tránh lỗi
  • Xem hướng dẫn về bản đồ thiết bị này để cấu hình đúng cách
  • Chạy trực tiếp các script huấn luyện (không dùng torchrun): python script.py
  • Data Parallelism hiện chưa được hỗ trợ với NPP

Tài nguyên

Ví dụ và Notebook của TRL

Tài liệu

Bản nghiên cứu

Update on GitHub