LangChain: Blog
85

Thủ thuật

Hướng dẫn tối ưu hóa tinh chỉnh LLM với LangSmith: Từ quản lý dữ liệu đến đánh giá hiệu năng

(giờ Việt Nam)

Tóm tắt AI

Bài viết cung cấp quy trình toàn diện sử dụng LangSmith để quản lý dữ liệu, tinh chỉnh và kiểm chứng hiệu quả các mô hình LLM như LLaMA2 và GPT-3.5, giúp nhà phát triển tối ưu hóa mô hình một cách hệ thống.

Bản dịch AI

Using LangSmith to Support Fine-tuning

Tóm tắt

Chúng tôi đã tạo một hướng dẫn về tinh chỉnh (fine-tuning) và đánh giá các LLM, sử dụng LangSmith để quản lý tập dữ liệu và thực hiện đánh giá. Chúng tôi thực hiện điều này trên cả LLM mã nguồn mở thông qua CoLab và HuggingFace để huấn luyện mô hình, cũng như sử dụng dịch vụ tinh chỉnh mới của OpenAI. Với tư cách là một trường hợp thử nghiệm, chúng tôi đã tinh chỉnh LLaMA2-7b-chat và gpt-3.5-turbo cho một tác vụ trích xuất (trích xuất bộ ba tri thức - knowledge graph triple extraction) bằng cách sử dụng dữ liệu huấn luyện được xuất từ LangSmith, đồng thời đánh giá kết quả bằng chính LangSmith. Hướng dẫn trên CoLab có tại đây.

Bối cảnh

Mối quan tâm đến việc tinh chỉnh mô hình đã tăng nhanh trong vài tuần qua. Điều này chủ yếu xuất phát từ hai nguyên nhân.

Thứ nhất, hệ sinh thái LLM mã nguồn mở đã phát triển vượt bậc, tiến triển từ các LLM mã nguồn mở vốn thua kém xa so với các mô hình tiên tiến nhất (SOTA) sang các LLM gần đạt chuẩn SOTA (ví dụ: Llama-2) có thể chạy trên máy tính cá nhân chỉ trong khoảng 1 năm! Động lực của sự tiến bộ này bao gồm kho dữ liệu huấn luyện ngày càng lớn (trục x, bên dưới) và việc tinh chỉnh (trục y) để mô hình tuân thủ chỉ dẫn và đưa ra phản hồi phù hợp với con người hơn. Các mô hình nền tảng mã nguồn mở hiệu năng cao mang lại nhiều lợi ích như tiết kiệm chi phí (ví dụ: cho các tác vụ tốn nhiều token), bảo mật, và - thông qua tinh chỉnh - cơ hội vượt qua các LLM SOTA với các mô hình mã nguồn mở nhỏ gọn hơn nhiều cho các tác vụ chuyên biệt.

Thứ hai, nhà cung cấp LLM hàng đầu là OpenAI đã phát hành hỗ trợ tinh chỉnh cho gpt-3.5-turbo (và các mô hình khác). Trước đây, việc tinh chỉnh chỉ khả dụng cho các mô hình cũ hơn. Những mô hình này không có khả năng mạnh mẽ như các mô hình mới, nghĩa là ngay cả sau khi tinh chỉnh, chúng thường không cạnh tranh được với GPT-3.5 và các ví dụ few-shot. Giờ đây, khi các mô hình mới hơn có thể được tinh chỉnh, nhiều người kỳ vọng điều này sẽ thay đổi.

Một số ý kiến cho rằng các tổ chức có thể chọn sử dụng nhiều LLM chuyên biệt được tinh chỉnh từ các mô hình nền tảng mã nguồn mở thay vì một mô hình tổng quát khổng lồ duy nhất. Với suy nghĩ này cùng sự hỗ trợ từ các thư viện như HuggingFace, bạn có thể tò mò về thời điểm và cách thức tinh chỉnh. Hướng dẫn này cung cấp cái nhìn tổng quan và cho thấy cách LangSmith có thể hỗ trợ quy trình đó.

Khi nào cần tinh chỉnh

