
Bên trong vLLM: Giải phẫu hệ thống suy luận LLM thông lượng cao (2025)
URL bài viết: https://www.aleksagordic.com/blog/vllm URL bình luận: https://news.ycombinator.com/item?id=49202852 Điểm: 26 # Bình luận: 1
Bên trong vLLM: Giải phẫu hệ thống suy luận LLM thông lượng cao
Từ paged attention, continuous batching, prefix caching, specdec, v.v. đến phục vụ động đa GPU, đa nút ở quy mô lớn
Ngày 29/8/2025
Trong bài viết này, chúng tôi sẽ dần giới thiệu tất cả các thành phần hệ thống cốt lõi và các tính năng nâng cao tạo nên một hệ thống suy luận LLM thông lượng cao hiện đại. Đặc biệt, chúng tôi sẽ phân tích cách thức hoạt động của vLLM [1].
Bài viết này là phần đầu tiên trong một chuỗi bài. Nó bắt đầu với phạm vi rộng và sau đó đi sâu vào chi tiết (theo phương pháp kim tự tháp ngược) để độc giả có thể hình thành một mô hình tinh thần cấp cao chính xác về toàn bộ hệ thống mà không bị sa lầy vào các chi tiết nhỏ.
Các bài viết sau sẽ đi sâu vào các hệ thống con cụ thể.
Bài viết này được cấu trúc thành năm phần:
Công cụ LLM & lõi công cụ: các nguyên tắc cơ bản của vLLM (lập lịch, paged attention, continuous batching, v.v.)
Các tính năng nâng cao: chunked prefill, prefix caching, guided & speculative decoding, disaggregated P/D
Mở rộng quy mô: từ thực thi một GPU đến đa GPU
Lớp phục vụ: giàn giáo web phân tán / đồng thời
Điểm chuẩn và tự động điều chỉnh: đo lường độ trễ và thông lượng
📝Ghi chú
Phân tích dựa trên commit 42172ad (ngày 9/8/2025).
Đối tượng mục tiêu: bất kỳ ai tò mò về cách thức hoạt động của các công cụ LLM tiên tiến, cũng như những người quan tâm đến việc đóng góp cho vLLM, SGLang, v.v.
Chúng tôi sẽ tập trung vào công cụ V1. Chúng tôi cũng đã khám phá V0 (hiện đã lỗi thời), điều này có giá trị để hiểu cách dự án phát triển và nhiều khái niệm vẫn được kế thừa.
Phần đầu tiên về Công cụ LLM / Lõi công cụ có thể hơi choáng ngợp/khô khan – nhưng phần còn lại của blog có rất nhiều ví dụ và hình ảnh. :)
Công cụ LLM & Lõi công cụ
Công cụ LLM là khối xây dựng cơ bản của vLLM. Bản thân nó đã cho phép suy luận thông lượng cao – nhưng chỉ trong môi trường ngoại tuyến. Độc giả chưa thể phục vụ nó cho khách hàng qua web.
Chúng tôi sẽ sử dụng đoạn mã suy luận ngoại tuyến sau làm ví dụ đang chạy (được điều chỉnh từ basic.py).
from vllm import LLM, SamplingParams
prompts = [
"Hello, my name is",
"The president of the United States is",
]
sampling_params = SamplingParams(temperature=0.8, top_p=0.95)
def main():
llm = LLM(model="TinyLlama/TinyLlama-1.1B-Chat-v1.0")
outputs = llm.generate(prompts, sampling_params)
if __name__ == "__main__":
main()📝Biến môi trường:
VLLM_USE_V1="1" # chúng tôi đang sử dụng công cụ V1
VLLM_ENABLE_V1_MULTIPROCESSING="0" # chúng tôi đang chạy trong một tiến trình đơn
Cấu hình này là:
ngoại tuyến (không có giàn giáo hệ thống web/phân tán)
đồng bộ (tất cả quá trình thực thi diễn ra trong một tiến trình chặn duy nhất)
GPU đơn (không có song song dữ liệu/mô hình/đường ống/chuyên gia; DP/TP/PP/EP = 1)
sử dụng transformer tiêu chuẩn [2] (hỗ trợ các mô hình lai như Jamba yêu cầu bộ cấp phát bộ nhớ KV-cache lai phức tạp hơn)
Từ đây, chúng ta sẽ dần xây dựng một hệ thống suy luận trực tuyến, không đồng bộ, đa GPU, đa nút – nhưng vẫn phục vụ một transformer tiêu chuẩn.
Trong ví dụ này, chúng ta thực hiện hai việc:
Khởi tạo một engine
Gọi hàm generate trên đó để lấy mẫu từ các lời nhắc đã cho
Hãy bắt đầu phân tích hàm tạo.
Hàm tạo LLM Engine
Các thành phần chính của engine là:
cấu hình vLLM (chứa tất cả các nút để cấu hình mô hình, bộ đệm, song song, v.v.)
bộ xử lý (chuyển đổi đầu vào thô → EngineCoreRequests thông qua xác thực, mã hóa và xử lý)
máy khách lõi engine (trong ví dụ đang chạy của chúng ta, chúng ta đang sử dụng InprocClient về cơ bản là == EngineCore; chúng ta sẽ dần xây dựng DPLBAsyncMPClient cho phép phục vụ ở quy mô lớn)
bộ xử lý đầu ra (chuyển đổi EngineCoreOutputs thô → RequestOutput mà người dùng thấy)
📝Lưu ý:
Với việc engine V0 bị loại bỏ, tên lớp và chi tiết có thể thay đổi. Tôi sẽ nhấn mạnh các ý tưởng cốt lõi hơn là các chữ ký chính xác. Tôi sẽ trừu tượng hóa một số nhưng không phải tất cả các chi tiết đó.
Bản thân lõi engine được tạo thành từ một số thành phần phụ:
Bộ thực thi mô hình (điều khiển các lượt chuyển tiếp trên mô hình, chúng ta hiện đang xử lý UniProcExecutor có một tiến trình Worker duy nhất trên một GPU). Chúng ta sẽ dần xây dựng MultiProcExecutor hỗ trợ nhiều GPU
Trình quản lý đầu ra có cấu trúc (được sử dụng để giải mã có hướng dẫn – chúng ta sẽ đề cập đến điều này sau)
Bộ lập lịch (quyết định yêu cầu nào sẽ đi vào bước engine tiếp theo) – nó còn chứa: cài đặt chính sách – có thể là FCFS (đến trước phục vụ trước) hoặc ưu tiên (các yêu cầu có độ ưu tiên cao hơn được phục vụ trước)
hàng đợi chờ và chạy
Trình quản lý bộ đệm KV – trái tim của paged attention [3]
Trình quản lý bộ đệm KV duy trì một free_block_queue – một nhóm các khối bộ đệm KV có sẵn (thường có thứ tự hàng trăm nghìn, tùy thuộc vào kích thước VRAM và kích thước khối). Trong quá trình paged attention, các khối đóng vai trò là cấu trúc lập chỉ mục ánh xạ các token tới các khối bộ đệm KV đã tính toán của chúng.
Các thành phần cốt lõi được mô tả trong phần này và mối quan hệ của chúng
Kích thước khối cho một lớp transformer tiêu chuẩn (không phải MLA [4]) được tính như sau:
2 (khóa/giá trị) * block_size (mặc định=16) * num_kv_heads * head_size * dtype_num_bytes (ví dụ: 2 cho bf16)
Trong quá trình xây dựng bộ thực thi mô hình, một đối tượng Worker được tạo và ba quy trình chính được thực thi. (Sau này, với MultiProcExecutor, các quy trình tương tự này chạy độc lập trên mỗi tiến trình worker trên các GPU khác nhau.)
Khởi tạo thiết bị: Gán một thiết bị CUDA (ví dụ: "cuda:0") cho worker và kiểm tra xem dtype của mô hình có được hỗ trợ hay không (ví dụ: bf16)
Xác minh có đủ VRAM, với gpu_memory_utilization được yêu cầu (ví dụ: 0.8 → 80% tổng VRAM)
Thiết lập cài đặt phân tán (DP / TP / PP / EP, v.v.)
Khởi tạo một model_runner (chứa bộ lấy mẫu, bộ đệm KV và các bộ đệm chuyển tiếp như input_ids, positions, v.v.)
Khởi tạo một đối tượng InputBatch (chứa các bộ đệm chuyển tiếp phía CPU, bảng khối để lập chỉ mục bộ đệm KV, siêu dữ liệu lấy mẫu, v.v.)
Tải mô hình: Khởi tạo kiến trúc mô hình
Tải trọng số mô hình
Gọi model.eval() (chế độ suy luận của PyTorch)
Tùy chọn: gọi torch.compile() trên mô hình
Khởi tạo bộ nhớ đệm KV.
Lấy thông số kỹ thuật bộ nhớ đệm KV theo từng lớp. Trong lịch sử, điều này luôn là...




Nguồn tin: Hacker News LLM — Tác giả: sebg. Bản dịch tiếng Việt do AI thực hiện, có thể có sai sót.