Repository navigation
Add native fine-tuning (LoRA and full) with a whisper-train command - #2886
kawshikbuet17 wants to merge 13 commits into
Conversation
Add a pure-PyTorch LoRA implementation in whisper/lora.py: LoRALinear, apply_lora, mark_only_lora_as_trainable, lora_state_dict, save_lora, load_lora and merge_lora. Adapter files store fp32 weights together with their config and the base model dimensions, so they load with a single call and mismatched base models fail with a clear error.
Resolve fp32/fp16/bf16/auto to autocast and GradScaler settings. auto selects bf16 on GPUs with native support, fp16 on other GPUs and fp32 on CPU; explicitly requesting bf16 on a GPU without native support raises an error suggesting fp16 instead of silently using emulation.
Add whisper/train.py (python -m whisper.train, whisper-train) for LoRA fine-tuning from JSONL or CSV manifests, with masked teacher-forcing loss, gradient accumulation, warmup with linear/cosine decay, gradient checkpointing, resumable checkpoints, and WER/CER evaluation against the base model using Whisper's own decoding.
Add a lora argument to load_model() and a --lora option to the CLI to apply a saved adapter. Behavior is unchanged when no adapter is given.
Cover output equivalence at initialization, trainable parameters, adapter save/load round trips, merging, training on synthetic audio, resuming, precision selection, and fp16 training on CUDA.
Decoding under bf16 autocast produced bf16 audio features, which decode() rejects. Decode with the fp32 path instead and add a bf16 GPU test.
agammann
left a comment
There was a problem hiding this comment.
One blocker for the documented per-sample language training mode.
The padding token was taken from a tokenizer that needs a global language, so a multilingual model trained only on per-row manifest languages failed before training started. The EOT token is the same for every language, so build it without one, and add a regression test for this mode.
|
@agammann Thanks, good catch. Fixed in 911a042: the padding token is the EOT token, which is the same for every language, so it is now taken from a tokenizer built without a language. I added |
|
Thanks for the fix. I rechecked head |
Summary
Whisper has no built-in way to fine-tune on your own data. This PR adds a small training command to the package that works with the existing models, checkpoints and CLI, with no new runtime dependencies.
whisper-trainfine-tunes any Whisper model on a JSONL or CSV manifest (audio,text, optionallanguage).--finetune lora, the default) freezes the model and trains low-rank adapters, about 0.2–0.4% of the parameters by default, saved as a small adapter file.--finetune full, optionally--freeze_encoder) saves a regular Whisper checkpoint.whisper audio.wav --model small --lora adapter.ptorwhisper.load_model("small", lora="adapter.pt"). Full checkpoints load with--model model.ptas before, and--export_mergedfolds an adapter into a plain checkpoint.--precision autopicks bf16 on GPUs with native support, else fp16 with a gradient scaler), gradient checkpointing and accumulation, warmup with linear/cosine schedules, validation loss and WER/CER before and after training, best-checkpoint selection, exact resume (--resume) and--keep_checkpoints.Existing behaviour is unchanged unless
whisper-trainor--lorais used.Changes
whisper/lora.py:LoRALinear,apply_lora, save/load andmerge_lora. It works with the existing KV-cache hooks.whisper/precision.py: precision selection, autocast and GradScaler helpers.whisper/train.py: thewhisper-trainCLI, with its entry point added inpyproject.toml.whisper/__init__.py,whisper/transcribe.py:lora=and--lorasupport.README.md: a short "Fine-tuning" section with trainable parameter counts per model.tests/test_lora.py,tests/test_train.py: unit and end-to-end tests. They run on CPU, and the fp16/bf16 tests also run on GPU when one is available.Details handled in the new code:
torch.cuda.is_bf16_supported()also reports emulated bf16 (e.g. on a T4), so native support is checked instead.SuppressBlankstops the decoder from ever predicting it.BasicTextNormalizerremoves.Testing
pytest tests: the full suite passes, including the existing tests and the new GPU fp16/bf16 tests (run on a Tesla T4 and an RTX 4090).Usage
whisper-train --model small --language en \ --train_manifest train.jsonl --val_manifest val.jsonl --output_dir runs/small-lora whisper audio.wav --model small --lora runs/small-lora/adapter_best.pt