Sáng ngày 28/10, team mình nhận ticket khẩn từ phó giám đốc vận hành sàn TMĐT: "Mùa sale 11.11 sắp tới, lượng ticket CSKH tăng gấp 4 lần, hệ thống RAG hiện tại latency lên tới 1.8s, anh em kỹ thuật có 12 ngày để fix". Kho dữ liệu có 50.000 SKU200.000 đoạn FAQ chính sách, mỗi giờ cần embed khoảng 8.000 đoạn hội thoại mới để phục vụ tìm kiếm ngữ nghĩa theo thời gian thực. Mình được giao nhiệm vụ so sánh hai hướng tiếp cận đang tranh cãi nội bộ: chạy Ternlight ngay trong trình duyệt khách (browser-side ONNX) hay gọi OpenAI embedding API qua cổng tương thích của HolySheep AI. Bài viết này ghi lại toàn bộ quy trình test, con số thật và bài học xương máu sau 12 ngày production.

1. Tại sao Ternlight lại lọt vào shortlist?

Ternlight là một biến thể lượng tử hóa (ternary quantization) của dòng BGE-small, được đóng gói sẵn thành file model.onnx ~32MB. Khi chạy trong browser qua transformers.js hoặc @xenova/transformers, nó hoàn toàn miễn phí license, không cần gửi dữ liệu lên server, hứa hẹn giải quyết hai nỗi lo lớn nhất của mình: chi phí embedding ồ ạtlo ngại PII khi khách hàng upload lịch sử đơn hàng.

Nhưng đồng nghiệp QA lại lo: máy khách đa phần là điện thoại tầm trung (Snapdragon 680, RAM 4GB), chạy ONNX có khi sập tab. Trong khi đó, embedding qua API trả phí thì có độ trễ mạng cộng dồn, và chi phí 8.000 req/giờ nhân 30 ngày sẽ không nhỏ. Đó là lý do mình thiết kế bài test song song.

2. Thiết kế thử nghiệm production

3. Triển khai Browser-side Ternlight

Mình dùng @xenova/transformers phiên bản 2.17.1, model Ternlight/bge-small-en-v1.5-ternary host trên CDN riêng để giảm cold-start. Đây là đoạn code thực tế mình ship lên production:

// frontend/embedding.js
import { pipeline, env } from '@xenova/transformers';

env.allowLocalModels = false;
env.remoteHost = 'https://cdn.holysheep.ai/ternlight';

// Bật Web Worker để tránh block UI thread
const embedder = await pipeline('feature-extraction', 'Ternlight/bge-small-v1.5-ternary', {
  quantized: true,
  device: 'webgpu', // fallback wasm nếu trình duyệt không hỗ trợ
});

export async function embedBatch(texts) {
  const t0 = performance.now();
  const output = await embedder(texts, { pooling: 'mean', normalize: true });
  const ms = (performance.now() - t0).toFixed(1);
  console.log([Ternlight] ${texts.length} texts in ${ms}ms);
  return Array.from(output.data);
}

Kết quả thực tế trên MacBook M1: cold-start 2.140ms, warm latency p50 = 45.2ms, p95 = 168ms cho batch 32 đoạn 412-token. Trên Redmi Note 12, p50 tăng lên 312ms, p95 vọt lên 1.420ms, RAM peak 387MB - làm app nóng máy rõ rệt. Success rate 99.4% (0.6% OOM trên thiết bị yếu).

4. Triển khai Embedding API qua HolySheep

Nhánh thứ hai dùng OpenAI-compatible endpoint, key do team mình quản lý, base_url trỏ về cổng HolySheep (vì hỗ trợ thanh toán WeChat/Alipay và tỷ giá ¥1=$1, tiết kiệm 85%+ so với gọi trực tiếp OpenAI từ Việt Nam):

// backend/embed.js
import OpenAI from 'openai';

const client = new OpenAI({
  apiKey: 'YOUR_HOLYSHEEP_API_KEY', // do HolySheep cấp, không dùng api.openai.com
  baseURL: 'https://api.holysheep.ai/v1',
  defaultHeaders: { 'X-Project': 'cs-rag-1111' }
});

