3 điểm bởi GN⁺ 7 giờ trước | 1 bình luận | Chia sẻ qua WhatsApp
  • Để cung cấp các cuộc hội thoại giọng nói tự nhiên cho hơn 900 triệu người dùng hoạt động hằng tuần, OpenAI đã tái thiết kế việc định tuyến gói tin nội bộ theo kiến trúc relay + transceiver trong khi vẫn giữ nguyên hành vi WebRTC tiêu chuẩn
  • WebRTC chuẩn hóa ICE, DTLS/SRTP, thương lượng codec, điều khiển chất lượng RTCP, khử tiếng vọng và bộ đệm jitter, nên phù hợp để xử lý luồng âm thanh liên tục độ trễ thấp giữa trình duyệt, ứng dụng di động và máy chủ
  • Phần lớn phiên của OpenAI là phiên 1:1, trong đó 1 người dùng nói chuyện với 1 mô hình hoặc 1 ứng dụng nói chuyện với 1 tác nhân thời gian thực, nên mô hình transceiver phù hợp hơn SFU về độ trễ và khả năng mở rộng so với các cuộc gọi nhiều bên
  • Mô hình WebRTC trên Kubernetes, nơi mỗi phiên phải mở ra 1 cổng UDP, khiến phạm vi cổng công khai lớn, cấu hình load balancer, health check, chính sách tường lửa và độ an toàn khi rollout trở nên phức tạp, nên cần một bề mặt UDP nhỏ và cố định
  • Relay tìm transceiver sở hữu dựa trên gợi ý định tuyến nằm trong ICE ufrag của gói STUN đầu tiên rồi chuyển tiếp đến đó; transceiver sở hữu ICE, DTLS, SRTP và vòng đời phiên, nhờ vậy vừa giữ được khả năng tương thích WebRTC tiêu chuẩn vừa duy trì đường ingress gần người dùng trên toàn cầu

Yêu cầu của AI giọng nói độ trễ thấp

  • AI giọng nói chỉ tạo cảm giác tự nhiên khi cuộc hội thoại diễn ra với tốc độ nói, và độ trễ mạng sẽ lập tức lộ ra dưới dạng khoảng lặng gượng gạo, ngắt lời bị cắt cụt hoặc phản hồi chen vào quá muộn
  • Ở quy mô của OpenAI, cần có khả năng tiếp cận toàn cầu cho hơn 900 triệu người dùng hoạt động hằng tuần, thiết lập kết nối thật nhanh để có thể bắt đầu nói ngay sau khi phiên khởi tạo, thời gian khứ hồi media thấp và ổn định, cùng jitter và mất gói thấp
  • ChatGPT voice, Realtime API, các agent trong workflow hội thoại, và mọi mô hình phải xử lý âm thanh trong lúc người dùng đang nói đều bị ảnh hưởng bởi các đặc tính độ trễ này
  • Để thay đổi cách định tuyến gói tin nội bộ mà vẫn giữ nguyên hành vi WebRTC tiêu chuẩn phía client, OpenAI đã tái thiết kế stack WebRTC theo kiến trúc tách biệt relay + transceiver

Vì sao chọn WebRTC

  • WebRTC là tiêu chuẩn mở để truyền âm thanh, video và dữ liệu độ trễ thấp giữa trình duyệt, ứng dụng di động và máy chủ, đồng thời cũng phù hợp làm nền tảng cho các hệ thống thời gian thực client-server
  • WebRTC chuẩn hóa việc thiết lập kết nối và vượt NAT thông qua ICE, truyền tải mã hóa bằng DTLS/SRTP, thương lượng codec, điều khiển chất lượng RTCP, cùng các tính năng phía client như khử tiếng vọng và đệm jitter
  • Nếu không có WebRTC, mỗi client sẽ phải tự giải quyết việc thiết lập kết nối trong môi trường NAT, mã hóa media, thương lượng codec và thích ứng với thay đổi mạng
  • Đặc tính quan trọng với sản phẩm AI là âm thanh đến dưới dạng luồng liên tục, cho phép bắt đầu phiên âm, suy luận, gọi công cụ và tạo giọng nói mà không cần chờ toàn bộ dữ liệu tải lên của người dùng kết thúc
  • Sự khác biệt này quyết định một hệ thống có mang lại cảm giác hội thoại thật sự hay chỉ giống kiểu push-to-talk
  • OpenAI dựa trên hệ sinh thái WebRTC với các triển khai mã nguồn mở trưởng thành và quá trình tiêu chuẩn hóa; nhờ nền tảng từ Justin Uberti và Sean DuBois, họ có thể xây dựng trên hạ tầng media đã được kiểm chứng mà không phải tự làm lại lớp truyền tải cấp thấp, mã hóa và điều khiển tắc nghẽn

