// BLOG — 2026-09-16

Nhồi 26MB vào AI không nổi: chỗ đắt tiền không nằm ở model, mà ở cái phễu trước nó

Mấy hôm nay dân dev rần rần kể nhau chuyện một anh làm bảo mật thử đưa nguyên một cái dump dữ liệu nặng cỡ 26MB cho một model ngôn ngữ đọc. Kết quả: không xong. Nhưng phần đáng nói nhất…

# Nhồi 26MB vào AI không nổi: chỗ đắt tiền không nằm ở model, mà ở cái phễu trước nó

Mấy hôm nay dân dev rần rần kể nhau chuyện một anh làm bảo mật thử đưa nguyên một cái dump dữ liệu nặng cỡ 26MB cho một model ngôn ngữ đọc. Kết quả: không xong. Nhưng phần đáng nói nhất không phải là thất bại đó — mà là việc anh ấy làm sau đó: ngồi viết một công cụ riêng để bóp đống dữ liệu ấy lại cho vừa.

Mình đọc xong thấy hơi nhột. Vài tháng trước mình đã làm đúng cái trò ấy, và mất mấy ngày mới chịu thừa nhận một chuyện: cái mình sai không phải là chọn model. Cái mình sai là đã để cho quyết định "nhét bao nhiêu vào" nằm ở cuối pipeline thay vì ở đầu.

[QUOTE — câu mình tự viết dán lên tường:]

Cửa sổ ngữ cảnh rộng không phải là một lời giải. Nó là một lời mời nhét nhiều hơn — và hoá đơn thì đi theo số thứ mình nhét.


Bản năng đầu tiên khi dữ liệu không vừa, và vì sao nó luôn sai

Khi dữ liệu vượt ngưỡng, ai cũng có cùng một phản xạ: kiếm cái gì đó to hơn. Model mạnh hơn, cửa sổ ngữ cảnh rộng hơn, gói đắt hơn. Mình đã đi đúng con đường đó, và nó dạy mình bốn bài hơi đau.

Một — tiền không tăng cùng nhịp với giá trị. Chi phí xử lý tỉ lệ gần như thẳng với lượng dữ liệu đưa vào. Nhưng giá trị của kết quả thì không. Nhồi gấp mười lần dữ liệu hầu như không bao giờ cho ra kết quả tốt gấp mười lần. Có lúc còn tệ hơn, vì phần dữ liệu thêm vào toàn là phần lặp lại.

Hai — nhồi nhiều làm model mờ mắt, chứ không làm nó sáng hơn. Đây là chỗ mình thấy nhiều anh em chưa tin cho tới khi tự thử. Trong một khối ngữ cảnh khổng lồ, tín hiệu thật chỉ chiếm một tỉ lệ rất nhỏ. Model không bỏ sót theo kiểu "lỗi" — nó trả lời trơn tru, tự tin, và bỏ qua đúng cái chi tiết mình cần nhất, vì chi tiết đó bị chôn giữa một rừng thứ na ná nhau. Mình gọi trạng thái đó là đọc hết nhưng không thấy gì. Nó nguy hiểm hơn lỗi rõ ràng, vì lỗi rõ ràng thì mình biết đường sửa.

Ba — mất khả năng tái lập, và đó là án tử trong kinh doanh. Càng nhồi nhiều, cùng một câu hỏi chạy hai lần càng dễ ra hai kết luận khác nhau. Với một người ngồi nghịch thì đó là chuyện nhỏ. Với một dịch vụ thu tiền thì đó là câu hỏi mình không trả lời nổi: "sao lần trước anh báo tôi thế này, lần này lại thế kia?"

Bốn — không ai chịu trách nhiệm được cho một hộp đen mình không đọc nổi. Mình từng có một báo cáo mà chính mình không giải thích được nó lấy kết luận từ đâu, vì mình không thể đọc lại 26MB kia bằng mắt. Cái mình tạo ra không phải một hệ thống — nó là một cái máy trả lời mà chính chủ cũng phải tin suông.

