Skip to content

Commit fd2b29f

Browse files
authored
Merge pull request #2560 from bghira/feature/pre-shuffled-captions
configurable caption_shuffle for cached text embeddings
2 parents 1d728a7 + aa5cc20 commit fd2b29f

File tree

9 files changed

+520
-8
lines changed

9 files changed

+520
-8
lines changed

documentation/DATALOADER.es.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,50 @@ Tanto `textfile` como `parquet` soportan multi-captions:
186186
- Útil cuando tus captions contienen saltos de línea intencionales que deben preservarse como un único caption.
187187
- Por defecto: `false` (los captions se dividen por saltos de línea)
188188

189+
### `caption_shuffle`
190+
191+
Genera variantes mezcladas determinísticas de captions basados en tags para aumento de datos. Esto ayuda al modelo a aprender que el orden de las tags no importa y reduce el sobreajuste a secuencias específicas de tags.
192+
193+
**Configuración:**
194+
195+
```json
196+
{
197+
"caption_shuffle": {
198+
"enable": true,
199+
"count": 3,
200+
"seed": 42,
201+
"split_on": "comma",
202+
"position_start": 1,
203+
"include_original": true
204+
}
205+
}
206+
```
207+
208+
**Parámetros:**
209+
210+
- `enable` (bool): Si se habilita el mezclado de captions. Por defecto: `false`
211+
- `count` (int): Número de variantes mezcladas a generar por caption. Por defecto: `1`
212+
- `seed` (int): Semilla para mezclado determinístico. Si no se especifica, usa el valor global `--seed`.
213+
- `split_on` (string): Delimitador para dividir captions en tags. Opciones: `comma`, `space`, `period`. Por defecto: `comma`
214+
- `position_start` (int): Mantener las primeras N tags en su posición original (útil para mantener tags de sujeto/estilo al principio). Por defecto: `0`
215+
- `include_original` (bool): Si se incluye el caption original sin mezclar junto con las variantes mezcladas. Por defecto: `true`
216+
217+
**Ejemplo:**
218+
219+
Con `split_on: "comma"`, `position_start: 1`, `count: 2`:
220+
221+
- Original: `"dog, running, park, sunny day"`
222+
- Resultado: `["dog, running, park, sunny day", "dog, park, sunny day, running", "dog, sunny day, running, park"]`
223+
224+
La primera tag "dog" permanece fija mientras las tags restantes se mezclan.
225+
226+
**Notas:**
227+
228+
- El mezclado se aplica durante el pre-cacheo de embeddings de texto, así que todas las variantes se calculan de una vez.
229+
- Durante el entrenamiento, se selecciona una variante aleatoriamente por muestra.
230+
- Si un caption tiene menos tags que `position_start + 2`, el mezclado se omite (nada significativo que mezclar).
231+
- Cuando `include_original: false` pero el mezclado no es posible, se incluye el original de todos modos con una advertencia.
232+
189233
### `metadata_backend`
190234

191235
- **Valores:** `discovery` | `parquet` | `huggingface`

documentation/DATALOADER.hi.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,50 @@ Metadata discovery के दौरान loader प्रत्येक file
186186
- उपयोगी जब आपके captions में intentional line breaks हों जिन्हें एक single caption के रूप में संरक्षित रखना हो।
187187
- Default: `false` (captions newlines द्वारा split होते हैं)
188188

