jvinhit//lab

Search posts

Type to search across journal entries.

navigate open esc close

LLM Cost Optimization — 10 patterns giảm hóa đơn 50-95% không mất quality

Mọi đòn bẩy chi phí LLM quy về 3 nhóm: đừng gọi model, gọi nhẹ hơn, rẻ hơn mỗi token. 10 pattern thực chiến (prompt cache, semantic cache, routing, distillation, batch, quantization, self-host), cost math, và ROI framework.

LLM rẻ ở prototype, đắt ở production. Một startup xài GPT-4 vô tư khi có 100 user. Lên 100K user, hoá đơn $200K/tháng và founder bắt đầu mất ngủ. Tin tốt: phần lớn con số đó cắt được 50–95% mà không mất quality — nếu bạn hiểu tiền chảy đi đâu.

Cả bài này xoay quanh một nguyên lý gốc. Trước khi nhớ 10 pattern, hãy nhớ phương trình:

chi phí = (số lần gọi) × (số token mỗi lần) × (giá mỗi token)

Ý tưởng lớn nhất: mọi kỹ thuật tối ưu chi phí, không trừ cái nào, chỉ làm một trong ba việc:

  1. Đừng gọi model (giảm số lần gọi) — caching, batch defer.
  2. Gọi nhẹ hơn (giảm token mỗi lần) — cắt output, quản context, RAG.
  3. Rẻ hơn mỗi token (giảm đơn giá) — routing model nhỏ, distillation, batch discount, quantization/self-host.

Khi bí, hỏi: “đòn bẩy này thuộc nhóm nào, và nó đánh vào thừa số lớn nhất trong hoá đơn của mình chưa?”

Ôn lại nền tảng token/giá ở Tokens & Pricing.


1. Vì sao cost matters — math gây sốc ở scale

Chatbot 100K user, 5 query/ngày/user, mỗi query 2K input + 500 output, Claude 3.5 Sonnet (giá ví dụ $3/$15 per 1M):

Mỗi query: 2K×$3/1M + 500×$15/1M = $0.006 + $0.0075 = $0.0135
Mỗi ngày:  100K × 5 × $0.0135 = $6.750
Mỗi tháng: ~$202.500   →   mỗi năm: ~$2,43 triệu

$2,4 triệu/năm cho một con chatbot. Và cost scale tuyến tính theo user: mỗi 10× user = 10× hoá đơn. Nếu doanh thu không scale theo kịp, margin chết.

Ba thừa số trong phương trình tương ứng ba nguồn rò rỉ điển hình:

Thừa sốNguồn rò rỉ thường gặpPattern xử lý
Số lần gọiHỏi lại câu đã hỏi; gọi realtime việc không gấpPrompt cache, semantic cache, batch
Token/lầnOutput dài dòng; resend cả history + docs mỗi turnOutput reduction, context mgmt, RAG
Giá/tokenDùng model premium cho task tầm thườngRouting, distillation, quantization

Hiểu lầm thường gặp: “tối ưu chi phí = chọn model rẻ hơn.” Đó chỉ là thừa số thứ ba. Thường thì số lần gọitoken/lần mới là chỗ đốt tiền lớn nhất — và sửa chúng không hề đụng tới chất lượng.


NHÓM 1 — Đừng gọi model (giảm số lần gọi)

2. Pattern 1: Prompt Caching — tiết kiệm 50–90% phần cached

Provider lưu (cache) phần đầu của prompt. Lần sau gửi đúng prefix đó → tính giá rẻ hẳn.

Ẩn dụ: như quán quen nhớ “phần như mọi khi” của bạn. Họ không bắt bạn đọc lại toàn bộ order từ đầu mỗi lần — chỉ hỏi phần thay đổi hôm nay. Đây thực chất là CDN/HTTP cache nhưng cho prompt.

ProviderGiá input đã cache
Anthropic10% giá thường (giảm 90%)
Google Gemini25% giá thường (giảm 75%)
OpenAI50% giá thường (tự động)

Cấu trúc prompt cho cache-friendly: bất biến lên đầu, biến đổi xuống cuối.

[PREFIX bất biến — sẽ được cache]    system prompt · rules · tool defs · docs · few-shot
[TAIL biến đổi — tính giá full]      câu hỏi user · history mới nhất

Anthropic cần đánh dấu breakpoint tường minh:

client.messages.create(
    model="claude-3-5-sonnet-20241022",
    system=[{
        "type": "text",
        "text": "System prompt dài + rules + docs...",
        "cache_control": {"type": "ephemeral"},  # mốc cache
    }],
    messages=[...],
)

