Product Management
Đăng nhập
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Bài 2 — ASR thực chiến: chọn engine, streaming và endpointing

Đã đọc 0/7 mục · còn khoảng 3 phút
Cách chúng tôi ghi nhận

Một mục được tính là đã đọc khi nó nằm giữa màn hình đủ lâu so với độ dài của nó (bảng và sơ đồ tính một nửa), bạn vẫn đang cuộn hoặc bấm phím, và bạn đã thấy tới cuối mục. Lướt nhanh hoặc để tab mở không được tính. Chúng tôi chỉ lưu thời gian đọc từng mục — không lưu gì khác.

ASR là cửa ngõ của mọi voice agent. Nếu text đầu ra sai, LLM dù thông minh đến đâu cũng trả lời trật. Bài này tập trung vào việc chọn và cấu hình ASR để nó chạy được trong hội thoại thời gian thực, không chỉ để "gõ lại băng ghi âm".

Batch vs Streaming ASR

  • Batch (file): gửi cả file audio, chờ transcript. Phù hợp voice message, phụ đề. Độ chính xác cao nhất nhưng phải chờ khách nói xong.
  • Streaming (realtime): gửi audio theo từng chunk (ví dụ 20ms), nhận transcript tăng dần (partial → final). Bắt buộc cho hội thoại trực tiếp.
Trong streaming có hai loại kết quả:
  • Partial (interim): transcript tạm, thay đổi liên tục. Dùng để hiển thị caption và để phát hiện barge-in.
  • Final: transcript đã ổn định cho một câu/đoạn. Dùng để feed vào LLM.
# Pseudocode xử lý stream ASR
async for event in asr_stream(mic_chunks):
    if event.type == "partial":
        ui.show_caption(event.text)      # hiển thị mờ
    elif event.type == "final":
        buffer.append(event.text)
        if endpoint_detected(event):     # khách đã dứt lời?
            send_to_llm(buffer.flush())

Endpointing: bài toán "khách nói xong chưa?"

Đây là phần khó bị đánh giá thấp nhất. Có ba tín hiệu để quyết định:

  • VAD (Voice Activity Detection): phát hiện có tiếng nói hay im lặng.
  • Silence timeout: im lặng bao lâu thì coi là hết câu (ví dụ 500-800ms).
  • Semantic endpointing: dùng ngữ nghĩa — "số điện thoại của tôi là không chín ba..." rõ ràng chưa xong dù có khoảng lặng.
Các bước cấu hình endpointing:

  • Đặt silence_threshold ban đầu ~700ms cho hội thoại thông thường.
  • Giảm xuống ~400ms cho câu trả lời ngắn (có/không, số).
  • Tăng lên ~1200ms khi ngữ cảnh là đọc dãy số dài, địa chỉ.
  • Kết hợp semantic: nếu câu kết thúc bằng liên từ ("và", "nhưng", "là") thì chờ thêm.

Tối ưu độ chính xác cho tiếng Việt

  • Chọn model hỗ trợ tiếng Việt tốt và test bằng chính dữ liệu domain của bạn.
  • Dùng vocabulary/phrase hints: nạp trước tên sản phẩm, tên riêng, thuật ngữ ("Vietcombank", "tài khoản thanh toán") để tăng nhận diện.
  • Chuẩn hóa audio đầu vào: sample rate 16kHz mono, khử ồn nhẹ, chuẩn hóa âm lượng (AGC).
  • Xử lý số và ngày tháng: bật inverse text normalization để "ba giờ chiều" → "15:00" nếu cần.

Checklist chọn ASR engine

  • [ ] Có streaming API độ trễ thấp không?
  • [ ] Chất lượng tiếng Việt (có dấu, giọng vùng miền) đo bằng WER trên tập test của bạn?
  • [ ] Hỗ trợ phrase hints / custom vocabulary?
  • [ ] Cho phép cấu hình endpointing / VAD?
  • [ ] Chi phí trên mỗi phút và giới hạn concurrency?
  • [ ] Có on-premise/self-host nếu dữ liệu nhạy cảm?

Đo chất lượng: WER

Đừng tin cảm tính. Đo WER (Word Error Rate) = (chèn + xóa + thay) / tổng từ. Tạo tập test 50-100 câu đại diện (có giọng vùng miền, có tiếng ồn), chạy qua từng engine, so WER. Một engine có WER 8% trên demo nhưng 25% trên giọng miền Trung của bạn là không dùng được.

Sai lầm thường gặp

  • Feed partial vào LLM. Partial thay đổi liên tục, LLM sẽ phản ứng với câu chưa hoàn chỉnh. Chỉ feed final.
  • Đặt silence timeout cố định. Một con số không hợp mọi ngữ cảnh; khách đọc số điện thoại sẽ bị cắt giữa chừng.
  • Không dùng phrase hints. Tên riêng và thuật ngữ domain là nơi ASR sai nhiều nhất.
  • Test bằng micro xịn phòng yên tĩnh. Sản xuất là điện thoại nén codec, có tiếng ồn quán cà phê.
  • Quên codec điện thoại. PSTN thường 8kHz — chọn model/cấu hình phù hợp, đừng giả định 16kHz.
Học xong bài này rồi? Tạo tài khoản miễn phí để lưu lại — lần sau vào là biết ngay đang dở ở đâu, và học hết khóa thì có chứng chỉ. Lưu tiến độ của tôi