VoxCPM2 LoRA Trainer
Train a Voice LoRA in ComfyUI — But Watch the UI Freeze
- train_config
- LoRA Output Path
The other two training nodes are prep. VoxCPM2 LoRA Trainer is the one that actually trains: it fine-tunes a LoRA adapter on the VoxCPM2 base model right inside ComfyUI, and it's the difference between cloning a voice and owning it. With a decent dataset and a trained adapter, people report near-total voice recreation - this is the node that makes "100% faithfully recreate voices" possible, per one community member running the VoxCPM LoRA workflow.
Read the warning in the node's own description twice: it blocks the ComfyUI interface for the whole run. That's not a bug, it's the design - training runs on the main thread, so queue it when you're done clicking and go make coffee. Or dinner.
How it works
It takes the train_config dictionary from the Train Config node, the dataset_path string from the Dataset Maker, and runs the underlying VoxCPM training loop - AdamW optimizer, cosine schedule with warmup, LoRA injected into the language-model backbone and the diffusion transformer (LM + DiT by default). Checkpoints land as .safetensors files plus a lora_config.json metadata file, saved to ComfyUI/models/loras/<output_name>/. Once done, the lora_name dropdown on the TTS and Voice Clone nodes picks them up after a browser refresh.
The inputs that matter
train_configanddataset_path- wire these from the other two nodes in the chain. Nothing to type.base_model_name- VoxCPM2, unless you have a reason to train V1.max_steps(default 1000) - total training duration. Rule of thumb from the guide: a ~5-minute dataset wants 1000–2000 steps.save_every_steps(default 200) - checkpoint interval. Keep this; the intermediate checkpoints are usually better than the final one, because overfitting sneaks in at the tail.output_name(defaultmy_lora_v1) - the subfolder name inmodels/loras. Make it descriptive; you'll be picking it from a dropdown later.num_workers(default 0) - dataloader workers. 0 runs on the main thread; bump it if data loading is your bottleneck.
Watch loss in the ComfyUI console (Step 10/1000, Loss: 2.145, LR: ...). It should trend down. A loss frozen at 0.0000 means something's broken, not that you've mastered the craft.
Install: the extra step
Same pack install (Manager, or git clone https://github.com/Saganaki22/ComfyUI-VoxCPM2.git into custom_nodes + pip install -r requirements.txt), but this node has a dependency the base requirements don't cover: argbind and datasets. The trainer imports them lazily and will throw an error with the exact command when they're missing - run it once and it goes away:
pip install argbind datasets
If you're on ComfyUI Portable on Windows, install into the embedded Python (python_embeded\python.exe -m pip install ...) instead.
Hardware reality
The README wants an NVIDIA GPU with at least 12GB VRAM, 24GB recommended for bigger batches. That's honest - this is the one node in the pack that actually spends VRAM, unlike inference. If you OOM, the first levers are max_batch_tokens and lora_rank in the config, not the trainer.
Common failures
- UI froze → you panicked and closed it. It wasn't broken. Next time, watch the console for loss lines before touching anything.
- Loss stuck at 0.0000 - dataset or data-loading issue; check the JSONL paths and that transcripts aren't empty.
- Clone sounds robotic or distorted after training - overfit. Pick an earlier
save_every_stepscheckpoint, or retrain with a lower learning rate (5e-5) rather than assuming more steps helps. - Effect too weak - either not enough steps or the rank is too low; rank 64–128 is where people report the jump.
When it works, the loop is satisfying: train a few checkpoints, flip them in the lora_name dropdown on the Voice Clone node, and A/B them on the same text until one sounds right. Then delete the rest.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| base_model_name | COMBO | VoxCPM2 | Base VoxCPM model to fine-tune. |
| train_config | * | Configuration dictionary from VoxCPM Train Config node. | |
| dataset_path | STRING | Path to the train.jsonl file. | |
| output_name | STRING | my_lora_v1 | Name of the subfolder in 'models/loras' to save results. |
| max_steps | INT | 1000100–100000 | Total number of training steps. |
| save_every_steps | INT | 20050–5000 | Save checkpoint every N steps. |
| num_workers | INT | 00–8 | Number of dataloader workers (0 for main thread). |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| LoRA Output Path | STRING | — |