W3 · Training / inference workflow
Bước inference: xử lý prompt và chọn token đầu tiên
Chạy toàn bộ token của prompt qua mô hình trong một lượt để lấp đầy KV cache ban đầu và lấy bảng logits ở vị trí cuối, từ đó chọn token trả lời đầu tiên.
1Định nghĩa
Prefill là pha đầu tiên của suy luận sau khi bộ lập lịch cấp lượt chạy cho mảng token từ bước tách token: worker đưa toàn bộ N token của prompt qua các lớp Transformer trong cùng một lượt tính song song. Vì mọi token đầu vào đã biết trước, không cần chờ nhau, và chính các phép tính đó là lượt forward quen thuộc ở cột 2 của sơ đồ, chỉ khác là trọng số đã đóng băng.
Tại mỗi lớp attention, cặp Key và Value của cả N vị trí được ghi vào KV cache trên HBM. Riêng bảng logits ở vị trí cuối prompt được chuyển sang bộ chọn token (sampling) để chọn token đầu tiên của câu trả lời, khép lại thời gian chờ token đầu (TTFT) và mở màn vòng decode.
Ví dụ đời thường: Prefill giống khoảnh khắc người phiên dịch nghe trọn vẹn câu hỏi của khách: nắm bắt toàn bộ ngữ cảnh trong một lần, ghi nhanh các ý chính ra sổ tay (KV cache) rồi bật ra ngay chữ đầu tiên của câu trả lời. Khác người phiên dịch, mô hình xử lý mọi từ của câu hỏi cùng lúc bằng phép nhân ma trận chứ không đọc tuần tự từng từ.
2Luồng
Đây là nửa đầu của ô 5B, ‘Prefill & decode’. Mũi tên vào mang N token ID; mũi tên ra mang hai thứ: KV cache (đi vào vòng decode) và một token đã chọn. Phép tính bên trong chính là cột 2 của sơ đồ, nhưng không có loss, backward hay cập nhật.
- Prompt đã thành token ID
Mảng ID shape (1, N) và vị trí 0 đến N − 1.
- Forward qua các lớp
Dùng đúng các ô 2A đến 2D như khi huấn luyện, song song cho cả N vị trí.
- Ghi Key và Value
Mỗi lớp lưu K, V của N vị trí vào KV cache.
- Chọn token đầu
Lấy logits ở vị trí cuối, chọn token, kiểm tra điều kiện dừng.
Mã Mermaid
flowchart TD
step1["Prompt đã thành token ID"]
step2["Forward qua các lớp"]
step3["Ghi Key và Value"]
step4["Chọn token đầu"]
step1 --> step2
step2 --> step3
step3 --> step4 3Giải pháp
Vị trí trên sơ đồ: nửa đầu của ô 5B "Prefill & decode" trong băng "Checkpoint → Inference". Phía trước nó là ô 5A (tách token), phía sau là vòng decode. Phần tính toán bên trong là chuỗi ô 2A đến 2D (forward) với các trọng số đã nạp từ checkpoint, không có ô 3A đến 3E.
Vấn đề cần giải. Để sinh token đầu tiên, mô hình cần hiểu cả prompt. Ngoài ra các token sinh sau sẽ lại cần Key và Value của prompt; nếu không lưu lại, mỗi bước sau phải tính lại toàn bộ prompt. Prefill làm cả hai việc trong một lượt.
Khái niệm tối thiểu. Prompt có N token. Mỗi lớp có n_kv đầu key/value, mỗi đầu có d_head chiều. KV cache lưu K và V cho mọi vị trí đã xử lý, ở mọi lớp. Số số trong cache = 2 (K và V) × số lớp × n_kv × số vị trí × d_head.
Ví dụ có số (minh họa). Prompt [1, 3] (“mèo ăn”) nên N = 2. Mô hình thu nhỏ: 2 lớp, n_kv = 2, d_head = 2, kiểu số 32 bit (4 byte). Sau prefill, cache có 2 × 2 × 2 × 2 × 2 = 32 số tức 128 byte; mỗi lớp giữ K và V shape (2, 2, 2) = (số đầu, số vị trí, d_head). Mỗi token mới sau này thêm 2 × 2 × 2 × 2 = 16 số = 64 byte.
Logits. Forward cho logits ở cả hai vị trí, nhưng chỉ logits ở vị trí cuối (sau “ăn”) dùng để chọn token tiếp theo; logits vị trí đầu (dự đoán chữ sau “mèo”) chính là bài tập của lúc huấn luyện và ở đây bị bỏ qua. Giả sử sau huấn luyện, logits ở vị trí cuối là [0,1; 0,2; 0,1; 0,3; 2,4; 0,2; 0,5] cho [pad, mèo, chó, ăn, cá, ngủ, eos] (số minh họa). Greedy chọn chỉ số 4, tức “cá”. Softmax cho xác suất của cá ≈ 0,59, các token khác từ 0,06 đến 0,09.
Cách đọc đầu ra. Có hai kết quả: cache đã đầy cho N vị trí và token đầu tiên “cá” (ID 4). Lưu ý token vừa chọn chưa có Key và Value trong cache, nó sẽ được tính khi được đưa vào forward ở bước decode đầu tiên. Cũng lưu ý ‘đã chọn cá’ chỉ nghĩa là cá có điểm cao nhất ở checkpoint này; không phải câu trả lời đã đúng hay hữu ích, và với sampling khác (nhiệt độ cao) kết quả có thể khác.
Thực thi và cầu nối sang Inference Engineering. Engine có thể chia prompt dài thành từng đoạn (chunked prefill) hoặc bỏ qua phần prefix đã có cache hợp lệ; kernel attention giảm số lần đọc ghi bộ nhớ giúp xử lý context hiệu quả hơn. Prefill thường tốn nhiều tính toán nhưng điểm nghẽn thực sự phụ thuộc mô hình, độ dài và kích thước nhóm, nên phải đo trước khi quyết định tối ưu phép nhân ma trận hay bộ nhớ. Xem xử lý prompt trước khi sinh, bộ nhớ đệm key và value và chọn token từ điểm số để đi sâu từng phần; tách máy xử lý prompt khỏi máy sinh token mô tả một cách tổ chức khi hai pha có đặc tính khác nhau.
Để chạy prefill bằng trọng số đã học và kiểm tra token đầu được chọn bằng greedy, mở giai đoạn 13 · Từ checkpoint sang suy luận của Bài Lab tổng hợp. Hãy tự đoán trước kích thước cache sau prefill từ số lớp, số đầu, N và d_head.
4Profiling
- Time to First Token
Thời gian từ lúc gửi yêu cầu đến token đầu tiên. Tách thành các phần: chờ trong hàng đợi, chuẩn bị đầu vào, prefill và xuất kết quả để biết phần nào chậm. Đo theo độ dài prompt khác nhau, không chỉ một độ dài, và ghi tải đồng thời.
- Tốc độ xử lý prompt và dùng lại prefix
Đếm số token đầu vào thực sự phải tính (không tính phần đã có trong cache), và so lần đầu với lần dùng lại cùng prefix. Trước khi nói prefix caching giúp ích, kiểm tra kết quả logits của hai đường (có cache và không có cache) trùng trong sai số số học.
- Kích thước cache sau prefill
Tính 2 × số lớp × n_kv × N × d_head × số byte mỗi số và đối chiếu với bộ nhớ thực tế bộ lập lịch đã đặt. Với ví dụ nhỏ là 128 byte. Sai khác lớn cho thấy cấu hình (số đầu, kiểu số) khác với giả định.
Mẹo đo lường: ghim số liệu trên workload thật, ghi cả p50/p95/p99 thay vì chỉ trung bình, và luôn ghi lại điều kiện chạy (batch, cache, đồng thời, phần cứng) trước và sau khi tối ưu. Số đo thiếu điều kiện chạy thì không so sánh được.
5Ví dụ
Tóm tắt tài liệu dài
Trước khi viết chữ đầu tiên, mô hình cần xử lý toàn bộ tài liệu; prompt dài làm tăng thời gian chờ ban đầu và tăng kích thước cache. Dự đoán: gấp đôi N thì kích thước cache thay đổi thế nào? Gấp đôi (tuyến tính theo N), còn thời gian prefill thường tăng nhanh hơn tuyến tính vì attention so mọi cặp vị trí, nhưng cần đo để biết cụ thể.
Hướng dẫn hệ thống lặp lại
Một engine có prefix caching có thể dùng lại phần đã xử lý nếu trạng thái mô hình và chuỗi token tương thích. Nếu hai yêu cầu cùng bắt đầu bằng 500 token hướng dẫn, 500 token đó chỉ cần prefill một lần. Chỉ cần một token khác trong phần chung là phần dùng lại bị cắt tại vị trí đó.
Tự kiểm tra: đọc logits vị trí cuối
Logits [0,1; 0,2; 0,1; 0,3; 2,4; 0,2; 0,5]: token nào được greedy chọn và xác suất xấp xỉ bao nhiêu? Đáp án: chỉ số 4 (cá), khoảng 0,59 (e^2,4 = 11,02 trên tổng khoảng 18,67). Hỏi thêm: token vừa chọn đã có K, V trong cache chưa? Chưa; K, V của nó chỉ có sau khi nó được đưa qua mô hình ở bước decode đầu tiên.
6Thuật ngữ
- Prefill
- Pha xử lý toàn bộ prompt đã biết, song song, trước khi sinh token mới.
- KV cache
- Bộ nhớ giữ cặp Key và Value của mọi token đã xử lý ở mỗi lớp để các bước sau không phải tính lại.
- Logits ở vị trí cuối
- Trong V điểm số của vị trí cuối prompt, điểm của mỗi token cho biết khả năng nó là token kế tiếp; sampling chọn token đầu tiên từ đây.
- Time to First Token (TTFT)
- Thời gian từ lúc gửi yêu cầu đến lúc có token đầu tiên, gồm chờ, tách token, prefill và chọn token.
- Greedy decoding
- Luôn chọn token có điểm cao nhất; xác định, không ngẫu nhiên.
Glossary (6)
- Tokenizer
- Bộ cắt văn bản thành token và tra ID; prefill nhận kết quả của nó.
- Prefix
- Phần đầu chuỗi token; prefix giống nhau có thể dùng chung kết quả prefill.
- Cache
- Bộ nhớ giữ kết quả dùng lại; ở đây là K và V của attention.
- Kernel
- Hàm tính toán chạy trên GPU, xử lý nhiều phần tử song song.
- Mask
- Quy tắc vị trí nào được nhìn nhau; prefill dùng cùng mask nhân quả như khi huấn luyện.
- Forward pass
- Lượt tính xuôi; prefill là một lượt forward trên cả prompt.
