Chuyển đến nội dung chính

Salesforce XGen-7B: Hướng dẫn từng bước sử dụng và tinh chỉnh XGen-7B

Hầu hết LLM mã nguồn mở có một nhược điểm lớn - độ dài ngữ cảnh ngắn. Vì độ dài ngữ cảnh về cơ bản là “bộ nhớ” của LLM, vấn đề này cần được giải quyết khẩn trương. Đó chính xác là điều mà Salesforce XGen 7B làm được - cung cấp độ dài ngữ cảnh 8k ấn tượng. Bài viết này là hướng dẫn cách sử dụng và tinh chỉnh nó.
· 15 phút đọc

Khám phá cùng AI

Hiện tại, đây là sáu LLM mã nguồn mở hot nhất:

  1. LLaMA2
  2. BLOOM
  3. Falcon 180B
  4. OPT-175B
  5. GPT-Neox
  6. Vicuna 13-B

Và tất cả đều có cùng một điểm bất lợi — độ dài ngữ cảnh rất ngắn, chỉ đạt tối đa 2048 token. So với các mô hình độc quyền như GPT-3.5 và GPT-4 có thể đạt tới 32k token (50 trang văn bản!), có vẻ các LLM mã nguồn mở đang chịu bất lợi lớn.

Độ dài ngữ cảnh về bản chất là “bộ nhớ” của LLM. Cửa sổ ngữ cảnh 2048 token nghĩa là mô hình chỉ có thể ghi nhớ 2048 token của cuộc hội thoại tại một thời điểm. Điều này ảnh hưởng đáng kể đến hiệu suất trong các tác vụ cần ngữ cảnh lớn như tóm tắt, dịch thuật, sinh mã, v.v.

Để giải quyết vấn đề then chốt này, Salesforce đã công bố mô hình XGen-7B với độ dài ngữ cảnh lên tới 8k token (dài gấp 4 lần các LLM tương tự). Bài viết này trình bày các đặc điểm chính của mô hình và hướng dẫn cách sử dụng cũng như tinh chỉnh nó trên một tập dữ liệu mẫu.

Vì sao chọn XGen 7B?

Với hầu hết mọi người, các con số như độ dài ngữ cảnh không có nhiều ý nghĩa cho đến khi được chuyển hóa thành lợi ích cụ thể. Vậy nên, dưới đây là một số tính năng chính và tác động của chúng đến các dự án của bạn:

Gọn nhẹ nhưng mạnh mẽ

Dù chỉ có 7 tỷ tham số, XGen hoạt động vượt kỳ vọng — mang lại hiệu năng ngang ngửa hoặc vượt qua nhiều mô hình lớn hơn. Hiệu quả này là bước ngoặt cho nhà phát triển và nhà nghiên cứu, cho phép chạy và triển khai ứng dụng AI tiên tiến ngay trên máy trạm cấu hình cao mà không cần tài nguyên đám mây khổng lồ. Sự cân bằng giữa kích thước và hiệu năng khiến XGen đặc biệt hấp dẫn với nhiều nhóm người dùng, từ startup nhỏ đến giới học thuật.

Nhiều biến thể linh hoạt

Thấu hiểu nhu cầu đa dạng, XGen cung cấp ba phiên bản, mỗi phiên bản phù hợp với các ứng dụng cụ thể:

  • XGen-7B-4K-base: Với độ dài chuỗi 4k token, phù hợp cho các tác vụ cần ngữ cảnh vừa phải. Được cấp phép theo giấy phép Apache 2.0.
  • XGen-7B-8K-base: Mô hình chủ lực với độ dài chuỗi 8k token, thiết kế cho các tác vụ phức tạp hưởng lợi từ việc phân tích khối văn bản lớn. Cũng theo giấy phép Apache 2.0, nghĩa là có thể sử dụng cho hầu hết mọi mục đích.
  • XGen-7B-{4K,8K}-inst: Được tinh chỉnh trên dữ liệu hướng dẫn công khai, chuyên cho các ứng dụng tương tác và hướng dẫn, cung cấp cho mục đích phi thương mại. Biến thể này lý tưởng cho công cụ giáo dục, bot tương tác và các ứng dụng cần chỉ dẫn.

Hiệu năng cao trên các benchmark

Sức mạnh của mô hình thể hiện qua các benchmark. XGen dẫn đầu ở nhiều bộ đánh giá đa dạng như MMLU, HumanEval, v.v. khi so với các mô hình cùng kích thước. Để phân tích chi tiết, bài thông báo cung cấp tổng quan toàn diện về thành tựu của XGen trên các benchmark.

Tối ưu cho tác vụ chuỗi dài

