Mô hình và nền tảng AI

Tối ưu hóa Bộ nhớ cho Sự suy luận và Điều chỉnh Mô hình Ngôn ngữ Lớn

mm
Thêm Unite.AI vào các nguồn ưu tiên của bạn trên Google

Các mô hình ngôn ngữ lớn (LLM) như GPT-4, Bloom và LLaMA đã đạt được khả năng đáng kể bằng cách mở rộng quy mô lên hàng tỷ tham số. Tuy nhiên, việc triển khai các mô hình khổng lồ này cho suy luận hoặc điều chỉnh là một thách thức do nhu cầu bộ nhớ khổng lồ của chúng. Trong bài viết kỹ thuật này, chúng tôi sẽ khám phá các kỹ thuật để ước tính và tối ưu hóa tiêu thụ bộ nhớ trong quá trình suy luận và điều chỉnh LLM trên các thiết lập phần cứng khác nhau.

Hiểu về Yêu cầu Bộ nhớ

Bộ nhớ cần thiết để tải một LLM chủ yếu được xác định bởi số lượng tham số và độ chính xác số được sử dụng để lưu trữ các tham số. Một quy tắc đơn giản là:

  • Tải một mô hình với X tỷ tham số yêu cầu khoảng 4X GB VRAM ở độ chính xác 32-bit float
  • Tải một mô hình với X tỷ tham số yêu cầu khoảng 2X GB VRAM ở độ chính xác 16-bit bfloat16/float16

Ví dụ, tải mô hình GPT-3 với 175 tỷ tham số sẽ yêu cầu khoảng 350GB VRAM ở độ chính xác bfloat16. Hiện tại, các GPU lớn nhất có sẵn trên thị trường như NVIDIA A100 và H100 chỉ cung cấp 80GB VRAM, đòi hỏi phải sử dụng các kỹ thuật song song tensor và mô hình.

Trong quá trình suy luận, dấu chân bộ nhớ được thống trị bởi các tham số mô hình và các tensor kích hoạt tạm thời được tạo ra. Một ước tính cao cấp cho sử dụng bộ nhớ đỉnh trong suy luận là tổng của bộ nhớ cần thiết để tải các tham số mô hình và bộ nhớ cho các kích hoạt.

Quantifying Inference Memory

Hãy lượng hóa nhu cầu bộ nhớ cho suy luận bằng cách sử dụng mô hình OctoCode, có khoảng 15 tỷ tham số ở định dạng bfloat16 (~ 31GB). Chúng tôi sẽ sử dụng Thư viện Transformers để tải mô hình và tạo văn bản:

from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
import torch

<p>model = AutoModelForCausalLM.from_pretrained(&quot;bigcode/octocoder&quot;,
torch_dtype=torch.bfloat16,
device_map=&quot;auto&quot;,
pad_token_id=0)
tokenizer = AutoTokenizer.from_pretrained(&quot;bigcode/octocoder&quot;)
pipe = pipeline(&quot;text-generation&quot;, model=model, tokenizer=tokenizer)</p>

<p>prompt = &quot;Câu hỏi: Hãy viết một hàm Python để chuyển đổi byte sang gigabyte.\n\nĐáp án:&quot;
result = pipe(prompt, max_new_tokens=60)[0][&quot;generated_text&quot;][len(prompt):]</p>

<p>def bytes_to_gigabytes(bytes):
return bytes / 1024 / 1024 / 1024</p>

<p>bytes_to_gigabytes(torch.cuda.max_memory_allocated())

Kết quả:

29.0260648727417

Sử dụng bộ nhớ đỉnh trên GPU là khoảng 29GB, phù hợp với ước tính của chúng tôi là 31GB để tải các tham số mô hình ở định dạng bfloat16.

Tối ưu hóa Bộ nhớ Suy luận với Quantization

Mặc dù bfloat16 là độ chính xác phổ biến được sử dụng để đào tạo LLM, các nhà nghiên cứu đã tìm thấy rằng việc định lượng hóa trọng số mô hình xuống độ chính xác thấp hơn như 8-bit hoặc 4-bit có thể giảm đáng kể nhu cầu bộ nhớ với tổn thất độ chính xác tối thiểu cho các nhiệm vụ suy luận như tạo văn bản.