LLM có thể học kiến thức mới theo ít nhất hai cách: cập nhật trọng số (ví dụ: tiền huấn luyện hoặc tinh chỉnh) hoặc thông qua prompt (ví dụ: truy xuất tăng cường thế hệ - RAG). Trọng số mô hình giống như bộ nhớ dài hạn, trong khi prompt giống như bộ nhớ ngắn hạn. Sách hướng dẫn (cookbook) của OpenAI có một phép so sánh hữu ích: Khi bạn tinh chỉnh một mô hình, nó giống như việc ôn thi cho một kỳ thi diễn ra sau một tuần. Khi bạn chèn kiến thức vào prompt (ví dụ: thông qua truy xuất), nó giống như việc làm bài thi với tài liệu mở.

Với suy nghĩ này, tinh chỉnh không được khuyến khích để dạy LLM kiến thức mới hoặc ghi nhớ sự kiện; bài nói chuyện này từ John Schulman của OpenAI lưu ý rằng tinh chỉnh có thể làm tăng tình trạng ảo giác (hallucinations). Tinh chỉnh phù hợp hơn để dạy các tác vụ chuyên biệt, nhưng cần được cân nhắc so với việc sử dụng prompt hoặc RAG. Như đã thảo luận ở đây, tinh chỉnh có thể hữu ích cho các tác vụ được xác định rõ ràng với nhiều ví dụ và/hoặc các LLM thiếu khả năng học trong ngữ cảnh (in-context learning) cho việc prompt few-shot. Blog của Anyscale đã tóm tắt những điểm này rất tốt: tinh chỉnh là để định hình (form), không phải để nạp dữ liệu thực tế (facts).

Cách tinh chỉnh

Có rất nhiều công thức tinh chỉnh LLaMA hữu ích đã được phát hành cho các tác vụ như trò chuyện, sử dụng một tập hợp con của kho dữ liệu OpenAssistant trên HuggingFace. Đáng chú ý, các công thức này hoạt động trên một GPU CoLab duy nhất, giúp quy trình làm việc trở nên dễ tiếp cận. Tuy nhiên, hai trong số những điểm khó khăn lớn nhất còn lại trong việc tinh chỉnh là thu thập/làm sạch tập dữ liệu và đánh giá. Dưới đây, chúng tôi chỉ ra cách LangSmith có thể được sử dụng để giải quyết cả hai vấn đề này (màu xanh lá cây, bên dưới).

Tác vụ

Các tác vụ như phân loại/gắn thẻ hoặc trích xuất rất phù hợp để tinh chỉnh; Anyscale đã báo cáo kết quả đầy hứa hẹn (vượt qua GPT-4) bằng cách tinh chỉnh các LLM LLaMA 7B và 13B cho các tác vụ trích xuất, chuyển đổi văn bản sang SQL và QA. Làm trường hợp thử nghiệm, chúng tôi chọn trích xuất các bộ ba tri thức dưới dạng (chủ thể, quan hệ, đối tượng) từ văn bản: chủ thể và đối tượng là các thực thể, còn quan hệ là thuộc tính hoặc kết nối giữa chúng. Các bộ ba này sau đó có thể được sử dụng để xây dựng đồ thị tri thức, các cơ sở dữ liệu lưu trữ thông tin về thực thể và mối quan hệ của chúng. Chúng tôi đã xây dựng một ứng dụng Streamlit công khai để trích xuất bộ ba từ văn bản đầu vào của người dùng nhằm khám phá khả năng trích xuất bộ ba bằng gọi hàm (function calling) của các LLM (GPT-3.5 hoặc 4). Song song đó, chúng tôi đã tinh chỉnh LLaMA2-7b-chat và GPT-3.5 cho tác vụ này bằng cách sử dụng các tập dữ liệu công khai.

Tập dữ liệu

Thu thập và làm sạch tập dữ liệu thường là một nhiệm vụ đầy thách thức khi huấn luyện LLM. Khi một dự án được thiết lập trong LangSmith, các thế hệ (generations) sẽ được tự động ghi lại, giúp dễ dàng thu thập một lượng lớn dữ liệu. LangSmith cung cấp giao diện có thể truy vấn để bạn sử dụng các bộ lọc phản hồi của người dùng, thẻ và các số liệu khác nhằm chọn lọc các trường hợp chất lượng kém, sửa lỗi đầu ra trong ứng dụng và lưu vào các tập dữ liệu mà bạn có thể sử dụng để cải thiện kết quả của mô hình (xem bên dưới).

