OpenArchLabOpen Architecture — From Models to Systems

W3 · Training / inference workflow

Bước inference: kết thúc và trả văn bản

Kiểm tra điều kiện dừng, giải mã dần các token đã sinh thành văn bản trả về client rồi giải phóng trạng thái riêng của yêu cầu, gồm các khối KV cache.

LESSON ID wf-output GROUP Kiến trúc huấn luyện
Mục lục bài học

1Định nghĩa

Hoàn tất câu trả lời là chặng cuối của luồng suy luận, diễn ra khi vòng decode gặp token kết thúc (eos), khớp chuỗi dừng (stop string), chạm trần số token tối đa hoặc nhận tín hiệu hủy từ người dùng. Ở chế độ trả kết quả trực tiếp (streaming), từng mảnh chữ được giải mã tăng dần (incremental detokenization) qua tokenizer ngay khi mỗi token vừa sinh ra.

Ngay khi yêu cầu kết thúc, bộ lập lịch rút nó khỏi danh sách chạy ở vòng kế tiếp, và trình quản lý bộ nhớ thu hồi hoặc đánh dấu tái dùng các khối KV cache riêng của yêu cầu để nhường bộ nhớ HBM cho yêu cầu mới.

Ví dụ đời thường: Hoàn tất giống nhân viên phục vụ bưng từng đĩa vừa nấu xong ra bàn (streaming), và ngay khi khách dùng bữa xong rời bàn, nhân viên thu dọn bát đĩa, lau mặt bàn (giải phóng KV cache) để đón khách kế tiếp. Khác nhà hàng, có một số thứ như công thức nấu ăn chung (prefix cache dùng chung) không được dọn đi chỉ vì một vị khách rời bàn.

2Luồng

Đây là ô 5C, điểm cuối của băng dưới. Mũi tên vào mang từng token ID từ vòng decode; mũi tên ra mang văn bản cho client, và một mũi tên khác trả bộ nhớ cho hệ thống. Checkpoint và trọng số không bị đụng tới: chỉ trạng thái riêng của yêu cầu được dọn.

Sơ đồ kiến trúc huấn luyện · 22 ô (1A → 5C)

Kiến trúc huấn luyện LLM · Ánh xạ với Bài Lab tổng hợp

Thứ tự đọc: 1A → 1B ở cột 1, 2A → 2D ở cột 2, 3A → 3E ở cột 3; mũi tên next batch từ 3E quay về cột 1 và mũi tên load weights đi xuống băng 5 (5A → 5C). Cột 4 không phải bước kế tiếp: 4A, 4B tiết kiệm bộ nhớ, còn 4C–4G là các phương pháp huấn luyện thay thế nhau. Di chuột hoặc bấm vào từng ô để đọc pop-over.

Sơ đồ kiến trúc huấn luyện LLM gồm 22 ô từ 1A đến 5C
5C5 · Checkpoint → Inference
logits → sampling → text

5C · Output

Chọn token từ logits, kiểm tra điều kiện dừng và ghép các token thành văn bản trả về.

Nhận gì
Logits ở vị trí cuối từ ô 5B, ở mỗi bước của vòng decode.
Làm gì, vì sao
Đổi logits thành xác suất bằng softmax rồi sampling (chọn một token: lấy token điểm cao nhất hoặc rút ngẫu nhiên có kiểm soát), kiểm tra điều kiện dừng (token kết thúc hoặc đủ độ dài) và ghép các token đã chọn thành văn bản bằng tokenizer.
Ra gì
Văn bản trả về cho người dùng; trạng thái riêng của yêu cầu, gồm KV cache, được giải phóng.
Ví dụ, cách đọc ô
Nhãn ô: logits → sampling → text. Ví dụ trong lab: các token s, u, a, dấu chấm và token kết thúc ghép thành "sua." rồi dừng vì gặp token kết thúc.
Lưu ý
Chọn token là bước riêng chứ không phải phép tính của mô hình: cùng logits có thể cho văn bản khác nhau nếu đổi cách sampling.
Sơ đồ luồng (4 bước)
  1. Nhận token đã chọn

    Sampling đã xong; đọc token cùng giới hạn sinh của yêu cầu.

  2. Giải mã và kiểm tra chuỗi dừng

    Dùng tokenizer đúng phiên bản; giữ lại phần văn bản chưa chắc an toàn để gửi.

  3. Gửi phần văn bản đã xác nhận

    Stream các phần chắc chắn, lưu tiến độ gửi và lý do kết thúc.

  4. Ngừng xếp lịch và trả trạng thái riêng

    Không forward thêm cho yêu cầu đã dừng; trả các khối KV riêng theo chính sách cache.

