Repository navigation
strip padding from text latent cache for variable length models - #1345
Conversation
Z-Image text caches pad all sequences to 512 tokens, but the padding is stripped at training time anyway. This removes padding before caching and restores it after loading, dramatically reducing text cache size on disk (typically ~80% for average-length prompts) with no change to training behavior. Only Z-Image is affected.
|
Tested. Works on Z-Image. Works with #1346 and Nerogar/mgds#44. |
|
Thanks for the PR! Z-Image is unusual in that there are two types of padding tokens, inner padding and outer padding. Inner padding is not masked for attention (and must therefore not be cut!), outer padding is masked. |
Thanks for flagging! I checked the linked issue & inner padding (which aligns sequences to SEQ_MULTI_OF) has attention_mask=1. StripPaddedTokens only removes positions where tokens_mask == 0 (outer padding), so inner padding is preserved. This matches the same boolean-mask filtering that encode_text() already applies at lines 171-172 of ZImageModel.py. No changes needed. |
dxqb
left a comment
There was a problem hiding this comment.
Thanks.
Please see my code comments.
I think the same could work for other models, not only Z-Image:
- Chroma
- Qwen
- probably others
it won't work for
- SDXL
- Flux1
- Flux2
Would you like to implement it for those models as well?
Addresses review feedback: renamed to PruneMaskedTokens/PadMaskedTokens, moved to MGDS (mgds#47), reorganized dataloader code, and added latent cache pruning for Chroma and Qwen.
dxqb
left a comment
There was a problem hiding this comment.
looks good to me, but I am a bit hesitant to merge this: any silent errors in this PR will be difficult to detect but screws up text conditioning and have very unexpected effects.
any way this can be thoroughly tested?
|
for a small dataset captioned by an AI, this reduced total cache size from 98 MB to 14 MB on Qwen |
|
tested for all 3 models identical for z-Image, identical for unmasked tokens on the other models (but if there isn't a bug in can be merged once Nerogar/mgds#47 is finished here is how I tested: |
Port of BitcrushedHeart's Nerogar#1345 to WanBaseDataLoader. umt5-xxl uses a 512-token max length but typical prompts are 80-250 tokens; caching the full padded tensor wastes significant disk space. PruneMaskedTokens strips padding before writing to cache; PadMaskedTokens restores to 512 on load. Guarded by config.latent_caching (always true for Wan LoRA). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Port of BitcrushedHeart's Nerogar#1345 to WanBaseDataLoader. umt5-xxl uses a 512-token max length but typical prompts are 80-250 tokens; caching the full padded tensor wastes significant disk space. PruneMaskedTokens strips padding before writing to cache; PadMaskedTokens restores to 512 on load. Guarded by config.latent_caching (always true for Wan LoRA). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…gar#1345) --------- Co-authored-by: BitcrushedHeart <215311041+BitcrushedHeart@users.noreply.github.com>
Summary
ZImageModel.encode_text()masks it out viatokens_mask)DiskCachesaves and restore it afterDiskCacheloads, dramatically reducing text cache size on disk with no change to training behaviorDetails
StripPaddedTokens(new, inmodules/dataLoader/zimage/): inserted afterEncodeQwenTextin_preparation_modules(). Uses the attention mask to boolean-indextokens,tokens_mask, andtext_encoder_hidden_state, keeping only real token positions before caching.PadTokens(new, inmodules/dataLoader/zimage/): inserted at the start of_output_modules(). Pads stripped tensors back toPROMPT_MAX_LENGTH(512) usingF.padsotorch.stack()batching still works. Old caches are compatible.