Đào sắc thái có sẵn
Không ai chỉ có một cách nói: người ta giảng giải, thuyết phục, kể chuyện, hướng dẫn. Việc đào tách những kiểu nói đó ra khỏi bản ghi dài bằng ngôn điệu đo được, chứ không bằng phỏng đoán.
mining-protocol.md
Clone một giọng thì dễ. Có được một giọng đọc đúng văn bản của mình, đổi sắc thái khi ý nghĩa đổi, và lặp lại y hệt khi chạy lại — đó mới là phần khó. Repo này là quy trình cho phần khó đó, chạy hoàn toàn trên máy bạn.
Repo này điều phối các engine mà bạn tự cài; nó không đóng gói dòng code nào của họ, và không chứa một file audio nào — có chủ đích.
Phần tổng hợp giọng nằm ở OmniVoice, phần khử tạp ở ClearerVoice-Studio, phần tách giọng ở python-audio-separator. Bạn cài chúng; repo này biết gọi chúng theo đúng thứ tự và biết khi nào phải dừng.
Không có máy chủ, không có tài khoản, không có khoá API. Mọi thứ chạy tại máy bạn; trạm giọng là thư mục của bạn và không bao giờ đi vào git.
Cài nó khi bạn cần một giọng đọc, và chỉ khi đó. Không có thứ tự cài bắt buộc, không có "bộ ba". Xem mục liên hệ với hai repo kia.
Mỗi thẻ dưới đây ghi kèm lệnh hoặc tài liệu tương ứng trong repo — không có dòng nào là lời hứa suông.
Không ai chỉ có một cách nói: người ta giảng giải, thuyết phục, kể chuyện, hướng dẫn. Việc đào tách những kiểu nói đó ra khỏi bản ghi dài bằng ngôn điệu đo được, chứ không bằng phỏng đoán.
Clip mẫu không phải một đầu vào bình thường — nó chính là giọng, và mọi thứ sinh ra sau đều thừa hưởng lỗi của nó. Mỗi ứng viên bị máy chấm, gồm cả một vòng đi–về qua nhận dạng tiếng nói.
Marker trong text quyết định clip mẫu nào đọc đoạn nào. Người gọi chỉ chọn một tên profile; phần diễn do câu chữ quyết định — nên sửa bài là đổi được cách đọc, không phải dựng lại giọng.
Mọi luật đều dựng bằng cách tổng hợp rồi cho nhận dạng nghe lại rồi so. Số đo nằm nguyên trong bảng — kể cả số đo đã lật đổ một niềm tin cũ.
Tách giọng khỏi nhạc nền rồi khử tạp âm, trước khi một clip được đưa qua cổng kiểm.
Video câm + lời dẫn → một MP4 có giọng và nhạc nền tuỳ chọn. Thư viện nhạc nền có lệnh riêng để liệt kê và chọn theo phong cách.
Đóng gói giọng cá nhân thành một file zip rồi bung ở máy khác; hoặc sao lưu cả trạm. Gói cá nhân không mang theo venv, cache hay output.
Thiếu gì thì chỉ đúng bước cài còn thiếu, thay vì để lỗi nổ ra giữa một lượt chạy dài.
Một giao diện web cục bộ để nghe thử nhanh, và một lệnh đọc một câu ra file.
Chạy như MCP server qua stdio cho agent gọi; hoặc cài như plugin để agent đọc skill
voice-routing và chỉ nạp đúng tài liệu của bước đang làm.
Hai bước đầu tốn công và chỉ chạy một lần cho mỗi giọng; hai bước sau là việc hằng ngày.
Quét cả thư mục bản ghi, tách các cụm có ngôn điệu khác nhau thành các ứng viên clip mẫu.
Mỗi ứng viên đi qua sáu cổng. Trượt bất kỳ cổng nào là bị loại và ứng viên kế tiếp được thử.
Viết kịch bản, đặt marker ở chỗ muốn đổi sắc thái. Không phải cấu hình gì thêm.
Một lệnh, một tên profile. Có --json thì dòng cuối stdout là một object JSON cho pipeline khác đọc.
Thường không có ai ngồi nghe, và nghe bằng tai cũng không mở rộng được cho hàng chục ứng viên. Cổng 1–4 rẻ nên chạy trước, trượt rồi thì bỏ qua phần việc GPU.
| # | Cổng | Loại khi | Bắt được |
|---|---|---|---|
| 1 | Clipping | peak ≥ −0,5 dB | bản ghi bị méo |
| 2 | Quá nhỏ | RMS < −34 dB | tỉ lệ tín hiệu/nhiễu không dùng được |
| 3 | Bám cao độ | > 35 % frame thất bại | còn sót nhạc nền, hoặc hai người nói chồng lên nhau |
| 4 | Đuôi lặng | 250 ms cuối không thấp hơn RMS của clip ít nhất 18 dB | clip kết thúc giữa chừng một từ |
| 5 | Round trip | tổng hợp 2 câu thăm dò, cho nhận dạng đọc ngược lại, CER > 0,25 | clip sinh ra lời nói bị méo |
| 6 | Leak probe | âm tiết đầu của output trùng âm tiết cuối của clip mẫu | đúng lỗi mà cổng 4 ngăn, bắt trực tiếp |
Cổng 4 thay cho một phép kiểm tưởng hiển nhiên. Bản đầu tiên kiểm xem
transcript có kết thúc bằng dấu câu không — và nó loại sạch ba trên ba ứng viên, làm dừng
cả quá trình dựng. Nguyên nhân: nhận dạng tiếng Việt thường xuyên bỏ dấu chấm cuối câu.
Toàn bộ số đo và lý do đổi nằm ở skills/voice-routing/references/verify-gates.md.
init trình bảng trước khi làmKhông có câu hỏi trống. init đưa ra bảng hai lựa chọn rồi chờ bạn chọn; không
có ai trả lời (CI, lịch chạy) thì nó in bảng đó ra và thoát mã 2 mà chưa ghi byte nào.
Nhờ AI agent cài. Trang /install/ có một prompt copy-dán (tiếng Việt và tiếng Anh) cho Claude Code, Codex hoặc Antigravity, trên Windows hoặc macOS: agent hỏi trước khi cài phần mềm, tải engine hay chọn chỗ đặt trạm.
git clone https://github.com/ducnguyen221/agent-voice-studio
# tạo venv, cài torch theo hệ điều hành + omnivoice==0.2.1 — xem docs/INSTALL.md
pip install -e . # trong venv engine — có lệnh voice-studio; xưởng Windows chạy lịch có trạm riêng: bản sao, docs/INSTALL.md mục 3
voice-studio init # trình bảng embedded | separate rồi chờ bạn chọn
voice-studio doctor # thiếu gì thì chỉ bước cài tiếp| Chế độ | Trạm nằm ở đâu | Chọn khi |
|---|---|---|
| embedded mặc định · khuyến nghị |
<repo>/workspaces/, cấu hình ở <repo>/.env |
Bấm Enter là xong, không phải đặt biến môi trường nào. init dựng sẵn cây
trạm và chép .env.example thành .env cho bạn điền. Cả
workspaces/ lẫn .env bị .gitignore chặn và hook
pre-commit chặn lần nữa. |
| separate | một thư mục ngoài repo, chỉ bằng --station DIR |
Bạn dùng nhiều máy, rành kỹ thuật, hoặc repo này là bản public của chính bạn — tức là trạm phải sống lâu hơn bản clone. |
.env giữ đường dẫn và cấu hình, không bao giờ giữ token.
Một cổng trong bộ test đối chiếu .env.example với những biến mà
mã thật sự đọc: khai thiếu là đỏ, khai thừa mà không nói rõ vì sao cũng đỏ.
Cài như plugin cho agent. Claude Code và Codex đều nhận repo này làm
marketplace; cài xong, agent đọc skills/voice-routing/SKILL.md
và chỉ nạp đúng tài liệu tham chiếu của bước đang làm thay vì nuốt cả bộ.
| Nền tảng | Bộ khung (CLI, trạm, test) | Tổng hợp giọng thật |
|---|---|---|
| Windows | đã chạy thật | đã chạy thật |
| macOS (Apple Silicon) | CI chạy mỗi lần đẩy mã: cài gói, --help, init cả hai chế độ, toàn bộ test |
đã chạy thật 30/09/2026 trên một máy M1 16 GB (MPS, fp16): doctor 16 PASS, speak mã 0, RTF 1,65 với --instruct, 2,7–4,8 với profile clone (chậm hơn thời gian thực). Test trên CI vẫn dùng module engine giả |
| Linux | CI chạy cổng kiểm repo | chưa kiểm |
Nói thẳng ra: cái đã được chứng minh trên mọi nền tảng là bộ khung — lệnh chạy, trạm dựng đúng, hợp đồng gọi giữ nguyên. Phần tổng hợp giọng có số đo thật trên Windows và trên một máy Mac Apple Silicon (M1, 30/09/2026). Đừng đọc bảng này rộng hơn thứ nó nói.
Chính là bảng mà voice-studio --help in ra — một cổng trong bộ test giữ cho hai
bên không trôi khỏi nhau.
| Lệnh | Làm gì |
|---|---|
| speak | text → file audio (hợp đồng ổn định, --json, mã 0/1/2/3) |
| narrate | video câm + lời dẫn → MP4 có giọng (+ nhạc nền) |
| make-profile | tạo profile giọng từ bản ghi / video / instruct |
| clone | dựng profile từ media dài hoặc URL — cần --consent |
| verify | soi một clip mẫu qua 6 cổng kiểm |
| reftext | thêm dấu ngắt vào lời mẫu theo khoảng lặng thật |
| clean | tách giọng + khử tạp âm cho clip mẫu |
| bgm | thư viện nhạc nền: list | pick <style> |
| tts | đọc nhanh một câu ra file |
| ui | giao diện web cục bộ để nghe thử |
| doctor | kiểm trạm giọng, chỉ bước cài còn thiếu |
| mcp | chạy MCP server (stdio) cho agent |
| lab | bộ dựng profile đa sắc thái: mine | build | split | organize |
| init | dựng trạm (embedded | separate) + station.json |
| export | đóng gói giọng cá nhân để chuyển máy (--personal) |
| import | nhập gói giọng cá nhân |
| backup | zip cả trạm (không venv/cache/out) |
| migrate | chuyển trạm embedded ra ngoài repo |
| update | cập nhật repo (git pull --ff-only) |
| uninstall | gỡ package + hook, giữ trạm và giọng (--dry-run xem trước) |
Hợp đồng cho pipeline khác. speak và
narrate là hợp đồng ổn định: có --json thì dòng cuối
stdout là đúng một object JSON, log người đọc đi stderr. Mã thoát:
0 ok · 1 lỗi engine · 2 gọi/cấu hình sai · 3 trạm/engine chưa cài.
Đây không phải lời khuyên. Ba luật đầu là lý do quy trình này tồn tại; luật thứ tư là điều kiện để được dùng nó.
Tổng hợp, cho nhận dạng nghe lại, so. "Nghe hay hơn" không phải một kết quả, và không ai kiểm lại được nó ở phiên sau.
Engine không tái lập nếu không ghim. Một phép so không ghim seed là đang đo nhiễu lấy mẫu, không phải đo thứ bạn vừa đổi.
Đừng bao giờ cho một clip qua cổng lấy lệ. Chi phí sửa về sau không nằm ở clip đó, mà ở toàn bộ bài đã đọc bằng nó.
Hai lệnh clone và make-profile chỉ dành cho giọng đã được
đồng ý; clone đòi cờ --consent tường minh để không ai lỡ tay.
Xin phép trước khi clone giọng người khác là điều kiện dùng repo này, không phải
một bước có thể bỏ khi vội.
Weights đi đường riêng. Giấy phép của model weights không theo giấy phép của code nạp chúng, và một số biến thể model tách giọng là phi thương mại. Bản weights của engine tổng hợp là CC-BY-NC. Hãy kiểm giấy phép của từng checkpoint mình tải trước khi dùng sản phẩm vào mục đích thương mại — repo này không kiểm hộ bạn việc đó.
Repo không chứa giọng. Không một file audio nào được đưa vào đây, và bộ
test có cổng chặn: tên profile thật, đường dẫn máy, tên người và file
*.wav/*.mp3/*.pt
đều bị bắt trước khi commit đi qua.
Ba repo cùng họ nói chuyện với nhau qua một hợp đồng duy nhất: mã thoát cộng một dòng JSON cuối stdout. Không có thứ tự cài bắt buộc và không có bộ nào phải cài đủ.
Dựng video. Gọi repo này để lồng tiếng cho một video câm. Thiếu trạm giọng thì render câm vẫn chạy — chỉ là không lồng tiếng được, và nó nói rõ điều đó thay vì nổ giữa chừng.
Quy trình sản xuất nội dung. Gọi được repo này khi nó có mặt; chưa cài thì pipeline vẫn chạy bình thường và nói rõ là đang thiếu năng lực giọng.
Cách dùng phổ biến nhất. Repo này đứng một mình: cài khi bạn cần một giọng đọc, và chỉ khi đó.
Nó không đóng gói dòng code nào của họ. Ba dự án dưới đây được gọi tới lúc chạy và do bạn tự cài; giấy phép của chúng áp cho chính chúng.
| Dự án | Giấy phép | Dùng để |
|---|---|---|
| OmniVoice (k2-fsa) | Apache-2.0 | tổng hợp và clone giọng |
| ClearerVoice-Studio (modelscope) | Apache-2.0 | khử tạp âm |
| python-audio-separator (nomadkaraoke) | MIT | tách giọng khỏi nền |
LICENSE; phần bên thứ ba ở NOTICE.