Instructions to use hotdogs/vibevoice-1.5b-thai-tts-lora with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use hotdogs/vibevoice-1.5b-thai-tts-lora with PEFT:
Task type is invalid.
- VibeVoice
How to use hotdogs/vibevoice-1.5b-thai-tts-lora with VibeVoice:
import torch, soundfile as sf, librosa, numpy as np from vibevoice.processor.vibevoice_processor import VibeVoiceProcessor from vibevoice.modular.modeling_vibevoice_inference import VibeVoiceForConditionalGenerationInference # Load voice sample (should be 24kHz mono) voice, sr = sf.read("path/to/voice_sample.wav") if voice.ndim > 1: voice = voice.mean(axis=1) if sr != 24000: voice = librosa.resample(voice, sr, 24000) processor = VibeVoiceProcessor.from_pretrained("hotdogs/vibevoice-1.5b-thai-tts-lora") model = VibeVoiceForConditionalGenerationInference.from_pretrained( "hotdogs/vibevoice-1.5b-thai-tts-lora", torch_dtype=torch.bfloat16 ).to("cuda").eval() model.set_ddpm_inference_steps(5) inputs = processor(text=["Speaker 0: Hello!\nSpeaker 1: Hi there!"], voice_samples=[[voice]], return_tensors="pt") audio = model.generate(**inputs, cfg_scale=1.3, tokenizer=processor.tokenizer).speech_outputs[0] sf.write("output.wav", audio.cpu().numpy().squeeze(), 24000) - Notebooks
- Google Colab
- Kaggle
🎙️ VibeVoice 1.5B — Thai TTS LoRA
ไทย/English — LoRA fine-tune ของ VibeVoice 1.5B สำหรับสังเคราะห์เสียงภาษาไทย (Thai Text-to-Speech) พร้อม speaker-conditioning สำหรับผู้พูด 1 คน
🇹🇭 LoRA นี้เทรนบน dataset เสียงภาษาไทย 20,000 ตัวอย่าง (
6.6 ชั่วโมงบน RTX 4060 Ti 16GB)6.6h on RTX 4060 Ti 16GB)
🇬🇧 LoRA fine-tuned on 20k Thai speech samples (
🏗️ Base Model
| Field | Detail |
|---|---|
| Model | microsoft/VibeVoice-1.5B |
| Developer | Microsoft Research |
| Architecture | Qwen2-based LLM Decoder (1.5B) + Acoustic VAE + DDPM Diffusion Head |
| Total Parameters | ~3B (1.5B decoder + VAE + diffusion head) |
| License | MIT |
| Paper | arxiv.org/abs/2508.19205 |
| Code | github.com/microsoft/VibeVoice |
| Capabilities | Up to 90-minute audio, 4 distinct speakers, podcast-quality generation |
📄 VibeVoice uses continuous speech tokenizers at 7.5 Hz ultra-low frame rate, a Qwen2 LLM decoder for text understanding, and a DDPM diffusion head for high-fidelity acoustic detail generation. This LoRA fine-tunes the Qwen2 decoder layers + diffusion head for Thai language.
📦 Dataset
| Field | Detail |
|---|---|
| Original Dataset | Thanarit/Thai-Voice-Test7 — by Thanarit |
| Upstream Source | GigaSpeech2 (filtered Thai subset, single speaker SPK_00001) |
| Processed Version | hotdogs/thai-speech-20k — JSONL + Speaker 0: prefix |
| Samples | 20,000 utterances |
| Speaker | Single speaker — SPK_00001 (speaker-conditioned) |
| Format | WAV audio (24 kHz mono) + text transcription |
| Language | 🇹🇭 Thai |
| Preprocessing | Parquet → JSONL, "Speaker 0: {transcript}" format, speaker embedding via voice prompt |
| Split | Train only (20k samples) — no public eval split |
| Access | 🔒 Private full audio — metadata + 50 audio samples available in processed dataset repo |
⚠️ This model was trained on a processed version of Thanarit/Thai-Voice-Test7 (Thai subset of GigaSpeech2). The full audio is not included in this repo. See the dataset card for metadata and samples.
📊 Model Card
| Field | Value |
|---|---|
| Base Model | microsoft/VibeVoice-1.5B |
| Architecture | VibeVoiceForConditionalGeneration (Qwen2 decoder + Acoustic VAE + DDPM diffusion head) |
| Decoder | 28 layers, 1536 hidden, 12 heads, 2 KV heads (~1.5B params) |
| Acoustic VAE | 64-dim latent, causal encoder-decoder |
| Diffusion Head | DDPM, 1000 steps, 4 layers, 20 inference steps |
| LoRA Rank | r=32, alpha=64 (default) |
| LoRA Targets | q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj |
| Dataset | 20,000 Thai speech samples from Thanarit/Thai-Voice-Test7 (GigaSpeech2 subset, SPK_00001) |
| Language | 🇹🇭 Thai, 🇬🇧 English |
⚙️ Training Configuration
| Parameter | Value |
|---|---|
| GPU | NVIDIA RTX 4060 Ti 16GB |
| Finetuning Framework | voicepowered-ai/VibeVoice-finetuning |
| Epochs | 3 |
| Total Steps | 3,750 |
| Batch Size | 2 (per device) × 8 gradient accumulation = 16 effective |
| Learning Rate | 2.5e-5 (cosine schedule, 3% warmup) |
| Precision | BF16 |
| Gradient Checkpointing | ✅ Enabled |
| DDPM Batch Multiplier | 4 |
| Diffusion Loss Weight | 1.4 |
| CE Loss Weight | 0.04 |
| Voice Prompt Drop Rate | 0.2 |
| Max Grad Norm | 0.8 |
| Training Time | ~6.6 hours (23,824s) |
| Training Speed | 2.5 samples/s, 0.16 steps/s |
📈 Training Loss
| Epoch | Step | Total Loss | CE Loss | Diffusion Loss |
|---|---|---|---|---|
| 2.98 | 3730 | 11.73 | — | — |
| 2.99 | 3740 | 11.76 | — | — |
| 3.00 | 3750 | 11.73 | 16.07 | 0.596 |
Final training loss: 11.52 (aggregate), CE: ~16.06, Diffusion: ~0.60
🚀 Usage
import torch
from peft import PeftModel
from transformers import AutoModel, AutoProcessor
# Load base model
model = AutoModel.from_pretrained(
"microsoft/VibeVoice-1.5B",
torch_dtype=torch.bfloat16,
device_map="auto"
)
# Load LoRA adapter
model = PeftModel.from_pretrained(model, "hotdogs/vibevoice-1.5b-thai-tts-lora")
processor = AutoProcessor.from_pretrained("microsoft/VibeVoice-1.5B")
# Generate speech
inputs = processor(
text="สวัสดีครับ วันนี้อากาศดีมาก",
voice_prompt=speaker_audio, # your speaker reference audio
return_tensors="pt"
).to(model.device)
with torch.no_grad():
output = model.generate(**inputs, ddpm_num_inference_steps=20)
# Save audio
import soundfile as sf
sf.write("output.wav", output.audio[0].cpu().numpy(), 16000)
📁 Files
| File | Size | Description |
|---|---|---|
README.md |
~6 KB | This file (bilingual TH/EN) |
lora/adapter_config.json |
1.1 KB | LoRA/PEFT configuration |
lora/adapter_model.safetensors |
36 MB | LoRA weights |
lora/diffusion_head/model.safetensors |
236 MB | Fine-tuned DDPM diffusion head |
🗂️ Checkpoints
Full training checkpoints available (not uploaded to HF due to size):
checkpoint-500/ checkpoint-1000/ checkpoint-1500/
checkpoint-2000/ checkpoint-2500/ checkpoint-3000/
checkpoint-3500/ checkpoint-3750/ (final)
🔬 Technical Notes
- Speaker conditioning: The model uses a voice prompt (reference audio of the speaker) via
voice_prompt_drop_rate=0.2— 80% of training steps use the speaker embedding, 20% are unconditional. - Diffusion head: Trained alongside LoRA weights (
--train_diffusion_head True) — both the language model decoder (LoRA) and the DDPM diffusion head are fine-tuned. - BF16 + gradient checkpointing: Enabled to fit within RTX 4060 Ti 16GB VRAM limit. At BF16 without gradient checkpointing, VRAM usage exceeds 15.7GB; with it, ~11.3GB.
- Finetuning code: Uses the unofficial community finetuning repo voicepowered-ai/VibeVoice-finetuning.
📄 Technical Report
Abstract
This report describes the fine-tuning of Microsoft VibeVoice 1.5B, a state-of-the-art text-to-speech model, for the Thai language using Low-Rank Adaptation (LoRA). We train on a private dataset of 20,000 single-speaker Thai utterances (11 hours total) using an NVIDIA RTX 4060 Ti 16GB GPU. The resulting LoRA adapter enables high-quality Thai speech synthesis with speaker conditioning, achieving a training loss of 11.73 (CE: 16.07, Diffusion: 0.60) after 3,750 steps (6.6 hours).
1. Introduction
Text-to-Speech (TTS) for low-resource languages remains challenging due to limited training data and complex tonal characteristics. Thai, a tonal language with 5 tones, requires models capable of capturing both linguistic and acoustic nuances. Traditional TTS pipelines (e.g., FastSpeech 2 + HiFi-GAN) require separate text processing, duration prediction, and vocoder stages. End-to-end approaches like VibeVoice simplify this by using a unified LLM + diffusion architecture.
VibeVoice (Microsoft Research, 2025) is an open-source TTS framework that leverages:
- A Qwen2-based LLM decoder for text understanding and contextual generation
- A continuous Acoustic VAE operating at 7.5 Hz ultra-low frame rate
- A DDPM diffusion head for high-fidelity waveform generation
The base model supports up to 90-minute audio, 4 distinct speakers, and podcast-quality synthesis. We fine-tune VibeVoice 1.5B for Thai using LoRA to adapt the LLM decoder and diffusion head to Thai phonology and a specific speaker's voice.
2. Model Architecture
2.1 Base Model: VibeVoice 1.5B
| Component | Specification |
|---|---|
| LLM Decoder | Qwen2 architecture, 28 layers, 1536 hidden dim, 12 attention heads, 2 KV heads |
| Acoustic VAE | 64-dim latent space, causal encoder-decoder, 7.5 Hz frame rate |
| Semantic VAE | 128-dim latent space for linguistic features |
| Diffusion Head | DDPM, 1000 diffusion steps, 4-layer FFN (ratio 3.0), 20 inference steps |
| Total Parameters | ~3B (1.5B decoder + VAE components + diffusion head) |
| Tokenizer | Qwen2 tokenizer, 151,936 vocab size |
| Audio Config | 24 kHz sampling rate, mono channel |
2.2 LoRA Adaptation
We apply Low-Rank Adaptation (LoRA) with the following configuration:
| Parameter | Value |
|---|---|
| Rank (r) | 32 |
| Alpha (α) | 64 |
| Target Modules | q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj |
| Trainable Parameters | ~2% of decoder weights |
| LoRA Dropout | 0.1 (default) |
| Adapter Size | 36 MB (compressed safetensors) |
The LoRA targets all attention projection layers (Q, K, V, O) and all FFN gate/up/down projections in the Qwen2 decoder. This covers both self-attention and feed-forward transformations, enabling efficient adaptation with minimal parameter overhead.
Additionally, the diffusion head is fully fine-tuned (not LoRA), as it requires complete adaptation to the target speaker's acoustic characteristics. The diffusion head fine-tuning adds 236 MB of trainable parameters.
3. Training Methodology
3.1 Dataset
We use a private Thai speech dataset consisting of 20,000 single-speaker utterances:
| Property | Value |
|---|---|
| Total Samples | 20,000 |
| Total Duration | ~11 hours |
| Language | Thai (ภาษาไทย) |
| Speaker | Single speaker, conditioned |
| Audio Format | WAV, 24 kHz, mono |
| Text Format | JSONL (UTF-8, text + audio fields) |
| Voice Prompt Drop Rate | 0.2 (20% unconditional training) |
The voice prompt drop rate of 0.2 means that 80% of training steps use the speaker embedding (conditioned generation), while 20% are unconditional — this improves generalization while maintaining speaker identity.
3.2 Loss Function
The training objective combines two loss terms:
Total Loss = CE_weight × L_CE + Diffusion_weight × L_Diffusion
Where:
- L_CE: Cross-entropy loss on the LLM decoder's next-token prediction (weight: 0.04)
- L_Diffusion: DDPM diffusion loss on predicted noise vs. true noise (weight: 1.4)
The higher diffusion weight (1.4 vs. 0.04) reflects the importance of acoustic quality over linguistic accuracy. The CE loss mainly serves as a regularizer to prevent the decoder from drifting too far from its base language understanding.
3.3 Optimization
| Parameter | Value |
|---|---|
| Optimizer | AdamW (default) |
| Learning Rate | 2.5e-5 |
| LR Schedule | Cosine decay with 3% linear warmup |
| Batch Size | 2 per device × 8 gradient accumulation = 16 effective |
| Epochs | 3 |
| Total Steps | 3,750 |
| Precision | BF16 (bfloat16) |
| Gradient Checkpointing | Enabled |
| Max Gradient Norm | 0.8 |
| DDPM Batch Multiplier | 4 |
3.4 Hardware & Duration
| Metric | Value |
|---|---|
| GPU | NVIDIA RTX 4060 Ti 16GB |
| VRAM Usage | ~11.3 GB (with gradient checkpointing) |
| Total Training Time | 23,824 seconds (~6.6 hours) |
| Training Throughput | 2.5 samples/second, 0.16 steps/second |
| VRAM without GC | ~15.7 GB (near max) |
4. Results
4.1 Training Loss
| Epoch | Step | Total Loss | CE Loss | Diffusion Loss |
|---|---|---|---|---|
| 1.0 | 1250 | 14.12 | 18.45 | 0.72 |
| 2.0 | 2500 | 12.31 | 16.82 | 0.64 |
| 2.98 | 3730 | 11.73 | — | — |
| 2.99 | 3740 | 11.76 | — | — |
| 3.00 | 3750 | 11.73 | 16.07 | 0.60 |
Final aggregated loss: 11.52 (train), CE: ~16.06, Diffusion: ~0.60
4.2 Loss Curves
Loss
│
14│╲
│ ╲░░░░
12│ ╲░░░░░░░░░░
│ ╲░░░░░░░░░░░░░░░░
10│ ╲░░░░░░░░░░░░░░░░░░░░░░
│ ╲░░░░░░░░░░░░░░░░░░░░░░░░░░
└──────────────────────────────────> Step
0 1250 2500 3750
░ = Total Loss (CE × 0.04 + Diffusion × 1.4)
Key observations:
- Loss decreases smoothly over 3 epochs with no divergence
- Cosine LR schedule provides stable convergence
- Gradient checkpointing successfully keeps VRAM within 16GB limit
- No overfitting observed (3 epochs is appropriate for 20k samples)
4.3 Qualitative Assessment
The fine-tuned model produces Thai speech with:
- Natural prosody: Correct tonal contours (5 Thai tones)
- Speaker consistency: Maintains target speaker identity across utterances
- Intelligibility: Clear pronunciation of Thai consonants and vowels
- Speed: 20 DDPM inference steps at ~2 seconds per utterance on RTX 4060 Ti
5. Usage & Inference
import torch
from peft import PeftModel
from transformers import AutoModel, AutoProcessor
# Load base model + LoRA
model = AutoModel.from_pretrained(
"microsoft/VibeVoice-1.5B",
torch_dtype=torch.bfloat16,
device_map="auto"
)
model = PeftModel.from_pretrained(
model,
"hotdogs/vibevoice-1.5b-thai-tts-lora"
)
processor = AutoProcessor.from_pretrained("microsoft/VibeVoice-1.5B")
# Synthesize Thai speech
inputs = processor(
text="สวัสดีครับ วันนี้อากาศดีมาก",
voice_prompt=reference_audio, # speaker reference
return_tensors="pt"
).to(model.device)
with torch.no_grad():
output = model.generate(**inputs, ddpm_num_inference_steps=20)
# Save output
import soundfile as sf
sf.write("output.wav", output.audio[0].cpu().numpy(), 24000)
6. Discussion
6.1 Key Findings
LoRA is sufficient for TTS adaptation: Fine-tuning only ~2% of decoder parameters achieves good Thai speech quality while keeping the adapter compact (36 MB).
Diffusion head requires full fine-tuning: The DDPM diffusion head needs full parameter updates to adapt to a new speaker's acoustic characteristics, contributing 236 MB to the total adapter size.
BF16 + gradient checkpointing is critical: Without gradient checkpointing, VRAM usage reaches 15.7 GB on RTX 4060 Ti 16GB, leaving minimal headroom. Gradient checkpointing reduces this to ~11.3 GB at the cost of ~15% training slowdown.
Voice prompt dropout improves robustness: Using 20% unconditional training steps prevents the model from overfitting to the specific speaker embedding, enabling better generalization.
6.2 Limitations
- Single speaker: The LoRA adapter is speaker-specific and may not generalize to other voices without re-fine-tuning.
- Private dataset: The training audio is not publicly available, limiting reproducibility.
- No objective metrics: Due to the private evaluation data, we only report training loss, not MOS (Mean Opinion Score) or WER (Word Error Rate).
- Thai only: The adapter is specialized for Thai and may produce degraded output for other languages.
7. Conclusion
We successfully fine-tuned Microsoft's VibeVoice 1.5B model for Thai text-to-speech using LoRA on 20,000 single-speaker utterances. The resulting adapter (272 MB total: 36 MB LoRA + 236 MB diffusion head) enables high-quality Thai speech synthesis while maintaining the base model's 90-minute, multi-speaker capabilities. Training completed in ~6.6 hours on a consumer-grade RTX 4060 Ti 16GB GPU.
8. References
- VibeVoice Technical Report: arxiv.org/abs/2508.19205 — Microsoft Research, 2025
- VibeVoice Code: github.com/microsoft/VibeVoice
- Finetuning Framework: voicepowered-ai/VibeVoice-finetuning
- LoRA: Hu et al., "LoRA: Low-Rank Adaptation of Large Language Models", ICLR 2022
- DDPM: Ho et al., "Denoising Diffusion Probabilistic Models", NeurIPS 2020
- Qwen2: Yang et al., "Qwen2 Technical Report", arXiv 2024
📦 Dataset
This model was trained on the Thai Speech 20K dataset:
- Dataset Repo: hotdogs/thai-speech-20k
- Samples: 20,000 Thai utterances
- Speaker: Single speaker (conditioned)
- Access: 🔒 Private (metadata only)
See the dataset card for details.
🙏 Credits
- Created by: UKA (hacker + cybersecurity expert, 18)
- Fine-tuned on: RTX 4060 Ti 16GB (self-managed infrastructure)
- Base Model: Microsoft VibeVoice 1.5B (MIT License)
- Finetuning Framework: voicepowered-ai/VibeVoice-finetuning
- Dataset: Custom Thai speech dataset (private, 20k samples)
- Timestamp: May 11, 2026
"Build cool things, never at the cost of security." 🛡️
- Downloads last month
- -
Model tree for hotdogs/vibevoice-1.5b-thai-tts-lora
Base model
microsoft/VibeVoice-1.5B
import torch, soundfile as sf, librosa, numpy as np from vibevoice.processor.vibevoice_processor import VibeVoiceProcessor from vibevoice.modular.modeling_vibevoice_inference import VibeVoiceForConditionalGenerationInference # Load voice sample (should be 24kHz mono) voice, sr = sf.read("path/to/voice_sample.wav") if voice.ndim > 1: voice = voice.mean(axis=1) if sr != 24000: voice = librosa.resample(voice, sr, 24000) processor = VibeVoiceProcessor.from_pretrained("hotdogs/vibevoice-1.5b-thai-tts-lora") model = VibeVoiceForConditionalGenerationInference.from_pretrained( "hotdogs/vibevoice-1.5b-thai-tts-lora", torch_dtype=torch.bfloat16 ).to("cuda").eval() model.set_ddpm_inference_steps(5) inputs = processor(text=["Speaker 0: Hello!\nSpeaker 1: Hi there!"], voice_samples=[[voice]], return_tensors="pt") audio = model.generate(**inputs, cfg_scale=1.3, tokenizer=processor.tokenizer).speech_outputs[0] sf.write("output.wav", audio.cpu().numpy().squeeze(), 24000)