189+
### `caption_shuffle`
190+
191+
Data augmentation के लिए tag-based captions के deterministic shuffled variants generate करता है। यह model को सिखाता है कि tag order महत्वपूर्ण नहीं है और specific tag sequences पर overfitting कम करता है।
192+
193+
**Configuration:**
194+
195+
```json
196+
{
197+
"caption_shuffle": {
198+
"enable": true,
199+
"count": 3,
200+
"seed": 42,
201+
"split_on": "comma",
202+
"position_start": 1,
203+
"include_original": true
204+
}
205+
}
206+
```
207+
208+
**Parameters:**
209+
210+
- `enable` (bool): Caption shuffling enable करना है या नहीं। Default: `false`
211+
- `count` (int): प्रति caption generate करने के लिए shuffled variants की संख्या। Default: `1`
212+
- `seed` (int): Deterministic shuffling के लिए seed। यदि specify नहीं किया गया, तो global `--seed` value उपयोग होता है।
213+
- `split_on` (string): Captions को tags में split करने के लिए delimiter। Options: `comma`, `space`, `period`। Default: `comma`
214+
- `position_start` (int): पहले N tags को उनकी original position में रखें (subject/style tags को पहले रखने के लिए उपयोगी)। Default: `0`
215+
- `include_original` (bool): Shuffled variants के साथ unshuffled original caption include करना है या नहीं। Default: `true`
216+
217+
**Example:**
218+
219+
`split_on: "comma"`, `position_start: 1`, `count: 2` के साथ:
220+
221+
- Original: `"dog, running, park, sunny day"`
222+
- Result: `["dog, running, park, sunny day", "dog, park, sunny day, running", "dog, sunny day, running, park"]`
223+
224+
पहला tag "dog" fixed रहता है जबकि बाकी tags shuffle होते हैं।
225+
226+
**Notes:**
227+
228+
- Shuffling text embed pre-caching के दौरान apply होता है, इसलिए सभी variants एक बार में calculate होते हैं।
229+
- Training के दौरान, प्रति sample एक variant randomly select होता है।
230+
- यदि caption में `position_start + 2` से कम tags हैं, तो shuffling skip होता है (shuffle करने के लिए कुछ meaningful नहीं)।
231+
- जब `include_original: false` लेकिन shuffling possible नहीं है, तो warning के साथ original include होता है।
232+
189233
### `metadata_backend`
190234

191235
- **Values:** `discovery` | `parquet` | `huggingface`