Kiến trúc chọn transceiver thay vì SFU

  • Khi nào SFU phù hợp

    • SFU là máy chủ media nhận luồng WebRTC của từng người tham gia rồi chọn lọc chuyển tiếp cho những người còn lại
    • Trong mô hình SFU, mỗi người tham gia kết thúc một kết nối WebRTC riêng biệt và AI cũng tham gia như một thành viên khác của phiên
    • Với các sản phẩm vốn dĩ là nhiều bên như gọi nhóm, lớp học hay họp cộng tác, SFU có thể là lựa chọn phù hợp
    • Nó cho phép tập trung codec âm thanh, thông điệp RTCP, data channel, ghi hình và chính sách theo từng luồng vào một chỗ
    • Ngay cả với sản phẩm client-to-AI, SFU cũng dễ trở thành điểm xuất phát mặc định vì có thể tái sử dụng cùng một hệ thống cho xử lý tín hiệu, định tuyến media, ghi lại, quan sát vận hành, cũng như các mở rộng tương lai như bàn giao cho con người hoặc thêm người tham gia
  • Khối lượng công việc của OpenAI

    • Phần lớn phiên của OpenAI là phiên 1:1, nơi 1 người dùng nói chuyện với 1 mô hình, hoặc 1 ứng dụng nói chuyện với 1 tác nhân thời gian thực
    • Dạng lưu lượng này nhạy cảm với độ trễ ở từng lượt trao đổi, nên OpenAI chọn mô hình transceiver
    • Trong mô hình transceiver, dịch vụ WebRTC edge kết thúc kết nối client rồi chuyển đổi media và sự kiện sang một giao thức nội bộ đơn giản cho suy luận mô hình, phiên âm, tạo giọng nói, sử dụng công cụ và điều phối
    • Transceiver là dịch vụ duy nhất sở hữu trạng thái phiên WebRTC, bao gồm ICE connectivity check, bắt tay DTLS, khóa mã hóa SRTP và vòng đời phiên
    • Khi giữ trạng thái phiên ở một nơi, việc hiểu quyền sở hữu phiên trở nên dễ hơn, còn các dịch vụ backend có thể mở rộng như dịch vụ thông thường thay vì phải hoạt động như một WebRTC peer

Triển khai ban đầu và các ràng buộc gặp phải trên Kubernetes

  • Triển khai đầu tiên của OpenAI là một dịch vụ Go đơn khối dựa trên Pion, phụ trách cả xử lý signaling lẫn kết thúc media
  • Dịch vụ transceiver này vận hành ChatGPT voice, WebRTC endpoint của Realtime API và nhiều dự án nghiên cứu
  • Ở lớp vận hành, transceiver xử lý signaling gồm thương lượng SDP, chọn codec, thông tin xác thực ICE và thiết lập phiên
  • Ở lớp media, nó kết thúc kết nối WebRTC downstream và duy trì kết nối upstream với các dịch vụ backend phục vụ suy luận và điều phối
  • OpenAI muốn chạy dịch vụ này trên Kubernetes để có thể scale up/down theo nhu cầu và di chuyển giữa các host
  • Mô hình WebRTC truyền thống kiểu 1 cổng cho mỗi phiên không phù hợp với môi trường Kubernetes, vì phải công khai, bảo mật và duy trì một dải cổng UDP lớn
  • Ở mức đồng thời cao, việc mỗi phiên dùng một cổng đồng nghĩa phải mở ra và quản lý một dải cổng UDP rất lớn
  • Cloud load balancer và Kubernetes Service không được thiết kế với giả định một dịch vụ sẽ cần hàng chục nghìn cổng UDP công khai, và khi dải cổng tăng lên, cấu hình load balancer, health check, chính sách tường lửa và độ an toàn khi rollout đều trở nên phức tạp hơn
  • Dải cổng UDP lớn cũng bất lợi cho bảo mật vì làm tăng bề mặt có thể truy cập từ bên ngoài và khiến việc kiểm toán chính sách mạng khó hơn
  • Trên Kubernetes, pod liên tục được thêm, xóa và reschedule, nên nếu mỗi pod phải đặt trước và công bố một dải cổng lớn, ổn định thì tính co giãn sẽ trở nên mong manh

