Bộ 05 · Đòn bẩy tối ưu: prefix caching và lượng tử hoá
Hai đòn bẩy thay đổi hoá đơn: dùng lại phần việc của prompt, và lưu hoặc tính bằng ít bit hơn. Bài 03, 04, 06, 11, 14, 22, 40, 46–54, 59. Trả lời thành tiếng mỗi câu trong khoảng một phút, rồi mới xem thẻ.
Q1 · Một dòng động giết chết cache ưu tiên
Bài: 03, 11, 46, 47
Ghi chú
Một trợ lý hỗ trợ gửi khoảng 3.300 token prompt, 2.900 token trong số đó giống hệt nhau giữa các người dùng, nhưng prefix hit rate chỉ khoảng 1%. Bộ dựng prompt đặt request ID và thời gian hiện tại ở dòng 2. Vì sao các token giống hệt phía sau không dùng lại được, cách sửa là gì, và tiết kiệm được bao nhiêu với khoảng 32 µs mỗi token prompt?
Trả lời trong 60 giây
- Vì sao token giống hệt không dùng lại được: trong causal attention, K và V của mỗi token phụ thuộc vào mọi token trước nó. Vì vậy nếu một token ở dòng 2 khác đi, K và V của mọi token sau nó cũng khác, kể cả chỗ văn bản giống hệt.
- vLLM áp đặt điều này thế nào: nó cache theo block 16 token và dùng hash block nối chuỗi, trong đó hash của mỗi block bao gồm hash của block trước. Nghĩa là trượt ở block chứa dòng 2 làm mọi block sau cũng trượt, đó là lý do hit rate khoảng 1%.
- Cách sửa: chuyển request ID và thời gian xuống cuối prompt, hoặc bỏ hẳn chúng khỏi prompt. Quy tắc là nội dung ổn định trước và nội dung thay đổi sau cùng, để 2.900 token dùng chung tạo thành một prefix liền mạch.
- Tiết kiệm bao nhiêu: trước khi sửa, prefill tính cả 3.300 token, mất 3.300 × 32 µs ≈ 105 ms. Sau khi sửa, chỉ ≈ 3.300 − 2.900 ≈ 400 token chưa cache phải tính, mất 400 × 32 µs ≈ 13 ms. Vậy mỗi request tiết kiệm 105 − 13 ≈ 92 ms, và vì 105 ÷ 13 ≈ 8, prefill rẻ hơn khoảng 8 lần.
Các con số chính: một cache hit cần prefix giống hệt tính từ token 1.
Câu hỏi tiếp theo hay gặp: "Trên hoá đơn API nó đáng bao nhiêu?" Lấy các request có 3.000 token system đã cache, 200 token đầu vào mới và 300 token đầu ra, giá mỗi triệu token là 0,55 USD đầu vào, 0,14 USD đầu vào đã cache và 2,19 USD đầu ra. Không cache, 1.000 request gửi 3,2 triệu token đầu vào ở 0,55 USD (1,76 USD) cộng 0,3 triệu token đầu ra ở 2,19 USD (0,66 USD), nên tốn ≈ 2,42 USD. Có cache, 3 triệu token system xuống giá cache (0,42 USD), 0,2 triệu token mới vẫn ở 0,55 USD (0,11 USD), và đầu ra vẫn 0,66 USD, nên tổng ≈ 1,19 USD, khoảng một nửa. Đầu ra như nhau trong cả hai trường hợp vì token đầu ra không bao giờ được giảm giá.
Mẹo
Tôi đã giải thích vì sao block của chính ID bị trượt nhưng không giải thích vì sao các token giống hệt phía sau cũng trượt. Thời gian tiết kiệm là hiệu số (105 − 13 ms); tỷ số là speedup.
Q2 · 80% hit, nhưng không nhanh hơn 80% ưu tiên
Bài: 47, 04
Ghi chú
Với prefix hit rate 80%, PM kỳ vọng TTFT giảm 80% và response nhanh hơn 5 lần. Thay vào đó TTFT trung bình đi từ 108 → 68 ms, thời gian end-to-end của câu trả lời dài gần như không đổi, và một batch job với 49% hit được throughput đầu vào 1,82 lần. Giải thích cả ba.
Trả lời trong 60 giây
- Vì sao TTFT giảm ít hơn hit rate: cache chỉ bỏ được phần prefill đã cache. TTFT còn gồm các chi phí cố định mà cache không đụng tới, như lập lịch, prefill phần đuôi chưa cache và chạy bước decode đầu tiên. Đó là lý do TTFT giảm từ 108 xuống 68 ms, khoảng 37%, thay vì 80%.
- Vì sao câu trả lời dài gần như không đổi: một câu trả lời dài, giả sử 1.000 token đầu ra, dành phần lớn thời gian ở decode. Cache không làm gì cho decode, nên gọt bớt prefill gần như không thay đổi thời gian end-to-end.
- Vì sao batch job được 1,82 lần: đây là định luật Amdahl. Nếu một phần h của prefill đã được cache, chỉ còn 1 − h phải tính, nên speedup prefill tốt nhất có thể là 1 ÷ (1 − hit rate). Với 49% hit là 1 ÷ 0,51 ≈ 1,96 lần, và 1,82 lần đo được gần với trần đó.
Các con số chính: speedup prefill tối đa = 1 ÷ (1 − h).
Câu hỏi tiếp theo hay gặp: "Khi nào prefix caching quan trọng nhất?" Khi các prompt dùng chung một prefix dài và đầu ra ngắn, vì khi đó prefill chiếm phần lớn công việc và phần lớn có thể bỏ qua. Trường hợp điển hình là RAG, agent với tool schema lớn, và chat nhiều lượt.
Mẹo
Tôi đã giải thích các chiều hướng nhưng không giải thích vì sao TTFT giảm ít hơn hit rate (chi phí cố định), và không đưa ra trần 1 ÷ (1 − h).
Q3 · Lý tưởng 75%, đo được 30% ưu tiên
Bài: 46, 48
Ghi chú
Phát lại một giờ prompt thật với cách hash nối chuỗi 16 token của server cho hit rate lý tưởng 75%. Hits ÷ queries của vLLM trong cùng giờ đó cho 30%. Cái gì gây ra khoảng chênh? Và nếu lần phát lại cũng thấp, làm sao tìm ra dòng cần sửa?
Trả lời trong 60 giây
- Lần phát lại giả định gì: nó giả định bộ nhớ không giới hạn, một cache duy nhất và cùng cách lấy dấu vân tay như server. Vì vậy nếu tỷ lệ lý tưởng cao còn tỷ lệ đo được thấp, prompt vẫn ổn và chính server đang đánh mất việc tái sử dụng vì phá vỡ một trong các giả định đó.
- Bộ nhớ: nếu cache quá nhỏ, block bị đuổi trước khi cùng prefix quay lại, nên một lần lặp mà lần phát lại tính là hit lại thành trượt trên server.
- Lấy dấu vân tay: nếu server dùng chat template hoặc tokenizer khác, hoặc thêm cache salt theo tenant, nó hash những token khác với lần phát lại, nên các prefix trông giống hệt trong lần phát lại không khớp trên server.
- Một cache: với nhiều replica đứng sau một load balancer ngẫu nhiên, mỗi replica chỉ thấy một lát các lần lặp, nên nhiều lần lặp rơi vào replica chưa từng thấy bản đầu tiên.
- Nếu lần phát lại cũng thấp: khi đó chính prompt làm vỡ prefix. Vẽ một histogram điểm khác biệt đầu tiên, cho thấy vị trí token mà mỗi request lần đầu khác với request trước đó từ cùng ứng dụng. Một cột cao ở vị trí thấp chỉ ra dòng động.
Các con số chính: không có; đây là một chẩn đoán.
Câu hỏi tiếp theo hay gặp: "Metric nào cho thấy eviction?" Tìm mức dùng KV cache bị ghim ở mức cao trong khi hit rate giảm dưới tải. Để xác nhận, so hit rate ở tải thấp và tải cao: nếu nó chỉ giảm dưới tải, block đang bị đuổi trước khi được dùng lại.
Mẹo
Tôi đã không biết bắt đầu từ đâu. Lối vào: liệt kê những gì lần phát lại giả định, rồi hỏi server thật phá vỡ giả định nào.
Q4 · Chat nhiều lượt, rồi cắt bớt ưu tiên
Bài: 14, 40, 48
Ghi chú
Một cuộc chat có system prompt 1.000 token; mỗi lượt thêm một câu hỏi 100 token và một câu trả lời 300 token. Qua 6 lượt, bao nhiêu token prefill khi không tái sử dụng và khi có prefix cache hoàn hảo? Tới lượt 7, ứng dụng bắt đầu cắt message cũ nhất ở mỗi lượt: chuyện gì xảy ra?
Trả lời trong 60 giây
- Không tái sử dụng: lượt n gửi lại system prompt, n câu hỏi và n − 1 câu trả lời trước, tức 1.000 + 100n + 300(n − 1) token. Qua 6 lượt là 1.100 + 1.500 + 1.900 + 2.300 + 2.700 + 3.100 = 12.600 token. Mỗi lượt gửi lại mọi thứ trước nó, nên tổng tăng theo bình phương số lượt.
- Có prefix cache hoàn hảo: toàn bộ cuộc hội thoại trước đã được cache, kể cả các câu trả lời của chính model, vì K và V của chúng đã được tính trong lúc sinh câu trả lời. Vì vậy sau lượt 1, vốn tính 1.100 token của nó, mỗi lượt chỉ tính câu hỏi 100 token mới cộng block cuối đầy một phần, vốn không được cache. Tổng ≈ 1.640 token, ít hơn 12.600 khoảng 7 lần, và tăng tuyến tính.
- Cắt ở lượt 7: bỏ message cũ nhất làm thay đổi các token ngay sau system prompt. Vì hash block được nối chuỗi, mọi thứ sau điểm đó đều trượt, và chuyện này lặp lại ở mỗi lượt. Vậy mỗi lượt phải tính lại ≈ 2.100 token thay vì ≈ 100.
- Cách tốt hơn: giữ cuộc hội thoại chỉ nối thêm. Khi buộc phải cắt, hãy thỉnh thoảng cắt một khúc lớn, hoặc tóm tắt một lần, để thỉnh thoảng mới phải trả giá tính lại toàn bộ thay vì ở mỗi lượt.
Các con số chính: prefix caching biến prefill bậc hai của một cuộc hội thoại thành bậc nhất.
Câu hỏi tiếp theo hay gặp: "Block của một request đã xong trong vLLM sẽ ra sao?" Chúng trở về free queue nhưng vẫn giữ KV đã cache, nên lượt sau vẫn dùng lại được cho tới khi chúng bị ghi đè. Block sâu nhất bị ghi đè trước, vì chúng ít được chia sẻ nhất.
Mẹo
"Giữ phần cũ nhất" quá mơ hồ. Hãy nói rõ: mọi thay đổi gần phần đầu đều tốn một lần tính lại toàn bộ, nên hãy cắt ít lần và cắt cả khối.
Q5 · Thứ tự RAG, định tuyến replica và cách ly tenant ưu tiên
Bài: 47, 48
Ghi chú
Một prompt RAG gồm 800 token hướng dẫn, 5 đoạn × 300 token, rồi một câu hỏi 50 token. Hai người dùng nhận cùng các đoạn nhưng theo thứ tự khác. Dùng lại được bao nhiêu, và làm sao gần tới 100%? Chuyện gì xảy ra với 4 replica sau round-robin, và làm sao ngăn khách hàng A và B dùng chung K/V đã cache?
Trả lời trong 60 giây
- Thứ tự đoạn khác nhau: prompt dài 800 + 5 × 300 + 50 = 2.350 token, nhưng hai prompt khác nhau ngay ở đoạn đầu tiên, nên chỉ 800 token hướng dẫn khớp. Đó là 800 ÷ 2.350 ≈ 34% được dùng lại.
- Gần tới 100%: sắp các đoạn theo một khoá ổn định, như document ID, để cả hai người dùng thấy chúng theo cùng thứ tự. Khi đó họ dùng chung phần hướng dẫn và cả năm đoạn, 800 + 1.500 = 2.300 token, tức 2.300 ÷ 2.350 ≈ 98%.
- Bốn replica sau round-robin: một lần lặp chỉ rơi vào replica giữ bản cache ≈ 1 trên 4 lần. Cách sửa là định tuyến theo hash prefix, hoặc theo session ID với chat. Định tuyến theo request ID không giúp gì, vì mỗi request có một ID duy nhất.
- Độ mịn của block: chỉ block 16 token đầy đủ được cache, nên với prompt 1.500 token, phần dùng lại được là 16 × ⌊1.500 ÷ 16⌋ = 16 × 93 = 1.488 token.
- Cách ly tenant: trộn một cache_salt theo tenant vào hash. Khi đó cùng văn bản từ hai tenant khác nhau cho hash khác nhau và không bao giờ khớp, mà cache vẫn bật.
Các con số chính: dùng lại được = 16 × ⌊số token ÷ 16⌋.
Câu hỏi tiếp theo hay gặp: "Định tuyến theo prefix có nhược điểm gì?" Một prefix nóng dồn toàn bộ lưu lượng của nó vào một replica, có thể làm replica đó quá tải. Vì vậy bạn cần phương án dự phòng có tính tới tải, gửi request đi nơi khác khi replica đó bận.
Mẹo
Tôi đã nói định tuyến "theo request ID hoặc một hash nào đó". Request ID rải request y như round-robin; khoá phải là prefix dùng chung.
Q6 · RadixAttention, eviction và churn ưu tiên
Bài: 47, 49
Ghi chú
Hai prompt dùng chung 47 token đầu: vLLM dùng lại bao nhiêu, và RadixAttention của SGLang dùng lại bao nhiêu? Dưới áp lực bộ nhớ, SGLang đuổi cái gì? Và một cache chứa được 4 prefix trong khi lưu lượng xoay vòng qua 5 (A tới E, hai lần): bao nhiêu hit với LRU?
Trả lời trong 60 giây
- Dùng lại prefix chung 47 token: vLLM chỉ dùng lại block 16 token đầy đủ, và 47 token chứa hai block đầy, nên nó dùng lại 32 token. RadixAttention của SGLang so khớp từng token, nên nó dùng lại cả 47.
- SGLang đuổi gì: nó không bao giờ đuổi một node đang được dùng, tức reference count lớn hơn 0. Trong số còn lại, nó đuổi lá LRU (lâu nhất không được dùng) trước, đó là lý do thân cây dùng chung như system prompt sống lâu nhất.
- 5 prefix qua một LRU 4 chỗ: mỗi prefix bị đuổi ngay trước khi nó quay lại, nên 0 trên 10 lần hit. Thêm một chỗ là cả 5 vừa, nên lượt đầu trượt và lượt hai trúng, cho 5 trên 10.
- Lập lịch có tính tới cache: phục vụ request có prefix đã cache dài nhất trước sẽ chạy hết một nhóm request trong khi prefix của chúng còn trong cache. Rủi ro là bỏ đói các request không chung prefix nào, vì chúng cứ bị đẩy lùi.
Các con số chính: working set chỉ hơi lớn hơn kích thước cache cho số hit gần bằng 0 với LRU.
Câu hỏi tiếp theo hay gặp: "Bạn sửa churn thế nào mà không thêm bộ nhớ?" Gom nhóm hoặc sắp xếp lại request theo prefix để request của mỗi prefix chạy cùng nhau, và ghim các prefix nóng nhất để chúng không bị đuổi.
Mẹo
Tôi đã bỏ sót quy tắc ghim (node đang dùng thì không đụng tới được) và gọi bỏ đói là "không còn chỗ cho cái ngắn hơn".
Q7 · Outlier, AWQ, GPTQ và SmoothQuant ưu tiên
Bài: 51, 52
Ghi chú
Vì sao vài giá trị outlier làm lượng tử hoá bit thấp trở nên khó, và AWQ, GPTQ, SmoothQuant mỗi cái lách vấn đề đó thế nào?
Trả lời trong 60 giây
- Vì sao outlier gây hại: mọi giá trị trong một nhóm dùng chung một scale, và một giá trị lớn quyết định scale của cả nhóm. Vì vậy lưới giãn ra để vừa nó, và các giá trị nhỏ bị làm tròn về 0. Nhóm nhỏ, như 128 trọng số hay 16 của NVFP4, hạn chế thiệt hại vì một outlier chỉ làm hỏng nhóm của chính nó.
- AWQ (chỉ trọng số, 4-bit): khoảng 1% kênh trọng số quan trọng nhất, và bạn tìm ra chúng nhờ activation lớn. AWQ phóng to các trọng số đó trước khi làm tròn để chúng có lưới mịn hơn, và chia activation tương ứng cho cùng hệ số để đầu ra không đổi.
- GPTQ (chỉ trọng số): nó lượng tử hoá ma trận theo từng cột và đẩy sai số làm tròn của mỗi cột sang các trọng số chưa lượng tử hoá, để lần làm tròn sau bù lại và các sai số triệt tiêu nhau. Nó đủ rẻ để lượng tử hoá một model 175B trong ≈ 4 GPU-giờ.
- SmoothQuant (W8A8): ở đây outlier nằm trong activation. Nó chia mỗi kênh activation cho một hệ số s và nhân trọng số tương ứng với s, nên tích không đổi nhưng cả hai giờ đều vừa INT8. Nghĩa là phép tính chạy ở 8 bit, nhanh hơn ≈ 1,5 lần và dùng nửa bộ nhớ.
Các con số chính: nhóm 128 với scale 16-bit tốn 4 + 16 ÷ 128 = 4,125 bit mỗi trọng số.
Câu hỏi tiếp theo hay gặp: "Mỗi định dạng mất mát tới đâu?" FP8 về cơ bản không mất mát. INT8 W8A8 mất khoảng 1–3%. Một bản lượng tử hoá 4-bit tốt giữ được khoảng 99% điểm gốc trên phần lớn benchmark.
Mẹo
Tôi đã nói AWQ cũng lượng tử hoá activation (nó chỉ lượng tử hoá trọng số) và bỏ sót thứ SmoothQuant mở khoá được (phép tính 8-bit).
Q8 · Vì sao 4-bit hết có lợi ở batch lớn ưu tiên
Bài: 50, 51, 53, 59
Ghi chú
Một model AWQ 4-bit với kernel Marlin nhanh hơn BF16 khoảng 3,5 lần ở batch 1, khoảng 1,5 lần ở batch 128, và hoà vốn ở prefill dài. Vì sao? Vì sao một kernel nở cả ma trận ra 16 bit trước lại chậm hơn cả BF16 thông thường? Bạn sẽ dùng gì cho một workload nặng về throughput trên H100?
Trả lời trong 60 giây
- Batch 1: một bước batch 1 bị giới hạn bởi việc đọc trọng số. Trọng số 4-bit ít byte hơn 16-bit 4 lần, nên bước nhanh lên gần 4 lần, hoặc ≈ 3,9 lần khi tính cả scale (16 ÷ 4,125 ≈ 3,9).
- Batch 128 và prefill dài: batch lớn hơn dùng lại mỗi trọng số cho nhiều token hơn, nên giới hạn chuyển từ byte sang phép tính. Phép tính vẫn chạy ở 16 bit, và kernel còn phải giải nén mọi tile, nên lợi thế của 4-bit co lại còn khoảng 1,5 lần và mất hẳn ở prefill dài.
- Vì sao nở trước chậm hơn BF16: một kernel ngây thơ đọc trọng số 0,5 byte, ghi lại thành 2 byte, rồi đọc lại 2 byte đó, tức 0,5 + 2 + 2 = 4,5 byte mỗi trọng số so với 2 byte của BF16 thông thường. Kernel tốt giải nén trong register và không bao giờ ghi trọng số 16-bit ngược lại bộ nhớ.
- Throughput trên H100: dùng FP8 W8A8. Cả trọng số và activation đi thẳng vào tensor core 8-bit, scale được áp một lần ở cuối, nên bạn được ≈ 2 lần phép tính (1.979 so với 989 TFLOPS). Vậy lựa chọn là 4-bit chỉ trọng số cho chatbot ưu tiên latency, và FP8 W8A8 cho batch job chạy qua đêm.
Các con số chính: 4-bit chỉ trọng số tiết kiệm byte; 8-bit trọng số + activation tiết kiệm phép tính. Prefill 2.000 token ≈ 32 ms phép tính so với < 5 ms đọc trọng số.
Câu hỏi tiếp theo hay gặp: "Một đồng nghiệp test 4-bit với prompt 2.000 token và max_tokens=1, không thấy thay đổi, và muốn bỏ nó." Bài test đó chỉ đo prefill, tức TTFT, mà prefill là compute-bound, nên trọng số nhỏ hơn gần như không thay đổi nó. Hãy benchmark decode thay vào đó: dùng prompt ngắn cố định và câu trả lời dài, và so TPOT. Nói chung, đánh giá prefill bằng MFU và decode bằng MBU, vì một bước decode chạy ở 1% MFU là bình thường.
Mẹo
Tôi đã không biết bắt đầu từ đâu. Hãy hỏi trước: workload này bị giới hạn bởi byte hay bởi phép tính?
Q9 · "Chỉ 0,8 điểm, ship thôi" ưu tiên
Bài: 06, 22, 54
Ghi chú
Model 4-bit đạt 71,2% so với 72,0% của BF16 trên 1.000 câu hỏi, và PM nói "chỉ 0,8 điểm, ship thôi." Bạn sẽ chạy những kiểm tra nào trước, và vì sao điểm số chưa đủ?
Trả lời trong 60 giây
- Trung bình che giấu các lần lật: một số câu trả lời có thể đi từ đúng sang sai trong khi số khác đi từ sai sang đúng, và điểm vẫn như cũ. Microsoft thấy độ chính xác dịch chuyển 2% hoặc ít hơn trong khi tới 13,6% câu trả lời bị lật.
- Khoảng cách so với bản gốc: đo tần suất token cao nhất khớp và KL divergence so với model BF16. Việc này không cần nhãn, chạy trong vài phút, và bắt được các lần chuyển đổi hỏng.
- Mức nhiễu nền: chạy baseline với chính nó trong cùng engine dưới tải, vì riêng batching đã làm một số câu trả lời thay đổi. Chỉ những lần lật vượt trên mức nền mới tính là lỗi của model 4-bit.
- Thanh sai số theo cặp: mỗi điểm số riêng lẻ có ±2,8 điểm, rộng hơn khoảng chênh 0,8, nên hãy so theo từng câu hỏi. Với 34 câu đi từ sai sang đúng và 42 câu đi từ đúng sang sai, hiệu số là −0,8 ± 1,7 điểm. Không có ý nghĩa thống kê, nhưng bạn vẫn nên đọc 42 câu đó.
- Sản phẩm của chính bạn: chấm vài trăm prompt thật, với template và độ dài của bạn, đặt cạnh nhau. Quyết định bằng một quy tắc viết ra trước khi chạy.
Các con số chính: ±1,96 × √(p(1 − p) ÷ n) ≈ ±2,8 ở n = 1.000, p ≈ 0,72.
Câu hỏi tiếp theo hay gặp: "Temperature 0 làm nó tất định mà, sao cần mức nhiễu nền?" Vì kích thước batch làm thay đổi phép tính, cùng một prompt có thể cho đầu ra khác nhau tuỳ cách nó được batch. Trong một bài test, 1.000 lần chạy một prompt ở T = 0 cho ra 80 kết quả khác nhau.
Mẹo
Tôi chỉ nêu các lần lật và đánh giá sản phẩm, và bỏ sót thanh sai số theo cặp.
Q10 · "4-bit mất 10 điểm" so với giữ lại 98,9% ưu tiên
Bài: 51, 54
Ghi chú
Một bài blog nói Llama 3.1 4-bit mất 10 điểm về code; nghiên cứu 500.000 lần đánh giá của Red Hat thấy 4-bit giữ lại 98,9% trên HumanEval. Cái gì giải thích khoảng chênh, và 98,9% có nghĩa là người dùng nhận cùng câu trả lời không?
Trả lời trong 60 giây
- Cấu hình không khớp: nếu bài blog dùng chat template không khớp hoặc system prompt sai, model bị hại bởi cấu hình, không phải bởi lượng tử hoá.
- Chấm điểm quá nhạy: kiểm tra khớp chính xác hoặc kiểm tra định dạng đánh một câu trả lời đúng nhưng diễn đạt khác thành sai, nên điểm giảm dù câu trả lời đúng. Bộ đánh giá nhỏ còn thêm nhiễu.
- Giữ lại không có nghĩa là giống hệt: giữ lại 98,9% so sánh điểm trung bình, nên nhiều câu trả lời riêng lẻ vẫn có thể bị lật trong khi trung bình giữ nguyên. Để biết người dùng có nhận cùng câu trả lời không, hãy kiểm tra số lần lật so với mức nhiễu nền và chạy prompt của chính bạn.
Các con số chính: 8-bit giữ lại > 99%; 4-bit 98,9% trên HumanEval (Red Hat, Llama 3.1).
Câu hỏi tiếp theo hay gặp: "Bộ đánh giá của bạn cho thấy giảm mạnh. Bạn kiểm tra gì đầu tiên?" Tôi sẽ kiểm tra chat template và script chấm điểm trước, rồi mới đổ lỗi cho trọng số.
Mẹo
Tôi đã không biết bắt đầu từ đâu. Trước khi đổ lỗi cho model, hãy hỏi bản thân bài test có được thiết lập đúng không.
Tự xây
exercises/02_prefill_tokens.py: đếm số token prefill của cả fleet với định tuyến round-robin so với định tuyến theo prefix trên 4 replica. Chạyuv run exercises/02_prefill_tokens.py.