documentation/DATALOADER.ja.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,50 @@ Hugging Face の音声データセットでは、キャプション(プロン
186186
- 意図的な改行を含むキャプションを単一のキャプションとして保持したい場合に便利です。
187187
- デフォルト: `false`(改行でキャプションを分割)
188188

189+
### `caption_shuffle`
190+
191+
タグベースのキャプションの決定論的シャッフルバリアントを生成し、データ拡張に使用します。これにより、モデルはタグの順序が重要でないことを学習し、特定のタグシーケンスへの過学習を軽減します。
192+
193+
**設定:**
194+
195+
```json
196+
{
197+
"caption_shuffle": {
198+
"enable": true,
199+
"count": 3,
200+
"seed": 42,
201+
"split_on": "comma",
202+
"position_start": 1,
203+
"include_original": true
204+
}
205+
}
206+
```
207+
208+
**パラメータ:**
209+
210+
- `enable` (bool): キャプションシャッフルを有効にするかどうか。デフォルト: `false`
211+
- `count` (int): キャプションごとに生成するシャッフルバリアントの数。デフォルト: `1`
212+
- `seed` (int): 決定論的シャッフルのシード。指定されていない場合、グローバル `--seed` 値を使用します。
213+
- `split_on` (string): キャプションをタグに分割する区切り文字。オプション: `comma``space``period`。デフォルト: `comma`
214+
- `position_start` (int): 最初の N 個のタグを元の位置に保持(主題/スタイルタグを先頭に保持するのに便利)。デフォルト: `0`
215+
- `include_original` (bool): シャッフルされていない元のキャプションをバリアントに含めるかどうか。デフォルト: `true`
216+
217+
**例:**
218+
219+
`split_on: "comma"``position_start: 1``count: 2` の場合:
220+
221+
- 元: `"dog, running, park, sunny day"`
222+
- 結果: `["dog, running, park, sunny day", "dog, park, sunny day, running", "dog, sunny day, running, park"]`
223+
224+
最初のタグ「dog」は固定されたまま、残りのタグがシャッフルされます。
225+
226+
**注意:**
227+
228+
- シャッフルはテキスト埋め込みのプリキャッシュ時に適用されるため、すべてのバリアントは一度に計算されます。
229+
- トレーニング中、サンプルごとに 1 つのバリアントがランダムに選択されます。
230+
- キャプションのタグ数が `position_start + 2` より少ない場合、シャッフルはスキップされます(意味のあるシャッフルができないため)。
231+
- `include_original: false` だがシャッフルできない場合、警告とともに元のキャプションが含まれます。
232+
189233
### `metadata_backend`
190234

191235
- **値:** `discovery` | `parquet` | `huggingface`

documentation/DATALOADER.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,50 @@ Both `textfile` and `parquet` support multi-captions:
220220
- Useful when your captions contain intentional line breaks that should be preserved as a single caption.
221221
- Default: `false` (captions are split by newlines)
222222

223+
### `caption_shuffle`
224+
225+
Generates deterministic shuffled variants of tag-based captions for data augmentation. This helps the model learn that tag order doesn't matter and reduces overfitting to specific tag sequences.
226+
227+
**Configuration:**
228+
229+
```json
230+
{
231+
"caption_shuffle": {
232+
"enable": true,
233+
"count": 3,
234+
"seed": 42,
235+
"split_on": "comma",
236+
"position_start": 1,
237+
"include_original": true
238+
}
239+
}
240+
```
241+
242+
**Parameters:**
243+
244+
- `enable` (bool): Whether to enable caption shuffling. Default: `false`
245+
- `count` (int): Number of shuffled variants to generate per caption. Default: `1`
246+
- `seed` (int): Seed for deterministic shuffling. If not specified, uses the global `--seed` value.
247+
- `split_on` (string): Delimiter for splitting captions into tags. Options: `comma`, `space`, `period`. Default: `comma`
248+
- `position_start` (int): Keep the first N tags in their original position (useful for keeping subject/style tags first). Default: `0`
249+
- `include_original` (bool): Whether to include the unshuffled original caption alongside shuffled variants. Default: `true`
250+
251+
**Example:**
252+
253+
With `split_on: "comma"`, `position_start: 1`, `count: 2`:
254+
255+
- Original: `"dog, running, park, sunny day"`
256+
- Result: `["dog, running, park, sunny day", "dog, park, sunny day, running", "dog, sunny day, running, park"]`
257+
258+
The first tag "dog" stays fixed while the remaining tags are shuffled.
259+
260+
**Notes:**
261+
262+
- Shuffling is applied during text embed pre-caching, so all variants are computed once upfront.
263+
- During training, one variant is randomly selected per sample.
264+
- If a caption has fewer tags than `position_start + 2`, shuffling is skipped (nothing meaningful to shuffle).
265+
- When `include_original: false` but shuffling isn't possible, the original is included anyway with a warning.
266+
223267
### `metadata_backend`
224268

225269
- **Values:** `discovery` | `parquet` | `huggingface`

documentation/DATALOADER.pt-BR.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,50 @@ Tanto `textfile` quanto `parquet` suportam multi-captions:
186186
- Útil quando suas captions contêm quebras de linha intencionais que devem ser preservadas como uma única caption.
187187
- Padrão: `false` (captions são divididas por novas linhas)
188188

189+
### `caption_shuffle`
190+
191+
Gera variantes embaralhadas determinísticas de captions baseadas em tags para aumento de dados. Isso ajuda o modelo a aprender que a ordem das tags não importa e reduz o overfitting em sequências específicas de tags.
192+
193+
**Configuração:**
194+
195+
```json
196+
{
197+
"caption_shuffle": {
198+
"enable": true,
199+
"count": 3,
200+
"seed": 42,
201+
"split_on": "comma",
202+
"position_start": 1,
203+
"include_original": true
204+
}
205+
}
206+
```
207+
208+
**Parâmetros:**
209+
210+
- `enable` (bool): Se deve habilitar o embaralhamento de captions. Padrão: `false`
211+
- `count` (int): Número de variantes embaralhadas a gerar por caption. Padrão: `1`
212+
- `seed` (int): Seed para embaralhamento determinístico. Se não especificado, usa o valor global `--seed`.
213+
- `split_on` (string): Delimitador para dividir captions em tags. Opções: `comma`, `space`, `period`. Padrão: `comma`
214+
- `position_start` (int): Manter as primeiras N tags em sua posição original (útil para manter tags de assunto/estilo primeiro). Padrão: `0`
215+
- `include_original` (bool): Se deve incluir a caption original não embaralhada junto com as variantes embaralhadas. Padrão: `true`
216+
217+
**Exemplo:**
218+
219+
Com `split_on: "comma"`, `position_start: 1`, `count: 2`:
220+
221+
- Original: `"dog, running, park, sunny day"`
222+
- Resultado: `["dog, running, park, sunny day", "dog, park, sunny day, running", "dog, sunny day, running, park"]`
223+
224+
A primeira tag "dog" permanece fixa enquanto as tags restantes são embaralhadas.
225+
226+
**Notas:**
227+
228+
- O embaralhamento é aplicado durante o pré-cache de embeddings de texto, então todas as variantes são calculadas de uma vez.
229+
- Durante o treinamento, uma variante é selecionada aleatoriamente por amostra.
230+
- Se uma caption tiver menos tags que `position_start + 2`, o embaralhamento é pulado (nada significativo para embaralhar).
231+
- Quando `include_original: false` mas o embaralhamento não é possível, a original é incluída mesmo assim com um aviso.
232+
189233
### `metadata_backend`
190234

191235
- **Valores:** `discovery` | `parquet` | `huggingface`

documentation/DATALOADER.zh.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,50 @@
186186
- 适用于包含有意换行的字幕,希望保持为单一字幕的情况。
187187
- 默认值: `false`(按换行符拆分字幕)
188188

189+
### `caption_shuffle`
190+
191+
生成基于标签的字幕的确定性打乱变体,用于数据增强。这有助于模型学习标签顺序不重要,并减少对特定标签序列的过拟合。
192+
193+
**配置:**
194+
195+
```json
196+
{
197+
"caption_shuffle": {
198+
"enable": true,
199+
"count": 3,
200+
"seed": 42,
201+
"split_on": "comma",
202+
"position_start": 1,
203+
"include_original": true
204+
}
205+
}
206+
```
207+
208+
**参数:**
209+
210+
- `enable` (bool): 是否启用字幕打乱。默认: `false`
211+
- `count` (int): 每个字幕生成的打乱变体数量。默认: `1`
212+
- `seed` (int): 确定性打乱的种子。如果未指定,使用全局 `--seed` 值。
213+
- `split_on` (string): 将字幕拆分为标签的分隔符。选项: `comma``space``period`。默认: `comma`
214+
- `position_start` (int): 保持前 N 个标签在原始位置(适用于保持主题/风格标签在前)。默认: `0`
215+
- `include_original` (bool): 是否在打乱变体中包含未打乱的原始字幕。默认: `true`
216+
217+
**示例:**
218+
219+
使用 `split_on: "comma"``position_start: 1``count: 2`
220+
221+
- 原始: `"dog, running, park, sunny day"`
222+
- 结果: `["dog, running, park, sunny day", "dog, park, sunny day, running", "dog, sunny day, running, park"]`
223+
224+
第一个标签"dog"保持固定,其余标签被打乱。
225+
226+
**注意:**
227+
228+
- 打乱在文本嵌入预缓存期间应用,因此所有变体一次性计算完成。
229+
- 训练期间,每个样本随机选择一个变体。
230+
- 如果字幕的标签数少于 `position_start + 2`,则跳过打乱(没有可以有意义地打乱的内容)。
231+
-`include_original: false` 但无法打乱时,原始字幕仍会被包含并显示警告。
232+
189233
### `metadata_backend`
190234

191235
- **取值:** `discovery` | `parquet` | `huggingface`

simpletuner/helpers/data_backend/factory.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,37 @@ def _maybe_convert_pixel_edge(field_name: str) -> None:
572572
f"(id={backend['id']}) When using a huggingface data backend, caption_strategy must be set to 'huggingface'."
573573
)
574574

