Lightweight Fine-Tuning: Một hướng đi cho những người làm AI trong kỉ nguyên của các Super Large Models (Phần 1)
Note: Tiêu đề và nội dung của bài viết này được lấy cảm hứng từ bài viết của sếp mình: "Hướng đi nào cho những người làm AI trong kỉ nguyên của các Super Large Models?". Recommend các bạn nên đọc để tìm thêm những hướng phát triển trong tương lai (nếu các bạn là AI Engineer).
Tất nhiên, khi sếp đã đặt vấn đề thì mình cũng muốn viết 1 bài để phân tích sâu thêm một số khía cạnh, trường hợp ở đây là về hướng đi "Đứng trên vai người khổng lồ" và "Tập trung vào specific domain hoặc private data"
Yên tâm, bài viết này sẽ không nặng kỹ thuật lắm đâu nên hi vọng các bạn có thể đồng hành cùng mình đến cuối (do có 2 phần mà)🤘
1. Mở đầu
Generative AI đã mở ra một kỷ nguyên hoàn toàn mới của AI, một sự nở rộ của những mô hình ngôn ngữ lớn (Large Langue Model - LLM), những mô hình mà mình vẫn hay gọi vui là "Text-To-Anything" với khả năng vượt trội, có thể thay thế con người ở nhiều lĩnh vực. Trong kỷ nguyên này, một cuộc chiến công nghệ của những Big Tech đang nổ ra, với tiền, với công nghệ, với hạ tầng, với lượng dữ liệu khổng lồ là điểm mấu chốt cho chiến thắng: OpenAI, Microsoft, Google, Meta, IBM, ... Và dễ thấy, bất cứ tiêu chí nào trong 4 tiêu chí trên, chúng ta đều không có cửa chen chân vào.
Một trong những hướng đi phù hợp nhất hiện nay là "Đứng trên vai người khổng lồ", tận dụng lượng thông tin đã được đào tạo của LLM để ứng dụng vào các domain nhỏ hơn, hoặc để bổ sung những nguồn dữ liệu hiếm hoi nhưng đặc thù (chưa được public) của chúng ta. Hai cách triển khai đem lại kết quả tốt nhất là Prompt Engineering (hay in-context learning) và Adatption (Thích ứng). Điểm qua một số thông tin thôi nào!
-
Prompt Engineering
Chúng ta có thể dễ dàng thấy rằng các mô hình Generative AI như ChatGPT, GPT-4, DALLE-2, Midjourney, ... có 1 điểm chung: Đầu vào là Text (Text to anything). Một thuật ngữ được dùng cho những text input này là Prompt (Lời nhắc)
Và do input là ngôn ngữ tự nhiên mà con người sử dụng, nó tồn tại những nhập nhằng nhất định. Việc cùng một nội dung nhưng cách diễn đạt khác nhau sẽ dẫn đến kết quả sinh ra từ mô hình rất khác nhau: có thể rất tốt, hoặc tệ hơn bao giờ hết. Như một lẽ dĩ nhiên, một hướng nghiên cứu, một ngành nghề mới ra đời: Prompt Engineering
Prompt engineering: còn được gọi là Prompt Design, đề cập đến các phương pháp giao tiếp với LLM để điều khiển hành vi của nó nhằm đạt được kết quả mong muốn mà không cần cập nhật trọng số mô hình. Đây là một môn khoa học thực nghiệm và hiệu quả của các phương pháp thiết kế lời nhắc có thể khác nhau tùy thuộc vào mô hình, do đó đòi hỏi nhiều thử nghiệm và kinh nghiệm.
Một cách dễ hình dung, hãy coi ChatGPT, GPT-4, ... như những máy nén thông tin, tri thức nhân loại diễn đạt trên Internet sẽ được tổ chức dưới dạng tham số của mạng neuron. Để sử dụng những tri thức này, ta cần cung cấp cho nó văn cảnh và yêu cầu nó trả lời theo một định dạng nào đấy (giải nén có điều kiện). Prompt Engineering chính là chìa khóa cho vấn đề giải nén này.
Prompt Engineering là một ngành nghề đầy hứa hẹn trong tương lai, không cần quá nhiều kiến thức về công nghệ lõi của mô hình, chỉ cần nắm bắt được việc sử dụng câu từ, kiến thức chuyên môn nhất định và thực nghiệm thật nhiều. Tuy nhiên, trong phạm vi bài viết này, đây không phải điều mình muốn đào sâu, thay vào đó, mình sẽ cung cấp một số nguồn tham khảo chất lượng cho mọi người:
-
Adaption
Prompt Engineering chỉ tinh chỉnh prompt mà không can thiệp trực tiếp vào mô hình. Hướng đi này cho phép triển khai ứng dụng nhanh, thậm chí với những mô hình close-source như ChatGPT, GPT4, ... thì nó là hướng đi duy nhất. Nhưng với những trường hợp domain hẹp, dữ liệu private hay task đặc thù, prompt engineering không giúp ích được quá nhiều, đó là khi chúng ta cần đến Adaption.
Adaption (thích ứng): là quá trình tinh chỉnh hoặc sửa đổi một mô hình ngôn ngữ được tiền huấn luyện để thực hiện một nhiệm vụ cụ thể.
Tại sao lại cần adaption?
- Những mô hình ngôn ngữ lớn (LLM) được training một cách tổng quát, không cố gắng thực hiện một nhiệm vụ nào cả (task-agnostic)
- Downstream task đôi khi có thể rất khác so với output của các mô hình ngôn ngữ: về định dạng (formating), về topic (topic shift), hay tính cập nhật dữ liệu thường xuyên hoặc dữ liệu đặc thù không được public (temporal shift).
Thông thường, có nhiều cách thực hiện adaption, phổ biến nhất có thể kể đến: Probing, Finetuning và Lightweight Finetuning (nhân vật chính của bài viết này). Các bạn có thể đọc thêm tại Lecture Note của CS324, một khóa học về Mô hình Ngôn ngữ Lớn tại Đại học Stanford
2. Adaption
Như đã trình bày ở trên, đôi khi chúng ta cần adapt các mô hình ngôn ngữ lớn vào các downstream task khác nhau, có thể rất khác biệt so với việc mô hình hóa ngôn ngữ. Và phần này sẽ nhắc sơ qua 1 chút về các hướng triển khai (lại thêm một phần mở bài phụ trước khi đến với chủ đề chính ...)
-
Probing (Dò tìm)
Probing là phương pháp thêm một task-specific prediction head vào kiến trúc LLM. Bằng việc coi mô hình ngôn ngữ như là một trích xuất biểu diễn tốt, chúng ta sẽ đóng băng (freeze) toàn bộ trọng số của LLM, và chỉ cập nhật duy nhất trọng số của prediction head dựa trên loss function định nghĩa cho task.
Có thể các bạn sẽ thấy cách triển khai này khá quen, chỉ là cái tên lạ lạ (Do mình lấy từ Lecture Note của CS324), thì nó chính là hướng adapt siêu kinh điển, chuyên được dùng với họ các mô hình BERT trước đây. Tất nhiên phương pháp này cũng có nhược điểm là có xu hướng giới hạn khả năng biểu đạt của mô hình.
-
Fine-tuning (Tinh chỉnh)
Fine-tuning là một kỹ thuật huấn luyện lại một mô hình ngôn ngữ lớn (LLM) để thích ứng với một nhiệm vụ cụ thể . Fine-tuning bao gồm việc điều chỉnh tất cả các trọng số của mô hình LLM dựa trên một tập dữ liệu có nhãn cho nhiệm vụ đó . Fine-tuning có thể đạt được hiệu suất cao trên các downstream task, nhưng cũng có một số nhược điểm, chẳng hạn như:
- Fine-tuning cần nhiều tài nguyên tính toán và bộ nhớ hơn các kỹ thuật prompt tuning, vì nó phải cập nhật hàng tỷ hoặc hàng nghìn tỷ trọng số của mô hình ngôn ngữ lớn.
- Fine-tuning có thể làm mất đi các thông tin học trước đó của LLM, do đó làm giảm hiệu suất trên các nhiệm vụ khác nhau hoặc các miền khác nhau.
- Fine-tuning cần phải lưu trữ một bản sao của mô hình LLM cho mỗi nhiệm vụ, do đó làm tăng chi phí chia sẻ và phục vụ các mô hình lớn.
-
Lightweight fine-tuning (Tinh chỉnh nhẹ)
Lightweight fine-tuning, trước hết cũng là một kĩ thuật fine-tuning. Tuy nhiên bên cạnh việc adapt với downstream task, lightweight fine-tuning cũng tập trung giải quyết vấn đề chi phí tính toán và lưu trữ của fine-tuning, là một trong những hướng nghiên cứu được quan tâm nhất hiện nay khi mà kích thước của LLM đang ngày càng lớn hơn bao giờ hết.
Lightweight fine-tuning là phương pháp tinh chỉnh một mô hình LLM để phù hợp với một nhiệm vụ hoặc lĩnh vực cụ thể với sự thay đổi tối thiểu các tham số của mô hình gốc. Nó có thể giảm chi phí tính toán và dung lượng bộ nhớ của việc tinh chỉnh, trong khi giữ lại khả năng tổng quát hóa của mô hình đã được tiền huấn luyện.
Có nhiều loại phương pháp lightweight fine-tuning khác nhau, có thể tạm chia thành adapter-based, prompt-based hoặc kết hợp cả hai. Trong phần 1 này, mình sẽ trình bày về prompt-based trước, cụ thể là: P-Tuning, Prompt Tuning và Prefix Tuning
3. P-Tuning, Prompt Tuning và Prefix Tuning
-
P-Tuning
- Paper: GPT Understands, Too (2021)
- Link: https://arxiv.org/abs/2103.10385
- Github: https://github.com/THUDM/P-tuning
P-tuning là một kỹ thuật tinh chỉnh hiệu quả về tham số giúp tạo ra các nhắc liên tục (continuous prompts) cho các mô hình ngôn ngữ lớn (LLM). Ý tưởng của P-tuning là tự động hóa và tối ưu quá trình design prompt thủ công. P-Tuning sẽ thêm một số learnable parameters (prompt embeddings) vào input, và quy định những prompt templates cho từng task cụ thể. Những embeddings này sau đó sẽ được cập nhật trong quá trình training thông qua Prompt Encoder (ở đây là mạng LSTM và MLP) dựa trên loss function được định nghĩa cho từng downstream task.
P-tuning có ưu điểm là không cần thiết kế prompt thủ công (bằng cách tự động tìm kiếm các prompt tốt hơn trong không gian liên tục), không làm thay đổi LLM và không cần nhiều dữ liệu huấn luyện.
Một số lợi thế của P-tuning so với fine-tuning có thể nhắc qua như:
- P-tuning chỉ cần tinh chỉnh một lượng nhỏ các tham số liên quan đến prompt, trong khi fine-tuning cần tinh chỉnh toàn bộ mô hình ngôn ngữ lớn. Điều này giúp tiết kiệm thời gian và tài nguyên tính toán.
- P-tuning không làm thay đổi mô hình ngôn ngữ lớn, do đó giữ được khả năng học trước của nó. Điều này có thể giúp tránh hiện tượng overfiting (quá khớp) và cải thiện hiệu suất trên các nhiệm vụ khác nhau.
- P-tuning không cần thiết kế prompt thủ công, mà có thể sử dụng các token chưa sử dụng để tạo ra các continuous prompts. Điều này giúp giảm thiểu sự phụ thuộc vào kỹ thuật của người dùng và tăng tính tự động hóa của quá trình tinh chỉnh.
Ngoài ra, cũng cần chú ý một số nhược điểm của P-Tuning:
- P-tuning có thể không thể khai thác hết tiềm năng của các mô hình ngôn ngữ lớn, vì nó chỉ tinh chỉnh một phần nhỏ các tham số. Fine-tuning có thể đạt được hiệu suất tốt hơn bằng cách điều chỉnh toàn bộ mô hình cho nhiệm vụ .
- P-tuning có thể không hoạt động tốt cho các nhiệm vụ rất khác biệt so với mục tiêu huấn luyện trước đó của các mô hình LLM, chẳng hạn như chú thích ảnh hoặc nhận dạng giọng nói. Fine-tuning có thể phù hợp hơn cho các nhiệm vụ này vì nó có thể thay đổi cấu trúc và đầu ra của mô hình
-
Prompt Tuning
- Paper: The Power of Scale for Parameter-Efficient Prompt Tuning (2021)
- Link: https://arxiv.org/abs/2104.08691
- Github: Không (nhưng có thể tham khảo 1 bản implementation của Nvidia)
Về cơ bản thì Prompt Tuning mang cùng tư tưởng với P-Tuning, cố gắng tự động tìm kiếm và đưa ra một prompt biểu diễn tốt hơn. Ở đây là "soft prompt", sự kết hợp giữa embedding của input token với một trainable tensor - cái mà có thể tối ưu thông qua quá trình lan truyền ngược để tăng performance trên từng downstream task.
Nếu phải tìm điểm khác nhau thì Prompt Tuning chỉ khác P-Tuning duy nhất ở là architecture được sử dụng để tune soft prompts trong quá trình training
- Ở prompt tuning, soft prompts được khởi tạo như 1 ma trận 2D (total_virtual_tokens X hidden_size) (có khá nhiều chiến lược khởi tạo). Với mỗi downstream task, model sẽ khởi tạo 1 ma trận 2D embedding riêng, và không share chung hệ số trong suốt quá trình training hay inference. Việc training là việc cập nhật giá trị cho từng ma trận embedding này, dựa trên loss fucntion của từng task.
- Ở P-tuning, một mạng LSTM được sử dụng để sinh ra virtual token embeddings. Trọng số của mạng LSTM sẽ được khởi tạo ngẫu nhiên và được cập nhật sau mỗi bước training. Trọng số này cũng được share cho các downstream task, nhưng cần đảm bảo virtual token embeddings cho mỗi task là duy nhất.
Prompt Tuning thường cần nhiều virtual token hơn cho mỗi tác vụ để đạt được kết quả tốt nhưng sử dụng số lượng tham số thấp hơn nhiều so với P-tuning (chủ yếu do mạng LSTM của P-Tuning tương đối nặng).
Một ưu điểm khác của Prompt tuning là ở phần "mixed-task inference". P-Tuning chia sẻ hệ số của LSTM cho toàn bộ task, nên trong trường hợp các task có liên quan bổ trợ nhau, đôi khi có thể insight được share giữa các task. Ngược lại, nếu các task hoàn toàn khác biệt nhau, performance của P-Tuning sẽ kém hơn Prompt Tuning rất nhiều.
Tất nhiên, việc so sánh ở trên không có nghĩa là chúng ta chỉ có thể chọn 1 trong 2. Prompt Tuning và P-Tuning hoàn toàn có thể được sử dụng kết hợp để bổ trợ cho nhau.
-
Prefix Tuning
- Paper: Prefix-Tuning: Optimizing Continuous Prompts for Generation (2021)
- Link: https://aclanthology.org/2021.acl-long.353/
- Github: https://github.com/XiangLi1999/PrefixTuning
Prefix-tuning lấy cảm hứng từ việc tạo ra các prompt cho mô hình ngôn ngữ, cho phép các token tiếp theo chú ý đến prefix như thể nó là các "token ảo" (virtual tokens). Prefix-tuning giữ nguyên các trọng số của mô hình LLM và thay vào đó tối ưu hóa một chuỗi các vector cụ thể cho nhiệm vụ (continuous task-specific vectors), gọi là prefix. Tác giả chỉ ra rằng chỉ bằng cách học 0.1% số tham số, prefix-tuning đạt được hiệu năng tương đương với tinh chỉnh trên toàn bộ dữ liệu, vượt trội hơn finetuning trong các cài đặt dữ liệu ít (low-data settings), và khả năng ngoại suy tốt hơn đối với các ví dụ có chủ đề chưa xuất hiện trong quá trình huấn luyện.
Prefix khác gì với Prompt Tuning và P-Tuning? Trước hết, chúng ta cần thấy là 3 phương pháp này cùng chung quan điểm, trong paper của prefix-tuning, tác giả còn gọi chung là nhóm "P*-tuning". Tuy nhiên, prefix-tuning có 1 số điểm đặc biệt sau:
- Mặc dù cùng thêm learnable tensor nhưng prefix-tuning tiến hành thêm vào toàn bộ transformer block thay vì chỉ thêm vào embedding layer như prompt tuning. Do đó, prefix tuning giúp kiểm soát tốt hơn quá trình sinh output và tăng hiệu quả của mô hình (Deep Prompt Tuning)
- Nhóm tác giả của prefix-tuning cũng nhận thấy rằng, việc cập nhật trực tiếp learnable tensor có thể khiến việc tối ưu hóa không ổn định và làm giảm nhẹ hiệu suất. Do đó, nhóm tác giả sử dụng 1 phương pháp reparametrize, phân tách tensor với là một tensor có cùng prefix length, nhưng số chiều nhỏ hơn. Khi đó, tham số cần tối ưu sẽ là ma trận và trọng số của mạng MLP, nhưng sau cùng sẽ dùng để tổng hợp thành ma trận và lưu lại.
Gần đây nhất, paper P-Tuning v2: Prompt Tuning Can Be Comparable to Fine-tuning Universally Across Scales and Tasks (2022) kết hợp tư tưởng Deep Prompt Tuning của prefix-tuning với P-Tuning, cũng đem lại những kết quả vượt trội
4. Tạm kết
Bài viết đến đây cũng tương đối dài rồi, nên mình sẽ tạm kết phần 1 ở đây. Tóm tắt lại một chút cả một đoạn trình bày dài ngoằng phía trên:
- Generative AI phát triển, thời đại của những LLM nở rộ, và đây là chiến trường cạnh tranh của những Big Tech mà chúng ta không có cơ hội chen chân vào. Một trong những hướng đi phù hợp nhất là "Đứng trên vai người khổng lồ"
- Để tận dụng sức mạnh của những LLM, chúng ta có thể sử dụng Prompt Engineering để thực hiện in-content learning, hoặc Adaptation để đạt được những kết quả tốt hơn với downstream task có domain hẹp hơn và dữ liệu đặc thù.
- Lightweight Finetuning (hay Parameter-Efficient Finetuning) là một hướng nghiên cứu mới hiện nay, thực hiện finetune LLM đồng thời cố gắng tối ưu vấn đề chi phí tính toán và lưu trữ của mô hình. Các phương pháp trong hướng này có thể chia thành Prompt-based, Adapter-based hoặc kết hợp cả hai.
- 3 phương pháp: P-Tuning, Prompt Tuning và Prefix Tuning, cùng chung tư tưởng tự động hóa và tối ưu quá trình design prompt thủ công, giúp đạt được performance tốt hơn trên từng downstream task. Ý tưởng chính là dựa trên việc sử dụng các learnable tensor có thể được tối ưu trong quá trình search trong không gian liên tục.
Trong phần 2, mình sẽ trình bày về các phương pháp Adapter-based Lightweight Finetuning (Adapter, LoRA, ...) cũng như giới thiệu 1 thư viện tích hợp các phương pháp lightweight FInetuning cực kỳ hữu ích của huggingface. Sẽ có khá nhiều điều thú vị ở phần sau, nên nhớ đón đợi nha 😄
Tài liệu tham khảo
- GPT Understands, Too (Paper)
- The Power of Scale for Parameter-Efficient Prompt Tuning (Paper)
- Prefix-Tuning: Optimizing Continuous Prompts for Generation (Paper)
- P-Tuning v2: Prompt Tuning Can Be Comparable to Fine-tuning Universally Across Scales and Tasks (Paper)
- CS324 Lecture Note
- Prompt Learning - NVIDIA
- Understanding Parameter-Efficient LLM Finetuning: Prompt Tuning And Prefix Tuning
- và một số nguồn tham khảo khác ...
All rights reserved