Kết nối với chúng tôi

Tối ưu hóa triển khai LLM: vLLM PagedAttention và tương lai của việc cung cấp AI hiệu quả

Trí tuệ nhân tạo

Tối ưu hóa triển khai LLM: vLLM PagedAttention và tương lai của việc cung cấp AI hiệu quả

mm
Triển khai Công cụ suy luận vLLM để chạy các mô hình ngôn ngữ lớn

Mô hình ngôn ngữ lớn (LLM) triển khai trên các ứng dụng trong thế giới thực đặt ra những thách thức đặc biệt, đặc biệt là về tài nguyên tính toán, độ trễ và hiệu quả chi phí. Trong hướng dẫn toàn diện này, chúng ta sẽ khám phá bối cảnh phân phát LLM, đặc biệt tập trung vào vLLM (Mô hình ngôn ngữ vectơ), một giải pháp đang định hình lại cách chúng ta triển khai và tương tác với các mô hình mạnh mẽ này.

Những thách thức của việc phục vụ các mô hình ngôn ngữ lớn

Trước khi đi sâu vào các giải pháp cụ thể, hãy xem xét những thách thức chính khiến LLM phải thực hiện một nhiệm vụ phức tạp:

Tài nguyên tính toán

LLM nổi tiếng với số lượng tham số khổng lồ, từ hàng tỷ đến hàng trăm tỷ. Ví dụ: GPT-3 tự hào có 175 tỷ tham số, trong khi các mẫu gần đây hơn như GPT-4 ước tính còn có nhiều hơn nữa. Kích thước tuyệt đối này chuyển thành các yêu cầu tính toán quan trọng để suy luận.

Ví dụ:
Hãy xem xét một mức độ tương đối khiêm tốn LLM với 13 tỷ tham số, chẳng hạn như LLaMA-13B. Ngay cả mô hình này cũng yêu cầu:

– Khoảng 26 GB bộ nhớ chỉ để lưu trữ các tham số mô hình (giả sử độ chính xác 16-bit)
– Bộ nhớ bổ sung để kích hoạt, cơ chế chú ý và tính toán trung gian
– Sức mạnh tính toán GPU đáng kể để suy luận theo thời gian thực

Độ trễ

Trong nhiều ứng dụng, chẳng hạn như chatbot hoặc tạo nội dung theo thời gian thực, độ trễ thấp rất quan trọng để mang lại trải nghiệm tốt cho người dùng. Tuy nhiên, sự phức tạp của LLM có thể dẫn đến thời gian xử lý đáng kể, đặc biệt đối với các chuỗi dài hơn.

Ví dụ:
Hãy tưởng tượng một chatbot dịch vụ khách hàng được hỗ trợ bởi LLM. Nếu mỗi phản hồi mất vài giây để tạo ra, cuộc trò chuyện sẽ khiến người dùng cảm thấy không tự nhiên và khó chịu.

Phí Tổn

Phần cứng cần thiết để chạy LLM trên quy mô lớn có thể cực kỳ đắt tiền. GPU hoặc TPU cao cấp thường rất cần thiết và mức tiêu thụ năng lượng của các hệ thống này là đáng kể.

Ví dụ:
Việc chạy một cụm GPU NVIDIA A100 (thường được sử dụng cho suy luận LLM) có thể tiêu tốn hàng nghìn đô la mỗi ngày phí điện toán đám mây.

Các phương pháp tiếp cận truyền thống để phục vụ LLM

Trước khi khám phá các giải pháp nâng cao hơn, hãy xem xét ngắn gọn một số phương pháp truyền thống để phục vụ LLM:

Triển khai đơn giản với Transformers ôm mặt

Thư viện Hugging Face Transformers cung cấp một cách đơn giản để triển khai LLM nhưng không được tối ưu hóa để phân phối thông lượng cao.

Mã ví dụ:

from transformers import AutoModelForCausalLM, AutoTokenizer
import torch

model_name = "meta-llama/Llama-2-13b-hf"
model = AutoModelForCausalLM.from_pretrained(model_name, device_map="auto")
tokenizer = AutoTokenizer.from_pretrained(model_name)

def generate_text(prompt, max_length=100):
inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
outputs = model.generate(**inputs, max_length=max_length)
return tokenizer.decode(outputs[0], skip_special_tokens=True)

