คู่มือฉบับสมบูรณ์ ตั้งแต่ทำความเข้าใจว่ามันคืออะไร ไปจนถึงสร้างไฟล์เสียงแรก ครอบคลุมทั้ง Windows, macOS และ Linux — ทั้งเครื่องที่มีการ์ดจอและเครื่องที่ไม่มี พร้อมวิธีเช็คว่าเครื่องคุณรันไหวแค่ไหน และปัญหาที่เจอบ่อยพร้อมทางแก้
มันคือ ตัวห่อ (wrapper) ที่เอาชิ้นส่วน 3 ชิ้นซึ่งกระจายอยู่คนละที่ มาประกอบให้ครบจนใช้งานได้จริงในคำสั่งเดียว — ไม่ใช่โมเดลใหม่
ทำไมต้องมีตัวนี้? repo ต้นทางของ JaiTTS วางไว้แบบสายวิจัย คือมีแต่โค้ด วัดผล (benchmark) แต่ไม่มีโค้ดสร้างเสียงจริง เขาชี้ให้ไปใช้ของ ThonburianTTS อีกที ส่วน weights ก็อยู่บน HuggingFace แยกอีกที่ คนทั่วไปเลยต้องประกอบเองหลายขั้นกว่าจะได้ยินเสียงแรก
โดย JTS AI Team — โมเดลไทย finetune มาจาก F5-TTS
น้ำหนักอยู่บน HuggingFace ที่ JTS-AI/JaiTTS-F5TTS
(model.pt 1.35 GB + vocab.txt)
โดยทีม ThonburianTTS (ม.มหิดล) — โค้ดที่รันโมเดลจริง
สัญญาอนุญาต MIT ถูก vendor ไว้ในโฟลเดอร์ flowtts/
โดยเพจ Ai Unlocked — สคริปต์ติดตั้งอัตโนมัติทั้ง 3 OS,
หน้าเว็บ Gradio, CLI, และแก้ dependency ที่ต้นทางตกหล่น
(accelerate, s3prl)
คุณภาพที่วัดได้: JaiTTS v1.0 ทำ CER 1.94% ซึ่งดีกว่า human baseline ที่ 1.98% และได้ SIM 0.62 (ความเหมือนของเสียงเทียบกับต้นแบบ)
สำคัญ: นี่คือ voice cloning ไม่ใช่ TTS เสียงสำเร็จรูป คุณต้องมีไฟล์เสียงต้นแบบ 3–10 วินาทีเสมอ ไม่มีเสียง preset ให้เลือกแบบ Google TTS
อัปโหลดเสียงใครก็ได้ แล้วให้อ่านข้อความไทยที่คุณพิมพ์ ด้วยน้ำเสียงและสำเนียงนั้น
หลังโหลดโมเดลครั้งแรกแล้ว ตัดเน็ตได้เลย เสียงและข้อความไม่หลุดออกไปไหน
หน้าเว็บผูกกับ 127.0.0.1 ไม่มี public share link
Windows, macOS (Apple Silicon ใช้ MPS), Linux — โค้ดเลือก CUDA / MPS / CPU ให้อัตโนมัติ ไม่ต้องตั้งค่าเอง
หน้าเว็บ Gradio สำหรับใช้มือ / CLI สำหรับเอาไปต่อกับสคริปต์หรือ batch งาน
มีปุ่มถอด transcript ให้ ใช้ typhoon-whisper-large-v3
ไม่ต้องนั่งพิมพ์เอง (โหลดโมเดลเพิ่ม ~3 GB ครั้งแรกที่กด)
พร้อม transcript กำกับครบ ถ้าไม่อยากอัดเสียงเอง เลือกใช้ได้ทันที
สไลเดอร์ NFE step, ความเร็วพูด, และ CFG strength ปรับสมดุลได้ตามงาน
ของต้นทางยังอยู่ครบ ใช้วัดคุณภาพเชิงตัวเลขได้ (ต้องติดตั้งโหมดเต็ม)
ต้องมีไฟล์เสียงต้นแบบเสมอ ใส่ข้อความอย่างเดียวแล้วกดสร้างไม่ได้
ดูหัวข้อสัญญาอนุญาตด้านล่าง — เป็นข้อจำกัดที่สำคัญที่สุดของโปรเจกต์นี้
สร้างเป็นไฟล์ทีละประโยค/ย่อหน้า ไม่ได้สตรีมเสียงออกมาทีละคำ
⚠️ เรื่องสัญญาอนุญาต — อ่านก่อนเอาไปใช้กับงานที่มีรายได้
model card ของ JaiTTS ระบุ Apache 2.0 ก็จริง แต่โมเดลฐานที่มัน finetune มาคือ F5-TTS ซึ่งเป็น CC BY-NC-4.0 — NC = Non-Commercial ห้ามใช้เชิงพาณิชย์
ใช้ทดลอง เรียนรู้ ใช้ภายใน หรือใช้ส่วนตัว ไม่มีปัญหา แต่ถ้าจะเอาไปทำงานขาย งานลูกค้า หรือคอนเทนต์หารายได้ ต้องเคลียร์กับ JTS AI Team ก่อน
ชิ้นส่วนอื่น: ThonburianTTS = MIT · Microsoft UniSpeech = CC BY-SA 3.0 · และ repo นี้เป็นของชุมชน ไม่ใช่ repo ทางการของทีม JaiTTS
แบ่งเป็น 3 ชั้น เข้าใจชั้นกลางแล้วจะแก้ปัญหาเป็นเองเกือบทุกเคส
ต้องป้อน 3 อย่างเสมอ: ไฟล์เสียงต้นแบบ, ข้อความที่พูดในไฟล์นั้น, และข้อความใหม่ที่อยากให้อ่าน ตัวที่คนพลาดบ่อยที่สุดคือตัวกลาง
โมเดลเทียบสัดส่วน "ความยาวเสียงต้นแบบ ต่อ ความยาวข้อความต้นแบบ" เพื่อประเมินว่าข้อความใหม่ควรยาวเท่าไร แล้วสังเคราะห์ mel-spectrogram ก่อนส่งให้ vocoder แปลงเป็นคลื่นเสียง
หน้าเว็บบันทึกลงโฟลเดอร์ outputs/ พร้อมแสดง
ความยาว/RMS/peak และภาพ spectrogram ให้ตรวจคุณภาพด้วยตา
💡 กุญแจสำคัญที่ต้องจำ: เพราะโมเดลใช้ สัดส่วน ของเสียงต้นแบบ ในการประเมินความยาว ถ้า ref เป็นภาษาอื่นแต่ข้อความเป็นไทย การประเมินจะเพี้ยนทันที — จากการทดสอบ ประโยคไทย 48 ตัวอักษรเดียวกัน ออกมายาว 14.65 วินาที เมื่อใช้ ref ภาษาอังกฤษ แต่ยาว 4.12 วินาที เมื่อใช้ ref ภาษาไทย ใช้ ref ภาษาไทยเสมอ
ข่าวดีคือ รันได้เกือบทุกเครื่อง — มีการ์ดจอก็เร็ว ไม่มีก็ยังรันได้แค่ช้าลง หัวข้อนี้ช่วยให้คุณรู้ว่าเครื่องตัวเองอยู่กลุ่มไหน
| รายการ | ต้องมี | วิธีติดตั้ง |
|---|---|---|
| uv | จำเป็น |
winget install --id=astral-sh.uv
brew install uv
curl -LsSf https://astral.sh/uv/install.sh | sh
|
| ffmpeg | จำเป็น |
winget install Gyan.FFmpeg — แต่ดูขั้นตอนที่ 5 ด้วย
brew install ffmpeg
sudo apt install ffmpeg หรือ sudo dnf install ffmpeg
|
| git | จำเป็น |
winget install Git.Git
brew install git (หรือมากับ Xcode CLT)
sudo apt install git
|
| Python | 3.11 | uv ติดตั้งให้อัตโนมัติ ไม่ต้องลงเอง |
| พื้นที่ดิสก์ | ~12 GB | โหมด TTS อย่างเดียวใช้น้อยกว่านี้มาก |
| RAM | 8 GB ขึ้นไป | 16 GB สบายกว่า โดยเฉพาะถ้ารันบน CPU |
โค้ดเลือกให้อัตโนมัติตามลำดับ CUDA → MPS → CPU ไม่ต้องตั้งค่าเอง
เร็วที่สุด — Windows ต้องใส่ธง -Cuda ตอนติดตั้ง
ส่วน Linux ได้ CUDA มาอัตโนมัติจาก PyPI
เร็วพอใช้ — M1/M2/M3/M4 ใช้ GPU ในตัวได้เลย ไม่ต้องตั้งค่าอะไร README ระบุราว 20 วินาที/ประโยค
ช้าแต่ใช้ได้ — ครอบคลุม Intel Mac, เครื่องที่ใช้ AMD บน Windows, และเครื่องที่ไม่มีการ์ดจอแยก เหมาะกับงานที่ไม่รีบ
VRAM ที่ต้องใช้จริง: จากการวัดขณะสังเคราะห์เสียง โมเดลกินหน่วยความจำ GPU สูงสุดราว 1.94 GB
แปลว่าการ์ด 4 GB ขึ้นไปก็พอ และ 6–8 GB สบายมาก ไม่จำเป็นต้องมีการ์ดตัวท็อป — VRAM ไม่ใช่คอขวดของงานนี้
นี่คือปัญหาที่คนเจอบ่อยแต่วินิจฉัยยาก เพราะมันติดตั้งผ่านปกติ แล้วไปพังตอนรัน วิธีเช็คที่แน่นอนที่สุดคือถามตัว PyTorch เอง (รันหลังติดตั้งเสร็จ):
.\.venv-tts\Scripts\python.exe -c "import torch; print(torch.cuda.get_device_capability(0)); print(torch.cuda.get_arch_list())".venv-tts/bin/python -c "import torch; print('MPS:', torch.backends.mps.is_available())".venv-tts/bin/python -c "import torch; print(torch.cuda.get_device_capability(0)); print(torch.cuda.get_arch_list())"
ตัวแรกคือ compute capability ของการ์ดคุณ ตัวที่สองคือรายชื่อสถาปัตยกรรมที่ PyTorch ตัวนั้นรองรับ — ถ้ารหัสของคุณอยู่ในลิสต์ = ใช้ได้แน่นอน
ตัวแรกคือ compute capability ของการ์ดคุณ ตัวที่สองคือรายชื่อสถาปัตยกรรมที่ PyTorch ตัวนั้นรองรับ — ถ้ารหัสของคุณอยู่ในลิสต์ = ใช้ได้แน่นอน
บน Mac ไม่มี CUDA — ถ้าได้ MPS: True แปลว่าเป็น Apple Silicon และจะใช้ GPU ในตัวอัตโนมัติ
ถ้าได้ False (เช่น Intel Mac) จะรันบน CPU ซึ่งยังใช้ได้แต่ช้ากว่ามาก
| การ์ด NVIDIA | สถาปัตยกรรม | รหัส | ใช้กับ build ปัจจุบัน |
|---|---|---|---|
| RTX 50 ซีรีส์ (5060–5090) | Blackwell | sm_120 | ได้ — แต่ต้องเป็น CUDA 12.8+ |
| RTX 40 ซีรีส์ (4060–4090) | Ada Lovelace | sm_89 | ได้ |
| RTX 30 ซีรีส์ (3050–3090) | Ampere | sm_86 | ได้ |
| RTX 20 / GTX 16 ซีรีส์ | Turing | sm_75 | ได้ |
| GTX 10 ซีรีส์และเก่ากว่า | Pascal และเก่ากว่า | sm_61 ลงไป | ไม่ได้ — ต้องใช้ CUDA build เก่า หรือรันบน CPU |
⚠️ จุดที่พลาดกันบ่อยที่สุดสำหรับการ์ด RTX 50 ซีรีส์
การ์ดตระกูล Blackwell ต้องใช้ PyTorch ที่ build ด้วย CUDA 12.8 ขึ้นไป
ถ้าได้ CUDA เวอร์ชันเก่ากว่านั้น มันจะติดตั้งผ่านปกติแล้วไปพังตอนรันด้วยข้อความ
no kernel image is available for execution on the device
โชคดีที่ setup.ps1 ตั้งค่าเริ่มต้นเป็น cu128 อยู่แล้ว
แต่คุณต้องใส่ธง -Cuda เอง ไม่งั้นบน Windows จะได้ torch เวอร์ชัน CPU
ปลายทางเหมือนกันทั้งสองทาง ต่างกันที่ว่าคุณจะพิมพ์คำสั่งเองทีละขั้น หรือให้ AI agent อ่านคู่มือแล้วจัดการให้
แนวคิดของวิธีนี้: AI agent อ่านโฟลเดอร์และรันคำสั่งได้เอง สิ่งที่มันขาดคือความรู้เรื่องบั๊กเฉพาะตัวของโปรเจกต์นี้ ถ้าปล่อยให้มันติดตั้งดิบๆ มันจะไปเจอ error เดียวกับที่คนอื่นเจอ แล้วเสียเวลาไล่แก้ทีละตัว
prompt ด้านล่างจึงบอกบั๊กทั้งหมดที่รู้แล้วไว้ล่วงหน้า พร้อมวิธีแก้ และกำหนดว่าต้องพิสูจน์ด้วยไฟล์เสียงจริงถึงจะนับว่าสำเร็จ
mkdir D:\JaiTTS cd D:\JaiTTSmkdir -p ~/JaiTTS cd ~/JaiTTSmkdir -p ~/JaiTTS cd ~/JaiTTS
claude
เลือกโฟลเดอร์ → วาง prompt
codex
ช่วยติดตั้ง JaiTTS-Easy (โปรแกรมโคลนเสียงพูดภาษาไทยแบบรันในเครื่อง)
ลงในโฟลเดอร์นี้ให้พร้อมใช้งาน
## เป้าหมาย
ติดตั้งจนสร้างไฟล์เสียงภาษาไทยได้จริง 1 ไฟล์
"ติดตั้งเสร็จ" อย่างเดียวยังไม่นับว่าสำเร็จ
## repo
https://github.com/aiunlocked1412/JaiTTS-Easy
## ขั้นตอน
1. ตรวจเครื่องก่อน แล้วรายงานให้ผมดู:
- ระบบปฏิบัติการและเวอร์ชัน
- มี uv / ffmpeg / git ครบไหม
- มีการ์ดจอ NVIDIA ไหม ถ้ามีให้บอกรุ่นและ compute capability
(Mac: บอกว่าเป็น Apple Silicon หรือ Intel)
- พื้นที่ว่างของไดรฟ์ (ต้องการ ~12 GB)
ถ้าเครื่องมือขาด ให้หยุดถามผมก่อน อย่าเพิ่งติดตั้งเอง
2. clone repo ลงในโฟลเดอร์นี้
3. รันสคริปต์ติดตั้งเฉพาะโหมด TTS
- Windows: .\setup.ps1 tts -Cuda
(ถ้าไม่มีการ์ด NVIDIA ให้ตัด -Cuda ออก)
- macOS/Linux: ./setup.sh tts
(อาจต้อง chmod +x setup.sh ก่อน)
4. โหลดชุดเสียงต้นแบบภาษาไทย 802 ไฟล์ (~392 MB)
uvx gdown '1syOkdb0G2Etsi1xG-xT1p6_EDPpoXMqD' -O data/jaitts_testset.zip
แล้วแตกไฟล์ลงโฟลเดอร์ data/ จากนั้นลบ __MACOSX และไฟล์ zip ทิ้ง
5. ทดสอบว่าสร้างเสียงได้จริง
- อ่านบรรทัดแรกของ data/jaitts_testset/th/meta.lst
รูปแบบคั่นด้วย | คือ:
utt_id | ข้อความของเสียงต้นแบบ | path ของเสียงต้นแบบ | ... | ...
ใช้คอลัมน์ 2 เป็น ref_text และคอลัมน์ 3 เป็น ref wav
- สังเคราะห์ประโยคภาษาไทยสั้นๆ 1 ประโยค พร้อมจับเวลา
- ตรวจไฟล์ผลลัพธ์ว่าไม่ใช่ความเงียบ (ดูค่า RMS และความยาว)
6. รายงานสรุป: รันบน CUDA / MPS / CPU, เวลาโหลดโมเดล,
เวลาสังเคราะห์, ความยาวเสียงที่ได้, และ path ของไฟล์เสียง
## ปัญหาที่รู้อยู่แล้ว — เจอเมื่อไหร่แก้ตามนี้ได้เลย ไม่ต้องถาม
A) [Windows] setup.ps1 พังด้วย
"The string is missing the terminator"
สาเหตุ: ไฟล์เป็น UTF-8 ไม่มี BOM ทำให้ PowerShell 5.1 อ่านเป็น
Windows-1252 แล้ว em dash กลายเป็นอักขระที่ PowerShell
ถือเป็น string delimiter จึงปิด string กลางคัน
แก้: สำรองไฟล์เดิมไว้ แล้วบันทึก setup.ps1 ใหม่เป็น UTF-8 with BOM
B) [ทุก OS] uv ล้มด้วย
"Missing expected target directory for Python minor version link"
แก้: รันคำสั่งเดิมซ้ำอีกครั้ง — Python ติดตั้งสมบูรณ์แล้ว
เป็นแค่ race condition ตอนดาวน์โหลดรอบแรก
C) [ทุก OS] "A virtual environment already exists at .venv-tts"
แก้: ลบโฟลเดอร์ .venv-tts แล้วรัน setup ใหม่
D) [Windows] ตอนสังเคราะห์เสียงพังด้วย
"Could not load this library: libtorchcodec_core*.dll"
สาเหตุ: torchaudio ส่งงานให้ torchcodec ซึ่งต้องการ FFmpeg
shared DLL แต่ ffmpeg บน Windows ส่วนใหญ่เป็น static build
แก้: โหลดไฟล์นี้
https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-n8.1-latest-win64-lgpl-shared-8.1.zip
แตกไฟล์ แล้วก๊อป *.dll จากโฟลเดอร์ bin ไปวางใน
.venv-tts\Lib\site-packages\torchcodec\
ห้ามแก้ PATH ของระบบ
[macOS] เจอปัญหาเดียวกันให้ brew reinstall ffmpeg
[Linux] ให้ติดตั้ง libavcodec / libavformat / libavutil เพิ่ม
E) [NVIDIA RTX 50 ซีรีส์] "CUDA error: no kernel image is available"
สาเหตุ: การ์ด Blackwell เป็น sm_120 ต้องใช้ torch ที่ build
ด้วย CUDA 12.8 ขึ้นไป
แก้: ลบ .venv-tts แล้วติดตั้งใหม่ให้ได้ cu128
ตรวจด้วย torch.cuda.get_arch_list() ว่ามี sm_120 อยู่จริง
## ข้อห้าม
- ห้ามแก้ PATH หรือ environment variable ของระบบ
- ห้ามเปลี่ยน ExecutionPolicy แบบถาวร ใช้ -Scope Process เท่านั้น
- ห้ามติดตั้งแพ็กเกจระดับระบบ (winget / brew / apt) โดยไม่ถามก่อน
- ห้ามรายงานว่าสำเร็จถ้ายังไม่มีไฟล์เสียงที่สร้างได้จริง
outputs/ ว่าเป็นเสียงพูดภาษาไทย ไม่ใช่ความเงียบหรือเสียงรบกวนhttp://127.0.0.1:7860 ดูว่าขึ้นหน้าจริง⚠️ ข้อควรระวังของวิธีนี้
AI จะรันคำสั่งใน terminal ของเครื่องคุณจริง และดาวน์โหลดไฟล์จากอินเทอร์เน็ตจริง อ่านสิ่งที่มันกำลังจะทำก่อนอนุมัติทุกครั้ง โดยเฉพาะคำสั่งลบไฟล์ และคำสั่งติดตั้งแพ็กเกจระดับระบบ
ถ้าเครื่องมือที่ใช้มีโหมดถามก่อนรัน ให้เปิดไว้ อย่าใช้โหมดอนุมัติอัตโนมัติทั้งหมด กับงานที่แตะระบบแบบนี้
ไม่แน่ใจว่าเครื่องมือที่มีทำได้ไหม? เกณฑ์ง่ายๆ คือมันต้อง (1) อ่านและเขียนไฟล์ในโฟลเดอร์ได้ และ (2) รันคำสั่ง terminal ได้ ถ้าเป็นแชทที่ตอบได้อย่างเดียวแต่รันคำสั่งไม่ได้ ให้ใช้ วิธีติดตั้งด้วยตนเอง แทน แล้วเอาแชทไว้ช่วยตอนติดปัญหา
Windows มีขั้นตอนพิเศษ 2 ขั้น (2 และ 5) ที่ README ไม่ได้เขียนไว้ และเป็นสาเหตุที่คนติดตั้งไม่ผ่าน — ห้ามข้าม
บน macOS ติดตั้งง่ายกว่า Windows มาก เพราะ Homebrew ลง ffmpeg มาให้ครบ และ Apple Silicon ใช้ GPU ในตัวได้เลยโดยไม่ต้องตั้งค่า
บน Linux ติดตั้งง่ายที่สุด เพราะ torch จาก PyPI มี CUDA มาให้พร้อมอยู่แล้ว ไม่ต้องระบุธงพิเศษเหมือน Windows
git clone https://github.com/aiunlocked1412/JaiTTS-Easy.git D:\JaiTTS cd D:\JaiTTSgit clone https://github.com/aiunlocked1412/JaiTTS-Easy.git ~/JaiTTS cd ~/JaiTTSgit clone https://github.com/aiunlocked1412/JaiTTS-Easy.git ~/JaiTTS cd ~/JaiTTS
setup.ps1 WINDOWS เท่านั้นThe string is missing the terminator
ตั้งแต่ยังไม่เริ่มติดตั้ง
setup.ps1 ถูกบันทึกเป็น UTF-8 ไม่มี BOM— (em dash) กลายเป็นตัวอักษรเพี้ยน 3 ตัว ซึ่งตัวสุดท้าย
เป็น string delimiter ที่ถูกต้องใน PowerShell เลยไปปิด string กลางคัน พังต่อกัน 5 จุด$p = "D:\JaiTTS\setup.ps1"
Copy-Item $p "$p.orig" -Force
$t = [System.IO.File]::ReadAllText($p, (New-Object System.Text.UTF8Encoding $false))
[System.IO.File]::WriteAllText($p, $t, (New-Object System.Text.UTF8Encoding $true))
pwsh) ให้รัน setup ด้วย pwsh แทน จะข้ามปัญหานี้ไปเลย เพราะ PS7 อ่านไฟล์เป็น UTF-8 เป็นค่าเริ่มต้นchmod +x setup.sh
chmod +x setup.sh
-Scope Process จะมีผลเฉพาะหน้าต่างนี้ ไม่ไปเปลี่ยนค่าถาวรของเครื่องSet-ExecutionPolicy -Scope Process Bypass -Force
which uv ffmpeg || brew install uv ffmpeg
which uv ffmpeg
tts = ติดตั้งเฉพาะส่วนสร้างเสียง ข้ามไฟล์วัดผลขนาดใหญ่
· -Cuda = ดึง torch เวอร์ชัน GPU
.\setup.ps1 tts -Cuda./setup.sh tts./setup.sh tts
-Cuda ออก จะได้ torch เวอร์ชัน CPU ซึ่งยังรันได้แต่ช้ากว่าMissing expected target directory for Python minor version link ให้รันซ้ำอีกครั้ง — เป็น race condition ของ uv ตอนโหลด Python รอบแรกA virtual environment already exists ให้ลบ .venv-tts ก่อนแล้วรันใหม่Missing expected target directory for Python minor version link ให้รันซ้ำอีกครั้ง — เป็น race condition ของ uvA virtual environment already exists ให้ rm -rf .venv-tts แล้วรันใหม่Missing expected target directory for Python minor version link ให้รันซ้ำอีกครั้ง — เป็น race condition ของ uvA virtual environment already exists ให้ rm -rf .venv-tts แล้วรันใหม่Could not load this library: libtorchcodec_core*.dll
avcodec, avformat, avutil, swresample, swscale)ffmpeg.exe ไม่มี DLL เลยวิธีที่ไม่แตะ PATH หรือ ffmpeg เดิมของคุณ — ก๊อป DLL เข้าไปใน venv โดยตรง:
$tmp = "$env:TEMP\ffshared"
$url = "https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-n8.1-latest-win64-lgpl-shared-8.1.zip"
Invoke-WebRequest -Uri $url -OutFile "$tmp.zip"
Expand-Archive "$tmp.zip" -DestinationPath $tmp -Force
$bin = (Get-ChildItem $tmp -Recurse -Directory -Filter bin)[0].FullName
Copy-Item "$bin\*.dll" -Destination ".\.venv-tts\Lib\site-packages\torchcodec" -Force
.venv-tts/bin/python -c "import torchaudio; print(torchaudio.load('flowtts/infer/examples/basic/basic_ref_en.wav')[1])"
libtorchcodec ให้ brew reinstall ffmpeg.venv-tts/bin/python -c "import torchaudio; print(torchaudio.load('flowtts/infer/examples/basic/basic_ref_en.wav')[1])"
libtorchcodec ให้ลง libavcodec-dev libavformat-dev libavutil-dev เพิ่มuvx gdown '1syOkdb0G2Etsi1xG-xT1p6_EDPpoXMqD' -O 'data\jaitts_testset.zip' Expand-Archive 'data\jaitts_testset.zip' -DestinationPath 'data' -Force Remove-Item -Recurse -Force 'data\__MACOSX' -ErrorAction SilentlyContinue Remove-Item -Force 'data\jaitts_testset.zip'mkdir -p data uvx gdown '1syOkdb0G2Etsi1xG-xT1p6_EDPpoXMqD' -O data/jaitts_testset.zip unzip -q -o data/jaitts_testset.zip -d data -x "__MACOSX/*" rm -rf data/__MACOSX data/jaitts_testset.zipmkdir -p data uvx gdown '1syOkdb0G2Etsi1xG-xT1p6_EDPpoXMqD' -O data/jaitts_testset.zip unzip -q -o data/jaitts_testset.zip -d data -x "__MACOSX/*" rm -rf data/__MACOSX data/jaitts_testset.zip
uvx รัน gdown แบบชั่วคราว ไม่ติดตั้งค้างใน venv.\.venv-tts\Scripts\python.exe -c "import torch; print(torch.__version__); print('cuda:', torch.cuda.is_available()); print(torch.cuda.get_arch_list() if torch.cuda.is_available() else 'CPU mode')".venv-tts/bin/python -c "import torch; print(torch.__version__); print('mps:', torch.backends.mps.is_available())".venv-tts/bin/python -c "import torch; print(torch.__version__); print('cuda:', torch.cuda.is_available()); print(torch.cuda.get_arch_list() if torch.cuda.is_available() else 'CPU mode')"
cuda: True และมีรหัส sm_ ที่ตรงกับการ์ดคุณอยู่ในลิสต์ · ถ้าได้ False ทั้งที่มีการ์ด NVIDIA แปลว่าลืมธง -Cudamps: True · Intel Mac จะได้ False ซึ่งปกติ จะรันบน CPU แทนcuda: True · ถ้าไม่มีการ์ดจะได้ CPU mode ซึ่งยังใช้งานได้model.pt 1.35 GB จาก HuggingFace อัตโนมัติ.\.venv-tts\Scripts\python.exe jaitts_webapp.py.venv-tts/bin/python jaitts_webapp.py.venv-tts/bin/python jaitts_webapp.py
http://127.0.0.1:7860 — เสร็จแล้วเลือกตามลักษณะงาน — หน้าเว็บสำหรับลองผิดลองถูก, CLI สำหรับงานซ้ำๆ
jaitts_webapp.py แล้วเปิด 127.0.0.1:7860jaitts_synth.py พร้อม 4 argument.\.venv-tts\Scripts\python.exe jaitts_synth.py ` "ข้อความที่อยากให้อ่าน" ` ref.wav ` "ข้อความที่พูดในไฟล์ ref จริงๆ" ` outputs\out.wav.venv-tts/bin/python jaitts_synth.py \ "ข้อความที่อยากให้อ่าน" \ ref.wav \ "ข้อความที่พูดในไฟล์ ref จริงๆ" \ outputs/out.wav.venv-tts/bin/python jaitts_synth.py \ "ข้อความที่อยากให้อ่าน" \ ref.wav \ "ข้อความที่พูดในไฟล์ ref จริงๆ" \ outputs/out.wav
| ลำดับ | argument | คำอธิบาย |
|---|---|---|
| 1 | text | ข้อความไทยที่ต้องการให้อ่าน |
| 2 | ref_voice | path ไฟล์เสียงต้นแบบ |
| 3 | ref_text | ข้อความที่พูดในไฟล์ต้นแบบ ต้องตรงเป๊ะ |
| 4 | output | path ไฟล์ผลลัพธ์ (โฟลเดอร์จะถูกสร้างให้อัตโนมัติ) |
💡 อยากทำงาน batch หลายประโยคโดยไม่โหลดโมเดลซ้ำ?
เขียนสคริปต์ Python เรียก load() จาก jaitts_synth ครั้งเดียว
แล้ววนเรียก pipeline หลายรอบ — ประโยคที่ 2 เป็นต้นไปจะเร็วขึ้นชัดเจน
เพราะไม่ต้องโหลดโมเดลใหม่ วิธีนี้ใช้ได้เหมือนกันทุก OS
คุณภาพผลลัพธ์ขึ้นกับเสียงต้นแบบมากกว่าอย่างอื่นทั้งหมด — ทำ 4 ข้อนี้ให้ถูกแล้วจบ
สั้นกว่านี้เสียงไม่นิ่ง ยาวกว่านี้โมเดลจัดการได้ไม่ดี จุดหวานอยู่ราว 5–8 วินาที
ไม่มีดนตรีประกอบ ไม่มีเสียงรบกวน ไม่มีเสียงคนอื่นแทรก ไม่มีเสียงก้อง
จุดที่คนพลาดมากที่สุด — ต้องพิมพ์สิ่งที่พูดในคลิปจริงๆ ทุกคำ ใส่ผิดปุ๊บเสียงเพี้ยนทันที
ใช้ ref ภาษาอื่นแล้วให้อ่านไทย จะทำให้ประเมินความยาวเสียงเพี้ยนอย่างรุนแรง
คำสั่งนี้เหมือนกันทุก OS — ตัดช่วงที่ต้องการจากคลิป แล้วแปลงเป็น WAV mono 24 kHz:
ffmpeg -i input.mp4 -ss 00:00:05 -t 8 -vn -ac 1 -ar 24000 ref.wav
| ธง | ความหมาย |
|---|---|
-ss 00:00:05 | เริ่มตัดที่วินาทีที่ 5 |
-t 8 | เอาความยาว 8 วินาที |
-vn | ตัดวิดีโอทิ้ง เอาแต่เสียง |
-ac 1 | แปลงเป็น mono |
-ar 24000 | ตั้ง sample rate 24 kHz ให้ตรงกับโมเดล |
ไฟล์อยู่ที่ data/jaitts_testset/th/prompt-wavs/
ส่วน transcript อยู่ใน meta.lst ซึ่งคั่นด้วย | 5 คอลัมน์:
| คอลัมน์ | เนื้อหา |
|---|---|
| 1 | utterance id |
| 2 | ข้อความของเสียงต้นแบบ ← ตัวนี้คือ ref_text ที่ต้องใช้ |
| 3 | path ของไฟล์เสียงต้นแบบ |
| 4 | ข้อความเป้าหมายของชุดทดสอบ |
| 5 | ข้อความเป้าหมายหลัง normalize |
ดูรายชื่อเสียงต้นแบบพร้อมข้อความ 20 รายการแรก:
Get-Content data\jaitts_testset\th\meta.lst -Encoding UTF8 | ForEach-Object { $c = $_ -split '\|'; "$($c[2].Split('/')[-1]) = $($c[1])" } | Sort-Object -Unique | Select-Object -First 20awk -F'|' '{split($3,a,"/"); print a[length(a)]" = "$2}' data/jaitts_testset/th/meta.lst | sort -u | head -20awk -F'|' '{split($3,a,"/"); print a[length(a)]" = "$2}' data/jaitts_testset/th/meta.lst | sort -u | head -20
💡 ทางลัด: ถ้าใช้หน้าเว็บ ไม่ต้องยุ่งกับ meta.lst เลย —
อัปโหลดไฟล์ wav แล้วกดปุ่ม ถอดข้อความอัตโนมัติ มันถอดให้เอง
(ครั้งแรกจะโหลด Typhoon Whisper ~3 GB)
| พารามิเตอร์ | ช่วง | ค่าเริ่มต้น | ผลเมื่อเพิ่ม | ใช้เมื่อไร |
|---|---|---|---|---|
| NFE step | 4–64 | 32 | คุณภาพดีขึ้น แต่ช้าลงเป็นเส้นตรง | ลดเหลือ 16 ตอนลองผิดลองถูก แล้วดันขึ้น 32–48 ตอนเรนเดอร์จริง |
| ความเร็วพูด | 0.5–2.0 | 1.0 | พูดเร็วขึ้น | ปรับให้เข้ากับจังหวะวิดีโอ — 0.9 ฟังสบายกว่าสำหรับงานบรรยาย |
| CFG strength | 1.0–4.0 | 2.5 | เกาะเสียงต้นแบบมากขึ้น แต่เสี่ยงเสียงแข็ง/มี artifact | ขึ้นเป็น 3.0 ถ้าเสียงไม่เหมือนต้นแบบ · ลงเหลือ 2.0 ถ้าเสียงบิดเบี้ยว |
วิธีจูนที่ประหยัดเวลาที่สุด: อย่าขยับพร้อมกันหลายตัว เริ่มจากหาเสียงต้นแบบที่ดีก่อน (มีผลมากที่สุด) → แล้วค่อยปรับ CFG ให้ความเหมือนพอใจ → แล้วค่อยดัน NFE ขึ้นตอนจะเรนเดอร์ไฟล์จริง → ปรับความเร็วเป็นอย่างสุดท้าย
ถ้าเครื่องคุณรันบน CPU ให้เริ่มที่ NFE 16 จะช่วยลดเวลารอลงได้เกือบครึ่งโดยคุณภาพยังพอรับได้
คลิกเพื่อดูรายละเอียด — ป้ายกำกับบอกว่าปัญหานั้นเกิดกับ OS ไหน
.\setup.ps1 แล้วขึ้น parse error 5 บรรทัดรวดpwsh) รันแทน$p = "D:\JaiTTS\setup.ps1"
$t = [System.IO.File]::ReadAllText($p, (New-Object System.Text.UTF8Encoding $false))
[System.IO.File]::WriteAllText($p, $t, (New-Object System.Text.UTF8Encoding $true))
%APPDATA%\uv\python\~/.local/share/uv/python/~/.local/share/uv/python/
Remove-Item -Recurse -Force .venv-tts .\setup.ps1 tts -Cudarm -rf .venv-tts ./setup.sh ttsrm -rf .venv-tts ./setup.sh tts
⚠️ ถ้าลบ .venv-tts อย่าลืมทำขั้นตอนที่ 5 (FFmpeg DLL) ใหม่ด้วย
เพราะ DLL ที่ก๊อปไว้จะหายไปพร้อม venv
site-packages\torchcodec\บน macOS และ Linux มักไม่เจอปัญหานี้ เพราะ Homebrew และ package manager ของ distro ลง shared library มาให้อยู่แล้ว — ถ้าเจอ ให้ติดตั้ง ffmpeg ใหม่จาก package manager
.\.venv-tts\Scripts\python.exe -c "import torch; print(torch.cuda.get_device_capability(0), torch.cuda.get_arch_list())"ปัญหานี้ไม่เกิดบน macOS เพราะไม่ได้ใช้ CUDA.venv-tts/bin/python -c "import torch; print(torch.cuda.get_device_capability(0), torch.cuda.get_arch_list())"
ถ้ารหัส capability ของคุณไม่อยู่ในลิสต์ที่ตามมา = ใช่ปัญหานี้
Get-NetTCPConnection -LocalPort 7860 -State Listen | ForEach-Object { Get-Process -Id $_.OwningProcess }lsof -nP -iTCP:7860 -sTCP:LISTENss -lptn 'sport = :7860'
ปิดโปรแกรมนั้น หรือแก้เลข port ในบรรทัดสุดท้ายของ jaitts_webapp.py
หน้าเว็บตั้งค่า default reference ไว้ที่ไฟล์ในโฟลเดอร์ data/jaitts_testset/
ซึ่งโหมด tts ไม่ได้โหลดมา โค้ดมี fallback ไว้แล้วเลยไม่ error
แค่เปิดมาว่างเปล่า
แก้ได้โดยทำขั้นตอนที่ 6 (โหลดชุด 802 ไฟล์) แล้ว restart หน้าเว็บ — ค่า default ถูกอ่านตอนเริ่มโปรแกรมเท่านั้น
device: cpu ทั้งที่มีการ์ดจอ แปลว่าติดตั้ง torch ผิดเวอร์ชันload() ครั้งเดียวแล้ววนลูป แทนการเรียกคำสั่งซ้ำๆรันบน CPU ช้าเป็นเรื่องปกติ ไม่ใช่ของเสีย — ถ้างานไม่รีบก็ยังใช้ได้ แต่ถ้าต้องทำเยอะ การมีการ์ดจอ NVIDIA แม้แค่ระดับกลางก็ต่างกันมาก
ความเร็วขึ้นกับ 3 อย่าง: ตัวเร่งที่ใช้ (CUDA/MPS/CPU), ค่า NFE step, และ ความยาวข้อความ
| ฮาร์ดแวร์ | เวลาต่อประโยค | ที่มาของตัวเลข |
|---|---|---|
| GPU ระดับสูง RTX 5080, CUDA |
~2–4.6 วินาที | วัดจริงขณะเขียนคู่มือนี้ (NFE 32) |
| Apple Silicon MPS |
~20 วินาที | ตัวเลขที่ README ของโปรเจกต์ระบุไว้ |
| CPU อย่างเดียว | ช้ากว่านั้นมาก | ไม่ได้วัด — ขึ้นกับ CPU แต่ละรุ่นมาก แนะนำให้ลด NFE เหลือ 16 |
| ขั้นตอน | เวลา | หมายเหตุ |
|---|---|---|
| โหลดโมเดลครั้งแรก | 44.8 วิ | รวมดาวน์โหลด model.pt 1.35 GB จาก HuggingFace |
| โหลดโมเดลครั้งต่อไป | 4.5–5.2 วิ | อ่านจาก cache ในเครื่อง |
| สังเคราะห์ประโยคแรก | 3.5–4.6 วิ | รวมเวลา warm-up |
| สังเคราะห์ประโยคถัดไป | 2.0–2.2 วิ | โมเดลค้างอยู่ในหน่วยความจำแล้ว |
| หน่วยความจำ GPU สูงสุด | 1.94 GB | การ์ด 4 GB ขึ้นไปเพียงพอ |
เทียบเป็น RTF (Real-Time Factor): บน RTX 5080 วัดได้ 0.54–0.95 แปลว่าสร้างเสียงได้เร็วกว่าเวลาจริง — เสียงยาว 4 วินาที ใช้เวลาสร้างราว 2–4 วินาที
ตัวแปรที่คุณควบคุมได้ง่ายที่สุดคือ NFE step — มันแปรผันตรงกับเวลาเกือบเป็นเส้นตรง ลดจาก 32 เหลือ 16 จะเร็วขึ้นประมาณเท่าตัว เหมาะมากตอนลองผิดลองถูก หรือตอนรันบนเครื่องที่ไม่มีการ์ดจอ
| ต้องการ | คำสั่ง |
|---|---|
| เปิดหน้าเว็บ |
.\.venv-tts\Scripts\python.exe jaitts_webapp.py
.venv-tts/bin/python jaitts_webapp.py
.venv-tts/bin/python jaitts_webapp.py
|
| สร้างเสียงผ่าน CLI |
.\.venv-tts\Scripts\python.exe jaitts_synth.py "ข้อความ" ref.wav "ref text" outputs\out.wav
.venv-tts/bin/python jaitts_synth.py "ข้อความ" ref.wav "ref text" outputs/out.wav
.venv-tts/bin/python jaitts_synth.py "ข้อความ" ref.wav "ref text" outputs/out.wav
|
| เช็คตัวเร่งความเร็ว |
.\.venv-tts\Scripts\python.exe -c "import torch; print(torch.cuda.is_available())"
.venv-tts/bin/python -c "import torch; print(torch.backends.mps.is_available())"
.venv-tts/bin/python -c "import torch; print(torch.cuda.is_available())"
|
| แปลงเสียงต้นแบบ | ffmpeg -i in.mp4 -ss 5 -t 8 -vn -ac 1 -ar 24000 ref.wav |
| ติดตั้งใหม่ทั้งหมด |
Remove-Item -Recurse -Force .venv-tts; .\setup.ps1 tts -Cuda
rm -rf .venv-tts && ./setup.sh tts
rm -rf .venv-tts && ./setup.sh tts
|
| ที่อยู่ | คืออะไร |
|---|---|
jaitts_webapp.py | หน้าเว็บ Gradio |
jaitts_synth.py | สคริปต์ CLI + ฟังก์ชัน load() สำหรับเขียนต่อ |
flowtts/ | โค้ดรันโมเดลจาก ThonburianTTS |
.venv-tts/ | Python environment ของโปรเจกต์ |
data/jaitts_testset/th/prompt-wavs/ | เสียงต้นแบบ 802 ไฟล์ |
data/jaitts_testset/th/meta.lst | ข้อความกำกับเสียงต้นแบบ |
outputs/ | ไฟล์เสียงที่สร้างได้ |
%USERPROFILE%\.cache\huggingface\
~/.cache/huggingface/
~/.cache/huggingface/
|
โมเดลที่โหลดมา (~1.4 GB, ลบได้แต่จะโหลดใหม่) |
⚠️ สองจุดที่จะกลับมาพังถ้าคุณสร้าง venv ใหม่หรือ clone ใหม่ (Windows)
1. encoding ของ setup.ps1 (ขั้นตอนที่ 2)
2. FFmpeg shared DLL ใน torchcodec (ขั้นตอนที่ 5)
ทั้งคู่เป็นปัญหาของสภาพแวดล้อม ไม่ใช่ของโค้ด และไม่มีเขียนไว้ใน README
✅ บน macOS ติดตั้งตรงไปตรงมา
ไม่มีปัญหา encoding และไม่ต้องจัดการ shared library เอง ถ้าใช้ Apple Silicon จะได้ GPU acceleration อัตโนมัติโดยไม่ต้องตั้งค่า
✅ บน Linux ติดตั้งง่ายที่สุด
torch จาก PyPI มี CUDA มาให้พร้อม ไม่ต้องระบุธงพิเศษ และ ffmpeg จาก package manager มี shared library มาให้อยู่แล้ว
เราใช้คุกกี้เพื่อพัฒนาประสิทธิภาพ และประสบการณ์ที่ดีในการใช้เว็บไซต์ของคุณ คุณสามารถศึกษารายละเอียดได้ที่ นโยบายความเป็นส่วนตัว และสามารถจัดการความเป็นส่วนตัวเองได้ของคุณได้เองโดยคลิกที่ ตั้งค่า
คุณสามารถเลือกการตั้งค่าคุกกี้โดยเปิด/ปิด คุกกี้ในแต่ละประเภทได้ตามความต้องการ ยกเว้น คุกกี้ที่จำเป็น
ยอมรับทั้งหมดประเภทของคุกกี้มีความจำเป็นสำหรับการทำงานของเว็บไซต์ เพื่อให้คุณสามารถใช้ได้อย่างเป็นปกติ และเข้าชมเว็บไซต์ คุณไม่สามารถปิดการทำงานของคุกกี้นี้ในระบบเว็บไซต์ของเราได้
คุกกี้ประเภทนี้จะทำการเก็บข้อมูลการใช้งานเว็บไซต์ของคุณ เพื่อเป็นประโยชน์ในการวัดผล ปรับปรุง และพัฒนาประสบการณ์ที่ดีในการใช้งานเว็บไซต์ ถ้าหากท่านไม่ยินยอมให้เราใช้คุกกี้นี้ เราจะไม่สามารถวัดผล ปรับปรุงและพัฒนาเว็บไซต์ได้
รายละเอียดคุกกี้
คุกกี้ประเภทนี้จะเก็บข้อมูลต่าง ๆ รวมทั้งข้อมูลส่วนบุคคลเกี่ยวกับตัวคุณเพื่อเราสามารถนำมาวิเคราะห์ และนำเสนอเนื้อหา ให้ตรงกับความเหมาะสมกับความสนใจของคุณ ถ้าหากคุณไม่ยินยอมเราจะไม่สามารถนำเสนอเนื้อหาและโฆษณาได้ไม่ตรงกับความสนใจของคุณ
รายละเอียดคุกกี้