Tác động thật (RAG bot, 5,5K token prefix, cache hit ~80%): từ ~$1.650/ngày xuống ~$536/ngày — giảm 67% chỉ bằng một thay đổi cấu trúc, không đụng logic.

Cẩn thận (misconception): “cache luôn bật sẵn và luôn rẻ.” Không. Cache vỡ khi đổi dù một byte trong prefix (xáo thứ tự prompt là mất cache); TTL ngắn (~5 phút); và ghi cache đắt hơn gọi thường một chút — cần ≥2 hit mới hoà vốn. Đừng cache thứ chỉ dùng một lần.

3. Pattern 2: Semantic Cache — tiết kiệm 30–70% với query trùng ý

Khác prompt cache (của provider). Đây là cache của bạn, so khớp theo ý nghĩa chứ không phải khớp chính xác chuỗi:

Query → embed → tìm trong cache theo vector similarity
  ├── Hit (sim > 0.95)  → trả thẳng câu trả lời đã lưu (không gọi LLM)
  └── Miss              → gọi LLM, rồi lưu lại cho lần sau

Ẩn dụ: như cuốn sổ FAQ ở quầy lễ tân. Ai hỏi câu đủ giống một câu đã trả lời → đưa luôn đáp án trong sổ, khỏi gọi chuyên gia.

def cached_chat(query, threshold=0.95):
    qv = embed(query)                          # text-embedding-3-small, rất rẻ
    hit = vector_search(qv, k=1)
    if hit and hit[0].score > threshold:
        return hit[0].response                  # 0 token LLM
    resp = llm_call(query)
    cache.add(qv, resp)
    return resp

Hiệu quả nhất khi query lặp lại nhiều: FAQ bot, customer support, product Q&A. Chi phí embedding (~$0.02/1M token) rẻ hơn gọi LLM hàng trăm lần → ROI rất cao.

Bẫy: threshold cao quá (0.99) → ít hit; thấp quá (0.85) → trả sai cho câu nuance khác. Và phải scope theo user: “lương của tôi” của A khác của B. Đặt TTL 1–7 ngày để tránh stale.

4. Pattern 3: Batch API — tiết kiệm 50% cho việc không gấp

Việc không cần realtime (report hằng ngày, backfill embedding, moderation ban đêm, gán nhãn dữ liệu) → gửi batch, nhận sau 1–24h, giảm thẳng 50% (OpenAI/Anthropic/Google đều có).

Ẩn dụ: như giặt đồ giờ thấp điểm hay sạc xe ban đêm — cùng công việc, rẻ một nửa vì bạn nhường chỗ cho việc gấp của người khác.

batch = client.batches.create(
    input_file_id="file-abc",
    endpoint="/v1/chat/completions",
    completion_window="24h",
)

Đánh đổi: độ trễ giờ tính bằng giờ, không stream, phải gom request.


NHÓM 2 — Gọi nhẹ hơn (giảm token mỗi lần)

5. Pattern 4: Output Token Reduction — tiết kiệm 30–60%

Output đắt gấp 3–5× input, nên cắt output ăn tiền nhất.

❌ "Explain RAG"                                  → ~2.000 token, lan man
✅ "Explain RAG in 100 words. Bullet points. No intro." → ~200 token

Công cụ: ràng buộc độ dài rõ ràng; ép structured output (JSON ngắn hơn văn xuôi); stop sequences; max_tokens cap.

Misconception: “càng ngắn càng rẻ.” Sai ở mức tổng. Ép ngắn quá → thiếu thông tin → user hỏi lại → tổng cost cao hơn. Điểm ngọt thường là 60–80% độ dài mặc định.

6. Pattern 5: Smart Context Management — tiết kiệm 30–70% input

Context dài đốt tiền mỗi turn, vì toàn bộ history bị gửi lại liên tục (xem Tokens & Context Windows). Phần lớn chat dùng context lãng phí.

  • Trim + rolling summary: giữ 3–5 turn gần nhất + tóm tắt phần cũ thay vì gửi cả 20 turn.
  • Lazy loading: đừng paste cả @src/ “phòng hờ”; chỉ add file thật sự cần.
  • Fork hội thoại: đổi chủ đề → mở chat mới, đừng kéo lê context cũ.
  • RAG thay long context: tài liệu 100K token mà chỉ cần 1 fact → chunk + embed + lấy top-3 (~3K token) thay vì nhồi cả 100K. Xem RAG Guide.
def trim(history, keep=10):
    if len(history) <= keep:
        return history
    summary = llm_summarize(history[:-keep])     # nén phần cũ một lần
    return [{"role": "system", "content": f"Earlier: {summary}"},
            *history[-keep:]]

