Musubi Cache Text Embeds (Wan)
The one caching step that makes training actually fast
- trigger_in
- dataset_toml_path
- trigger_out
- status_message
The third node in the jaimitoes/ComfyUI_Wan2_1_lora_trainer chain, and honestly the one that earns its keep. Wan 2.1's text encoder is a big T5 (umt5-xxl). Running every caption through it once and caching the result is the single biggest speed lever in any modern LoRA training run - the community's training knowledge base is blunt about this: cache the text embeddings and you never load the encoder again. That's exactly what this node does, and it's why musubi-based training can run thousands of steps without dragging a multi-gigabyte language model through every batch.
Like its sibling WanCacheLatents, this is the vendored musubi-tuner cache_text_encoder_outputs.py behind a ComfyUI node. The pack chains everything: dataset config → cache latents → cache text → train, in one trigger-driven queue.
How it works
It takes the dataset_toml_path from the latents node, resolves your chosen T5 against ComfyUI's text_encoders folder, and runs the cache. Each caption gets encoded once and the embeddings are written into the same dataset1_cache_directory from your config. The trainer at the end of the chain then reads those cached embeddings, so the 8-bit or bf16 T5 never has to be resident during training. There's a progress bar, and like the latents node it computes batch counts from your dataset blueprint so the bar actually moves.
The inputs that matter
t5_name- the T5 text encoder that matches your base model. For Wan 2.1 that'smodels_t5_umt5-xxl-enc-bf16.pth(from Wan-AI/Wan2.1-I2V-14B-720P). If this doesn't match the model you plan to train, your caption embeddings are wrong and the LoRA will be wrong in ways that are hard to diagnose.fp8_t5- off by default, and the author's own tooltip is appropriately spooky: saves a lot of memory, but "can be experimental and not always stable, and not all GPUs support it." T5 is the memory hog of the cache stage, so this is the knob if you're squeezed. Only flip it if you have to.skip_existing- your resume switch. If a cache run died halfway, turn this on and the node skips files that already have embeddings.keep_cache- on. Turning it off risks the cache being cleaned up after the operation, which defeats the entire point.
device, batch_size_override, and num_workers_override behave exactly like the latents node: cuda unless you're patient, and 0 means "use the values from the dataset config."
Outputs
dataset_toml_path(STRING) - the config path, passed through. This is normally what you feed into the big WanLoRATrainer node'sdataset_config_tomlinput.trigger_out(any) - "text_ok" or "error_trigger"; chain it to the trainer'strigger_in.status_message(STRING) - what happened, in text.
Note the node is defensive about the chain: if the incoming trigger says error or skipped, or the TOML path doesn't exist, it bails immediately with a "Skipped: prev error" message instead of half-running on garbage.
Install
Same pack, same ritual:
cd ComfyUI/custom_nodes
git clone https://github.com/jaimitoes/ComfyUI_Wan2_1_lora_trainer
..\..\..\python_embeded\python -m pip install -r requirements.txt
restart, and launch ComfyUI from the custom .bat in the README (it loads Visual Studio Build Tools so the trainer subprocess inherits a working environment). The Include_and_libs.zip extraction into python_embeded is part of the same setup.
Where people get burned
Mostly two things. First, picking a T5 that doesn't match the base - cache a different encoder than the one the trainer expects and you'll chase ghost quality problems for a week. Second, re-running the cache pointlessly: if your captions and text model haven't changed, skip it (skip_existing) and go straight to training. The README's golden rule for the whole pack applies here harder than anywhere: separate, per-LoRA cache folders, or the caches from one project silently contaminate the next.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| dataset_config_toml | STRING | — | |
| trigger_in | * | — | |
| t5_name | COMBO | Text Encoder (T5). Select the T5 model that your base model uses. This component is the "translator" that converts your prompts (text) into a language the image model understands. | |
| fp8_t5 | BOOLEAN | false | Enable to use 8-bit precision (FP8) for the T5 text encoder. Saves a lot of memory, but can be experimental and not always stable, and not all GPUs support it. |
| device | COMBO | cuda | Choose the hardware device to use for processing. `cuda` uses your NVIDIA GPU (much faster), while `cpu` uses your computer's main processor (much slower). |
| batch_size_override | INT | 0 | Override the default batch size used for processing data. `0` means use the default value from the dataset configuration. A higher number processes more items at once, but uses more memory. |
| num_workers_override | INT | 0 | Override the default number of workers for loading data. `0` means use the default value from the dataset configuration. A higher number can speed up data loading, but consumes more CPU and RAM. |
| skip_existing | BOOLEAN | false | If enabled, the node will skip processing files that already have existing cached versions, saving time and computation. |
| keep_cache | BOOLEAN | true | If enabled, the processed data will be kept in the cache directory even after this operation completes, so it can be reused later without reprocessing. If disabled, cached files might be removed. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| dataset_toml_path | STRING | — |
| trigger_out | * | — |
| status_message | STRING | — |