Sau bốn bài đó, mình đổi câu hỏi. Không còn hỏi "model nào đọc được 26MB này", mà hỏi: trong 26MB này, có bao nhiêu phần trăm thật sự là tín hiệu? Câu trả lời thường ở mức một con số rất nhỏ — và cái nghề thật sự ở đây là đi tìm con số nhỏ đó, chứ không phải trả tiền để cho model đọc phần còn lại.


Phễu: giảm ở tầng rẻ nhất trước khi chạm tới tầng đắt nhất

Nguyên tắc mình đặt ra cho mọi pipeline có dữ liệu lớn — nghe thì hiển nhiên nhưng hầu như lần nào cũng bị vi phạm: thứ tự tầng là theo giá, không theo độ thông minh. Tầng rẻ nhất chạy trước, chưa chắc đúng nhưng đủ để cắt phần lớn khối lượng; tầng đắt nhất chạy cuối, trên một lượng dữ liệu mà nó thật sự cần.

Bốn tầng mình đang dùng, kể từ tầng rẻ nhất:

Tầng 0 — bóc cấu trúc, đừng đọc chữ. Một file 26MB gần như luôn chứa phần lớn là cấu trúc lặp: khuôn mẫu, header, định dạng lặp đi lặp lại, các trường không bao giờ đổi. Chuyện này không cần model. Nó là bài toán parse. Ngồi viết đúng một đoạn parse cho đúng định dạng, mình cắt được phần lớn khối lượng mà chưa tốn một token nào — và đây là tầng duy nhất mà chi phí bằng không thật, không phải "rẻ".

Tầng 1 — gửi phần đã đổi, đừng gửi toàn bộ trạng thái. Nếu mục đích của lần chạy này là "hôm nay có gì mới", thì phần lớn dữ liệu hôm nay là dữ liệu hôm qua viết lại. So sánh với lần chạy trước, chỉ giữ phần khác biệt. Cái này biến một đầu vào có kích thước tăng vô hạn thành một đầu vào gần như cố định — và đó là khác biệt giữa một hệ co giãn được và một hệ trả tiền ngày càng đắt cho cùng một kết quả.

Tầng 2 — nén phải có đường về. Đây là chỗ mình từng làm sai và đã trả giá. Nén xong, xoá bản gốc, đầu ra mỏng thật đấy — nhưng lần sau muốn kiểm tra lại một chi tiết thì chỉ còn một đường: chạy lại từ đầu. Mình gọi đó là tiết kiệm giả. Bản nén bắt buộc phải mang theo con trỏ về gốc: một chỉ dấu dòng, một khoảng, một số nhận dạng. Nén không phải là xoá. Nén là giảm khối lượng nhưng giữ nguyên khả năng quay lại.

Tầng 3 — chỉ gọi model trên phần còn lại, và gọi theo câu hỏi cụ thể. Sau ba tầng kia, cái tới tay model không còn là "đây, đọc hết đi", mà là "đây là một câu hỏi, đây là tập ứng viên liên quan, nếu không đủ thì nói là không đủ". Model làm đúng cái nó giỏi nhất: đọc ít, kết luận, và được phép trả về "thiếu dữ liệu". Cái quyền nói "không biết" đó quan trọng ngang với câu trả lời — nó là thứ giữ cho hệ không tự bịa.

Viết ra thì nó chỉ là một hàm ngắn thế này — pseudo-code minh hoạ, không phải nguồn triển khai:

# Pseudo-code minh hoạ — KHÔNG phải nguồn triển khai
def phan_tich(nguon_tho, cau_hoi):
    # Tầng 0: bóc cấu trúc, không tốn token
    ban_ghi = parse_theo_cau_truc(nguon_tho)

    # Tầng 1: chỉ giữ phần mới so với lần chạy trước
    ban_ghi_moi = diff_voi_lan_truoc(ban_ghi)

    # Tầng 2: nén nhưng mang theo con trỏ về gốc
    lat_cat = nen(ban_ghi_moi)          # mỗi dòng giữ (tệp, dòng, khoảng)
    ghi_log_da_luot(lat_cat)            # bỏ gì cũng phải biết là đã bỏ gì

    # Tầng 3: chỉ phần liên quan mới chạm tới model
    ung_vien = truy_theo_cau_hoi(lat_cat, cau_hoi)
    if lat_cat.qua_mong_cho(cau_hoi):
        return "chưa đủ dữ liệu để kết luận — cần xem thêm phần nào"
    return model(ung_vien, cau_hoi)     # trả kèm con trỏ để kiểm tra lại

Dòng log ở tầng 2 là dòng mình thêm vào sau vài lần đau. Bỏ mà không biết mình bỏ gì là nguồn gốc của mọi loại lỗi im lặng: hệ vẫn chạy êm, vẫn trả kết quả, chỉ là kết quả thiếu đúng một thứ không ai biết là nó từng tồn tại.


Nén nó rơi theo bậc, không rơi theo đường chéo

Kể bằng hình dạng thì anh em dễ thấy hơn là bằng con số tuyệt đối. Giả sử đầu vào thô là 100% — một dump cỡ vài chục MB, rơi vào khoảng vài triệu token nếu đếm thô bằng ký tự:

| Tầng | Còn lại (minh hoạ) | Ai làm |

|---|---|---|

| Dữ liệu thô | 100% | — |

| Sau bóc cấu trúc + gộp trùng | ~10–20% | luật/parse, gần như 0 token |

| Sau chỉ giữ phần đã đổi | ~1–3% | so sánh trạng thái, 0 token |

| Sau truy vấn theo câu hỏi | ~0,1–0,5% | một lần gọi model |

Ba dòng đầu của bảng này là chỗ mình học được điều quan trọng nhất: phần lớn công việc giảm khối lượng không cần AI chút nào. Mình từng coi chuyện đó là việc lặt vặt phải làm xong trước khi vào phần hay; hoá ra nó chính là phần hay. Số trong bảng là tỷ lệ minh hoạ cho thấy hình dạng, không phải số đo của một hệ cụ thể — nhưng hình dạng đó thì mình gặp lại ở mọi pipeline dữ liệu lớn mình từng chạm.

Và chú ý dòng cuối: chỉ một lần duy nhất chạm tới model, trên khoảng một phần mấy trăm dữ liệu ban đầu. Chất lượng ở đây thường tăng chứ không giảm, vì model không còn phải tự lọc giữa một rừng thứ na ná. Ít hơn mà đúng hơn.


Vì sao chuyện nén lại là chuyện tiền

Tới đây thì phần tiền gần như tự hiện ra, nhưng mình muốn nói rõ vì nó là lý do mình chịu bỏ buổi tối ngồi viết tầng 0.

Nếu chi phí leo theo dữ liệu, khách thành công sẽ làm mình phá sản. Một dịch vụ tự động hoá mà mỗi lần chạy lại trả tiền cho toàn bộ dữ liệu đầu vào thì có một nghịch lý chết người: khách càng dùng nhiều, càng nhiều dữ liệu, mình càng lỗ trên mỗi đơn. Khách nhỏ thì lỗ ít, khách ruột thì lỗ nặng. Cái phễu nén là thứ duy nhất biến đường chi phí đó từ dốc đứng thành gần như nằm ngang — và khi nó nằm ngang, mình mới dám bán dịch vụ phân tích cho những khách mà trước đây giá thành không cho phép chạm tới.

Nén xong thì mới được phép chọn mức theo việc. Trước khi nén mình không có lựa chọn nào: mọi việc đều phải ném vào con mạnh nhất, vì dữ liệu không vừa ở đâu khác. Sau khi nén, mình tách được theo bậc: việc trích và lọc thì một mức rẻ là đủ, việc kết luận mới cần mức mạnh. Mặc định dùng mức cao nhất cho mọi việc không phải là cẩn thận — nó là bỏ tiền để không phải nghĩ.