Ẩn dụ: như cuộc họp dài — đừng đọc lại toàn bộ biên bản mỗi lần ai đó phát biểu. Tóm tắt phần đã chốt, chỉ giữ chi tiết những phút gần đây.


NHÓM 3 — Rẻ hơn mỗi token (giảm đơn giá)

7. Pattern 6: Model Routing — tiết kiệm 60–90%, giữ quality

Không phải task nào cũng cần model lớn. Phân loại độ khó rồi route:

Query → classifier (rule hoặc LLM nhỏ)
  ├── Đơn giản ("dịch", "format JSON")     → GPT-4o-mini  (~$0.15/1M)
  ├── Trung bình ("giải thích hàm này")    → Claude Haiku (~$0.8/1M)
  └── Phức tạp ("design architecture X")   → Claude Sonnet (~$3/1M)

Ẩn dụ: như phân loại bệnh nhân (triage) ở phòng cấp cứu. Y tá đẩy ca nhẹ sang phòng khám thường, ca nặng mới tới bác sĩ chuyên khoa. Không ai đưa một vết xước giấy cho bác sĩ phẫu thuật chấn thương.

Classifier rule-based gần như free; classifier bằng LLM nhỏ chính xác hơn, cost ~$0.0001/query (không đáng kể). Vendor sẵn có: OpenRouter, Martian, NotDiamond.

Bắt buộc A/B test: routing có thể tụt quality. Giữ 10% traffic ở model premium làm đối chứng; nếu quality nhánh route không tụt quá 2–3% (user rating, conversion) thì router an toàn.

8. Pattern 7: Distillation — tiết kiệm 90–99% inference ở volume lớn

Dùng output của model lớn (teacher) để fine-tune model nhỏ (student). Kết quả: ~90–95% chất lượng teacher với giá student.

Ẩn dụ: như thợ cả dạy thợ học việc. Sau khi học đủ các ca quen thuộc, thợ học việc tự làm phần lớn công việc thường nhật với chi phí thấp; thợ cả chỉ vào cuộc khi gặp ca lạ.

One-time: chạy ~10K example qua GPT-4 (~$300) + fine-tune mini (~$100) ≈ $400
Per query: GPT-4 $0.02 → mini fine-tuned $0.001  (giảm ~95%)
Break-even: ~25K query. Ở 1M query/tháng → tiết kiệm ~$19K/tháng.

Nên distill khi: volume lớn (>100K query/tháng), task hẹp (1 domain), chấp nhận tụt 2–5% quality. Xem Fine-tuning Basics.

9. Pattern 8: Quantization (self-host) — giảm 50–75% VRAM, 30–50% latency

Nén weight từ fp16 xuống int8/int4 để model nhỏ vừa GPU rẻ hơn.

Ẩn dụ: như nén ảnh JPEG — file nhỏ đi nhiều, chất lượng giảm rất ít nếu chọn mức nén hợp lý.

Llama 3.3 70B:  fp16 140GB  →  int8 70GB  →  int4 35GB VRAM
FormatQuality dropVRAM giảm
fp16 → int8<1%50%
fp16 → int4 (Q4_K_M) ⭐2–5%75%
fp16 → int210–30%87.5%

Sweet spot production: int4 (Q4_K_M). Format: GGUF (Ollama, llama.cpp), AWQ (batch inference), GPTQ. Xem Open Source LLM Ecosystem.

10. Pattern 9: Streaming + Early Stop — tiết kiệm 10–30% (biến thiên)

Stream output; khi user bấm “Stop” (thấy AI đi lạc) → abort → không trả tiền cho phần output còn lại. Cần nút “Stop generation” rõ ràng trong UI.

11. Pattern 10: Self-host Break-even — tiết kiệm 70–95% ở scale rất lớn

API (Sonnet):   ~$0.0135/query
Self-host (Llama 70B, 2×H100 thuê ~$2.880/tháng):
  ~$0.000022/query ở 100% utilization
Break-even thô:  $0.0135 × N = $2.880  →  N ≈ 213K query/tháng

Misconception nguy hiểm nhất của cả bài: “self-host luôn rẻ hơn.” Break-even thô bỏ qua chi phí ẩn: DevOps ($5–20K/tháng nhân sự), SLA/độ tin cậy bạn tự gánh, quality Llama 70B < Sonnet ở nhiều task, và gánh nặng tự nâng cấp model. Thực tế thường 1M+ query/tháng mới đáng, và chỉ khi đã có đội DevOps.


12. ROI Framework — làm pattern nào trước

TIER 1 — Easy wins (tuần này)
  Prompt caching · Output reduction · Structured output · Streaming + stop