print(generate_text("The future of AI is"))

Mặc dù phương pháp này hoạt động nhưng không phù hợp với các ứng dụng có lưu lượng truy cập cao do sử dụng tài nguyên không hiệu quả và thiếu tối ưu hóa để phân phát.

Sử dụng TorchServe hoặc các khung tương tự

Các khung như TorchServe cung cấp khả năng phục vụ mạnh mẽ hơn, bao gồm cân bằng tải và tạo phiên bản mô hình. Tuy nhiên, chúng vẫn không giải quyết được những thách thức cụ thể của việc phân phát LLM, chẳng hạn như quản lý bộ nhớ hiệu quả cho các mô hình lớn.

Tìm hiểu về quản lý bộ nhớ trong việc cung cấp LLM

Quản lý bộ nhớ hiệu quả là rất quan trọng để phục vụ các mô hình ngôn ngữ lớn (LLM) do cần có nhiều tài nguyên tính toán. Các hình ảnh sau đây minh họa các khía cạnh khác nhau của việc quản lý bộ nhớ, những khía cạnh không thể thiếu để tối ưu hóa hiệu suất LLM.

Bộ nhớ được phân đoạn và phân trang

Hai sơ đồ này so sánh kỹ thuật quản lý bộ nhớ phân đoạn và bộ nhớ phân trang, thường được sử dụng trong các hệ điều hành (OS).

  • Bộ nhớ được phân đoạn: Kỹ thuật này chia bộ nhớ thành các phân đoạn khác nhau, mỗi phân đoạn tương ứng với một chương trình hoặc quy trình khác nhau. Ví dụ: trong bối cảnh phục vụ LLM, các phân đoạn khác nhau có thể được phân bổ cho các thành phần khác nhau của mô hình, chẳng hạn như cơ chế mã hóa, nhúng và chú ý. Mỗi phân khúc có thể phát triển hoặc thu hẹp một cách độc lập, mang lại sự linh hoạt nhưng có khả năng dẫn đến sự phân mảnh nếu các phân khúc không được quản lý đúng cách.
  • Bộ nhớ phân trang: Ở đây, bộ nhớ được chia thành các trang có kích thước cố định, được ánh xạ vào bộ nhớ vật lý. Các trang có thể được hoán đổi vào và ra khi cần, cho phép sử dụng hiệu quả tài nguyên bộ nhớ. Trong phân phối LLM, điều này có thể rất quan trọng để quản lý lượng lớn bộ nhớ cần thiết để lưu trữ trọng số mô hình và các phép tính trung gian.

Quản lý bộ nhớ trong hệ điều hành so với vLLM

Hình ảnh này tương phản việc quản lý bộ nhớ hệ điều hành truyền thống với phương pháp quản lý bộ nhớ được sử dụng trong vLLM.

  • Quản lý bộ nhớ hệ điều hành: Trong các hệ điều hành truyền thống, các quy trình (ví dụ: Quy trình A và Quy trình B) được phân bổ các trang bộ nhớ (Trang 0, Trang 1, v.v.) trong bộ nhớ vật lý. Sự phân bổ này có thể dẫn đến sự phân mảnh theo thời gian khi các tiến trình yêu cầu và giải phóng bộ nhớ.
  • Quản lý bộ nhớ vLLM: Khung vLLM sử dụng bộ nhớ đệm Khóa-Giá trị (KV) để quản lý bộ nhớ hiệu quả hơn. Các yêu cầu (ví dụ: Yêu cầu A và Yêu cầu B) là các khối được phân bổ của bộ đệm KV (Khối KV 0, Khối KV 1, v.v.). Cách tiếp cận này giúp giảm thiểu sự phân mảnh và tối ưu hóa việc sử dụng bộ nhớ, cho phép phục vụ mô hình nhanh hơn và hiệu quả hơn.

Cơ chế chú ý trong LLM

Cơ chế chú ý trong LLM

Cơ chế chú ý trong LLM

Cơ chế chú ý là thành phần cơ bản của các mô hình máy biến áp, thường được sử dụng cho LLM. Sơ đồ này minh họa công thức chú ý và các thành phần của nó:

  • Truy vấn (Q): Một mã thông báo mới trong bước giải mã hoặc mã thông báo cuối cùng mà mô hình đã thấy.
  • Phím (K): Bối cảnh trước đó mà mô hình nên tham gia.
  • Giá trị (V): Tổng có trọng số so với bối cảnh trước đó.