Hãy xem xét tiết kiệm bộ nhớ từ định lượng hóa 8-bit và 4-bit của mô hình OctoCode:

&amp;lt;/div&amp;gt;
# Định lượng hóa 8-bit
model = AutoModelForCausalLM.from_pretrained(&quot;bigcode/octocoder&quot;, load_in_8bit=True,
pad_token_id=0)
pipe = pipeline(&quot;text-generation&quot;, model=model, tokenizer=tokenizer)
result = pipe(prompt, max_new_tokens=60)[0][&quot;generated_text&quot;][len(prompt):]
bytes_to_gigabytes(torch.cuda.max_memory_allocated())&lt;/pre&gt;
Kết quả:
15.219234466552734
# Định lượng hóa 4-bit
model = AutoModelForCausalLM.from_pretrained(&quot;bigcode/octocoder&quot;, load_in_4bit=True,
low_cpu_mem_usage=True, pad_token_id=0)
pipe = pipeline(&quot;text-generation&quot;, model=model, tokenizer=tokenizer)
result = pipe(prompt, max_new_tokens=60)[0][&quot;generated_text&quot;][len(prompt):]
bytes_to_gigabytes(torch.cuda.max_memory_allocated())

Kết quả:

9.543574333190918

Với định lượng hóa 8-bit, nhu cầu bộ nhớ giảm từ 31GB xuống 15GB, trong khi định lượng hóa 4-bit giảm thêm xuống chỉ 9,5GB! Điều này cho phép chạy mô hình OctoCode 15 tỷ tham số trên các GPU tiêu dùng như RTX 3090 (24GB VRAM).

Tuy nhiên, lưu ý rằng định lượng hóa hung hăng hơn như 4-bit đôi khi có thể dẫn đến suy giảm độ chính xác so với độ chính xác 8-bit hoặc bfloat16. Có một sự cân bằng giữa tiết kiệm bộ nhớ và độ chính xác mà người dùng nên đánh giá cho trường hợp của họ.

Định lượng hóa là một kỹ thuật mạnh mẽ có thể cho phép triển khai LLM trên các môi trường có tài nguyên hạn chế như các thể hiện đám mây, thiết bị biên hoặc thậm chí điện thoại di động bằng cách giảm đáng kể dấu chân bộ nhớ.

Ước tính Bộ nhớ cho Điều chỉnh Mô hình

Mặc dù định lượng hóa chủ yếu được sử dụng cho suy luận hiệu quả, các kỹ thuật như song song tensor và mô hình là rất quan trọng để quản lý nhu cầu bộ nhớ trong quá trình đào tạo hoặc điều chỉnh mô hình ngôn ngữ lớn.

Sử dụng bộ nhớ đỉnh trong quá trình điều chỉnh thường cao hơn 3-4 lần so với suy luận do nhu cầu bộ nhớ bổ sung cho:

  • Độ dốc
  • Trạng thái tối ưu hóa
  • Kích hoạt từ quá trình chuyển tiếp được lưu trữ cho quá trình ngược

Một ước tính thận trọng là điều chỉnh mô hình LLM với X tỷ tham số yêu cầu khoảng 4 * (2X) = 8X GB VRAM ở độ chính xác bfloat16.

Ví dụ, điều chỉnh mô hình LLaMA 7 tỷ tham số sẽ yêu cầu khoảng 7 * 8 = 56GB VRAM trên mỗi GPU ở độ chính xác bfloat16. Điều này vượt quá khả năng chứa bộ nhớ của các GPU hiện tại, đòi hỏi phải sử dụng các kỹ thuật điều chỉnh phân tán.

Kỹ thuật Điều chỉnh Phân tán

