Retune the remaining appearance recipes (lighting/material/environment/mood) to structure-safe palette transfer

Same root cause and fix as palette/style: on Krea 2 the inert global axis left
these recipes silent (or, for environment's soft blur, morphing the subject into
the reference's shape). Switch each to palette-wash prep with a live shape so it
borrows the reference palette at demo strength, subject kept, render-validated.

- lighting: soft blur -> palette wash, shape 0.25 -> 0.8, study 256
- texture gentle (material): strong blur -> palette wash, shape 0.35 -> 1.0, color 0.8
- environment: soft blur -> palette wash, shape 0.7, study 256 (no more subject morph)
- mood board: soft blur -> palette wash, shape 0.15 -> 0.65, cap 0.6 -> 0.9
- ROLE_PULL_DEFAULTS lighting/material/environment/loose shapes raised to match

On a dissimilar subject all appearance recipes converge to structure-safe
palette transfer; surface-finish and scene-compositing remain out of reach of
the non-spatial conditioning (documented). 51/51 tests pass.
This commit is contained in:
Kevin Gilper
2026-07-03 09:41:16 -04:00
parent 065f766126
commit 65ba36985e
3 changed files with 36 additions and 21 deletions
+1 -1
View File
@@ -12,7 +12,7 @@
- `docs/deepstack-layers/`: an authoritative determination of what the `layers` values scale (verified from the Krea 2 model - 12 text-encoder layer taps, `hidden_states[2,5,8,...,35]`, flattened to a 30720-wide conditioning; the "deepstack" name is a documented misnomer for the separate 3 vision taps), where the specific numbers came from (adopted from the ComfyUI-ConditioningKrea2Rebalance node's defaults plus shallow=structure/deep=appearance design reasoning, with only the scalar shape/cap knobs empirically tuned - not a per-tap sweep), a reproducible table-shape analysis, and a turnkey single-tap measurement sweep (still to be run).
- `docs/deepstack-layers/` authoritative design basis (README section 3.5): the 12-layer text conditioning is UniFusion-style Layerwise Attention Pooling over every-third Qwen3-VL layer (per the Krea 2 Technical Report + the UniFusion paper), which favors early-to-middle layers with the penultimate contributing least - so the shipped tables' deep-tap spikes are shifted deeper than the design and the model's own learned weighting, with concrete source-backed improvement directions.
- `docs/deepstack-layers/` derivation harness (a reliable, targeted methodology for setting the layer values): Stage 0 extracts Krea 2's own learned per-tap weighting (`txtfusion.projector`) and scores the shipped tables against it (they only weakly track the model - motivation to re-derive); Stage 1 is a no-render selectivity harness (a `KG Conditioning Probe` node + variance-decomposition analysis, with a passing synthetic self-test) that measures what each tap encodes from controlled reference sets; Stages 2-3 (metric-scored render validation and black-box optimization of the 12-gain vector against a stated objective) are documented for a V10 render box.
- Appearance-recipe retune (render-validated on the real Krea 2 model): the `suggest the color palette` and `suggest the visual style` recipes now actually transfer the reference's palette at normal strengths - they were near-silent before. Root cause found by rendering: on Krea 2 the Qwen3-VL text encoder emits no pooled output, so the recipes' `global` (pooled) pull is inert and their whole effect was routed through a dead axis; the live lever is the token-path `shape` pull under structure-destroying image prep. Palette moves `shape` 0.05 -> 0.7; style moves `shape` 0.35 -> 0.8 with coarser prep (study 384 -> 256). Both stay subtle at low card strength and clearly borrow the reference palette by ~0.65 while keeping the subject; validated on a geometric and a natural reference. Code comments in `conditioning.py`/`recipes.py` record that appearance strength rides `shape`, not `global`, on this model.
- Appearance-recipe retune (render-validated on the real Krea 2 model): the `suggest the color palette` and `suggest the visual style` recipes now actually transfer the reference's palette at normal strengths - they were near-silent before. Root cause found by rendering: on Krea 2 the Qwen3-VL text encoder emits no pooled output, so the recipes' `global` (pooled) pull is inert and their whole effect was routed through a dead axis; the live lever is the token-path `shape` pull under structure-destroying image prep. Palette moves `shape` 0.05 -> 0.7; style moves `shape` 0.35 -> 0.8 with coarser prep (study 384 -> 256). Both stay subtle at low card strength and clearly borrow the reference palette by ~0.65 while keeping the subject; validated on a geometric and a natural reference. Code comments in `conditioning.py`/`recipes.py` record that appearance strength rides `shape`, not `global`, on this model. The same fix was applied and render-validated for the other appearance recipes (`copy lighting and mood`, `suggest material or texture`, `use the background/setting`, `mood board only`): each now uses palette-wash prep with a live `shape` so it transfers the reference palette at normal strength with the subject kept, instead of silently doing nothing (or, for the background/environment recipe, morphing the subject toward the reference's shape). On a subject unlike the reference these recipes all converge to structure-safe palette transfer; painting the reference's finish onto the subject's surface or compositing its scene behind the subject is a known limitation of the non-spatial conditioning, not a tuning gap. Structural recipes (subject/pose/layout/framing/shape) are unchanged.
- Stack: `Balance strong cards` - an optional per-phase budget on summed departure from neutral, so several hot cards degrade gracefully instead of fighting.
- Stack: `Reuse image studies` - a content-keyed cache of the base encode and ingredient deltas; re-runs that change only strengths, direction, timing, or balance skip every encoder pass.
- Stack: two new outputs - `stack_report` (plain-language account of caps, curves, guard actions, balance, timing, and encoder pass counts) and `prepared_references` (contact sheet of exactly what the vision encoder studied).
+15 -7
View File
@@ -52,10 +52,14 @@ QUICK_RECIPES.update({
},
"environment": {
"role": "environment",
"treatment": "soft blur",
# Render-tuned 2026-07-03: soft blur pulled the reference's FORM onto the
# subject (a bowl became a jar) - the conditioning is non-spatial, so it
# cannot place a scene *behind* the subject. Palette wash keeps it
# structure-safe: it borrows the setting's palette/mood, subject intact.
"treatment": "palette wash",
"color": 1.0,
"detail": 0.6,
"study": "stack",
"detail": 0.3,
"study": "256",
"framing": "stack",
"subject": "avoid",
"early": 1.1,
@@ -84,17 +88,21 @@ QUICK_RECIPES.update({
},
"mood board": {
"role": "loose",
"treatment": "soft blur",
# Render-tuned 2026-07-03: palette wash + a live shape so the loose vibe
# actually reads a gentle borrowed palette (old shape 0.15 / cap 0.6 on
# the inert global axis showed nothing). Kept soft via a lower shape than
# palette and a modest cap.
"treatment": "palette wash",
"color": 1.0,
"detail": 0.35,
"detail": 0.2,
"study": "256",
"framing": "stack",
"subject": "avoid",
"early": 0.8,
"late": 0.8,
"guard": False,
"cap": 0.6,
"shape": 0.15,
"cap": 0.9,
"shape": 0.65,
"global": 0.7,
"layers": STYLE_LAYER_PULL,
},
+20 -13
View File
@@ -26,10 +26,10 @@ ROLE_PULL_DEFAULTS = {
"composition": {"shape": 1.25, "global": 0.35},
"framing": {"shape": 0.9, "global": 0.25},
"identity": {"shape": 1.0, "global": 1.0},
"environment": {"shape": 0.65, "global": 0.8},
"lighting": {"shape": 0.25, "global": 1.25},
"material": {"shape": 0.18, "global": 1.2},
"loose": {"shape": 0.12, "global": 0.65},
"environment": {"shape": 0.7, "global": 0.8},
"lighting": {"shape": 0.8, "global": 1.25},
"material": {"shape": 1.0, "global": 1.2},
"loose": {"shape": 0.65, "global": 0.65},
"shape only": {"shape": 1.2, "global": 0.05},
"text/logo safe": {"shape": 0.08, "global": 0.0},
}
@@ -115,17 +115,19 @@ QUICK_RECIPES = {
},
"lighting": {
"role": "lighting",
"treatment": "soft blur",
"treatment": "palette wash",
"color": 0.85,
"detail": 0.55,
"study": "stack",
# Render-tuned 2026-07-03: soft blur leaked the reference's form onto the
# subject; palette wash + live shape borrows the light/tone palette safely.
"detail": 0.15,
"study": "256",
"framing": "stack",
"subject": "avoid",
"early": 1.0,
"late": 0.55,
"guard": False,
"cap": 1.25,
"shape": 0.25,
"shape": 0.8,
"global": 1.3,
"layers": LIGHTING_LAYER_PULL,
},
@@ -152,17 +154,22 @@ QUICK_RECIPES = {
},
"texture gentle": {
"role": "material",
"treatment": "strong blur",
"color": 0.65,
"detail": 0.05,
"study": "stack",
"treatment": "palette wash",
# Render-tuned 2026-07-03: strong blur at a live shape leaked the whole
# reference into frame; palette wash keeps it structure-safe. Material's
# layer table has weaker deep-tap spikes than style/palette, so it needs
# a higher shape (1.0) to fire at demo strength. Transfers the reference's
# surface/finish palette - literal texture-on-surface is not reachable.
"color": 0.8,
"detail": 0.1,
"study": "256",
"framing": "stack",
"subject": "avoid",
"early": 0.5,
"late": 0.75,
"guard": False,
"cap": 0.95,
"shape": 0.35,
"shape": 1.0,
"global": 1.55,
"layers": MATERIAL_LAYER_PULL,
},