575+
# Validate and store caption_shuffle config
576+
caption_shuffle = backend.get("caption_shuffle", {})
577+
if caption_shuffle:
578+
if not isinstance(caption_shuffle, dict):
579+
raise ValueError(
580+
f"(id={backend['id']}) caption_shuffle must be a dictionary, got {type(caption_shuffle).__name__}"
581+
)
582+
# Validate split_on
583+
valid_split_on = {"comma", "space", "period"}
584+
split_on = caption_shuffle.get("split_on", "comma")
585+
if split_on not in valid_split_on:
586+
raise ValueError(
587+
f"(id={backend['id']}) caption_shuffle.split_on must be one of {valid_split_on}, got '{split_on}'"
588+
)
589+
# Validate count
590+
count = caption_shuffle.get("count", 1)
591+
if not isinstance(count, int) or count < 1:
592+
raise ValueError(f"(id={backend['id']}) caption_shuffle.count must be a positive integer, got {count}")
593+
# Validate position_start
594+
position_start = caption_shuffle.get("position_start", 0)
595+
if not isinstance(position_start, int) or position_start < 0:
596+
raise ValueError(
597+
f"(id={backend['id']}) caption_shuffle.position_start must be a non-negative integer, got {position_start}"
598+
)
599+
# Set seed default from args if not specified
600+
if "seed" not in caption_shuffle:
601+
global_seed = _get_arg_value(args, "seed")
602+
if global_seed is not None:
603+
caption_shuffle["seed"] = global_seed
604+
output["config"]["caption_shuffle"] = caption_shuffle
605+
575606
if not is_audio_dataset:
576607
maximum_image_size = backend.get("maximum_image_size", _get_arg_value(args, "maximum_image_size"))
577608
target_downsample_size = backend.get("target_downsample_size", _get_arg_value(args, "target_downsample_size"))

0 commit comments

Comments
 (0)