Vấn đề cổng đơn và quyền sở hữu phiên

  • Nhiều hệ thống WebRTC giảm vấn đề số lượng cổng bằng cách dùng một cổng UDP duy nhất cho mỗi máy chủ và ghép kênh ở tầng ứng dụng
  • Thiết kế một cổng cho mỗi máy chủ giúp giảm số cổng, nhưng lại tạo ra vấn đề thứ hai là phải giữ được quyền sở hữu của từng phiên trên toàn bộ fleet
  • ICE và DTLS là các giao thức có trạng thái, nên tiến trình đã tạo ra phiên phải tiếp tục nhận được các gói của phiên đó để xác thực connectivity check, hoàn tất bắt tay DTLS, giải mã SRTP và xử lý các thay đổi phiên về sau như ICE restart
  • Nếu gói của cùng một phiên đến một tiến trình khác, thiết lập có thể thất bại hoặc media có thể bị hỏng
  • Mục tiêu của OpenAI là chỉ phơi ra một bề mặt UDP nhỏ và cố định trên Internet công cộng nhưng vẫn định tuyến được mọi gói đến đúng transceiver đang sở hữu phiên WebRTC đó
  • Các hướng tiếp cận đã xem xét

    • IP:port riêng cho từng phiên cho phép đường media trực tiếp client-server và không có tầng forwarding trên đường dữ liệu, nhưng đòi hỏi 1 cổng UDP công khai cho mỗi phiên và dải cổng lớn này không phù hợp với Kubernetes, cloud load balancer và bảo mật
    • IP:port riêng cho từng máy chủ có bề mặt UDP công khai nhỏ hơn nhiều so với việc phơi ra theo từng phiên và một socket dùng chung có thể ghép kênh nhiều phiên, nhưng trong một fleet cân bằng tải dùng chung, gói đầu tiên có thể đến nhầm instance nên cần một cách xác định chắc chắn để chuyển nó đến đúng tiến trình đang sở hữu phiên
    • TURN relay cho phép client chỉ cần truy cập vào địa chỉ và cổng của TURN relay, đồng thời tập trung chính sách tại edge, nhưng việc cấp phát TURN thêm vòng khứ hồi khi thiết lập và việc di chuyển hay khôi phục allocation giữa các máy chủ TURN vẫn khó
    • Kiến trúc relay + transceiver của OpenAI, theo kiểu stateless forwarder + stateful terminator, giữ được bề mặt UDP công khai nhỏ trong khi transceiver vẫn sở hữu toàn bộ phiên WebRTC, nhưng phải đánh đổi bằng một hop forwarding bổ sung trước khi media đến được transceiver sở hữu và cần phối hợp tùy biến giữa relay với transceiver

Kiến trúc relay + transceiver

  • Kiến trúc OpenAI triển khai tách riêng định tuyến gói tinkết thúc giao thức
  • Signaling đi đến transceiver để thiết lập phiên, còn media trước tiên đi vào relay
  • Relay là tầng forwarding UDP nhẹ với footprint công khai nhỏ, còn transceiver là endpoint WebRTC có trạng thái ở phía sau
  • Relay không giải mã media, không chạy state machine của ICE và cũng không tham gia thương lượng codec
  • Relay chỉ đọc đúng lượng metadata của gói cần thiết để chọn đích rồi chuyển tiếp gói đến transceiver đang sở hữu phiên
  • Transceiver vẫn nhìn thấy luồng WebRTC bình thường và sở hữu toàn bộ trạng thái giao thức
  • Từ góc nhìn của client, phiên WebRTC không hề thay đổi

