Mô tả những gì còn lại trong bộ nhớ
Trong quá trình sinh tự hồi quy, các khóa và giá trị của những token đã xử lý có thể được giữ lại cho các bước tiếp theo. Cache này thuộc các lớp attention. Do đó khối lượng của nó phụ thuộc vào mô hình và lịch sử được giữ lại, không chỉ vào số lượng tham số. Ngữ cảnh của một cuộc hội thoại cũng bao gồm các hướng dẫn, các tin nhắn trước đó và các tài liệu do ứng dụng thêm vào.
Quyết định đầu tiên của bạn mang tính vận hành: bao nhiêu chuỗi sẽ phải duy trì hoạt động, đến độ dài nào? Một hàng đợi hai mươi yêu cầu mà hai yêu cầu được thực thi đồng thời không nhất thiết đại diện cho hai mươi cache thường trú. Hãy ghi nhận việc tiếp nhận yêu cầu thực tế và các chuỗi bổ sung có thể được tạo ra bởi quá trình sinh.
Hãy chuẩn bị một phiếu ghi với bản sửa đổi của mô hình, các lớp attention, các đầu KV, kích thước của khóa và giá trị, dtype của chúng và chiến lược cache. Hãy đếm token sau tokenizer và mẫu hội thoại. Một giới hạn ký tự không mô tả được việc cấp phát này.
Nguồn kỹ thuật: Hugging Face — cách hoạt động và hình dạng của cache theo lớp
Sử dụng các đầu KV, đặc biệt với GQA
Số lượng đầu truy vấn Q và số lượng đầu KV có thể khác nhau. Trong attention đa đầu cổ điển, chúng trùng khớp. Với MQA, một đầu KV duy nhất được chia sẻ; GQA nhóm nhiều đầu Q quanh một đầu KV. Hãy đọc num_key_value_heads trong cấu hình khi trường này tồn tại và kiểm tra ý nghĩa của nó đối với kiến trúc.
Ví dụ, bốn mươi đầu Q và tám đầu KV tạo thành năm đầu Q cho mỗi nhóm KV. Công thức của bộ nhớ đệm được lưu dùng tám, không phải bốn mươi. Tỷ lệ này không mô tả toàn bộ bộ nhớ của attention: các phép toán hoặc chuyển đổi có thể tạo ra các biến tạm.
Đừng chỉ thay đổi con số này để giảm nhu cầu bộ nhớ của một mô hình đã được huấn luyện. Sơ đồ attention là một phần trong kiến trúc của nó. Hai mô hình có số đầu khác nhau không trở thành các biến thể tương đương chỉ bằng một phép tính dung lượng; chất lượng của chúng phải được đánh giá riêng.
Nguồn kỹ thuật: Hugging Face — các trường LlamaConfig và phân biệt MHA, MQA, GQA · PyTorch — kích thước Q/K/V và các ràng buộc của attention GQA
Đặt công thức và đơn vị của nó
Trong trường hợp đồng nhất, L là số lớp, Hkv là số đầu KV, D là kích thước của chúng, T là số vị trí được lưu giữ cho mỗi chuỗi, B là số chuỗi và q là số byte cho mỗi giá trị. Hệ số hai tính cả K và V. Phép xấp xỉ này giả định các khóa và giá trị có cùng kích thước và cùng định dạng, không nén cũng không chia sẻ tiền tố.
Chỉ chuyển đổi kết quả cuối cùng: một GiB bằng 1 073 741 824 byte; một GB thập phân bằng 1 000 000 000 byte. Hãy giữ đơn vị byte trong bảng của bạn để tránh việc làm tròn hoặc đổi đơn vị che mất một khác biệt.
Với các độ dài khác nhau mà không padding, hãy thay B × T bằng tổng các vị trí thực sự được lưu. Với các lớp không đồng nhất, hãy tính tổng theo từng lớp. Lưu trữ dày đặc kèm padding, cấp phát theo khối hoặc đặt trước tĩnh đòi hỏi phải đếm các vị trí đã cấp phát, vốn có thể vượt quá số token hữu ích.
Nguồn kỹ thuật: Hugging Face — kích thước các tensor của bộ nhớ đệm · NIST — đơn vị thập phân và tiền tố nhị phân
Ví dụ minh họa: sáu chuỗi, không đo GPU
Hãy lấy một kiến trúc giả định gồm bốn mươi lớp, tám đầu KV và kích thước 128. Giả sử một bộ nhớ đệm đồng nhất với hai byte cho mỗi giá trị. Mỗi chuỗi nhận tối đa 3 072 token đầu vào và một phần đặt trước cho 1 024 token bổ sung, tức giới hạn 4 096 vị trí. Đây là các giả định mang tính minh họa, không phải cấu hình đã được kiểm chứng của một mô hình.
Chi phí tính toán cho mỗi vị trí và mỗi chuỗi là 2 × 40 × 8 × 128 × 2 = 163 840 byte. Một chuỗi 4 096 vị trí khi đó tương ứng 671 088 640 byte, tức 0,625 GiB. Sáu chuỗi cho 4 026 531 840 byte, tức 3,75 GiB chỉ riêng cho bộ nhớ đệm.
Tăng gấp đôi độ dài được lưu giữ cũng tăng gấp đôi khoản này trong công thức. Thay tám đầu KV bằng bốn mươi đầu sẽ nhân nó lên năm lần, với mọi giả định khác không đổi. Những tỷ lệ này không báo trước bất kỳ sự tăng tốc, mất chất lượng hay khả năng tương thích nào của một mô hình thực tế.
| Số chuỗi B | Số vị trí T | Số đầu KV | Byte đã tính | GiB |
|---|---|---|---|---|
| 1 | 4 096 | 8 | 671 088 640 | 0,625 |
| 6 | 4 096 | 8 | 4 026 531 840 | 3,75 |
| 6 | 8 192 | 8 | 8 053 063 680 | 7,5 |
| 6 | 4 096 | 40 | 20 132 659 200 | 18,75 |
Điều chỉnh ngân sách theo chiến lược bộ nhớ đệm
Bộ nhớ đệm động lớn dần theo các vị trí được lưu giữ. Bộ nhớ đệm tĩnh đặt trước một dung lượng tối đa: hãy định cỡ phần đặt trước đó, chứ không chỉ dựa vào truy vấn ngắn quan sát được lúc khởi động. Với attention cửa sổ trượt, một số lớp có thể giới hạn lịch sử của chúng; các lớp attention đầy đủ đòi hỏi một phép tính riêng.
Lượng tử hóa bộ nhớ đệm và chuyển nó sang CPU là những chiến lược khác, phụ thuộc vào mô hình và phần mềm. Chúng thay đổi các ràng buộc về lưu trữ, truyền tải hoặc tính toán. Lượng tử hóa trọng số không chứng minh rằng bộ nhớ đệm có cùng định dạng.
Hãy ghi lại lớp bộ nhớ đệm và các tham số rõ ràng của nó. Cũng nên kiểm tra việc giải phóng các vị trí sau khi một yêu cầu kết thúc hoặc bị hủy. Với một tải trộn lẫn các chuỗi ngắn và dài, việc đặt trước tối đa đồng nhất có thể nặng hơn so với chỉ tổng nội dung hữu ích.
Nguồn kỹ thuật: Hugging Face — bộ nhớ đệm động, tĩnh, lượng tử hóa và chuyển sang CPU
Kiểm tra một tải đại diện theo từng bước
Hãy xây dựng ba trường hợp: đầu vào thông thường, đầu vào dài dự kiến và số yêu cầu đồng thời tối đa được phép. Cố định mô hình, tokenizer, gabarit, giới hạn sinh và quy tắc kết thúc. Hãy thay đổi từng chiều một; một câu trả lời bị rút ngắn hoặc một tài liệu bị cắt bớt sẽ thay đổi khối lượng công việc được thực hiện.
Hãy đo riêng thời gian tải, xử lý đầu vào ban đầu và sinh đầu ra. Đồng bộ device quanh các pha được tính thời gian, ghi lại mức bộ nhớ ban đầu và các đỉnh. Phương pháp ghi bộ nhớ giải thích vì sao allocated và reserved không cộng lại với nhau và vì sao hiệu giữa các cực đại của chúng không cô lập được cache.
Bài kiểm tra của bạn phải đưa ra một ngưỡng đã được thử nghiệm và các đầu ra chấp nhận được: ID của các request đã hoàn tất, lỗi, độ dài sinh ra và tiêu chí chất lượng. Một lần chạy trên đầu vào ngắn không xác nhận được mức đồng thời tối đa. Một lỗi bộ nhớ trước khi kết thúc không cấu thành phép đo nhu cầu của một lần chạy đầy đủ.
Nguồn kỹ thuật: PyTorch — đồng bộ công việc trên device đã chọn · PyTorch — phạm vi của các bộ đếm bộ nhớ
Loại bỏ những lỗi làm sai lệch lựa chọn
Đừng biến cache đã tính thành tổng dung lượng GPU. Hãy thêm phân tích về weights, activations tạm thời, các đầu ra được giữ lại và phần mềm. Cũng đừng tự động chia dung lượng này cho số card: việc đặt các lớp hoặc các head phải được cấu hình thực sự và kiểm tra trên từng device.
Notebook IteraGPU Lab là một bài tập đo đạc trên một mạng dense nhỏ không có attention. Nó giúp đọc các pha bộ nhớ; tham số context của nó không xác nhận phép tính KV này. Hãy dùng fiche tải và hồ sơ inference để chuẩn bị thử nghiệm cho model của riêng bạn.
Chỉ so sánh dung lượng của các gói sau khi đã phân biệt khối lượng số học, mức tối đa thực sự quan sát được và các trường hợp chưa được kiểm tra. Gói thuê tổ chức khung thời gian làm việc của bạn; nó không bảo đảm bất kỳ độ dài context hay tốc độ sinh nào.
- Nhầm lẫn giữa Q heads và KV heads: xem lại cấu hình của kiến trúc.
- Chỉ dự trù cho prompt: tính cả phần sinh và phần dự trữ thực tế.
- Đọc "weights 4 bit" thành "cache 4 bit": hãy ghi lại cả hai định dạng.
- Quên mức đồng thời: đếm các chuỗi thực sự thường trú.
- Hứa hẹn bộ nhớ chung giữa các card: kiểm tra việc đặt thực tế.
Câu hỏi thực tế
Tôi có thể biết cache KV chỉ từ số lượng tham số không?
Không. Còn cần kiến trúc của các lớp attention, các KV head, kích thước của chúng, định dạng cache, các vị trí được giữ lại và các chuỗi thường trú. Hai model có kích thước gần nhau có thể đòi hỏi ngân sách KV khác nhau.
Cache tĩnh có chỉ tiêu tốn độ dài request của tôi không?
Cần định cỡ dung lượng dự trữ của nó. Một request ngắn không cho phép suy ra mức phân bổ tối đa này. Hãy ghi lại các tham số của cache và đo cấu hình thực sự được tạo.
Kết quả của công thức có đủ để chọn card không?
Nó chỉ ước tính cache theo các giả định đã công bố. Việc chọn còn phải tính đến các khoản bộ nhớ khác, khả năng tương thích phần mềm và một lần thử đầy đủ với context, mức đồng thời và chất lượng mang tính đại diện.