Mã Mermaid
flowchart TD
  step1["Nhận token đã chọn"]
  step2["Giải mã và kiểm tra chuỗi dừng"]
  step3["Gửi phần văn bản đã xác nhận"]
  step4["Ngừng xếp lịch và trả trạng thái riêng"]
  step1 --> step2
  step2 --> step3
  step3 --> step4

3Giải pháp

Vị trí trên sơ đồ: ô 5C "Output" ở cuối băng "Checkpoint → Inference". Nó nhận từng token từ vòng decode (ô 5B) và gửi văn bản ra ngoài; không có phép tính ma trận mới. Đây là nơi duy nhất mà token ID được đổi ngược thành chữ cho người đọc.

Vấn đề cần giải. Vòng decode chỉ biết token ID. Người dùng cần chữ, cần nhận sớm (streaming), cần biết vì sao câu trả lời dừng, và hệ thống cần lấy lại tài nguyên đúng lúc để phục vụ người tiếp theo.

Khái niệm tối thiểu. Tokenizer ánh xạ ngược từ ID sang mảnh chữ. Một token có thể chỉ là một phần của ký tự hay của từ, nên giải mã từng token độc lập đôi khi cho ra ký tự hỏng. Điều kiện dừng gồm: eos, stop string, max_tokens, hủy. Streaming buffer giữ phần chữ chưa chắc chắn.

Ví dụ có số (minh họa, bảng từ vựng nhỏ: 3 = ăn, 4 = cá, 6 = eos). Vòng decode trả các ID [4, 6]. Token 4 giải mã thành “cá” và được gửi. Token 6 là eos, không hiển thị. Vòng dừng với lý do eos; văn bản cuối là “cá”. Nếu thay vào đó dịch vụ cho tối đa 2 token mới và mô hình sinh [4, 3] (“cá ăn”) thì dừng với lý do độ dài, không phải eos. Lý do kết thúc cần phân biệt để biết câu trả lời có bị cắt cụt hay không.

Stop string bị chia thành nhiều token. Dịch vụ cấu hình loại “<END>” khỏi response. Một mảnh là “ <EN”, mảnh sau là “D>bỏ qua”. Nếu gửi ngay “ <EN” thì lỡ khách đã thấy một nửa chuỗi dừng. Giải pháp: giữ hậu tố có thể là đầu của chuỗi dừng, nhận ra “<END>” khi mảnh sau tới, không gửi chuỗi dừng và cắt luôn phần sau nó (“bỏ qua”) theo quy định API.

Đánh đổi khi gửi. Gửi từng mẩu rất nhỏ làm tăng số lần gửi (chi phí phụ); gom nhiều mẩu giảm chi phí nhưng thêm độ trễ hiển thị. Khi yêu cầu kết thúc hoặc bị hủy, ngừng xếp lịch và giảm tham chiếu trạng thái riêng. Khối cache của prefix dùng chung có bộ đếm tham chiếu; chỉ giải phóng khi không còn yêu cầu nào dùng, không xóa vì một yêu cầu dừng.

Cách đọc đầu ra và giới hạn. Đầu ra gồm văn bản trả về, lý do kết thúc và số token đã sinh. Điều có thể kết luận: ghép các mẩu đã gửi phải bằng văn bản cuối theo cùng chính sách cắt stop string; đó là kiểm tra logic của bước này. Không thể kết luận: một phản hồi đúng định dạng không bảo đảm đúng nội dung; và việc dọn đúng không chứng minh độ trễ hay bộ nhớ đỉnh tốt.

Dùng lại checkpoint và cầu nối sang Inference Engineering. Vì checkpoint không đổi suốt quá trình, kết thúc một yêu cầu chỉ dọn trạng thái riêng của nó, không nạp lại hay ghi lại trọng số. Mỗi phần của ô này có bài riêng ở khóa Inference Engineering: chọn token và xuất văn bản, tokenizer, cổng tiếp nhận và kiểm soát yêu cầu, bộ nhớ đệm key và value và giữ dịch vụ ổn định. Hugging Face Transformers có sẵn stopping criteria và TextStreamer để xử lý điều kiện dừng và đưa chữ ra ngoài; việc hủy yêu cầu mạng và dọn tài nguyên engine vẫn cần tích hợp ở tầng phục vụ. Hai phương pháp huấn luyện thêm ảnh hưởng tới cách chọn eos và mẫu hội thoại: fine-tuning và distillation.