Ví dụ, chúng tôi đã tạo các tập dữ liệu huấn luyện và kiểm tra trên LangSmith từ các bộ ba đồ thị tri thức trong các tập dữ liệu công khai BenchIE và CarbIE; chúng tôi đã chuyển đổi chúng sang định dạng JSON chung với mỗi bộ ba được biểu diễn dưới dạng {s: chủ thể, object: đối tượng, relation: quan hệ} và chia ngẫu nhiên dữ liệu kết hợp thành một tập huấn luyện gồm ~1500 câu được gán nhãn và một tập kiểm tra gồm 100 câu. CoLab cho thấy cách tải các tập dữ liệu LangSmith một cách dễ dàng. Sau khi tải xong, chúng tôi tạo các chỉ dẫn để tinh chỉnh bằng cách sử dụng system prompt bên dưới và các token chỉ dẫn LLaMA (như đã thực hiện ở đây):

"bạn là một mô hình có nhiệm vụ trích xuất các bộ ba đồ thị tri thức từ văn bản được cung cấp. ""Các bộ ba bao gồm:\n""- \"s\": chủ thể, là thực thể chính mà câu nói đề cập đến.\n""- \"object\": đối tượng, là thực thể hoặc khái niệm mà chủ thể có liên quan.\n""- \"relation\": mối quan hệ giữa chủ thể và đối tượng. ""Với một câu đầu vào, hãy xuất ra các bộ ba đại diện cho kiến thức chứa trong câu đó."

Lượng tử hóa (Quantization)

Như đã trình bày trong hướng dẫn tuyệt vời tại đây, chúng tôi tinh chỉnh một mô hình LLaMA chat 7B tham số. Chúng tôi muốn thực hiện điều này trên một GPU duy nhất (hướng dẫn HuggingFace tại đây), điều này đặt ra một thách thức: nếu mỗi tham số là 32 bit, một mô hình LLaMA2 7B tham số sẽ chiếm 28GB, vượt quá VRAM của một chiếc T4 (16GB). Để giải quyết vấn đề này, chúng tôi lượng tử hóa các tham số mô hình, nghĩa là gom nhóm các giá trị (ví dụ: thành 16 giá trị trong trường hợp lượng tử hóa 4-bit), giúp giảm bộ nhớ cần thiết để lưu trữ mô hình (7B * 4 bit / tham số = 3.5GB) khoảng 8 lần.

LoRA và qLoRA

Với mô hình đã nằm trong bộ nhớ, chúng ta vẫn cần một cách để tinh chỉnh trong giới hạn tài nguyên GPU còn lại. Đối với điều này, tinh chỉnh hiệu quả tham số (PEFT) là một phương pháp phổ biến: LoRA đóng băng các trọng số mô hình đã được tiền huấn luyện và chèn các ma trận phân rã hạng có thể huấn luyện vào từng lớp của kiến trúc mô hình (xem tại đây), giúp giảm số lượng tham số cần huấn luyện để tinh chỉnh (ví dụ: ~1% tổng số mô hình). qLoRA mở rộng điều này bằng cách đóng băng các trọng số đã được lượng tử hóa. Trong quá trình tinh chỉnh, các trọng số bị đóng băng được giải lượng tử hóa cho các bước truyền xuôi và truyền ngược, nhưng chỉ các bộ điều hợp (adapters) LoRA (tập hợp nhỏ) mới được lưu trong bộ nhớ, giúp giảm dấu chân của mô hình đã tinh chỉnh.

Huấn luyện

Chúng tôi bắt đầu với mô hình LLaMA-7b chat đã được tiền huấn luyện là llama-2-7b-chat-hf và tinh chỉnh trên ~1500 chỉ dẫn trong CoLab trên một chiếc A100. Về cấu hình huấn luyện, chúng tôi sử dụng các tham số tinh chỉnh LLaMA từ đây: BitsAndBytes tải mô hình cơ sở với độ chính xác 4-bit nhưng các bước truyền xuôi và truyền ngược ở định dạng fp16. Chúng tôi sử dụng Tinh chỉnh có giám sát (SFT) để tinh chỉnh dựa trên các chỉ dẫn của mình, quy trình này khá nhanh (< 15 phút) trên một chiếc A100 cho khối lượng dữ liệu nhỏ này.