Định tuyến gói đầu tiên và cách tận dụng ICE ufrag

  • Trọng tâm của kiến trúc này là relay định tuyến gói đầu tiên của client ngay trên chính đường đi của gói
  • Trong một phiên WebRTC đã có sẵn móc định tuyến gốc của giao thức, đó là ICE username fragment, hay ufrag
  • Ufrag là một định danh ngắn được trao đổi trong quá trình thiết lập phiên và được đưa lại vào các connectivity check của STUN
  • OpenAI tạo server-side ufrag sao cho nó mang đủ metadata định tuyến để relay có thể suy ra cluster đích và transceiver sở hữu
  • Trong signaling, transceiver cấp phát trạng thái phiên và trả về trong SDP answer một relay VIP dùng chung cùng cổng UDP
  • VIP là địa chỉ IP ảo ở phía trước fleet relay, kết hợp với cổng để cung cấp cho client một đích duy nhất, ổn định như 203.0.113.10:3478 ngay cả khi phía sau có nhiều instance relay
  • Gói đầu tiên trên đường media từ client thường là một STUN binding request, và ICE dùng nó để xác minh rằng gói có thể tới được địa chỉ đã công bố
  • Relay chỉ phân tích vừa đủ gói STUN đầu tiên để đọc server ufrag, giải mã gợi ý định tuyến và chuyển gói đến đúng transceiver sở hữu phiên
  • Mỗi transceiver nhận trên socket UDP dùng chung, tức một endpoint hệ điều hành gắn với IP:port nội bộ, thay vì một socket riêng cho từng phiên
  • Khi relay tạo phiên từ source IP:port của client đến đích transceiver, các gói DTLS, RTP và RTCP tiếp theo sẽ chảy trong phiên đó mà không cần giải mã lại ufrag
  • Phiên trong relay chỉ giữ trạng thái tối thiểu gồm session in-memory cho việc forwarding gói, các bộ đếm giám sát và timer phục vụ hết hạn cũng như dọn dẹp phiên
  • Nếu relay khởi động lại và mất phiên, gói STUN tiếp theo sẽ tạo lại phiên nhờ gợi ý định tuyến trong ufrag
  • Sau khi đường đi được thiết lập, Redis cache sẽ lưu mapping <client IP + Port, transceiver IP + Port> để có thể phục hồi sớm hơn, ngay cả trước khi gói STUN tiếp theo xuất hiện

Global Relay và đường ingress gần người dùng

  • Sau khi thu nhỏ bề mặt UDP công khai xuống một số lượng địa chỉ và cổng nhỏ, ổn định, OpenAI có thể triển khai cùng một mẫu relay trên toàn cầu
  • Global Relay là một fleet các điểm ingress relay phân tán theo địa lý, cùng triển khai hành vi packet-forwarding như nhau
  • Việc có ingress phân bố rộng giúp gói từ người dùng đi vào mạng của OpenAI tại relay gần về mặt địa lý và topology mạng, thay vì phải vượt Internet công cộng đến một region xa trước
  • Cách này làm giảm độ trễ, jitter và các đợt mất gói có thể tránh được trước khi lưu lượng chạm tới backbone
  • OpenAI dùng geo và proximity steering của Cloudflare cho signaling để yêu cầu HTTP hoặc WebSocket ban đầu đến được cluster transceiver gần nhất
  • Context của yêu cầu sẽ quyết định vị trí của phiên và điểm ingress Global Relay sẽ được quảng bá cho client
  • SDP answer cung cấp địa chỉ Global Relay, còn ufrag mang đủ thông tin để Global Relay định tuyến media đến đúng cluster chỉ định rồi relay tiếp tục chuyển tới transceiver đích
  • Kết hợp signaling được geo-steer với Global Relay cho phép cả thiết lập lẫn media đều đi theo đường vào gần người dùng, trong khi phiên vẫn được cố định vào một transceiver duy nhất
  • Kiến trúc này giảm thời gian khứ hồi của signaling và connectivity check ICE đầu tiên, từ đó trực tiếp rút ngắn thời gian người dùng phải chờ trước khi có thể bắt đầu nói

