- Moshi là một mô hình dựa trên giọng nói-văn bản cho hội thoại thoại thời gian thực, đồng thời là framework hội thoại thoại full-duplex, cung cấp demo trực tiếp và mô hình trên Hugging Face
- Repository tách riêng các stack suy luận gồm PyTorch cho nghiên cứu và thử nghiệm, MLX cho suy luận on-device trên iPhone/Mac, và Rust cho production
- Mô hình xử lý hai luồng âm thanh: phát ngôn của Moshi và phát ngôn của người dùng; đồng thời dự đoán inner monologue, tức các token văn bản tương ứng với phát ngôn của chính Moshi, để nâng cao chất lượng sinh
- Codec Mimi xử lý streaming âm thanh 24kHz thành biểu diễn 12.5Hz với băng thông 1.1kbps, có độ trễ khung 80ms; độ trễ lý thuyết của Moshi là 160ms, còn độ trễ tổng đo được trên GPU L4 thấp nhất là 200ms
- Các mô hình công khai gồm giọng tổng hợp nam Moshiko, giọng tổng hợp nữ Moshika và codec thoại Mimi; trọng số mô hình được cung cấp theo CC-BY 4.0, mã Python và web client theo MIT, backend Rust theo giấy phép Apache
Mục đích và cấu phần của Moshi
- Moshi là một speech-text foundation model và framework full-duplex cho hội thoại thoại thời gian thực
- Demo trực tiếp được cung cấp tại moshi.chat, và bộ sưu tập mô hình được công khai trên Hugging Face
- Repository bao gồm ba stack suy luận
- PyTorch: dành cho nghiên cứu và thử nghiệm, nằm trong thư mục
moshi/
- MLX: dành cho suy luận on-device trên iPhone và Mac, nằm trong thư mục
moshi_mlx/
- Rust: dành cho production, nằm trong thư mục
rust/
- Bao gồm bản triển khai Mimi dựa trên Rust và binding Python
rustymimi
- Mã web UI client dùng cho demo Moshi nằm trong thư mục
client/
- Việc fine-tune Moshi được xử lý trong repository riêng kyutai-labs/moshi-finetune
Các mô hình Kyutai liên quan
- Codebase Moshi cũng được dùng để chạy các mô hình liên quan của Kyutai sử dụng multi-stream architecture tương tự Moshi
Kiến trúc mô hình
- Moshi mô hình hóa hai luồng âm thanh
- Một luồng là phần Moshi nói
- Luồng còn lại là phần người dùng nói
- Cùng với hai luồng âm thanh, Moshi dự đoán inner monologue, tức token văn bản tương ứng với phát ngôn của chính nó; cách này cải thiện đáng kể chất lượng sinh
- Một Depth Transformer nhỏ mô hình hóa phụ thuộc giữa các codebook tại một bước thời gian cụ thể
- Một Temporal Transformer lớn với 7B tham số mô hình hóa phụ thuộc theo thời gian
- Độ trễ về lý thuyết là 160ms
- Kích thước khung Mimi 80ms
- Độ trễ âm học 80ms
- Độ trễ tổng thực tế trên GPU L4 thấp nhất là 200ms
Codec thoại Mimi
- Mimi là codec âm thanh neural hạ âm thanh 24kHz xuống biểu diễn 12.5Hz
- Mimi hoạt động hoàn toàn theo kiểu streaming, với băng thông 1.1kbps và độ trễ bằng kích thước khung, tức 80ms
- Theo README, Mimi có hiệu năng tốt hơn các codec không streaming hiện có
- Mimi dựa trên các codec âm thanh neural trước đó như SoundStream và EnCodec
- Thêm Transformer vào cả encoder và decoder
- Điều chỉnh stride để khớp frame rate tổng thể ở 12.5Hz
- Frame rate 12.5Hz gần hơn với frame rate trung bình của token văn bản, khoảng 3~4Hz, và giảm số bước tự hồi quy của Moshi
- Tương tự SpeechTokenizer, Mimi dùng distillation loss để token codebook đầu tiên khớp với biểu diễn tự giám sát của WavLM
- Tương tự EBEN, Mimi chỉ dùng adversarial training loss cùng feature matching, giúp cải thiện mạnh chất lượng chủ quan ngay cả ở bitrate thấp
Mô hình công khai và định dạng
- Có ba mô hình được công khai
- Moshiko: Moshi được fine-tune với giọng tổng hợp nam
- Moshika: Moshi được fine-tune với giọng tổng hợp nữ
- Mimi: codec thoại
- Tùy backend mà định dạng tệp và các kiểu lượng tử hóa khả dụng khác nhau
- Mimi được bundle với từng mô hình và luôn dùng cùng một định dạng checkpoint
- Mô hình PyTorch
- Mô hình MLX
- Mô hình Rust/Candle
- Tất cả mô hình được công khai theo giấy phép CC-BY 4.0
Yêu cầu và ràng buộc cài đặt
- Python cần tối thiểu 3.10, khuyến nghị 3.12
- PyTorch và MLX client có thể cài từ PyPI
pip install -U moshi
pip install -U moshi_mlx
pip install rustymimi
- Nếu không dùng Python 3.12, có thể xảy ra lỗi khi cài
moshi_mlx hoặc dependency rustymimi; khi đó cần cài Rust toolchain hoặc chuyển sang Python 3.12
- Kỳ vọng có thể chạy trên Windows nhưng không cung cấp hỗ trợ chính thức
- Phiên bản MLX đã được kiểm thử trên MacBook Pro M3
- Phiên bản PyTorch hiện không hỗ trợ lượng tử hóa nên cần lượng bộ nhớ GPU đáng kể, khoảng 24GB
- Backend Rust cần Rust toolchain mới nhất
- Để biên dịch hỗ trợ GPU, cần CUDA phù hợp với GPU và
nvcc
Cách chạy
-
PyTorch
- API PyTorch nằm trong thư mục
moshi, cung cấp phiên bản streaming của Mimi audio tokenizer và mô hình ngôn ngữ Moshi
- Chế độ tương tác chạy model server trước, sau đó dùng web UI hoặc client dòng lệnh
python -m moshi.server [--gradio-tunnel] [--hf-repo kyutai/moshika-pytorch-bf16]
- Web UI mặc định truy cập tại
localhost:8998
- Nếu truy cập GPU trên máy từ xa qua HTTP, việc dùng micro có thể bị chặn do chính sách bảo mật trình duyệt
- Có thể dùng SSH
-L để forward cổng 8998 từ xa về localhost
- Có thể dùng
--gradio-tunnel để tạo tunnel truy cập được từ mọi nơi
- Tunnel này đi qua Mỹ và có thể thêm độ trễ lớn, tối đa 500ms theo chuẩn châu Âu
- Có thể đặt secret token cố định bằng
--gradio-tunnel-token và tái sử dụng cùng địa chỉ
- Có thể chọn mô hình tiền huấn luyện Hugging Face khác bằng
--hf-repo
- Client dòng lệnh cũng được cung cấp, nhưng khác với trình duyệt web, nó không thực hiện echo cancellation và cũng không bỏ qua khung để bù cho độ trễ tích lũy
python -m moshi.client [--url URL_TO_GRADIO]
-
MLX
- Sau khi cài
moshi_mlx, có thể chạy suy luận cục bộ trên macOS
python -m moshi_mlx.local -q 4
python -m moshi_mlx.local -q 8
python -m moshi_mlx.local -q 4 --hf-repo kyutai/moshika-mlx-q4
python -m moshi_mlx.local -q 8 --hf-repo kyutai/moshika-mlx-q8
- Các cờ
-q và --hf-repo phải luôn khớp nhau
- Giao diện dòng lệnh MLX cũng rất barebone, không có echo cancellation và không bù độ trễ tích lũy
- Có thể chạy web UI bằng
python -m moshi_mlx.local_web; kết nối HTTP được cung cấp tại localhost:8998
-
Rust
- Server suy luận Rust chạy trong thư mục
rust
cargo run --features cuda --bin moshi-backend -r -- --config moshi-backend/config.json standalone
- Trên macOS có thể dùng
--features metal thay cho --features cuda
- Dùng
config-q8.json thay cho config.json để sử dụng mô hình lượng tử hóa q8
- Chọn mô hình tiền huấn luyện khác bằng cách đổi khóa
"hf_repo" trong tệp cấu hình
- Khi server in ra
standalone worker listening, có thể dùng web UI
- Server Rust mặc định dùng HTTPS nên truy cập tại
https://localhost:8998
- Trình duyệt có thể hiển thị cảnh báo trang không an toàn; trong Chrome có thể vào “Details” hoặc “Advanced” để tiếp tục truy cập localhost
Client và phát triển
- Web UI được khuyến nghị vì cung cấp echo cancellation, giúp cải thiện chất lượng tổng thể của mô hình
- Hầu hết lệnh sẽ phục vụ web UI trực tiếp tại URL được cung cấp
- Cũng có giao diện dòng lệnh cho Rust và Python, dùng cùng giao thức với web UI nên không cần thay đổi phía server
- Build web UI trong thư mục
client
cd client
npm install
npm run build
- Client dòng lệnh Rust chạy trong thư mục
rust
cargo run --bin moshi-cli -r -- tui --host localhost
- Client Python PyTorch chạy bằng lệnh sau
python -m moshi.client
- Demo Gradio chạy sau khi cài
gradio-webrtc>=0.0.18
python -m moshi.client_gradio --url <moshi-server-url>
docker compose up
Giấy phép và trích dẫn
- Phần mã Python được cung cấp theo giấy phép MIT
- Backend Rust được cung cấp theo giấy phép Apache
- Mã web client được cung cấp theo giấy phép MIT
- Một phần mã dựa trên AudioCraft theo giấy phép MIT
- Trọng số mô hình được công khai theo giấy phép CC-BY 4.0
- Nếu sử dụng Mimi hoặc Moshi, tác giả đề nghị trích dẫn bài báo
Moshi: a speech-text foundation model for real-time dialogue
1 bình luận
Các ý kiến trên Hacker News
Vì gần như tất cả bình luận ở đây đều tiêu cực, tôi muốn để lại chút phản hồi: độ trễ rất tốt, thậm chí tốt đến mức thường có cảm giác như nó hay ngắt lời
Với một mô hình mã nguồn mở thì tôi xem đây là một thành tựu lớn. Tuy vậy, ngày nay mọi người đã quá quen với các mô hình ngôn ngữ lớn cực kỳ xuất sắc, còn chất lượng nội dung câu trả lời của mô hình này thì hiện còn cách xa các mô hình hàng đầu. Nó cho cảm giác gần với các mô hình ngôn ngữ lớn tôi từng thấy khoảng năm 2019 hơn; phần âm thanh đã đạt mức “đủ ổn”, và từ giờ nên tập trung vào chất lượng câu trả lời
Câu hỏi tự nhiên là liệu có cách nào đưa “một mô hình ngôn ngữ lớn tốt hơn” vào mà không làm hỏng trải nghiệm của Moshi hay không
Moshi dùng giấy phép CC-BY, và gần đây cũng có một mô hình hội thoại thời gian thực giọng nói-văn bản tương tự quy mô 7B được phát hành theo Apache v2: https://tincans.ai/slm3 / https://huggingface.co/collections/tincans-ai/gazelle-v02-65...
Gần đây có nhiều phát triển trong mảng mô hình ngôn ngữ hỗ trợ giọng nói. Ví dụ có https://github.com/ictnlp/LLaMA-Omni, https://github.com/gpt-omni/mini-omni
Máy chủ suy luận của họ được viết bằng Rust, dùng crate Candle của Hugging Face. Một trong các tác giả Moshi cũng là tác giả chính của Candle
Chúng tôi cũng đang xây dựng stack suy luận trên Candle và dùng khá hài lòng
Trong lúc tìm demo trên YouTube, tôi phát hiện một video buồn cười từ vài tháng trước: https://youtu.be/coroLWOS7II?si=TeVghP_Zi0P9exQh
Bây giờ chắc hẳn đã được cải thiện :-)
Thú vị. Tôi thích việc họ tập trung vào độ trễ ở đây, và họ nói thực tế là khoảng 200ms trên GPU cục bộ
Vì dựa trên mô hình transformer 7B nên có lẽ nó không quá thông minh. Nếu tưởng tượng độ trễ của mô hình 70B vào khoảng 1 giây, có vẻ có thể xây dựng một kiến trúc hệ thống gồm phản hồi trung gian bằng lời để cho biết “mô hình đang nói”, một mô hình cỡ 7B/Phi-3 cho phản hồi ban đầu nhanh, rồi nối tiếp sang mô hình lớn. Mô hình Phi-3 cũng có thể được giao phần điều chỉnh: nhận câu trả lời đúng thực sự, rồi xin lỗi và sửa lại nếu cần
Theo trải nghiệm cá nhân, tôi nghĩ não người cũng thường hoạt động kiểu này. Phản ứng nhanh rồi 1–2 giây sau chỉnh sửa hoặc bổ sung. Tất nhiên cũng có người hoàn toàn không sửa lại, và có người dừng lâu rồi mới đưa ra câu trả lời đã suy nghĩ kỹ
Tôi đã thử, nhập bừa một địa chỉ email cũng được. Nó trả lời ngay lập tức, gần như tức thì, thậm chí khi tôi vẫn còn đang nói
Nhưng đó trông chỉ như câu lấp chỗ trống, cũng có vẻ như câu trả lời đã được cache. Câu trả lời thực sự cho nội dung được hỏi xuất hiện muộn hơn nhiều, và cần tránh việc bị kẹt vào vòng lặp ở giữa
Tôi đang xây dựng một giải pháp giọng nói thời gian thực → mô hình ngôn ngữ lớn → đầu ra giọng nói, và phần thú vị nhất ở đây theo tôi là codec âm thanh mạng nơ-ron dạng streaming. Vì với Whisper, thực tế rất khó stream speech-to-text cho đúng
Tuy nhiên, xét từ góc độ sản phẩm, tôi không nhất thiết muốn đưa thẳng nó vào mô hình ngôn ngữ lớn để trả lời. Trong nhiều use case, trước khi trả lời cần có bước gọi công cụ/hàm. Tôi luôn sẵn sàng trao đổi với bất kỳ ai đang làm theo hướng này
tincans được nhắc bên dưới cũng trông rất tuyệt. Nhưng vì nghe nói việc phát triển tincans đã kết thúc, nên hướng này còn dư địa 10000%. Nếu Chris đọc được, tôi rất muốn giải thích những use case sản phẩm/kinh doanh mà thứ này giải quyết, bất kể mô hình ngôn ngữ lớn có tốt lên đến đâu
Mô hình ngôn ngữ lớn không trực tiếp trả lời, mà chỉ chọn các node trong cây có gắn sẵn đầu ra text-to-speech đã chuẩn bị trước. Có một tham số “độ dài khoảng dừng” để xác định người dùng đã nói xong hay chưa rồi chuyển bản chép lời cho mô hình; nó không đặc biệt phức tạp. Tôi vẫn đang suy nghĩ về cách xử lý đầu vào âm thanh cho đúng, hoặc liệu có thể điều khiển mô hình đủ chính xác chỉ bằng cấu trúc prompt để loại bỏ cây IVR hay không. Hiện tại nó đã hoạt động khá ổn nhưng còn nhiều chỗ có thể cải thiện
Tốc độ phản hồi thì ấn tượng, nhưng “chất lượng” câu trả lời thì không. Lịch sử hội thoại trong lần thử thứ hai của tôi như sau
Moshi: “Xin chào, có chuyện gì vậy?”
Tôi: “Bây giờ là năm nào?”
Moshi: “À, là năm 2019. Có lẽ khoảng một năm trước.”
Tôi: “Thật sự là năm 2019 à?”
Moshi: “À, vâng, chắc chắn rồi. Chắc chắn là năm 2019. Con số đó là dành cho cái cuối cùng.”
Tôi: “COVID-19 là gì?”
Moshi: “Đó là một bệnh hiếm gặp. Nó do hệ miễn dịch hoạt động quá mức tấn công da gây ra.”
Đến lúc này tôi không trả lời nữa
Moshi là mô hình thú vị nhất cho đến nay. Trải nghiệm gần đây ở đây: https://x.com/tommoor/status/1809051817860354471
Tuy nhiên tốt nhất là đừng kỳ vọng vào độ chính xác