Update example to cover some common issues
This commit is contained in:
@@ -101,6 +101,17 @@ conditioning, preferred for all new models over the older `PromptEmbeds`:
|
|||||||
natural length and pad to the batch max only at the model call
|
natural length and pad to the batch max only at the model call
|
||||||
(`src/pipeline.py:pad_prompt_embeds`) — caches stay small and any prompts
|
(`src/pipeline.py:pad_prompt_embeds`) — caches stay small and any prompts
|
||||||
can share a batch.
|
can share a batch.
|
||||||
|
- **Keep each per-item tensor 2D `(L, D)`.** This is a hard requirement, not a
|
||||||
|
convention: `BaseModel.predict_noise` infers the text batch size from the
|
||||||
|
embed list, and it only counts the list as one-per-item when each tensor is
|
||||||
|
2D (`len(text_embeds[0].shape) == 2`). A 3D per-item tensor is read as an
|
||||||
|
already-batched `(B, L, D)` and its *first axis* is taken as the batch size —
|
||||||
|
so a single 3D prompt of length `L` looks like a batch of `L`, and training
|
||||||
|
dies with *"Batch size of latents must be the same or half the batch size of
|
||||||
|
text embeddings."* If your conditioning has an extra axis (e.g. a stack of N
|
||||||
|
encoder layers, giving `(L, N, D)`), **flatten it into the feature axis**
|
||||||
|
(`(L, N*D)`) in `get_prompt_embeds` and **restore it** (`reshape(B, Lt, N, D)`)
|
||||||
|
in `get_noise_prediction` / the pipeline, right before the model call.
|
||||||
- Add as many keys as your model needs (`pooled_embeds`, image features, …).
|
- Add as many keys as your model needs (`pooled_embeds`, image features, …).
|
||||||
- Keys that must not be dtype-cast (token ids, masks) go in
|
- Keys that must not be dtype-cast (token ids, masks) go in
|
||||||
`embeds.frozen_dtype_keys`.
|
`embeds.frozen_dtype_keys`.
|
||||||
@@ -119,6 +130,21 @@ With `train.gradient_checkpointing: true`, `BaseSDTrainProcess` calls
|
|||||||
set **and** `torch.is_grad_enabled()` is true — never gate on `self.training`.
|
set **and** `torch.is_grad_enabled()` is true — never gate on `self.training`.
|
||||||
See `src/model.py` for the full pattern and rationale.
|
See `src/model.py` for the full pattern and rationale.
|
||||||
|
|
||||||
|
## Quantization
|
||||||
|
|
||||||
|
With `quantize: true`, `quantize_model` swaps every `nn.Linear` for an
|
||||||
|
`optimum.quanto` quantized one. Their matmul kernel **only accepts 2D or 3D
|
||||||
|
activations** (`assert activations.ndim in (2, 3)`) — a `Linear` you feed a 4D
|
||||||
|
tensor works fine in bf16 but throws once quantized. If your network applies a
|
||||||
|
`Linear` over a 4D tensor (e.g. projecting a `(B, L, D, N)` layer axis),
|
||||||
|
reshape to 3D for the call and back afterwards.
|
||||||
|
|
||||||
|
Also watch out for **slow bf16 kernels on vendored components**: `Conv3d` has no
|
||||||
|
fast cuDNN bf16 path (it falls back to a slow one). If a frozen sub-model carries
|
||||||
|
a `Conv3d` you don't actually run — e.g. a vision tower's patch embed on a VL
|
||||||
|
text encoder — drop it (`text_encoder.model.visual = None`) to skip loading it;
|
||||||
|
if you must run one, consider running that component in fp16/fp32.
|
||||||
|
|
||||||
## Adapting this template
|
## Adapting this template
|
||||||
|
|
||||||
### Editing / instruct model (image in, image out)
|
### Editing / instruct model (image in, image out)
|
||||||
|
|||||||
@@ -330,6 +330,15 @@ class ExampleModel(BaseModel):
|
|||||||
batch max is deferred to get_noise_prediction / the pipeline,
|
batch max is deferred to get_noise_prediction / the pipeline,
|
||||||
which keeps caches small and lets any prompts share a batch.
|
which keeps caches small and lets any prompts share a batch.
|
||||||
|
|
||||||
|
Each per-prompt tensor MUST be 2D ``(L, D)`` -- BaseModel infers the
|
||||||
|
text batch size from the list and only treats it as one-per-prompt
|
||||||
|
when the tensors are 2D; a 3D per-prompt tensor is misread as an
|
||||||
|
already-batched ``(B, L, D)`` and training fails with a latents-vs-
|
||||||
|
text batch-size mismatch. If your conditioning has an extra axis
|
||||||
|
(e.g. N stacked encoder layers -> ``(L, N, D)``), flatten it here
|
||||||
|
(``(L, N*D)``) and restore it (``reshape(B, Lt, N, D)``) at the
|
||||||
|
model call.
|
||||||
|
|
||||||
You can store any number of keys (pooled embeds, image features,
|
You can store any number of keys (pooled embeds, image features,
|
||||||
...). If a key must keep its dtype when everything else is cast
|
...). If a key must keep its dtype when everything else is cast
|
||||||
(masks, token ids), list it in ``embeds.frozen_dtype_keys``.
|
(masks, token ids), list it in ``embeds.frozen_dtype_keys``.
|
||||||
|
|||||||
Reference in New Issue
Block a user