Cách relay được triển khai

  • Dịch vụ relay được viết bằng Go và cố ý giữ phạm vi triển khai thật hẹp
  • Trên Linux, kernel networking stack nhận UDP packet từ network interface rồi chuyển cho socket, còn relay là một tiến trình Go thông thường trong userspace đọc packet header từ socket
  • Relay cập nhật một lượng nhỏ flow state rồi chuyển tiếp gói mà không kết thúc WebRTC
  • OpenAI không dùng kernel-bypass framework, nơi tiến trình userspace trực tiếp polling network queue để đạt packet rate cao hơn, vì cho rằng cách đó làm tăng độ phức tạp vận hành
  • Các lựa chọn thiết kế chính

    • Không kết thúc giao thức: relay chỉ phân tích STUN header và ufrag, sau đó với DTLS, RTP và RTCP thì dùng trạng thái cache để giữ packet ở dạng opaque
    • Trạng thái tạm thời: duy trì một map in-memory nhỏ với timeout ngắn, ánh xạ từ địa chỉ client sang đích transceiver để phục vụ flow state và quan sát vận hành
    • Khả năng mở rộng theo chiều ngang: nhiều instance relay chạy song song phía sau load balancer, và vì trạng thái relay không phải hard WebRTC state nên khi khởi động lại, traffic drop nhỏ và flow recovery diễn ra nhanh
  • Các biện pháp tối ưu hóa

    • SO_REUSEPORT là tùy chọn socket của Linux cho phép nhiều worker relay trên cùng một máy bind vào cùng một cổng UDP, để kernel phân phối packet đến các worker và tránh nút thắt ở một vòng lặp đọc duy nhất
    • runtime.LockOSThread cố định mỗi goroutine đọc UDP vào một OS thread cụ thể
    • Khi dùng SO_REUSEPORT cùng với pin thread, các packet của cùng một flow có xu hướng ở lại trên cùng một CPU core, giúp cải thiện cache locality và giảm context switching
    • Buffer được cấp phát sẵn và giảm sao chép tối đa giúp hạ chi phí parsing và allocation, đồng thời tránh áp lực garbage collection của Go
    • Cách triển khai này đã xử lý được lưu lượng media thời gian thực toàn cầu của OpenAI với footprint relay tương đối nhỏ, nên OpenAI giữ thiết kế đơn giản hơn thay vì chọn hướng kernel bypass

Kết quả và bài học rút ra

  • Kiến trúc này cho phép chạy WebRTC media trên Kubernetes mà không cần phơi ra hàng nghìn cổng UDP
  • Bề mặt UDP nhỏ và cố định giúp bảo mật và cân bằng tải dễ hơn, đồng thời cho phép hạ tầng mở rộng mà không cần đặt trước một dải cổng công khai lớn
  • Thiết kế này giữ nguyên hành vi WebRTC tiêu chuẩn phía client và xác nhận rằng với khối lượng công việc của OpenAI, mô hình không dùng SFU là lựa chọn mặc định phù hợp
  • Phần lớn phiên là point-to-point, nhạy cảm với độ trễ, và việc các dịch vụ suy luận không phải hoạt động như WebRTC peer giúp mở rộng dễ hơn
  • Việc đặt độ phức tạp vào một lớp định tuyến mỏng phù hợp hơn là đẩy nó sang toàn bộ dịch vụ backend hoặc yêu cầu hành vi client tùy biến
  • Bằng cách mã hóa metadata định tuyến vào trường gốc của giao thức, họ có được định tuyến chắc chắn cho gói đầu tiên, bề mặt UDP công khai nhỏ và sự linh hoạt để đặt ingress gần người dùng trên toàn thế giới
  • Những lựa chọn đặc biệt quan trọng

    • Giữ nguyên semantics của giao thức ở edge: client tiếp tục dùng WebRTC tiêu chuẩn nên khả năng tương tác giữa trình duyệt và thiết bị di động được duy trì
    • Giữ trạng thái phiên khó ở một chỗ: transceiver sở hữu ICE, DTLS, SRTP và vòng đời phiên, còn relay chỉ chuyển gói
    • Định tuyến bằng thông tin đã có sẵn trong thiết lập: ICE ufrag cung cấp hook định tuyến cho gói đầu tiên mà không cần phụ thuộc vào tra cứu trên hot path
    • Ưu tiên tối ưu cho common case hơn kernel bypass: một triển khai Go hẹp, sử dụng cẩn thận SO_REUSEPORT, pin thread và parsing ít cấp phát, đã đủ cho khối lượng công việc của OpenAI
    • AI giọng nói thời gian thực chỉ hoạt động tốt khi hạ tầng làm cho độ trễ trở nên không thể cảm nhận, và OpenAI đã chọn thay đổi cách triển khai WebRTC chứ không thay đổi hành vi mà client mong đợi từ WebRTC

