170 lines
6.6 KiB
Markdown
170 lines
6.6 KiB
Markdown
# ESP32 Whisper Fine-Tune Project
|
|
|
|
## Project Overview
|
|
|
|
This is a **Russian-language AI model fine-tuning pipeline** designed for eventual deployment on an ESP32 device. The project fine-tunes three model families using **LoRA (Low-Rank Adaptation)**:
|
|
|
|
1. **Whisper** — Speech-to-Text (STT) models (`openai/whisper-small`, `openai/whisper-medium`) fine-tuned on the Common Voice 17.0 Russian dataset.
|
|
2. **LLM** — Llama 3.2 models fine-tuned for conversational Russian dialogue with a custom persona ("Maven/Мейвен") — a lively, fast-paced conversational character.
|
|
3. **TTS** — Text-to-Speech pipeline using Qwen3-TTS VoiceDesign for synthetic voice generation, with tools for voice discovery and dataset QA.
|
|
|
|
The project also includes helper utilities for data cleaning and a web-based QA server for reviewing TTS audio datasets.
|
|
|
|
## Directory Structure
|
|
|
|
| Directory/File | Purpose |
|
|
|---|---|
|
|
| `whisper/` | Whisper STT fine-tuning scripts and saved model checkpoints |
|
|
| `whisper/main.py` | Trains `whisper-small` with LoRA on Common Voice 17.0 RU |
|
|
| `whisper/train.py` | Trains `whisper-medium` with LoRA; custom `WhisperLoraTrainer` class |
|
|
| `whisper/check_lora_weights.py` | Inspects LoRA adapter weights |
|
|
| `whisper/eval_test.py` | Evaluation/testing script for Whisper models |
|
|
| `whisper/sanity_test.py` | Quick sanity check for model loading |
|
|
| `whisper/whisper_lora/` | Output directory for whisper-small LoRA checkpoints |
|
|
| `whisper/whisper-medium-ru-lora/` | Output directory for whisper-medium LoRA checkpoints |
|
|
| `whisper/whisper-small-ru-lora/` | Output directory for whisper-small LoRA checkpoints |
|
|
| `whisper/whisper-small/` | Base whisper-small model artifacts |
|
|
| `llm/` | LLM fine-tuning scripts for Llama 3.2 and Qwen3 |
|
|
| `llm/train_llama.py` | Fine-tunes Llama 3.2 3B with LoRA; supports multiple dataset sources (JSONL, Parquet, HF datasets); custom conversational persona |
|
|
| `llm/llama-eval-test.py` | Interactive chat/evaluation script for trained Llama LoRA checkpoints |
|
|
| `llm/Llama-3.2-3b-ru-lora/` | Llama 3.2 3B LoRA checkpoint output |
|
|
| `llm/Llama-3.2-4b-ru-lora/` | Llama 3.2 4B LoRA checkpoint output |
|
|
| `llm/qwen3-4b-2507-ru-lora/` | Qwen3 4B LoRA checkpoint output |
|
|
| `llm/data/` | Training data (JSONL files, etc.) |
|
|
| `tts/` | Text-to-Speech voice generation and dataset tools |
|
|
| `tts/find_voice.py` | Interactive voice discovery tool using Qwen3-TTS VoiceDesign; generates candidate voices and lets you pick one |
|
|
| `tts/generate_synthetic_voice.py` | Synthetic voice generation script |
|
|
| `tts/generate_synthetic_styles.py` | Generates diverse voice styles |
|
|
| `tts/homograph_processor.py` | Homograph processing for TTS text normalization |
|
|
| `tts/data/` | TTS dataset files |
|
|
| `tts/dataset/` | TTS dataset organization |
|
|
| `tts/ref/` | Reference voice audio samples (indexed subdirectories) |
|
|
| `ui/tts-qa-srv.py` | Web-based QA server for reviewing TTS audio datasets; FastAPI + Vue-style SPA with keep/delete workflow |
|
|
| `helpers/jsonl_cleaner.py` | CLI tool to clean JSONL files of markdown formatting and emojis |
|
|
| `clean_tmpfs.sh` | Shell script to clean tmpfs, /dev/shm, and Hugging Face cache artifacts |
|
|
| `requirements.txt` | Python dependencies |
|
|
|
|
## Key Technologies
|
|
|
|
- **PyTorch** — Deep learning framework
|
|
- **Hugging Face Transformers** — Model loading, training, and inference
|
|
- **PEFT (LoRA)** — Parameter-Efficient Fine-Tuning
|
|
- **Datasets** — Hugging Face Datasets library for data loading and preprocessing
|
|
- **bitsandbytes** — 4-bit quantization for efficient training
|
|
- **Common Voice 17.0** — Speech dataset (Russian subset)
|
|
- **Qwen3-TTS** — Text-to-Speech voice generation
|
|
- **FastAPI + Uvicorn** — Web server for TTS QA interface
|
|
- **jiwer, librosa, soundfile** — Audio metrics and processing
|
|
|
|
## Building and Running
|
|
|
|
### Prerequisites
|
|
|
|
```bash
|
|
python -m venv .venv
|
|
source .venv/bin/activate
|
|
pip install -r requirements.txt
|
|
```
|
|
|
|
### Whisper Fine-Tuning
|
|
|
|
```bash
|
|
# Train whisper-small with LoRA
|
|
cd whisper
|
|
python main.py
|
|
|
|
# Train whisper-medium with LoRA
|
|
cd whisper
|
|
python train.py
|
|
|
|
# Evaluate a trained model
|
|
python eval_test.py
|
|
|
|
# Check LoRA weights
|
|
python check_lora_weights.py
|
|
```
|
|
|
|
### LLM Fine-Tuning
|
|
|
|
```bash
|
|
# Train Llama 3.2 with LoRA
|
|
cd llm
|
|
python train_llama.py
|
|
|
|
# Interactive evaluation
|
|
python llama-eval-test.py
|
|
```
|
|
|
|
### TTS Voice Discovery
|
|
|
|
```bash
|
|
cd tts
|
|
python find_voice.py
|
|
# Interactively generates candidate voices and lets you pick one
|
|
# Saves selected voice to ref/<index>/maven_reference.wav
|
|
```
|
|
|
|
### TTS Dataset QA Server
|
|
|
|
```bash
|
|
cd ui
|
|
python tts-qa-srv.py --wavs dataset/test --txt data/neutral-voice-dataset-list-clean.txt --port 8765
|
|
# Open http://localhost:8765 in browser
|
|
# Keyboard shortcuts: k=keep, d=delete, ←/←=navigate, space=play/pause
|
|
```
|
|
|
|
### Data Cleaning
|
|
|
|
```bash
|
|
# Clean JSONL files of markdown and emojis
|
|
python helpers/jsonl_cleaner.py input.jsonl output.jsonl
|
|
```
|
|
|
|
### Cache Cleanup
|
|
|
|
```bash
|
|
./clean_tmpfs.sh
|
|
```
|
|
|
|
## Configuration Notes
|
|
|
|
- **Cache paths** are configured to use `/mnt/D/.cache/huggingface` and `/mnt/D/tmp` in `whisper/train.py` and `llm/train_llama.py`. Adjust these paths for your environment.
|
|
- **Dataset**: Whisper models use `fsicoli/common_voice_17_0` (Russian subset).
|
|
- **LLM training data**: JSONL files in `llm/data/cleaned.jsonl`, plus optional Parquet and HF dataset sources.
|
|
- **Quantization**: LLM training uses 4-bit quantization via bitsandbytes (`nf4`, double quantization, bfloat16 compute).
|
|
|
|
## Training Hyperparameters
|
|
|
|
### Whisper
|
|
| Parameter | small | medium |
|
|
|---|---|---|
|
|
| LoRA r | 8 | 32 |
|
|
| LoRA alpha | 32 | 64 |
|
|
| LoRA dropout | 0.1 | 0.05 |
|
|
| Learning rate | 1e-4 | 5e-5 |
|
|
| Max steps | 4000 | 4000 |
|
|
| Warmup steps | 100 | 500 |
|
|
| Batch size (train/eval) | 2/2 | 2/2 |
|
|
|
|
### LLM (Llama 3.2 3B)
|
|
| Parameter | Value |
|
|
|---|---|
|
|
| LoRA r | 16 |
|
|
| LoRA alpha | 32 |
|
|
| LoRA dropout | 0.1 |
|
|
| Learning rate | 1e-4 |
|
|
| Epochs | 3 |
|
|
| Gradient accumulation | 8 |
|
|
| Max length | 1024 |
|
|
| Optim | paged_adamw_8bit |
|
|
|
|
## Development Conventions
|
|
|
|
- All models use **LoRA** for parameter-efficient fine-tuning (only adapter weights are saved).
|
|
- Russian language (`ru`) is the primary target for all models.
|
|
- The LLM is trained with a custom **persona** ("Maven/Мейвен") — a conversational, energetic character. The system prompt enforces strict JSON output format: `{"response":"...","mood":"..."}`.
|
|
- TTS voice discovery uses **Qwen3-TTS VoiceDesign** to generate synthetic voices interactively.
|
|
- The QA server uses a **keep/delete workflow** for curating TTS datasets, with state persistence to JSON.
|
|
- Dataset preprocessing includes casting audio to 16kHz, removing unnecessary columns, and mapping text through the processor.
|
|
- Progress is logged to **TensorBoard** for all training runs.
|