Công thức tính toán điểm chú ý bằng cách lấy tích số chấm của truy vấn bằng các khóa, chia tỷ lệ theo căn bậc hai của thứ nguyên khóa, áp dụng hàm softmax và cuối cùng lấy tích số chấm với các giá trị. Quá trình này cho phép mô hình tập trung vào các phần có liên quan của chuỗi đầu vào khi tạo từng mã thông báo.

So sánh thông lượng phân phát

vLLM: Cung cấp LLM dễ dàng, nhanh chóng và giá rẻ với PagedAttention

vLLM: Cung cấp LLM dễ dàng, nhanh chóng và giá rẻ với PagedAttention

Hình ảnh này trình bày sự so sánh về thông lượng phân phát giữa các khung khác nhau (HF, TGI và vLLM) bằng cách sử dụng người mẫu LLaMA trên các thiết lập phần cứng khác nhau.

  • LLaMA-13B, A100-40GB: vLLM đạt thông lượng cao hơn 14x – 24 lần so với HuggingFace Transformers (HF) và thông lượng cao hơn 2.2x – 2.5 lần so với HuggingFace Text Generation Inference (TGI).
  • LLaMA-7B, A10G: Xu hướng tương tự cũng được quan sát thấy, vLLM hoạt động tốt hơn đáng kể cả HF và TGI.

vLLM: Kiến trúc phục vụ LLM mới

vLLM, được phát triển bởi các nhà nghiên cứu tại UC Berkeley, thể hiện một bước nhảy vọt đáng kể trong công nghệ phục vụ LLM. Hãy cùng khám phá các tính năng và cải tiến chính của nó:

PagedChú ý

Trọng tâm của vLLM là PagedAttention, một thuật toán chú ý mới lấy cảm hứng từ việc quản lý bộ nhớ ảo trong hệ điều hành. Đây là cách nó hoạt động:

Phân vùng bộ nhớ đệm khóa-giá trị (KV): Thay vì lưu trữ toàn bộ bộ đệm KV liên tục trong bộ nhớ, PagedAttention chia nó thành các khối có kích thước cố định.
Lưu trữ không liền kề: Các khối này có thể được lưu trữ không liền kề trong bộ nhớ, cho phép quản lý bộ nhớ linh hoạt hơn.
Phân bổ theo yêu cầu: Các khối chỉ được phân bổ khi cần thiết, giảm lãng phí bộ nhớ.
Chia sẻ hiệu quả: Nhiều chuỗi có thể chia sẻ các khối, cho phép tối ưu hóa các kỹ thuật như lấy mẫu song song và tìm kiếm chùm tia.

Hình minh họa:


Bộ đệm KV truyền thống:
[Mã thông báo 1 KV][Mã thông báo 2 KV][Mã thông báo 3 KV]…[Mã thông báo N KV]
(Cấp phát bộ nhớ liền kề)

PagedAttention KV Cache:
[Khối 1] -> Địa chỉ vật lý A
[Khối 2] -> Địa chỉ vật lý C
[Khối 3] -> Địa chỉ vật lý B
...
(Cấp phát bộ nhớ không liền kề)

Cách tiếp cận này làm giảm đáng kể sự phân mảnh bộ nhớ và cho phép sử dụng bộ nhớ GPU hiệu quả hơn nhiều.

Batch liên tục

vLLM triển khai tính năng phân nhóm liên tục, xử lý động các yêu cầu khi chúng đến thay vì chờ tạo thành các lô có kích thước cố định. Điều này dẫn đến độ trễ thấp hơn và thông lượng cao hơn.

Ví dụ:
Hãy tưởng tượng một luồng yêu cầu đến:


Thời gian 0ms: Yêu cầu A đến
Thời gian 10ms: Bắt đầu xử lý Yêu cầu A
Thời gian 15ms: Yêu cầu B đến
Thời gian 20ms: Bắt đầu xử lý Yêu cầu B (song song với A)
Thời gian 25ms: Yêu cầu C đến
...