1 bình luận

 
Ý kiến trên Hacker News
  • Rất cảm ơn OpenAI đã giới thiệu trường hợp sử dụng thư viện Pion mà tôi đang làm
    Nếu chưa quen với WebRTC thì đây là một lĩnh vực khá thú vị, và tôi cũng đang làm cuốn sách giải thích cách nó hoạt động, WebRTC for the Curious
    https://github.com/pion/webrtc
    https://webrtcforthecurious.com

    • Tôi đang dùng Pion. Nhưng tôi tự hỏi liệu cách tiếp cận của OpenAI có thực sự cần thiết không
      Có vẻ như họ đã tăng độ phức tạp lên rất nhiều để cắt giảm một phần vốn đã thuộc loại nhanh trong cấu hình AI giọng nói. Có vẻ mô hình nhanh và phát hiện hoạt động giọng nói (VAD) chính xác quan trọng hơn nhiều so với việc tinh chỉnh từng chút thời gian truyền WebRTC
    • Cảm ơn vì đã đăng toàn bộ cuốn sách lên mạng
      Trước đây tôi từng đọc một phần vì có ý tưởng dùng kênh dữ liệu WebRTC để gửi dữ liệu từ cơ sở dữ liệu tới trình duyệt qua CLI, và nhờ đó hiểu ra rằng nó sẽ không thật sự phù hợp với nhu cầu của mình. Cuối cùng tôi dùng control plane tập trung và WebSocket
      Dù vậy, tôi vẫn cảm thấy có thể làm điều gì đó thú vị với tổ hợp kênh dữ liệu WebRTC + Apache Arrow ArrayBuffer không sao chép + duckdb WASM, chỉ là vẫn chưa nghĩ ra sẽ làm gì
    • Hơi lạc đề một chút, nhưng tôi tò mò vì sao toàn bộ codebase lại được đặt ở thư mục gốc thay vì trong các thư mục src lồng nhau
      Việc vào README khó hơn nhiều
  • Độ trễ thấp, về mặt triển khai, gần như là một nỗi khổ hơn là lợi thế
    Khi chỉ muốn trò chuyện thoải mái, con người tự nhiên sẽ dừng lại một chút, nhưng GPT lại hiểu đó là “đã nói xong” và lập tức bắt đầu thao thao bất tuyệt
    Khi có tuổi hơn, tôi mất nhiều thời gian hơn để tìm đúng từ mình muốn, nên những GPT giọng nói quá nhanh này gây khó chịu nhiều hơn là giúp ích. Tôi phải nghĩ xong cả câu trong đầu trước khi nói, hoàn toàn không tự nhiên chút nào

    • Ở đây đang trộn lẫn hai tầng độ trễ khác nhau
      Độ trễ trong bài viết nói về độ trễ truyền của chính luồng âm thanh, còn độ trễ trong tình huống này gần hơn với việc phản hồi bắt đầu nhanh đến mức nào bên trong luồng âm thanh
    • Tôi cũng đã gặp và đúng là rất phiền
      Nó tạo ra áp lực phải tiếp tục nói dù mình vẫn chưa nghĩ xong, nên cảm giác khá gượng gạo. Nếu đang tìm từ phù hợp thì bạn cần có cơ hội để tìm ra nó
      Tôi nghĩ giải pháp không phải là một giao thức có độ trễ cao hơn mà là xử lý khoảng dừng thông minh hơn. Khi độ trễ thấp, bot có thể dừng nói ngay lập tức khi người dùng chen vào
    • Trong hội thoại giọng nói, tôi yêu cầu nó hoàn toàn không trả lời hoặc chỉ nói “đã hiểu” cho tới khi tôi dùng một từ khóa nhất định
      Không hoàn hảo, nhưng đỡ ngắt lời hơn
    • Cái này liên quan đến phát hiện hoạt động giọng nói (VAD) nhiều hơn là độ trễ được nói đến trong bài
    • Đây là một bài toán khó. Để bot khỏi thao thao bất tuyệt, tôi thấy mình vô thức thêm các cụm đệm
      Ngoài ra, có vẻ nó dùng phần lớn trí tuệ để nghe cho hợp lý hơn là để nghĩ về vấn đề. Kiểu như “Vâng, tất nhiên rồi. Tôi hiểu tại sao bạn lại muốn như vậy…” Có lẽ vì có giới hạn thời gian và xử lý giọng nói đắt hơn. Phản hồi văn bản dành nhiều thời gian hơn cho chính nhiệm vụ
  • “Hơn 900 triệu người dùng hoạt động hằng tuần” rõ ràng có lẽ là đang nói đến toàn bộ người dùng ChatGPT, và trong số đó tỷ lệ dùng tính năng giọng nói chắc nhỏ hơn nhiều
    Những con số kiểu này ảnh hưởng đến quyết định kinh doanh như sẽ đổ bao nhiêu tối ưu hóa phần cứng và phần mềm vào bài toán này

    • Đúng vậy. Có lẽ vì thế họ dùng từ “reach”
      Ý là tổng số người dùng có thể được tiếp cận tính năng này, bất kể họ có thực sự dùng hay không
  • Rất vui vì họ chia sẻ, nhưng cần nhớ rằng mô hình âm thanh thời gian thực của OpenAI hiện vẫn dừng ở mức năng lực của dòng 4o
    Dù vậy nó vẫn cực kỳ hữu ích, và thật tiếc là lĩnh vực này chưa có đối thủ cạnh tranh thực sự. Trải nghiệm giống hội thoại thật đã giúp ích rất nhiều cho việc diễn đạt ý tưởng và khái niệm
    Chỉ đáng lưu ý là giờ đây nó không còn là mô hình tiên phong như lúc mới ra mắt nữa. Nếu Sam thấy điều này thì mong là sẽ có một mô hình âm thanh thời gian thực mới

    • Ở realtime/voice mode của OpenAI, phần giọng nói thì tuyệt vời, nhưng so với các mô hình mới nhất thì nó khá ngớ ngẩn và thường lặp lại cùng một điều
      Gemini flash live 3.1 của Google tốt hơn, đặc biệt nếu dùng qua API. Nó hỗ trợ gọi công cụ, và nếu tự cấu hình thì còn có thể nối sang các LLM thông minh hơn, đồng thời chỉnh được mức suy luận. Mức suy luận cao vẫn đủ gần thời gian thực, và có thể tăng cường câu trả lời bằng tìm kiếm Google. Nếu bạn thích giọng nói hai chiều thì hiện tại đây có lẽ là lựa chọn tốt nhất, và có thể thử trong AI Studio
  • Với ai muốn bước vào lĩnh vực này, pipecat là một kho mã nguồn mở và cộng đồng rất tốt
    https://github.com/pipecat-ai/pipecat

    • Giá mà tôi biết đến Pipecat sớm hơn nhiều
      Tôi mới biết nó vài tuần trước, và sau khi Gemma 4 ra mắt, tôi đang tự xây từ đầu một trợ lý giọng nói chạy hoàn toàn cục bộ với Gemma 4 + Kokoro TTS + Whisper: https://github.com/pncnmnp/strawberry
      Mô hình smart turn của Pipecat thực sự rất tốt cho phát hiện hoạt động giọng nói (VAD): https://huggingface.co/pipecat-ai/smart-turn-v3
  • Nếu mô hình tốt hơn sẽ suy nghĩ nhiều hơn trước khi trả lời thì tôi sẵn sàng chờ phản hồi lâu hơn
    Miễn là nó hỗ trợ chen ngang tốt, không bắt đầu trả lời ngay chỉ vì tôi dừng 1 giây, và biết phán đoán thông minh xem tôi đã nói xong chưa

  • Đây có thể không đơn thuần chỉ là vấn đề độ trễ
    Nếu giữ người dùng ở lại trong hội thoại giọng nói, bạn sẽ thu được dữ liệu huấn luyện mà văn bản không bao giờ cho được. Nên tôi tự hỏi có phải vì thế mà họ chọn cách làm transceiver thay vì SFU, và chấp nhận gần như bỏ qua hội thoại nhiều bên

  • Có thể hiểu là OpenAI giờ không còn dùng LiveKit cho WebRTC/âm thanh nữa sao?

    • Có vẻ vậy
      Với kiến trúc này, máy chủ LiveKit có lẽ không đúng thứ họ muốn. Phần thảo luận về SFU trong bài thực ra cũng gần như nói vậy. Dù thế, trong SDK phía client vẫn có nhiều thứ hữu ích
  • Nếu transceiver bị crash giữa chừng khi đang stream thì phiên đang hoạt động sẽ được khôi phục thế nào?
    Hệ thống có tự động tái lập context trong một phiên WebRTC mới không?

  • Nếu muốn kết bạn thì tôi nghĩ tham gia câu lạc bộ hoặc nhóm gặp gỡ dưới bất kỳ hình thức nào sẽ tốt hơn