Để thấy vòng sinh kết thúc, ghép mẩu đã stream khớp văn bản cuối và cache riêng được giải phóng trong khi checkpoint được giữ, mở giai đoạn 13 · Từ checkpoint sang suy luận của Bài Lab tổng hợp. Hãy đoán trước lý do kết thúc của một prompt ngắn.

4Profiling

  • Đúng điều kiện dừng

    Kiểm tra các tình huống biên: eos ngay đầu response, stop string nằm vắt qua ranh giới hai token, nhiều stop string, max_tokens bằng 0 và hủy giữa chừng; ghi lý do kết thúc cùng số token đã sinh. Kết quả đúng ở các ca này cho thấy logic dừng đúng, không nói gì về chất lượng câu trả lời.

  • Stream khớp kết quả cuối

    Ghép các mẩu đã gửi rồi so với văn bản cuối theo cùng chính sách cắt stop string. Thử cả ký tự Unicode nhiều byte, vì giải mã từng token có thể cho ký tự dở dang. Dùng đúng quy tắc giải mã của tokenizer thật.

  • Độ trễ gửi và dọn yêu cầu

    Ghi thời điểm token sẵn sàng, văn bản được gửi và client nhận; đo thời gian từ lúc kết thúc hoặc hủy tới lúc ngừng xếp lịch và trả bộ nhớ riêng. Kiểm tra logic ở mức mã không đo mạng hay độ trễ của thiết bị; hai nhóm phép đo này phải làm riêng.

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ụ

Stop string bị chia làm hai token

Dịch vụ cấu hình loại “<END>” khỏi response. Một mảnh là “ <EN”, mảnh tiếp là “D>bỏ qua”. Bộ output giữ “ <EN”, phát hiện chuỗi hoàn chỉnh khi mảnh sau tới, không gửi chuỗi dừng hay phần “bỏ qua”. Tự kiểm tra: nếu gửi ngay “ <EN” thì client thấy gì và sai ở đâu? Client sẽ thấy một nửa chuỗi dừng mà hợp đồng yêu cầu ẩn; không rút lại được vì đã gửi.

Người dùng bấm dừng trong chatbot

Dịch vụ gửi tín hiệu hủy tới engine, chốt phần response đã có theo hợp đồng API, không sinh thêm cho yêu cầu và trả cache riêng. Prefix cache đang được yêu cầu khác dùng vẫn phải được giữ. Dự đoán: nếu engine bỏ qua tín hiệu hủy thì điều gì xảy ra? Nó vẫn sinh token và giữ cache cho người không còn đọc, lãng phí GPU và bộ nhớ.

Giới hạn trả lời ngắn

Dịch vụ cho tối đa hai token mới. Dù mô hình chưa chọn eos, vòng sinh vẫn dừng ở giới hạn; lý do kết thúc cần phân biệt hết ngân sách với kết thúc tự nhiên để client biết có thể câu trả lời bị cụt. Tự kiểm tra: với [4, 3] và max_tokens = 2, lý do là gì? Độ dài (length), không phải eos.

6Thuật ngữ

End-of-sequence token (eos)
Token đặc biệt báo hết chuỗi; dùng đúng mã của checkpoint và không hiển thị nó như văn bản.
Incremental detokenization
Giải mã dần các token đã sinh thành văn bản bằng tokenizer của mô hình, giữ trạng thái cần thiết (ví dụ ký tự UTF-8 dở dang) để tạo văn bản đúng.
Stop string
Chuỗi ký tự người dùng đặt làm điều kiện dừng; giữ hay cắt nó khỏi response tùy hợp đồng dịch vụ.
Streaming buffer
Phần văn bản tạm giữ trước khi gửi, ví dụ phần có thể là đầu của một chuỗi dừng chưa gõ xong.
Lý do kết thúc (finish reason)
Cho biết vì sao vòng sinh dừng: eos, stop string, hết max_tokens hoặc bị hủy.
Cancellation
Tín hiệu hủy yêu cầu, ví dụ khi người dùng ngắt kết nối; phải truyền tới bộ điều phối và bước dọn tài nguyên.
Glossary (5)
Prefix
Phần đầu chuỗi token; khối cache của prefix dùng chung có thể được giữ lại cho yêu cầu khác.
Cache
Bộ nhớ giữ kết quả để dùng lại; cuối yêu cầu, phần cache riêng được trả lại.
Overhead
Chi phí phụ, ví dụ mỗi lần gửi một mẩu rất nhỏ ra mạng.
Forward pass
Lượt tính xuôi; yêu cầu đã dừng không còn được xếp vào forward nữa.
Reference count
Số yêu cầu đang dùng chung một khối cache; chỉ khi bằng 0 mới an toàn giải phóng khối đó.

7Bài liên quan

8Nguồn