Với việc phân nhóm liên tục, vLLM có thể bắt đầu xử lý từng yêu cầu ngay lập tức thay vì chờ nhóm chúng thành các nhóm được xác định trước.

Lấy mẫu song song hiệu quả

Đối với các ứng dụng yêu cầu nhiều mẫu đầu ra cho mỗi lời nhắc (ví dụ: trợ lý viết sáng tạo), khả năng chia sẻ bộ nhớ của vLLM sẽ tỏa sáng. Nó có thể tạo ra nhiều đầu ra trong khi sử dụng lại bộ đệm KV cho các tiền tố được chia sẻ.

Mã ví dụ sử dụng vLLM:

from vllm import LLM, SamplingParams

llm = LLM(model="meta-llama/Llama-2-13b-hf")
prompts = ["The future of AI is"]

# Generate 3 samples per prompt
sampling_params = SamplingParams(n=3, temperature=0.8, max_tokens=100)
outputs = llm.generate(prompts, sampling_params)

for output in outputs:
print(f"Prompt: {output.prompt}")
for i, out in enumerate(output.outputs):
print(f"Sample {i + 1}: {out.text}")

Mã này tạo ra nhiều mẫu một cách hiệu quả cho lời nhắc nhất định, tận dụng tối ưu hóa của vLLM.

Đo điểm chuẩn hiệu suất vLLM

Để thực sự đánh giá cao tác động của vLLM, hãy xem một số so sánh hiệu suất:

So sánh thông lượng

Dựa trên thông tin được cung cấp, vLLM vượt trội hơn đáng kể so với các giải pháp cung cấp khác:

– Thông lượng cao hơn tới 24 lần so với Máy biến áp ôm mặt
– Thông lượng cao hơn 2.2 lần đến 3.5 lần so với Suy luận tạo văn bản ôm khuôn mặt (TGI)

Hình minh họa:


Thông lượng (Mã thông báo/giây)
|
| ****
| ****
| ****
| **** ****
| **** **** ****
| **** **** ****
|————————
HF TGI vLLM

Hiệu suất bộ nhớ

PagedAttention của vLLM mang lại mức sử dụng bộ nhớ gần như tối ưu:

– Chỉ lãng phí khoảng 4% bộ nhớ, so với 60-80% ở các hệ thống truyền thống
– Hiệu quả này cho phép phục vụ các mô hình lớn hơn hoặc xử lý nhiều yêu cầu đồng thời hơn với cùng một phần cứng

Bắt đầu với vLLM

Bây giờ chúng ta đã khám phá những lợi ích của vLLM, hãy cùng tìm hiểu quy trình thiết lập và sử dụng nó trong các dự án của bạn.

Cài đặt 6.1

Việc cài đặt vLLM rất đơn giản bằng pip:

!pip install vllm

6.2 Cách sử dụng cơ bản cho suy luận ngoại tuyến

Đây là một ví dụ đơn giản về việc sử dụng vLLM để tạo văn bản ngoại tuyến:

from vllm import LLM, SamplingParams

# Initialize the model
llm = LLM(model="meta-llama/Llama-2-13b-hf")

# Prepare prompts
prompts = [
"Write a short poem about artificial intelligence:",
"Explain quantum computing in simple terms:"
]

# Set sampling parameters
sampling_params = SamplingParams(temperature=0.8, max_tokens=100)

# Generate responses
outputs = llm.generate(prompts, sampling_params)

# Print the results
for output in outputs:
print(f"Prompt: {output.prompt}")
print(f"Generated text: {output.outputs[0].text}\n")

Tập lệnh này trình bày cách tải mô hình, đặt tham số lấy mẫu và tạo văn bản cho nhiều lời nhắc.

6.3 Thiết lập máy chủ vLLM

Để phục vụ trực tuyến, vLLM cung cấp máy chủ API tương thích với OpenAI. Đây là cách thiết lập nó:

1. Khởi động máy chủ:

python -m vllm.entrypoints.openai.api_server --model meta-llama/Llama-2-13b-hf

2. Truy vấn máy chủ bằng cách sử dụng Curl:

curl http://localhost:8000/v1/completions \
-H "Content-Type: application/json" \
-d '{
"model": "meta-llama/Llama-2-13b-hf",
"prompt": "The benefits of artificial intelligence include:",
"max_tokens": 100,
"temperature": 0.7
}'