Một số phương pháp điều chỉnh phân tán đã được đề xuất để vượt qua các hạn chế về bộ nhớ GPU cho các mô hình lớn:

  1. Đồng song song Dữ liệu: Phương pháp đồng song song dữ liệu cổ điển nhân bản toàn bộ mô hình trên nhiều GPU trong khi chia và phân phối các lô dữ liệu đào tạo. Điều này giảm thời gian đào tạo tuyến tính với số lượng GPU nhưng không giảm nhu cầu bộ nhớ đỉnh trên mỗi GPU.
  2. Giai đoạn ZeRO 3: Một hình thức nâng cao của đồng song song dữ liệu, phân vùng các tham số mô hình, độ dốc và trạng thái tối ưu hóa trên các GPU. Nó giảm bộ nhớ so với đồng song song dữ liệu cổ điển bằng cách chỉ giữ dữ liệu phân vùng cần thiết trên mỗi GPU trong các giai đoạn đào tạo khác nhau.
  3. Đồng song song Tensor: Thay vì nhân bản mô hình, đồng song song tensor chia các tham số mô hình thành hàng hoặc cột và phân phối chúng trên các GPU. Mỗi GPU hoạt động trên một tập hợp phân vùng của các tham số, độ dốc và trạng thái tối ưu hóa, dẫn đến tiết kiệm bộ nhớ đáng kể.
  4. Đồng song song Dòng ống: Kỹ thuật này phân vùng các lớp mô hình trên các GPU/làm việc khác nhau, với mỗi thiết bị thực hiện một tập hợp con của các lớp. Các kích hoạt được truyền giữa các công nhân, giảm bộ nhớ đỉnh nhưng tăng thêm tải trọng truyền thông.

Ước tính sử dụng bộ nhớ cho các phương pháp phân tán này không đơn giản vì sự phân phối của các tham số, độ dốc, kích hoạt và trạng thái tối ưu hóa khác nhau giữa các kỹ thuật. Hơn nữa, các thành phần khác nhau như thân chuyển đổi và đầu mô hình ngôn ngữ có thể hiển thị các hành vi phân bổ bộ nhớ khác nhau.

Giải pháp LLMem

Các nhà nghiên cứu gần đây đã đề xuất LLMem, một giải pháp ước tính chính xác nhu cầu bộ nhớ GPU khi áp dụng các phương pháp điều chỉnh phân tán cho LLM trên nhiều GPU.

Ước tính Sử dụng Bộ nhớ GPU cho Điều chỉnh Mô hình Ngôn ngữ Lớn

Ước tính Sử dụng Bộ nhớ GPU cho Điều chỉnh Mô hình Ngôn ngữ Lớn

LLMem xem xét các yếu tố như tái kết hợp các tham số trước khi tính toán (Giai đoạn ZeRO 3), thu thập đầu ra trong quá trình ngược (đồng song song tensor) và các chiến lược phân bổ bộ nhớ khác nhau cho thân chuyển đổi và đầu mô hình ngôn ngữ.

Kết quả thực nghiệm cho thấy LLMem có thể ước tính sử dụng bộ nhớ GPU đỉnh cho điều chỉnh mô hình LLM trên một GPU đơn với tỷ lệ lỗi lên đến 1,6%, vượt qua tỷ lệ lỗi trung bình của DNNMem là 42,6%. Khi áp dụng các phương pháp điều chỉnh phân tán cho LLM với hơn một tỷ tham số trên nhiều GPU, LLMem đạt được tỷ lệ lỗi trung bình ấn tượng là 3,0%.

Bằng cách ước tính chính xác nhu cầu bộ nhớ từ trước, LLMem có thể giúp người dùng chọn phương pháp điều chỉnh phân tán hiệu quả nhất, tránh các vấn đề hết bộ nhớ trong khi giảm thiểu thời gian đào tạo.

Kỹ thuật Tiềm năng

