Bài viết này sẽ hướng dẫn bạn thực hiện fine-tuning mô hình ChatGLM3-6B sử dụng phương pháp LORA - một kỹ thuật fine-tuning hiệu quả về mặt tài nguyên.
Giới thiệu về LORA:
LORA (Low-Rank Adaptation) là phương pháp được đề xuất trong bài báo nghiên cứu tại địa chỉ arxiv:2106.09685. Thay vì thay đổi toàn bộ các tham số của mô hình gốc, LORA hoạt động bằng cách thêm các ma trận có rank thấp vào các lớp attention của mô hình.
Để hiểu đơn giản: Hãy tưởng tượng bạn có một "chuyên gia" đã được huấn luyện sẵn (pre-trained model). Khi cần chuyên gia này thực hiện một nhiệm vụ mới, thay vì huấn luyện lại toàn bộ (rất tốn kém), LORA chỉ thêm vào hai "quyển sổ tay" nhỏ: một quyển để ghi nhận kiến thức mới (ma trận A) và một quyển để áp dụng kiến thức đó (ma trận B). Chỉ cần cập nhật hai ma trận này, mô hình đã có thể thực hiện tốt nhiệm vụ mới mà không làm mất kiến thức gốc.
Cấu hình hệ thống:
- Hệ điều hành: Ubuntu 22.04
- CPU: 12 cores
- RAM: 90GB (chế độ GPU chỉ cần 16GB)
- GPU: RTX 4090 (24GB)
- Môi trường: Jupyter Notebook
Quy trình thực hiện:
Bước 1: Tải mã nguồn và mô hình
# Clone repository ChatGLM3
git clone https://github.com/THUDM/ChatGLM3
# Cài đặt các thư viện phụ thuộc
cd ChatGLM3 && pip install -r requirements.txt
# Cài đặt modelscope và tải mô hình
pip install modelscope
from modelscope import snapshot_download
model_dir = snapshot_download("ZhipuAI/chatglm3-6b", revision = "v1.0.0")
Bước 2: Di chuyển mô hình vào thư mục làm việc
Mô hình tải về sẽ nằm trong thư mục cache. Di chuyển sang thư mục ChatGLM3 để dễ quản lý:
# Sao chép mô hình vào thư mục làm việc
cp -r /root/.cache/modelscope/hub/ZhipuAI/chatglm3-6b /ChatGLM3
Bước 3: Chuẩn bị dữ liệu huấn luyện
Cần chuẩn bị ít nhất hai file: train.json (dữ liệu huấn luyện) và dev.json (dữ liệu validation).
File train.json:
{"content": "Bạn là ai", "summary": "Tôi là trợ lý AI được huấn luyện để hỗ trợ bạn trong các tác vụ lập trình và kỹ thuật."}
{"content": "Xin chào", "summary": "Xin chào! Tôi là trợ lý AI, rất vui được hỗ trợ bạn."}
{"content": "Lập trình viên", "summary": "Một lập trình viên đang ngồi trước màn hình máy tính. Đôi mắt anh ấy tập trung vào dòng code đang hiển thị, các ngón tay di chuyển linh hoạt trên bàn phím. Năm tháng đã để lại dấu ấn trên khuôn mặt anh ấy, nhưng đam mê với công nghệ vẫn luôn bùng cháy."}
{"content": "Liên hệ", "summary": "Bạn có thể liên hệ qua địa chỉ email: contact@example.com"}
File dev.json sử dụng cùng nội dung (cho mục đích minh họa).
Lưu hai file này tại đường dẫn: ChatGLM3/finetune_demo/data/TrainData/
Bước 4: Cài đặt các thư viện fine-tuning
cd finetune_demo
pip install -r requirements.txt
Bước 5: Chuyển đổi định dạng dữ liệu
Dữ liệu cần được chuyển sang định dạng JSONL với cấu trúc conversations:
import json
from typing import Union
from pathlib import Path
def resolve_path(path: Union[str, Path]) -> Path:
return Path(path).expanduser().resolve()
def create_directory(dir_name: Union[str, Path]):
dir_name = resolve_path(dir_name)
if not dir_name.is_dir():
dir_name.mkdir(parents=True, exist_ok=False)
def transform_dataset(source_dir: Union[str, Path], target_dir: Union[str, Path]):
def _transform(input_path: Path, output_path: Path):
create_directory(output_path.parent)
with open(input_path, encoding='utf-8') as fin:
with open(output_path, 'wt', encoding='utf-8') as fout:
for line in fin:
record = json.loads(line)
sample = {
'conversations': [
{'role': 'user', 'content': record['content']},
{'role': 'assistant', 'content': record['summary']}
]
}
fout.write(json.dumps(sample, ensure_ascii=False) + '\n')
source_dir = resolve_path(source_dir)
target_dir = resolve_path(target_dir)
train_path = source_dir / 'train.json'
if train_path.is_file():
output_file = target_dir / train_path.relative_to(source_dir)
_transform(train_path, output_file)
dev_path = source_dir / 'dev.json'
if dev_path.is_file():
output_file = target_dir / dev_path.relative_to(source_dir)
_transform(dev_path, output_file)
# Thực hiện chuyển đổi
transform_dataset('data/TrainData', 'data/TrainData_processed')
Sau khi chạy đoạn code trên, dữ liệu sẽ có định dạng:
{"conversations": [{"role": "user", "content": "Bạn là ai"}, {"role": "assistant", "content": "Tôi là trợ lý AI được huấn luyện để hỗ trợ bạn trong các tác vụ lập trình và kỹ thuật."}]}
Bước 6: Cấu hình và chạy fine-tuning
Mở file cấu hình tại: ChatGLM3/finetune_demo/configs/lora.yaml
Chạy lệnh fine-tuning:
CUDA_VISIBLE_DEVICES=0 python finetune_hf.py data/TrainData_processed /ChatGLM3/chatglm3-6b configs/lora.yaml
Thời gian huấn luyện ước tính khoảng 40 phút. Kết quả đầu ra:
trainable params: 1,949,696 || all params: 6,245,533,696 || trainable%: 0.0312
{'eval_rouge-1': 100.0, 'eval_rouge-2': 100.0, 'eval_rouge-l': 100.0, 'eval_bleu-4': 1.0, 'eval_runtime': 4.07, 'eval_samples_per_second': 0.737, 'epoch': 2000.0}
Saving model checkpoint to ./output/checkpoint-2000
Mô hình sau khi fine-tuning sẽ được lưu tại: ChatGLM3/finetune_demo/output/checkpoint-2000
Bước 7: Sử dụng mô hình đã fine-tuning để suy luận
Dùng file inference_hf.py có sẵn để kiểm tra kết quả:
# Test với prompt đầu tiên
CUDA_VISIBLE_DEVICES=0 python inference_hf.py output/checkpoint-2000/ --prompt "Bạn là?"
Kết quả trả về:
Tôi là trợ lý AI được huấn luyện để hỗ trợ bạn trong các tác vụ lập trình và kỹ thuật.
# Test với prompt thứ hai
CUDA_VISIBLE_DEVICES=0 python inference_hf.py output/checkpoint-2000/ --prompt "Lập trình viên"
Kết quả trả về:
Một lập trình viên đang ngồi trước màn hình máy tính. Đôi mắt anh ấy tập trung vào dòng code đang hiển thị, các ngón tay di chuyển linh hoạt trên bàn phím...
Tổng kết:
Phương pháp LORA cho phép fine-tuning hiệu quả với chỉ 0.03% số tham số của mô hình gốc, giảm đáng kể tài nguyên GPU cần thiết. Đây là giải pháp lý tưởng khi cần điều chỉnh mô hình cho các tác vụ cụ thể mà không có nguồn lực huấn luyện lớn.