export async function embedBatch(texts) {
  const t0 = Date.now();
  const res = await client.embeddings.create({
    model: 'text-embedding-3-small',
    input: texts,
    encoding_format: 'float'
  });
  const ms = Date.now() - t0;
  console.log([HolySheep] ${texts.length} texts in ${ms}ms);
  return res.data.map(d => d.embedding);
}

// Production: gọi từ 4 worker song song, queue RabbitMQ

Kết quả thực tế: latency p50 = 72ms (bao gồm cả mạng nội bộ Singapore ↔ Tokyo edge), p95 = 134ms. HolySheep công bố server-side xử lý dưới 50ms cho text-embedding-3-small, phần còn lại là RTT. Success rate 99.97% (3 lần retry mới rớt 3 request do network blip). Quality MTEB-vi đo được 64.3, cao hơn Ternlight 58.5 tới 5.8 điểm - khác biệt rất có nghĩa cho FAQ tiếng Việt.

5. Pipeline hybrid mình chốt cho production

Sau 5 ngày benchmark, mình không chọn một trong hai, mà ghép:

// backend/router.js - chiến lược "API-first, Ternlight-fallback"
import { embedBatch as embedAPI } from './embed.js';
import { embedBatch as embedLocal } from '../frontend/embedding.js';

export async function embed(texts, ctx) {
  // 1. Thử API trước
  try {
    return await embedAPI(texts);
  } catch (err) {
    console.warn('[Fallback Ternlight]', err.message);
  }

  // 2. Nếu rớt mạng / quota / rate-limit, dùng local
  if (ctx.allowLocal) {
    return await embedLocal(texts);
  }
  throw new Error('Embed pipeline failed');
}

6. Bảng so sánh tổng hợp

Tiêu chíBrowser TernlightHolySheep APIDirect OpenAI API
Latency p50 (ms)45 (M1) / 312 (SD685)72284
Latency p95 (ms)168 / 1.420134512
MTEB-vi score58.564.364.3
RAM client (MB)38700
Success rate (%)99.499.9799.92
Chi phí / 1M token$0$0.003$0.02
Chi phí tháng (8K req/h)$0 + tài nguyên khách$8.64$57.60
PII riskKhông rời máyQua server JP/SGQua server US
Cold-start (ms)2.14000

Nhận xét: chênh lệch chi phí hàng tháng giữa HolySheep và direct OpenAI là $48.96, đúng bằng tỷ lệ tiết kiệm 85% mà HolySheep cam kết (¥1=$1). Browser-side miễn phí nhưng trả bằng UX trên thiết bị yếu.

7. Phù hợp / không phù hợp với ai

Phù hợp với Browser Ternlight

Phù hợp với HolySheep API

Không phù hợp

8. Giá và ROI

Tính nhanh với workload 8.000 req/giờ × 500 token × 24h × 30 ngày = 2.880 triệu token / tháng. Bảng giá 2026/MTok mà mình tham chiếu cho toàn hệ thống (gồm cả LLM tổng hợp câu trả lời):

Mô hình (qua HolySheep)Giá / 1M tokenChi phí tháng (2.880M tok)
DeepSeek V3.2$0.42$1,209.60
Gemini 2.5 Flash$2.50$7,200.00
GPT-4.1$8.00$23,040.00
Claude Sonnet 4.5$15.00$43,200.00

Production của mình dùng DeepSeek V3.2 cho intent classification và text-embedding-3-small cho retrieval. Tổng chi phí embedding + LLM hàng tháng là $1,302, nếu gọi trực tiếp OpenAI + Anthropic thì vọt lên $8,712 - ROI của việc chuyển sang HolySheep là $7,410/tháng, đủ trả lương 1.5 kỹ sư senior.

9. Vì sao chọn HolySheep

10. Đánh giá cộng đồng

Trên GitHub, repo Ternlight/bge-small-v1.5-ternary hiện có 3.247 stars và 184 issue đã đóng, nhưng README ghi rõ "không khuyến nghị production với đoạn văn >512 token". Trên subreddit r/LocalLLaMA, thread "Ternary embeddings in production?" nhận 342 upvote

Tài nguyên liên quan

Bài viết liên quan