Dù có phần lặp lại, tôi nhấn mạnh rằng XGen được tối ưu mạnh cho các tác vụ cần cửa sổ ngữ cảnh lớn. Khả năng này rất quan trọng cho các ứng dụng như tóm tắt tài liệu chi tiết, nơi việc nắm bắt toàn bộ văn bản giúp tạo bản tóm tắt chính xác. Tương tự, trong hỏi đáp toàn diện và sinh nội dung dài, khả năng xử lý lượng thông tin lớn của XGen tạo ra đầu ra mạch lạc, phù hợp ngữ cảnh hơn.

Chi tiết huấn luyện Salesforce XGen 7B

Vậy XGen đạt được kết quả ấn tượng này như thế nào? Tất nhiên, câu trả lời nằm ở phương pháp huấn luyện và tối ưu hóa do các nhà nghiên cứu AI của Salesforce sử dụng.

Chiến lược huấn luyện của XGen gồm hai giai đoạn. Ở giai đoạn 1, một mô hình mới được huấn luyện trên 1,37 nghìn tỷ token, bao gồm dữ liệu ngôn ngữ tự nhiên và mã nguồn.

image2.png

Ở giai đoạn hai, thêm 55 tỷ token mã nguồn được dùng để huấn luyện nhằm cải thiện khả năng sinh mã:

image1.png

Việc huấn luyện được thực hiện bằng thư viện nội bộ tên là JaxFormer, được thiết kế riêng để huấn luyện LLM hiệu quả với song song dữ liệu và mô hình trên phần cứng TPU-v4.

Yêu cầu tiên quyết và cài đặt XGen 7B

Dù nhỏ, XGen 7B vẫn là một mạng nơ-ron rất lớn. Nếu chạy không dùng tài nguyên đám mây, bạn cần máy cục bộ cấu hình cao. Yêu cầu chính là RAM đủ lớn, vượt xa 32 GB, vì mô hình ~30 GB khi tải từ HuggingFace. Với GPU, càng lớn càng tốt.

Nếu PC của bạn không đáp ứng được, lựa chọn rẻ nhất là Colab Pro với 40 GB RAM và 40 GB GPU vRAM (A100). Trong hướng dẫn này, tôi dùng Colab Pro:

image3.png

Sau khi thiết lập máy tương thích, đến lúc cài đặt và tải mô hình. Nếu bạn thực hiện trên máy cục bộ, bước 0 là tạo môi trường ảo:

$ conda create -n xgen -y
$ conda activate xgen

Để tải mô hình từ HuggingFace, bắt buộc phải cài torch có hỗ trợ GPU. Đây là lệnh cài tất cả thư viện cần thiết:

$ pip install torch torchvision torchaudio transformers[torch]

Chúng ta cũng sẽ cần các thư viện sau cho bước tinh chỉnh sau này:

$ pip install accelerate peft bitsandbytes trl datasets --upgrade

Đừng quên khởi động lại kernel sau khi cài thư viện.

Tôi sẽ giải thích từng thư viện khi tới phần tương ứng.

Giờ hãy chạy mô hình lần đầu bằng đoạn mã sau.

import torch
from transformers import AutoTokenizer, AutoModelForCausalLM