TIER 2 — Medium (tháng này)
  Model routing · Semantic cache · Context trim / RAG · Batch API
TIER 3 — High (quý này, cần team)
  Distillation · Quantization · Self-host · Custom batch pipeline

Quy tắc: đo trước, tối ưu sau, và đi từ Tier 1. Đừng nhảy thẳng self-host khi prompt caching còn chưa bật.

Monitoring tối thiểu

Theo dõi: cost/request (P50/P95/P99), cost/user, cache hit rate, phân bố model. Công cụ: Helicone, Langfuse, dashboard provider. Đặt alert: chi tiêu/ngày > ngưỡng, cost/user bất thường, cache hit tụt.

Production thực tế: các sản phẩm support-bot như Intercom Fin tính tiền theo mỗi lần giải quyết (per resolution) chứ không theo token — mô hình giá đó chỉ sống được nhờ caching + routing quyết liệt. Prompt caching (Anthropic ~90% off) và Batch API (50% off) là tính năng có thật, công khai, áp dụng được ngay hôm nay.


Key Takeaways

  • Một phương trình cai trị tất cả: chi phí = số lần gọi × token/lần × giá/token. Mỗi pattern chỉ đánh vào một thừa số.
  • Ba nhóm đòn bẩy: đừng gọi (cache, batch) · gọi nhẹ hơn (cắt output, context, RAG) · rẻ hơn mỗi token (routing, distillation, quantization).
  • Phần lớn tiền nằm ở số-lần-gọi và token/lần, không phải đơn giá — và sửa chúng không hạ chất lượng.
  • Output đắt gấp 3–5× input: cắt output là đòn bẩy trực tiếp nhất.
  • Caching là quả ngọt dễ hái nhất (50–90%), nhưng vỡ khi đổi 1 byte prefix và TTL ngắn.
  • Self-host chỉ đáng ở 1M+ query/tháng sau khi tính chi phí ẩn.

Common Mistakes

  • Đồng nhất “tối ưu chi phí” với “đổi model rẻ” — bỏ quên hai thừa số lớn hơn.
  • Nhảy thẳng self-host khi chưa bật prompt caching (free).
  • Cache thứ chỉ dùng một lần, hoặc xáo thứ tự prompt làm vỡ cache.
  • Ép output ngắn quá → user hỏi lại → tổng cost tăng.
  • Semantic cache không scope theo user → trả nhầm dữ liệu người khác.
  • Routing không A/B test → âm thầm tụt quality.
  • Tối ưu mà không monitoring → đoán mò, sửa sai chỗ.

When Should You Use This?

Quy môViệc nên làm
Prototype / <1K userĐừng tối ưu sớm. Bật prompt caching (free) là đủ. Tập trung vào product.
10K user (~$240K/năm)Tier 1 toàn bộ + bắt đầu routing & semantic cache. Dựng monitoring.
100K user (~$2,4M/năm)Tier 1+2 bắt buộc. Cân nhắc distillation cho task hẹp volume lớn.
1M+ userThêm Tier 3: self-host + quantization cho phần ổn định, vẫn dùng API cho phần khó.

Khi KHÔNG nên tối ưu: lúc còn tìm product-market fit, hoặc khi cost chưa phải ràng buộc thật. Tối ưu sớm = phức tạp hoá hệ thống cho một vấn đề chưa tồn tại. Đo đã, rồi mới cắt.

Quick Start Guide

Làm trong tuần này, theo thứ tự ROI giảm dần:

  1. Bật prompt caching — đưa system prompt + rules + docs lên đầu, giữ bất biến; với Anthropic thêm cache_control. (giảm 50–90% phần cached, ~0 công sức)
  2. Siết output — thêm “ngắn gọn, bullet, không mở bài” + max_tokens hợp lý vào prompt mặc định.
  3. Thêm nút Stop + streaming — ngừng đốt token khi AI đi lạc.
  4. Dựng monitoring — log cost/request + cache hit rate (Helicone / Langfuse) để biết tiền chảy đâu trước khi tối ưu sâu.
  5. Sau khi có số liệu: thêm model routing cho query đơn giản và semantic cache nếu traffic lặp lại nhiều.

Triết lý cuối cùng: đo trước, tối ưu sau. Không có dữ liệu = đoán mò = tối ưu nhầm thừa số.


Đọc thêm

Reference

  • Anthropic — Prompt Caching docs (giảm tới ~90% input đã cache)
  • OpenAI / Anthropic / Google — Batch API (giảm 50%)
  • “Optimizing LLM Cost” — Helicone blog series
  • vLLM throughput benchmarks
  • “Distilling the Knowledge in a Neural Network” — Hinton et al. 2015