Thiết lập này cho phép bạn phục vụ LLM của mình với giao diện tương thích với API của OpenAI, giúp dễ dàng tích hợp vào các ứng dụng hiện có.

Các chủ đề nâng cao về vLLM

Mặc dù vLLM cung cấp những cải tiến đáng kể trong việc phân phối LLM nhưng vẫn có những cân nhắc bổ sung và các chủ đề nâng cao cần khám phá:

7.1 Lượng tử hóa mô hình

Để phục vụ hiệu quả hơn nữa, đặc biệt là trên phần cứng có bộ nhớ hạn chế, có thể sử dụng kỹ thuật lượng tử hóa. Mặc dù bản thân vLLM hiện không hỗ trợ lượng tử hóa nhưng nó có thể được sử dụng cùng với các mô hình lượng tử hóa:

from transformers import AutoModelForCausalLM, AutoTokenizer
import torch

# Load a quantized model
model_name = "meta-llama/Llama-2-13b-hf"
model = AutoModelForCausalLM.from_pretrained(model_name, device_map="auto", load_in_8bit=True)
tokenizer = AutoTokenizer.from_pretrained(model_name)

# Use the quantized model with vLLM
from vllm import LLM

llm = LLM(model=model, tokenizer=tokenizer)

7.2 Suy luận phân tán

Đối với các mô hình cực lớn hoặc ứng dụng có lưu lượng truy cập cao, có thể cần phải suy luận phân tán trên nhiều GPU hoặc máy. Mặc dù vLLM về cơ bản không hỗ trợ tính năng này nhưng nó có thể được tích hợp vào các hệ thống phân tán bằng cách sử dụng các framework như Ray:

import ray
from vllm import LLM

@ray.remote(num_gpus=1)
class DistributedLLM:
  def __init__(self, model_name):
    self.llm = LLM(model=model_name)

  def generate(self, prompt, params):
    return self.llm.generate(prompt, params)

# Initialize distributed LLMs
llm1 = DistributedLLM.remote("meta-llama/Llama-2-13b-hf")
llm2 = DistributedLLM.remote("meta-llama/Llama-2-13b-hf")

# Use them in parallel
result1 = llm1.generate.remote("Prompt 1", sampling_params)
result2 = llm2.generate.remote("Prompt 2", sampling_params)

# Retrieve results
print(ray.get([result1, result2]))

7.3 Giám sát và quan sát

Khi phục vụ LLM trong sản xuất, việc giám sát là rất quan trọng. Mặc dù vLLM không cung cấp tính năng giám sát tích hợp nhưng bạn có thể tích hợp nó với các công cụ như Prometheus và Grafana:

from prometheus_client import start_http_server, Summary
from vllm import LLM

# Define metrics
REQUEST_TIME = Summary('request_processing_seconds', 'Time spent processing request')

# Initialize vLLM
llm = LLM(model="meta-llama/Llama-2-13b-hf")

# Expose metrics
start_http_server(8000)

# Use the model with monitoring
@REQUEST_TIME.time()
  def process_request(prompt):
      return llm.generate(prompt)

# Your serving loop here

Thiết lập này cho phép bạn theo dõi các số liệu như thời gian xử lý yêu cầu, có thể được hiển thị trực quan trong bảng điều khiển Grafana.

Kết luận

Phục vụ các Mô hình ngôn ngữ lớn một cách hiệu quả là một nhiệm vụ phức tạp nhưng quan trọng trong thời đại AI. vLLM, với thuật toán PagedAttention cải tiến và cách triển khai được tối ưu hóa, thể hiện một bước tiến đáng kể trong việc giúp việc triển khai LLM trở nên dễ tiếp cận hơn và tiết kiệm chi phí hơn.

Bằng cách cải thiện đáng kể thông lượng, giảm lãng phí bộ nhớ và cho phép các tùy chọn cung cấp linh hoạt hơn, vLLM mở ra những khả năng mới để tích hợp các mô hình ngôn ngữ mạnh mẽ vào nhiều ứng dụng. Cho dù bạn đang xây dựng một chatbot, hệ thống tạo nội dung hay bất kỳ ứng dụng hỗ trợ NLP nào khác, việc hiểu và tận dụng các công cụ như vLLM sẽ là chìa khóa thành công.

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