tokenizer = AutoTokenizer.from_pretrained("Salesforce/xgen-7b-8k-base", trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained("Salesforce/xgen-7b-8k-base", torch_dtype=torch.bfloat16)

inputs = tokenizer("DataCamp is one he ...", return_tensors="pt")
sample = model.generate(**inputs, max_length=128)

print(tokenizer.decode(sample[0]))

Lớp AutoTokenizer tải bộ tokenizer tự động cho mô hình độ dài 4098 xgen-7b-4k-base. Lớp AutoModelForCausalLM dùng để tải các mô hình sinh văn bản.

Chúng ta chỉ định prompt là inputs và truyền nó vào model.generate với độ dài token tối đa 128. Lần chạy đầu sẽ mất thời gian vì mô hình cần được tải xuống.

Đây là đầu ra tôi nhận được cuối cùng:

DataCamp is one of the world’s leading providers of data science courses and training...

Phần đầu phản hồi khá ổn, nhưng dần kém đi về cuối. Ta cần tinh chỉnh để có hiệu suất tốt hơn.

Tinh chỉnh Salesforce XGen 7B

LLM không giống các mô hình sklearn - bạn không thể chỉ tinh chỉnh siêu tham số trong vài dòng mã. Vì vậy, chúng ta sẽ tinh chỉnh XGen 7B qua vài bước. Tôi gợi ý bạn đi qua từng bước thật bình tĩnh vì sẽ có nhiều chi tiết.

Lưu ý quy trình dưới đây có thể áp dụng cho nhiều LLM trên HuggingFace miễn là bạn có đủ tài nguyên tính toán.

Bắt đầu thôi.

1. Cài đặt

Chúng ta đã đề cập bước này trước đó. Giờ hãy điểm lại các thư viện đã cài và lý do cần chúng:

  • torch: Thư viện PyTorch cho tensor và mạng nơ-ron; hỗ trợ tăng tốc GPU.
  • transformers: Thư viện của Hugging Face cho các mô hình NLP tiền huấn luyện.
  • datasets: Để tải và xử lý dữ liệu dễ dàng với các dataset của HuggingFace.
  • accelerate: Thư viện chính thức của HuggingFace để đơn giản hóa huấn luyện phân tán LLM.
  • peft: gói giúp tinh chỉnh một phần nhỏ tham số LLM để tăng tốc huấn luyện
  • bitsandbytes: thư viện tối ưu LLM về bộ nhớ và hiệu năng tính toán.
  • trl: Các kỹ thuật tinh chỉnh mô hình lớn bằng RLHF (học tăng cường với phản hồi con người).

Chúng ta sẽ giải thích lợi ích của từng thư viện khi sử dụng chúng.

2. Import các mô-đun cần thiết

import os
import torch

from datasets import load_dataset
from transformers import (
   AutoModelForCausalLM,
   AutoTokenizer,
   BitsAndBytesConfig,
   TrainingArguments,
   pipeline,
)

from peft import LoraConfig
from trl import SFTTrainer

Tổng quan về các lớp và hàm mới được import:

  • BitsAndBytesConfig: Cấu hình tối ưu tham số mô hình bằng kỹ thuật bits and bytes, nâng cao hiệu quả bộ nhớ và tính toán.
  • TrainingArguments: Chỉ định tham số huấn luyện (vd. learning rate, batch size) để tinh chỉnh mô hình.
  • pipeline: Đơn giản hóa việc áp dụng mô hình cho các tác vụ như sinh văn bản.
  • LoraConfig: Cấu hình áp dụng LoRA (Low-Rank Adaptation), phương pháp tinh chỉnh hiệu quả tham số bằng cách điều chỉnh một tập tham số nhỏ.
  • SFTTrainer: Lớp huấn luyện cho Supervised Fine-Tuning (SFT), hỗ trợ quá trình huấn luyện với phản hồi con người hoặc dữ liệu gán nhãn.

3. Định nghĩa cấu hình cho mô hình gốc và mô hình tinh chỉnh

# Model from HF
base_model = "Salesforce/xgen-7b-8k-base"

# New instruction dataset
guanaco_dataset = "mlabonne/guanaco-llama2-1k"

# Fine-tuned model
new_model = "xgen-7b-8k-tuned"

Với tập dữ liệu, chúng ta sẽ dùng Guanaco LLaMA2, gồm 1000 cặp hướng dẫn - phản hồi để tinh chỉnh LLM cho các tác vụ tương tác và hướng dẫn (như chatbot).

4. Tải dữ liệu

dataset = load_dataset(guanaco_dataset, split="train")

Để tải dữ liệu từ HuggingFace, ta dùng hàm load_dataset chỉ định đường dẫn và phần dữ liệu (split). Ta có thể xem mẫu bằng cách chuyển sang dạng văn bản và lấy ngẫu nhiên một cặp hướng dẫn - phản hồi:

>>> dataset["text"][89]

<s>[INST] In England, what vegetable is referred to as a rocket? [/INST] The species name for "rocket" is "Eruca vesicaria", and it's also sometimes called "eruca".
However, other countries have different names for it:
* Arugula - America
* Garden Rocket or Rocket - Britain, Australia, South Africa, Ireland, New Zealand

Other names include "ruchetta", "rucola", "rucoli", "rugula", "colewoort", and "roquette".

The word transferred from Latin to Italian to English, which might explain the variants with similar pronunciation. </s>

5. Định nghĩa tham số lượng tử hóa

Lượng tử hóa là kỹ thuật mạnh trong máy học để giảm số bit biểu diễn dữ liệu. Điều này thực hiện bằng cách xấp xỉ dữ liệu gốc với ít bit hơn, tạo biểu diễn gọn nhẹ hơn.

Lượng tử hóa có thể giúp giảm bộ nhớ mô hình, cải thiện hiệu năng tính toán và đôi khi còn cải thiện độ chính xác.

compute_dtype = torch.float16

quant_config = BitsAndBytesConfig(
   load_in_4bit=True,
   bnb_4bit_quant_type="nf4",
   bnb_4bit_compute_dtype=compute_dta

Đầu tiên, ta đặt kiểu dữ liệu cho mỗi tensor bằng compute_dtype là float16. Sau đó, dùng BitsAndBytesConfig, ta định nghĩa các tham số lượng tử hóa sau:

  • load_in_4bit=True: Chỉ định dữ liệu đầu vào sẽ được lượng tử hóa về 4 bit.
  • bnb_4bit_compute_dtype=compute_dtype: Chỉ định kiểu dữ liệu dùng cho tính toán, đặt là float16 như trên.
  • bnb_4bit_quant_type="nf4": Chỉ định kiểu lượng tử hóa 4 bit, ở đây là "nf4".

nf4 là một loại lượng tử hóa không đồng đều với 4 bit. Lượng tử hóa không đồng đều đôi khi tốt hơn loại đồng đều cơ bản.

6. Định nghĩa mô hình và tham số

model = AutoModelForCausalLM.from_pretrained(
   base_model,
   quantization_config=quant_config,
   device_map="auto"
)

Bước này tương tự lần tải XGen ban đầu, nhưng lần này chúng ta truyền tham số lượng tử hóa vào quantization_config và đặt device_map là auto để tự động dùng GPU.

7. Tải tokenizer

tokenizer = AutoTokenizer.from_pretrained(base_model, trust_remote_code=True)
tokenizer.pad_token = tokenizer.eos_token
tokenizer.padding_side = "right"

Sau khi tải tokenizer, ta cấu hình tham số padding. Trong NLP, token đệm là ký hiệu đặc biệt không mang nghĩa, được thêm vào mỗi đầu vào để mọi chuỗi có cùng độ dài. Token có độ dài cố định là yêu cầu của nhiều kiến trúc mô hình NLP.

tokenizer.pad_token = tokenizer.eos_token đặt token đệm trùng với token kết thúc câu (EOS). Đây là thực hành phổ biến để mô hình phân biệt kết thúc câu với token đệm. tokenizer.padding_side = "right" chỉ định việc đệm được thêm ở bên phải chuỗi đầu vào.

8. Tham số PEFT

peft_params = LoraConfig(
   lora_alpha=16,
   lora_dropout=0.1,
   r=64,
   bias="none",
   task_type="CAUSAL_LM",
)

Các LLM tiền huấn luyện cần lượng dữ liệu và tài nguyên tính toán khổng lồ để tinh chỉnh. Bằng cách dùng Parameter-efficient Fine-tuning (PEFT), ta chỉ tinh chỉnh một phần nhỏ tham số mô hình, giúp giảm mạnh thời gian chạy. Bạn có thể đọc thêm trong tài liệu chính thức.

Lớp LoraConfig đặt cấu hình cho phương pháp Low-Rank Adaptation. LoRA là một dạng tham số hóa trong PEFT. Tổng thể, đoạn mã trên điều khiển độ mạnh thích nghi của các lớp LoRA, số tham số có thể huấn luyện và các khía cạnh khác của lớp.

9. Thiết lập tham số huấn luyện

training_params = TrainingArguments(
   output_dir="./results",
   num_train_epochs=1,
   per_device_train_batch_size=1,
   gradient_accumulation_steps=1,
   optim="paged_adamw_32bit",
   learning_rate=2e-4,
   weight_decay=0.001,
   fp16=False,
   bf16=False,
   max_grad_norm=0.3,
   max_steps=-1,
   warmup_ratio=0.03,
   group_by_length=True,
   lr_scheduler_type="constant",
)

Ngoài những gì đã định nghĩa, tinh chỉnh XGen cần khoảng chục tham số huấn luyện nữa. Bao gồm các tham số quen thuộc như learning rate, bộ điều chỉnh learning rate, số epoch, bộ tối ưu, cùng một số tham số mới như warmup_ratio, fp16, bf16, weight_decay, v.v.

Để tập trung, chúng ta sẽ không đi sâu vào từng tham số; tôi giới thiệu bài viết xuất sắc về tinh chỉnh LLaMA2 có giải thích chi tiết.

10. Cuối cùng, tinh chỉnh!

Để tinh chỉnh mô hình PEFT, ta sẽ dùng lớp SFTTrainer (Supervised fine-tuning) từ thư viện trl, bước then chốt trong RLHF.

trainer = SFTTrainer(
   model=model,
   train_dataset=dataset,
   peft_config=peft_params,
   dataset_text_field="text",
   max_seq_length=None,
   tokenizer=tokenizer,
   args=training_params,
   packing=False,
)

Để khởi tạo trainer, ta cung cấp mô hình, tập huấn luyện, tham số PEFT, tham số huấn luyện và tokenizer. Để bắt đầu quá trình tinh chỉnh, chỉ cần gọi .train():

trainer.train()

Tùy tham số huấn luyện (đặc biệt số epoch), thời gian huấn luyện có thể từ 15 phút đến vài giờ.

11. Đánh giá

Sau khi huấn luyện xong, ta có thể kiểm thử mô hình đã tinh chỉnh:

prompt = "Who wrote Python?"
pipe = pipeline(task="text-generation", model=model, tokenizer=tokenizer, max_length=200)

result = pipe(f"<s>[INST] {prompt} [/INST]")
print(result[0]['generated_text'])

Trước khi truyền prompt vào model đã tinh chỉnh, ta đưa model và tokenizer vào một pipeline. Hàm pipeline dùng để tải mô hình tiền huấn luyện, tiền xử lý đầu vào bằng tokenizer và áp dụng (nếu có) bước hậu xử lý tùy chỉnh cho văn bản sinh ra.

Ở trên, ta chạy pipeline với prompt định dạng đặc biệt được bao bằng <s>[INST] {prompt} [/INST], đúng như hướng dẫn dùng trong huấn luyện. Đây là kết quả:

<s>[INST] Who wrote Python? [/INST] Python was created by Guido van Rossum, a Dutch computer programmer. He started working on the language in the late 1980s and released the first version in 1991. </s>

Python is a high-level, general-purpose programming language that is widely used in various fields, including data science, machine learning, and web development. It is known for its readability, flexibility, and ease of use, making it a popular choice for beginners and experienced developers alike. </s>

Python is an open-source language, meaning that anyone can access and modify the source code, making it a popular choice for developers who want to contribute to the community. </s>...

12. Lưu mô hình và tokenizer

Khi đã hài lòng với mô hình, ta có thể lưu lại:

trainer.model.save_pretrained(new_model)
trainer.tokenizer.save_pretrained(new_model)

Bạn có thể tải lại bằng lớp AutoModelForCausalLM như sau:

fine_tuned_xgen = AutoModelForCausalLM.from_pretrained(new_model, ...)

Kết luận

Bắt đầu với các Mô hình ngôn ngữ lớn (LLM) như XGen 7B của Salesforce khá đơn giản, nhưng tùy biến cho nhu cầu cụ thể thì phức tạp hơn. Trải nghiệm tinh chỉnh XGen 7B trên một tập dữ liệu hướng dẫn nhỏ minh họa thách thức này. Việc thích ứng mô hình cho nhiều tác vụ đòi hỏi truy cập các tập dữ liệu phù hợp (qua thư viện datasets của Hugging Face) và tài nguyên tính toán đủ để huấn luyện mô hình 7 tỷ tham số trên các tập dữ liệu đó.

Quy trình tinh chỉnh có thể tóm tắt như sau:

  1. Cài đặt thư viện
  2. Import các mô-đun cần thiết
  3. Định nghĩa cấu hình tổng quát
  4. Tải tập dữ liệu để tinh chỉnh
  5. Định nghĩa tham số lượng tử hóa với bitsandbytes
  6. Định nghĩa mô hình và tham số khởi tạo qua transformers
  7. Tải tokenizer phù hợp với mô hình
  8. Định nghĩa tham số PEFT với LoRA bằng LoraConfig
  9. Thiết lập tham số huấn luyện qua transformers
  10. Tinh chỉnh mô hình với SFTTrainer từ trl
  11. Kiểm thử/đánh giá mô hình với prompt mẫu
  12. Lưu mô hình và tokenizer để dùng sau

Nếu một số khái niệm hoặc đoạn mã vẫn còn lạ lẫm, tôi khuyến nghị các tài nguyên xuất sắc sau:

Cảm ơn bạn đã đọc!

Bexruz (Bex) Tuychiev

Tác giả

Bexruz (Bex) Tuychiev

Tôi là người sáng tạo nội dung về khoa học dữ liệu với hơn 2 năm kinh nghiệm và là một trong những tài khoản có lượng người theo dõi lớn nhất trên Medium. Tôi thích viết các bài chuyên sâu về AI và ML với chút giọng điệu mỉa mai, vì bạn cũng phải làm gì đó để chúng bớt khô khan. Tôi đã xuất bản hơn 130 bài viết và một khóa học trên DataCamp, cùng với một khóa nữa đang được thực hiện. Nội dung của tôi đã được hơn 5 triệu lượt xem, trong đó 20 nghìn người đã trở thành người theo dõi trên cả Medium và LinkedIn. 

Chủ đề

Liên quan