Và mỗi tầng nên trả tiền theo hình dạng công việc của nó. Đây là chỗ mình thấy một hướng đang được chia sẻ nhiều: tách tầng lập kế hoạch ra khỏi tầng thực thi, để tầng lập kế hoạch chạy trên một gói trả phí cố định, còn tầng thực thi trả theo lượng thật. Nghe như mẹo hoá đơn, nhưng logic bên trong thì đúng: "nghĩ nhiều, chạy ít" và "chạy nhiều, nghĩ ít" là hai hình dạng khác nhau, không nên bị nhét vào cùng một bảng giá.

Cuối cùng, cái này là trải nghiệm, không chỉ là hoá đơn. Một bài review về AI agent cho người dùng phổ thông mình đọc tuần này có điểm rất hợp chỗ này: thứ phân biệt sản phẩm thắng không phải sức mạnh model, mà là cảm giác khi dùng. Người dùng cuối không nhìn thấy số token — họ chỉ thấy chậm, thấy đắt, thấy câu trả lời nhảm. Pipeline nén gọn cho phản hồi nhanh, rẻ và nhất quán hơn; và nhất quán mới là thứ khiến người ta tin để quay lại lần hai.


Ba cái bẫy của việc nén, để anh em khỏi trả giá như mình

Nén mất đường về. Mình đã nói ở trên nhưng nói lại vì đây là cái mình thấy nhiều người dính nhất: tiết kiệm mà mất khả năng truy ngược là tiết kiệm giả. Bao giờ cũng giữ con trỏ.

Nén sai thì hỏng im lặng, tệ hơn cả lỗi. Lọc quá tay, bỏ mất một nhóm dữ liệu, hệ vẫn chạy trơn tru và trả kết quả tự tin. Không có báo lỗi đỏ nào cả. Cách chống duy nhất mình biết: bắt buộc ghi lại phần bị bỏ (bao nhiêu, loại gì), và có một cửa để nói "không đủ dữ liệu" thay vì cố trả lời.

Không đo thì không biết mình đang tiết kiệm hay đang tự lừa. Hai con số mình theo dõi từ đó tới nay: tỷ lệ dữ liệu thật sự đi vào model, và số lần phải chạy lại vì kết quả không dùng được. Con số đầu giảm mà con số thứ hai tăng thì mình không tối ưu — mình chỉ đang chuyển chi phí từ hoá đơn sang thời gian của chính mình.


Cái mình giữ lại

Nghề nén là một nghề kỳ lạ. Nó không hào nhoáng, không có bảng xếp hạng, không ai viết status khoe "hôm nay tôi nén được 99%". Nhưng nó là thứ duy nhất mình thấy cắt chi phí một cách thật — không phải cắt bằng cảm giác tiết kiệm — mà vẫn giữ, thậm chí tăng, chất lượng đầu ra.

Nên mình đã thôi chờ cửa sổ ngữ cảnh to hơn. Cửa sổ to là một lời mời nhét nhiều hơn, và mình đã thấy quá rõ cái nhét thêm chưa bao giờ là thứ quyết định chất lượng. Thứ quyết định chất lượng là cái mình chịu bỏ lại — và cái mình giữ con trỏ về để có thể quay lại bất cứ lúc nào.

Vậy nên câu hỏi mình để lại cho anh em: trong pipeline của anh em, tầng đắt nhất đang nhận bao nhiêu phần trăm dữ liệu — và trong phần đó, bao nhiêu thật sự là tín hiệu? Nếu con số đó làm anh em hơi khó chịu, thì anh em đang ở đúng chỗ mình từng ở.

Một phần của chuỗi mổ xẻ kỹ thuật tại zeodavu.com/blog. Nếu thấy hữu ích, theo dõi [zeodavu.com](/blog) — mỗi bài là một thứ mình thật sự dùng, vấp, và sửa lại.