Mặc dù định lượng hóa, đồng song song tensor và mô hình là các kỹ thuật đã được thiết lập, các nhà nghiên cứu tiếp tục khám phá các phương pháp mới để đẩy ranh giới của đào tạo và triển khai LLM hiệu quả.

  1. LoRA và QLoRA: Những kỹ thuật này liên quan đến việc đào tạo một mô-đun bộ điều chỉnh nhỏ để cập nhật mô hình ngôn ngữ lớn đã được đào tạo trước với kiến thức mới thay vì điều chỉnh trực tiếp số lượng tham số khổng lồ. Điều này có thể dẫn đến tiết kiệm bộ nhớ đáng kể trong khi vẫn giữ lại hầu hết hiệu suất của mô hình.
  2. FlashAttention: Cơ chế chú ý tự là một nút thắt cổ chai về bộ nhớ và tính toán trong các mô hình chuyển đổi. FlashAttention xấp xỉ sự chú ý tiêu chuẩn với độ phức tạp tuyến tính, giảm nhu cầu bộ nhớ từ bậc hai xuống bậc một trong chiều dài chuỗi đầu vào.
  3. Mixture-of-Experts: Phương pháp này định tuyến có điều kiện mỗi mẫu dữ liệu đầu vào đến một mô hình chuyên gia chuyên dụng thay vì xử lý nó thông qua toàn bộ mô hình. Sự sparsity động này có thể tiết kiệm bộ nhớ bằng cách chỉ kích hoạt một tập hợp con của các chuyên gia cho mỗi mẫu.
  4. Phẫu thuật Mô hình Đảo ngược: Các nhà nghiên cứu đã khám phá nén mô hình phẫu thuật bằng cách loại bỏ lặp đi lặp lại các thành phần ít quan trọng như đầu chú ý để trao đổi bộ nhớ/tốc độ cho độ chính xác.
  5. Offloading: Cuối cùng, các kỹ thuật offload tham số, trạng thái tối ưu hóa hoặc kích hoạt đến RAM CPU hoặc đĩa có thể bổ sung bộ nhớ GPU hạn chế cho các mô hình lớn.

Những phương pháp tiên tiến này minh họa cho hệ sinh thái nghiên cứu sôi động tập trung vào việc dân chủ hóa đào tạo và triển khai LLM hiệu quả trên các môi trường phần cứng đa dạng.

Kết luận

Nhu cầu bộ nhớ của các mô hình ngôn ngữ lớn tạo ra những thách thức đáng kể cho việc áp dụng rộng rãi của chúng trong các ứng dụng thực tế. Bằng cách hiểu các kỹ thuật ước tính bộ nhớ và tận dụng định lượng hóa, chiến lược đào tạo phân tán và các đổi mới mới nổi, chúng ta có thể tối ưu hóa việc triển khai LLM trên các thiết bị có tài nguyên hạn chế.

Các công cụ như LLMem mở đường cho việc ước tính bộ nhớ chính xác, cho phép người dùng chọn cấu hình điều chỉnh phân tán hiệu quả nhất, tránh các vấn đề hết bộ nhớ trong khi giảm thiểu thời gian đào tạo.

Khi phần cứng tiến bộ và nghiên cứu phát triển, chúng ta có thể mong đợi đào tạo và suy luận LLM hiệu quả hơn, thúc đẩy tiến bộ trong xử lý ngôn ngữ tự nhiên và trí tuệ nhân tạo.

Đạt được sự cân bằng giữa khả năng của mô hình, độ chính xác và sử dụng tài nguyên sẽ là rất quan trọng để mở khóa toàn bộ tiềm năng của các mô hình ngôn ngữ lớn trên nhiều lĩnh vực và trường hợp sử dụng. Bằng cách chấp nhận các kỹ thuật tối ưu hóa bộ nhớ, chúng ta tiến gần hơn đến một tương lai nơi trí tuệ ngôn ngữ hàng đầu là khả dụng, có thể mở rộng và bền vững.

Tôi đã dành 5 năm qua để đắm mình trong thế giới hấp dẫn của Máy học và Học sâu. Đam mê và chuyên môn của tôi đã dẫn tôi đến việc đóng góp vào hơn 50 dự án kỹ thuật phần mềm đa dạng, với sự tập trung đặc biệt vào AI/ML. Sự tò mò liên tục của tôi cũng đã thu hút tôi đến với Xử lý Ngôn ngữ Tự nhiên, một lĩnh vực tôi渴望 khám phá thêm.