Tinh chỉnh OpenAI

Để tinh chỉnh mô hình chat GPT-3.5-turbo của OpenAI, chúng tôi đã chọn 50 ví dụ từ tập dữ liệu huấn luyện và chuyển đổi chúng thành danh sách các tin nhắn trò chuyện theo định dạng mong đợi:

{ "messages": [ { "role": "user", "content": "Trích xuất các bộ ba từ câu sau:\n\n{sentence}"}, { "role": "assistant", "content": "{triples}" },...]}

Vì mô hình cơ sở vốn đã rất mạnh mẽ, chúng tôi không cần nhiều dữ liệu để đạt được hành vi mong muốn. Dữ liệu huấn luyện nhằm mục đích hướng dẫn mô hình luôn tạo ra định dạng và phong cách chính xác thay vì dạy nó những thông tin quan trọng. Như chúng ta sẽ thấy trong phần đánh giá bên dưới, 50 ví dụ huấn luyện là đủ để mô hình dự đoán các bộ ba theo đúng định dạng mỗi lần.

Chúng tôi đã tải dữ liệu tinh chỉnh lên thông qua SDK openai và sử dụng mô hình kết quả trực tiếp trong lớp ChatOpenAI của LangChain. Mô hình đã tinh chỉnh có thể được sử dụng trực tiếp:

from langchain.chat_models import ChatOpenAIllm = ChatOpenAI(model="ft:gpt-3.5-turbo-0613:{openaiOrg}::{modelId}")

llm = ChatOpenAI(model="ft:gpt-3.5-turbo-0613:{openaiOrg}::{modelId}")

Toàn bộ quá trình chỉ mất vài phút và không yêu cầu thay đổi mã trong chuỗi (chain) của chúng tôi, ngoại trừ việc loại bỏ nhu cầu thêm các ví dụ few-shot vào mẫu prompt. Sau đó, chúng tôi đã so sánh mô hình này với các mô hình khác để định lượng hiệu suất của nó. Bạn có thể xem ví dụ về toàn bộ quá trình trong notebook CoLab của chúng tôi.

Đánh giá

Chúng tôi đã đánh giá từng mô hình bằng cách sử dụng LangSmith, áp dụng một trình đánh giá LLM (GPT-4) để chấm điểm từng dự đoán, trình đánh giá này được hướng dẫn để xác định các sai lệch thực tế giữa các nhãn và các bộ ba được dự đoán. Điều này sẽ phạt kết quả khi nó dự đoán các bộ ba không có trong nhãn hoặc khi dự đoán không bao gồm một bộ ba, nhưng nó sẽ khoan dung nếu cách diễn đạt chính xác của đối tượng hoặc quan hệ khác biệt theo cách không làm thay đổi ý nghĩa. Trình đánh giá chấm điểm kết quả trên thang điểm từ 0-100. Chúng tôi đã chạy các đánh giá trong CoLab để dễ dàng cấu hình trình đánh giá tùy chỉnh và các chuỗi để kiểm tra.

Bảng dưới đây hiển thị kết quả đánh giá cho mô hình llama base chat và biến thể đã tinh chỉnh. Để so sánh, chúng tôi cũng đã đo điểm chuẩn 3 chuỗi sử dụng các mô hình chat của OpenAI: gpt-3.5-turbo sử dụng prompt few-shot, một mô hình gpt-3.5-turbo được tinh chỉnh trên 50 điểm dữ liệu huấn luyện và một chuỗi gpt-4 few-shot:

llama-2 đã tinh chỉnh

Đọc bài gốc

Bài viết được AI dịch và tổng hợp tự động từ LangChain: Blog. Liên kết bài gốc ở phía trên. Dữ liệu đồng bộ qua API công khai được ghi nguồn tại AI HOT (canonical) ↗. AIHOT.vn luôn dẫn nguồn đầy đủ — nếu bạn thấy điểm cần chỉnh sửa, hãy gửi ý kiến tại trang phản hồi.